Skip to content

Commit 1d45355

Browse files
committed
[Day 24] Some experiments
1 parent acd0b09 commit 1d45355

File tree

1 file changed

+172
-0
lines changed

1 file changed

+172
-0
lines changed

src/day24.jl

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,178 @@ using AdventOfCode2024
44

55

66
function day24(input::String = readInput(joinpath(@__DIR__, "..", "data", "day24.txt")))
7+
state, rules = parse_input(input)
8+
maxnumber = maximum(max(_to_number(k[2]), _to_number(k[3]), _to_number(k[4])) for k rules)
9+
orig_state = copy(state)
10+
run!(state, rules)
11+
p1 = result_to_number(state, maxnumber)
12+
13+
wrong_indices = Int[]
14+
# for index ∈ 0:maxnumber-1
15+
# state = copy(orig_state)
16+
# init!(state, maxnumber-1, index, 1, 0)
17+
# run!(state, rules)
18+
# result = result_to_number(state, maxnumber)
19+
# expected = 1 << index
20+
# # println("index: $index, result = $result, expected = $expected")
21+
# if result != expected
22+
# push!(wrong_indices, index)
23+
# end
24+
# end
25+
for index 0:maxnumber-1
26+
if !check_adder_at_index(orig_state, rules, index, maxnumber)
27+
push!(wrong_indices, index)
28+
end
29+
end
30+
31+
current_record = 4
32+
swapps = String[]
33+
swapps_inds = []
34+
for i 1:size(rules, 1)
35+
current_record == 0 && break
36+
for j i+1:size(rules, 1)
37+
first, second = swap_outputs!(rules, i , j)
38+
if less_wrong_indices(orig_state, rules, maxnumber, current_record)
39+
println("swapped outputs = $first, $second, current_record = $current_record")
40+
push!(swapps, first)
41+
push!(swapps, second)
42+
push!(swapps_inds, (i, j))
43+
current_record -= 1
44+
current_record == 0 && break
45+
else
46+
swap_outputs!(rules, i, j)
47+
end
48+
end
49+
end
50+
return swapps, swapps_inds
51+
52+
# return less_wrong_indices(orig_state, rules, maxnumber, 4)
53+
54+
# index = 5
55+
# rule_indices = collect(get_rule_indices(rules, index))
56+
# for i ∈ 1:size(rule_indices, 1)
57+
# for j ∈ i+1:size(rule_indices, 1)
58+
# first, second = swap_outputs!(rules, i, j)
59+
# if check_adder_at_index(orig_state, rules, maxnumber, index)
60+
# println("YES")
61+
# println("first = $first, second = $second")
62+
# else
63+
# swap_outputs!(rules, i, j)
64+
# end
65+
# end
66+
# end
67+
68+
end
69+
70+
_to_id(number::Int, pre::String) = pre * lpad(number, 2, '0')
71+
# _to_number(id::String) = tryparse(Int, id[2:end])
72+
_to_number(id::String) = isdigit(id[end]) ? parse(Int, id[2:end]) : 0
73+
74+
function less_wrong_indices(state, rules, maxnumber, prevrecord)
75+
wrong_indices = Int[]
76+
for index 0:maxnumber-1
77+
if !check_adder_at_index(state, rules, index, maxnumber)
78+
push!(wrong_indices, index)
79+
length(wrong_indices) >= prevrecord && return false
80+
end
81+
end
82+
return true
83+
end
84+
85+
function swap_outputs!(rules, i, j)
86+
first = rules[i][end]
87+
second = rules[j][end]
88+
rules[i] = (rules[i][1], rules[i][2], rules[i][3], second)
89+
rules[j] = (rules[j][1], rules[j][2], rules[j][3], first)
90+
return first, second
91+
end
92+
93+
function get_rule_indices(rules, ind)
94+
indices = Set{Int}()
95+
queue = [_to_id(ind, "x"), _to_id(ind, "y")]
96+
while !isempty(queue)
97+
elem = popfirst!(queue)
98+
for (i, rule) enumerate(rules)
99+
if rule[2] == elem || rule[3] == elem
100+
push!(indices, i)
101+
if rule[4] queue
102+
push!(queue, rule[4])
103+
end
104+
end
105+
end
106+
end
107+
return indices
108+
end
109+
110+
function check_adder_at_index(state, rules, index, maxnumber)
111+
s = copy(state)
112+
init!(s, maxnumber-1, index, 1, 0)
113+
run!(s, rules)
114+
return result_to_number(s, maxnumber) == (1 << index)
115+
end
116+
117+
function init!(state, last, index, x, y)
118+
for i 0:last
119+
if i == index
120+
state[_to_id(i, "x")] = x
121+
state[_to_id(i, "y")] = y
122+
else
123+
state[_to_id(i, "x")] = false
124+
state[_to_id(i, "y")] = false
125+
end
126+
end
127+
end
128+
129+
function result_to_number(state, maxnumber)
130+
number = 0
131+
for i 0:maxnumber
132+
!haskey(state, _to_id(i, "z")) && return -1
133+
number += state[_to_id(i, "z")] * 2^i
134+
end
135+
return number
136+
end
137+
138+
function parse_input(input)
139+
inits, rules = split(input, "\n\n")
140+
init = Dict{String,Bool}()
141+
reg1 = r"(.+):\s(\d)"
142+
for line split(rstrip(inits), "\n")
143+
m = match(reg1, line)
144+
if m.captures[2] == "1"
145+
init[m.captures[1]] = true
146+
else
147+
init[m.captures[1]] = false
148+
end
149+
end
150+
reg2 = r"([a-z0-9]+)\s+(AND|OR|XOR)\s+([a-z0-9]+)\s+->\s+([a-z0-9]+)"
151+
rule = Tuple{String,String,String,String}[]
152+
for line split(rstrip(rules), "\n")
153+
m = match(reg2, line)
154+
push!(rule, (string(m.captures[2]), string(m.captures[1]), string(m.captures[3]), string(m.captures[4])))
155+
end
156+
return init, rule
157+
end
158+
159+
function run!(state, rules)
160+
changed = true
161+
while changed
162+
changed = false
163+
for (op, inp1, inp2, out) rules
164+
if haskey(state, inp1) && haskey(state, inp2)
165+
if !haskey(state, out)
166+
changed = true
167+
end
168+
if op == "AND"
169+
state[out] = state[inp1] & state[inp2]
170+
elseif op == "OR"
171+
state[out] = state[inp1] | state[inp2]
172+
elseif op == "XOR"
173+
state[out] = state[inp1] state[inp2]
174+
end
175+
end
176+
end
177+
end
178+
# return state
7179
end
8180

9181
end # module

0 commit comments

Comments
 (0)