# rotate 90 deg r ← ⍉≡⇌ # 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 ) # 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⊞=. °⊏ # 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! NewP ← ( # get the next three prime candidates (lower right is odd square) ⊃((+5+∩×₄⊃×₂ⁿ₂) | (+3+⊃×₆(×4ⁿ2)) | (+7+⊃×₁₀(×4ⁿ2)) ) ++∩₃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 ) # 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...