-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathproblem118.jl
117 lines (104 loc) · 2.29 KB
/
problem118.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
PRIME_UPPER = 99999999
SIEVE = [true for _ in 1:PRIME_UPPER]
function isprimetest(x)
if x < 2
false
else
for i = 2 : x ÷ 2
if x % i == 0
return false
end
end
true
end
end
function isprime(x)
if x < 2
false
elseif x < PRIME_UPPER
SIEVE[x]
else
isprimetest(x)
end
end
tonumber(lst) = reduce((acc, x) -> 10 * acc + x, lst, init=0)
# Heap's algorithm (https://en.wikipedia.org/wiki/Heap%27s_algorithm)
function _permutations(arr, k, results)
if k == 1
push!(results, copy(arr))
else
_permutations(arr, k - 1, results)
for i = 1:k-1
if k % 2 == 0
arr[[i,k]] = arr[[k,i]]
else
arr[[1,k]] = arr[[k,1]]
end
_permutations(arr, k - 1, results)
end
end
nothing
end
function permutations(arr)
results = []
_permutations(arr, length(arr), results)
results
end
function countsolutions(lst)
if length(lst) > 1 && sum(lst) % 3 == 0
return 0 # All permutations will be divisible by 3
end
count(x -> isprime(tonumber(x)), permutations(lst))
end
function _subsets(lst, idx)
if idx > length(lst)
[[]]
else
rest = _subsets(lst, idx + 1)
[rest ; map(xs -> [lst[idx] ; xs], rest)]
end
end
subsets(lst) = _subsets(lst, 1)
function partitions(lst)
if isempty(lst)
[[]]
else
results = []
for sub = subsets(lst[2:end])
push!(sub, lst[1])
remaining = sort(collect(setdiff(Set(lst), Set(sub))))
for xs = partitions(remaining)
push!(results, [[sub];xs])
end
end
results
end
end
function run(digits)
count = 0
for part = partitions(collect(1:digits))
inner = 1
for xs = part
tmp = countsolutions(xs)
if tmp == 0
inner = 0
break
end
inner = inner * tmp
end
count = count + inner
end
count
end
# Run the sieve
SIEVE[1] = false
for i = 1:PRIME_UPPER
if SIEVE[i]
j = i + i
while j < PRIME_UPPER
SIEVE[j] = false
j = j + i
end
end
end
println(run(9))