-
Notifications
You must be signed in to change notification settings - Fork 0
/
day12_part2.jakt
155 lines (126 loc) · 4.04 KB
/
day12_part2.jakt
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/// Expect:
/// - output: "1000000000508\n"
import reader
import utility
struct Rule {
pattern: [bool]
result: bool
}
function main() {
mut rules: [Rule] = []
mut initial_state: [bool] = []
mut state_offset = -4
for (i, line) in utility::enumerate(reader::lines_string(day: 12).iterator()) {
if i == 0 {
let state_string = line.replace(replace: "initial state: ", with: "")
initial_state = [false;state_string.length()+8]
mut offset = 4
for char_ in utility::string_to_char_array(state_string) {
initial_state[offset] = match char_ {
b'#' => true
else => false
}
offset++
}
} else {
let line_parts = line.split(' ')
mut current_pattern: [bool] = []
for char_ in utility::string_to_char_array(line_parts[0]) {
current_pattern.push(match char_ {
b'#' => true
else => false
})
}
rules.push(Rule(
pattern: current_pattern
result: match line_parts[2].byte_at(0) {
b'#' => true
else => false
}
))
}
}
mut current_state = initial_state
mut count = 0
while true {
let (get_current_state, get_state_offest) = apply_rules(current_state, state_offset, &rules)
if state_equal(previous_state: current_state, current_state: get_current_state) {
let remaining = 50000000000 - count
println("{}", score_state(current_state, state_offset: state_offset+remaining))
break
}
current_state = get_current_state
state_offset = get_state_offest
count++
}
}
function state_equal(previous_state: &[bool], current_state: &[bool]) -> bool {
if previous_state.size() != current_state.size() {
return false
}
for i in 4..(current_state.size() - 4) {
if current_state[i] != previous_state[i] {
return false
}
}
return true
}
function apply_rules(current_state: [bool], mut state_offset: i64, rules: &[Rule]) throws -> ([bool], i64) {
mut new_state: [bool] = [false;current_state.size()*3]
mut first_true = new_state.size()
mut last_true = 0uz
for i in 0..current_state.size() {
for rule in *rules {
if i + rule.pattern.size() > current_state.size() {
continue
}
mut found = true
for j in i..(i + rule.pattern.size()) {
if current_state[j] != rule.pattern[j-i] {
found = false
break
}
}
if found {
let mid_point = i + (rule.pattern.size() / 2)
new_state[current_state.size() + mid_point] = rule.result
if rule.result and mid_point < first_true {
first_true = mid_point
} else if rule.result and mid_point > last_true {
last_true = mid_point
}
}
}
}
state_offset += first_true as! i64
state_offset -= 4
return (new_state[(current_state.size() + first_true - 4)..(current_state.size() + last_true + 5)].to_array(), state_offset)
}
function score_state(current_state: [bool], state_offset: i64) -> i64 {
mut total = 0
for i in 0..current_state.size() {
if current_state[i] {
total += (i as !i64 + state_offset)
}
}
return total
}
function print_state_base(initial_state: [bool], current_state: [bool]) {
for i in 4..(initial_state.size()-4) {
if initial_state[i] {
print("#")
} else {
print(".")
}
}
println("")
for i in 4..(current_state.size() - 4) {
if current_state[i] {
print("#")
} else {
print(".")
}
}
println("")
println("")
}