Advertisement
Guest User

Primality in HPR + macros

a guest
Nov 9th, 2015
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.56 KB | None | 0 0
  1. // Primality tester in HPR + macros
  2. // Takes input as the unary version of a list [p, p-1, ..., 2, 1]
  3. // For example, input 4 is encoded as 111101110110100
  4. // Prints 1 is p is a prime, otherwise an empty line
  5.  
  6. // No numbers
  7. def no_nums 0 #(-)()
  8.  
  9. // No non-empty lists
  10. def no_list 0 #(*)()
  11.  
  12. // Delete numbers
  13. def del_nums 0 !(-)(<no_nums>)
  14.  
  15. // Delete lists
  16. def del_list 0 #(<del_nums>)()
  17.  
  18. // Do until no change (optimized)
  19. def fix 1 !({0})(#({0})())
  20.  
  21. // Do until condition holds
  22. def until 2 !({1})({0})
  23.  
  24. // True condition / empty environment
  25. def true/empty 0 <del_nums><del_list>
  26.  
  27. // Logical not of condition
  28. def not 1 <until>({0},<true/empty>)
  29.  
  30. // Empty or revert
  31. def bool 1 <not>(<not>({0}))
  32.  
  33. // Logical or of two conditions
  34. def or 2 <bool>({0}){1}
  35.  
  36. // Splat list to environment
  37. def splat 0 #(<until>(<no_list>,*)<del_list>)(<del_nums>)
  38.  
  39. // Take all up to maximum
  40. def upto_max 0 <del_nums><fix>(-<splat>)
  41.  
  42. // Take only maximum
  43. def max 0 <upto_max>#(-)(<del_list>)
  44.  
  45. // Head is maximal
  46. def max_head 0 <del_nums>#(*)(<max>)<del_list>
  47.  
  48. // Head of list is in evironment
  49. def has_head 0 #(*)()<del_list>
  50.  
  51. // Add first element without popping list
  52. def peek 0 #(*<del_list>)(<del_nums>)
  53.  
  54. // Only the number zero
  55. def zero 0 <del_nums>*<del_list><until>(-,-)
  56.  
  57. // Only the number one
  58. def one 0 <del_nums>*<del_list><until>(--,-)
  59.  
  60. // Head is 1
  61. def is_one 0 <del_nums>#(<one>)(*<del_list>)
  62.  
  63. // Delete one number from the environment that's also in the list:
  64. // Rotate until head is in the environment, then delete it using symmetric differences
  65. def del_any 0 #(#(<until>(<has_head>,$)<del_nums>*)()<del_list>)(<del_nums>)
  66.  
  67. // Delete all but zero
  68. def del_pos 0 <until>(-<del_list>,<del_any>)
  69.  
  70. // The number zero is in the environment
  71. def has_zero 0 <not>(<del_pos><del_list>)
  72.  
  73. // The environment has a positive value strictly below head (doesn't work for maximal head):
  74. // Rotate list (at least once) until head is found in environment
  75. // or is maximal, check that it's not maximal
  76. def has_below 0 $<until>(<or>(<has_head>,<max_head>),$)<not>(<max_head>)
  77.  
  78. // Head divides maximum: Take maximum value, then keep taking the head value and
  79. // decrementing (at least once) until the lowest value reaches 0, stop when there's only 0 or
  80. // something between the head value and 0, check that it's the former
  81. def head_divides 0 <max><until>(<or>(<has_below>,-<del_list>),<peek>-<until>(<has_zero>,-))-<del_list>
  82.  
  83. // Main program: rotate until head divides maximum, then check that head equals 1
  84. $<until>(<or>(<is_one>,<head_divides>),$)<not>(<is_one>)<one>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement