parent
c3a12cbf59
commit
6ecae2b5bf
@ -0,0 +1,60 @@ |
||||
require "advent" |
||||
raw = input(2020, 14).lines |
||||
input = [] of {UInt64, UInt64, Array(Int32), UInt64, UInt64} |
||||
|
||||
and_mask = (2_u64**63) + (2_u64**63-1) |
||||
or_mask = 0_u64 |
||||
floats = [] of Int32 |
||||
|
||||
raw.each do |line| |
||||
if data = line.match(/^mask = (.+)$/) |
||||
new_mask = data[1] |
||||
and_mask = (2_u64**63) + (2_u64**63-1) |
||||
or_mask = 0_u64 |
||||
floats = [] of Int32 |
||||
new_mask.reverse.chars.each_with_index do |c, i| |
||||
floats << i if c == 'X' |
||||
or_mask = or_mask | (1_u64 << i) if c == '1' |
||||
and_mask = and_mask & ~(1_u64 << i) if c == '0' |
||||
end |
||||
elsif data = line.match(/^mem\[(\d+)\] = (\d+)$/) |
||||
input << {and_mask, or_mask, floats, data[1].to_u64, data[2].to_u64} |
||||
else |
||||
raise "Invalid line" |
||||
end |
||||
end |
||||
|
||||
def part1(input) |
||||
memory = {} of UInt64 => UInt64 |
||||
input.each do |i| |
||||
and_mask, or_mask, floats, addr, v = i |
||||
memory[addr] = (v & and_mask) | or_mask |
||||
end |
||||
memory.values.sum |
||||
end |
||||
|
||||
def generate_possible(indices, index, n, &block : UInt64 -> _) |
||||
if index == indices.size |
||||
yield n |
||||
return |
||||
end |
||||
float_addr = indices[index] |
||||
no = n | (1_u64 << float_addr) |
||||
generate_possible(indices, index+1, no, &block) |
||||
nz = n & ~(1_u64 << float_addr) |
||||
generate_possible(indices, index+1, nz, &block) |
||||
end |
||||
|
||||
def part2(input) |
||||
memory = {} of UInt64 => UInt64 |
||||
input.each do |i| |
||||
_, or_mask, floats, addr, v = i |
||||
generate_possible(floats, 0, addr | or_mask) do |addr| |
||||
memory[addr] = v |
||||
end |
||||
end |
||||
memory.values.sum |
||||
end |
||||
|
||||
puts part1(input) |
||||
puts part2(input) |
Loading…
Reference in new issue