-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathproblem186.odin
95 lines (83 loc) · 2.32 KB
/
problem186.odin
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
package main
import "core:fmt"
Partition :: struct {
subset_indices: map[int]int,
subsets: [][dynamic]int,
}
new_partition :: proc(singletons: [dynamic]int) -> Partition {
indices := make(map[int]int)
subsets := make([][dynamic]int, len(singletons))
for element, index in singletons {
indices[element] = index
subsets[index] = [dynamic]int{element}
}
return Partition{indices, subsets}
}
subset_length :: proc(partition: ^Partition, element: int) -> int {
index := partition.subset_indices[element]
return len(partition.subsets[index])
}
merge_subsets :: proc(partition: ^Partition, a: int, b: int) {
a_index := partition.subset_indices[a]
b_index := partition.subset_indices[b]
if a_index == b_index {
return
}
if len(partition.subsets[a_index]) < len(partition.subsets[b_index]) {
merge_subsets(partition, b, a)
return
}
append(&partition.subsets[a_index], ..partition.subsets[b_index][:])
for elem in partition.subsets[b_index] {
partition.subset_indices[elem] = a_index
}
}
LaggedFibonacciState :: struct {
array: [55]int,
index: int,
}
new_lagged_fibonacci_state :: proc() -> LaggedFibonacciState {
state_array: [55]int
for i in 1..<56 {
state_array[i - 1] = (100_003 - 200_003 * i + 300_007 * i * i * i) % 1_000_000
}
return LaggedFibonacciState{state_array, 0}
}
actual_index :: proc(state: ^LaggedFibonacciState, offset: int) -> int {
return (state.index + offset) %% 55
}
next_elem :: proc(state: ^LaggedFibonacciState) -> int {
current_value := state.array[actual_index(state, 0)]
state.array[actual_index(state, 0)] = (
state.array[actual_index(state, -24)] + state.array[actual_index(state, -55)]
) % 1_000_000
state.index += 1
return current_value
}
all_callers :: proc() -> [dynamic]int {
callers := make([dynamic]int, 1_000_000)
for i in 0..<1_000_000 {
callers[i] = i
}
return callers
}
main :: proc() {
callers := all_callers()
cohorts := new_partition(all_callers())
state := new_lagged_fibonacci_state()
prime_minister := 524_287
index := 0
for {
caller := next_elem(&state)
callee := next_elem(&state)
if caller == callee {
continue
}
merge_subsets(&cohorts, caller, callee)
if subset_length(&cohorts, prime_minister) >= 990_000 {
fmt.println(index + 1)
break
}
index += 1
}
}