diff --git a/58/main.ua b/58/main.ua index dc73e57..4924c6a 100644 --- a/58/main.ua +++ b/58/main.ua @@ -1,66 +1,12 @@ -# rotate 90 deg -r ← ⍉≡⇌ +# project euler 58 -# create spiral numbers with n rows and cols -# spiral ? n -s ← ( - +1⇡ⁿ2 # create n^2 numbers - ⊸( - ⊸(-1×2√/↥) # t*2 - 1, where t = sqrt(max(range(n^2))) = n - ⌈÷2↙ # create [1 1 2 2 3 ...] until sum is n^2 - ) - ⊜□˜▽+1°⊏ # successively take 1, 1, 2, 2, 3, ... until all n^2 numbers taken - ⇌/◇(˜⊂r)⍜⊢⍚¤ # combine all taken with rotating array to form spiral -) +p ← =1⧻°/× +Sieve ← ▽⊸≡p+2⇡ -# memoized recursive version of s -σ ← |1 memo( - ⨬(⊂⊸(++1⇡∩/↥⊃△(⊢⊢)) r σ-1 - | ⋅(¤[1]) # base-case - )⊸=1 -) - -# generates each diagonal of spiral array -Σ ← +1\+ +¤[2 4 6]×8 ⇡⌊÷2 - -# get numbers on diagonal -d ← ⊜°¤ ↥⊸r⊞=. °⊏ +Primes ← Sieve 37417 # is_prime(n) ? n -p ← =1⧻°/× - -┌─╴test - p ↚ ⊜(⊜⋕⊸≠@\s)⊸≠@\n - ⍤⤙≍ s 7 p $ 37 36 35 34 33 32 31 - $ 38 17 16 15 14 13 30 - $ 39 18 5 4 3 12 29 - $ 40 19 6 1 2 11 28 - $ 41 20 7 8 9 10 27 - $ 42 21 22 23 24 25 26 - $ 43 44 45 46 47 48 49 -└─╴ - -Sol! ← +1×2⧻⍢(+2⟜(÷⊃⧻/+≡p ^0)|⋅(>0.1)) ⊙1 - -# Sol!(d s) 3 # too slow -# (σ -1×2) == s -# Sol!(d σ -1×2) 3 # too slow (too much memory usage) -# Sol!(⊂˜↯1÷2-1⟜(♭ Σ)) 3 # still too slow - -# okay... let's do it mathematically from scratch: - -# primes on diagonals/number of elements on diagonals -# Chance ← ÷-1×2⟜( -# ⊃((+5+∩×₄⊃×₂ⁿ₂)⇡ -# | (+3+⊃×₆(×4ⁿ2))⇡ -# | (+7+⊃×₁₀(×4ⁿ2))⇡ -# ) ⌊÷2 -# /+≡p⊂⊂ -# ) -# -# ⍢(+2|>0.1 Chance) 3 - -# that solved it in 4 minutes (with p memoized)... too slow! +# p ← ⨬(=|1)⊸=¯1⊸(⍣⊢¯1▽⤚(=0≡◿) Primes ¤) NewP ← ( # get the next three prime candidates (lower right is odd square) @@ -71,18 +17,18 @@ NewP ← ( ++∩₃p # count how many are prime (0-3) ) -# initial values are: -# - 5: the amount of numbers so far; 1, 3, 5, 7, 9 (counter for diagonal) -# - NewP.: = 3, since 3, 5, 7 are prime (counter for primes on diagonal) -# - 0: current NewP generation. NewP 0 is 3 (see above) -5 NewP. 0 -⍢(+4 ⊙+ ⊙⊙(⊸NewP+1) # add 4 for new corners, generate NewP(n+1) -| >0.1 ÷ # check prime ratio +Sol ← ( + # initial values are: + # - 5: the amount of numbers so far; 1, 3, 5, 7, 9 (counter for diagonal) + # - NewP.: = 3, since 3, 5, 7 are prime (counter for primes on diagonal) + # - 0: current NewP generation. NewP 0 is 3 (see above) + 5 NewP. 0 + ⍢(+4 ⊙+ ⊙⊙(⊸NewP+1) # add 4 for new corners, generate NewP(n+1) + | >0.1 ÷ # check prime ratio + ) + # discard number of primes and diagonal values, + # scale generation up to side length + # newp gen 0 -> 0*2 + 3 = side length 3 + # newp gen 1 -> 1*2 + 3 = side length 5, ... + ⋅⋅(+3×2) ) -# discard number of primes and diagonal values, -# scale generation up to side length -# newp gen 0 -> 0*2 + 3 = side length 3 -# newp gen 1 -> 1*2 + 3 = side length 5, ... -⋅⋅(+3×2) - -# that's a 240x speedup, from 4 minutes to 1 second. we can go faster...