-
Notifications
You must be signed in to change notification settings - Fork 0
/
p014.jl
96 lines (73 loc) · 2.4 KB
/
p014.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
#=
The following iterative sequence is defined for the set of positive integers:
n → n/2 (n is even)
n → 3n + 1 (n is odd)
Using the rule above and starting with 13, we generate the following sequence:
13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.
Which starting number, under one million, produces the longest chain?
NOTE: Once the chain starts the terms are allowed to go above one million.
=#
# AKA the 3N+1 problem
# --- it's not known for sure whether some sequence goes on forever (presumably by growing to infinity... are infinite loops possible?)
#NOTE: all this dynamic programming stuff was probably unnecessary, could brute force it fast enough
# (esp. since the longest sequence is only 525 terms)
global N = 10000000 # 1e7>>1e6, make this as large as it needs to be
global sl = zeros(Int, N) # sl: sequence length
function collatz(num::Int)
# returns the length of the Collatz sequence for a given starting number
count = 1
n = num
while n != 1
if n%2 == 0 # even
n = Int(n/2)
else # odd
n = 3*n + 1
end
count += 1
end
return count
end
# DYNAMIC PROGRAMMING
function collatz_dynamic(num, N)
# if already calculated, just look up the sequence length
if num < N
if sl[num] > 0
return sl[num]
else
return collatz(num)
end
else
return collatz(num)
end
end
# RECURSION
function collatz_recursive(num, N)
if num == 1
this_sl = 1
else
if num%2 == 0 # even
next = Int(num/2)
else # odd
next = 3*num + 1
end
if next < N
this_sl = 1 + collatz_recursive(next, N) # RECURSION
else
this_sl = 1 + collatz(next) # can't look it up
end
end
sl[num] = this_sl # DYNAMIC
return this_sl
end
# recursion check the length of first 1 million Collatz sequences
for i=1:999999
dummy = collatz_recursive(i, N)
end
longest = maximum(sl)
print("The longest Collatz (3N+1) sequence with starting number <1e6 is: $longest \n")
startingnum = findall(sl .== 525)
print("starting number of the sequence is $startingnum \n plotting... (?) \n")
# PLOT THE SOLUTION
using UnicodePlots
lineplot(1:1000000, sl[1:1000000], title="Example", name="Collatz sequences (3N+1 problem)", xlabel="starting number", ylabel="sequence length")