Advertisement
enfiskutensykkel

Makefile Sieve of Eratosthenes

Jun 19th, 2019
1,005
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Make 2.05 KB | None | 0 0
  1. ### List operators
  2. slice = $(wordlist 2,$(words $1),$1)
  3. repl = $(if $(call eq,$(words $4),$1),$3,$(call repl,$1,$2,$3 $2,$(words $4) $4))
  4. rotate = $(call slice,$1) $(firstword $1)
  5. map = $(if $2,$(call map,$1,$(call slice,$2),$3,$4 $(call $1,$3,$(firstword $2),$4)),$4)
  6. fold = $(if $2,$(call fold,$1,$(call slice,$2),$(call $1,$3,$(firstword $2))),$3)
  7. zip = $(if $2,$(call zip,$1,$(call slice,$2),$(call rotate,$3),$4 $(call $1,$(firstword $2),$(firstword $3))),$4)
  8.  
  9. ### Arithmetic operators
  10. inc = $(words $(call repl,$1,_) _)
  11. max = $(words $(subst __,_,$(join $(call repl,$1,_),$(call repl,$2,_))))
  12.  
  13. eq = $(filter $1,$2)
  14. gt = $(filter-out $2,$(call max,$1,$2))
  15. gte = $(call gt,$1,$2)$(call eq,$1,$2)
  16.  
  17. add = $(words $(call repl,$1,_) $(call repl,$2,_))
  18. sub = $(words $(filter-out __,$(join $(call repl,$1,_),$(call repl,$2,_))))
  19. mul = $(words $(call repl,$1,$(call repl,$2,_)))
  20. div = $(if $(call gte,$1,$2),$(call add,1,$(call div,$(call sub,$1,$2),$2)),0)
  21. double = $(call mul,2,$1)
  22.  
  23. isqrt_cand = $(if $(call gt,$(call mul,$(call inc,$1),$(call inc,$1)),$2),$1,$(call inc,$1))
  24. isqrt = $(if $(call gte,$1,2),$(call isqrt_cand,$(call double,$(call isqrt,$(call div,$1,4))),$1),$1)
  25.  
  26. ### Main program body
  27. head = $(firstword $2)
  28. count = $(words $3)
  29.  
  30. # Repeat function N times
  31. loop = $(call fold,$2,$(call map,count,$(call repl,$1,_)),$3)
  32.  
  33. # Skip into a list
  34. skip = $(call loop,$1,slice,$2)
  35.  
  36. # Eliminate multiples of a number (sieve)
  37. cycle = $(call slice,$(call repl,$1,_)) 0
  38. eliminate = $(if $(call eq,$2,0),0,$1)
  39. sieve = $(call zip,head,$(call repl,$(call double,$1),_),$2) $(call zip,eliminate,$(call skip,$(call double,$1),$2),$(call loop,$(call sub,$1,1),rotate,$(call cycle,$1)))
  40.  
  41. # Helper function to call our sieve function
  42. dispatch = $(if $(call gt,$2,1),$(call sieve,$2,$1),$1)
  43.  
  44. ### Entry point
  45. n := 100
  46. s := $(call isqrt,$(n))
  47. numbers := $(call map,count,$(call repl,$(n),_))
  48. primes := $(filter-out 0,$(call skip,2,$(call loop,$(s),dispatch,$(numbers))))
  49.  
  50. print = $(info $2)
  51.  
  52. ### Targets
  53. .PHONY: all
  54. all: ; $(call map,print,$(primes))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement