Code for the Advent of Code event
aoc
advent-of-code
1#!/usr/bin/env ruby
2# frozen_string_literal: true
3
4MEMORY = Hash.new(0)
5MEMORY2 = Hash.new(0)
6
7INPUT = ARGF.readlines
8
9def apply_mask(bits, mask)
10 bits = ([0] * (mask.size - bits.size)) + bits
11 bits.map.with_index do |bit, index|
12 mask[index] == ?X ? bit : mask[index].to_i
13 end
14end
15
16def apply_mask2(bits, mask)
17 bits = ([0] * (mask.size - bits.size)) + bits
18 bits.map.with_index do |bit, index|
19 mask[index] == ?X ? :X : (bit | mask[index].to_i)
20 end
21end
22
23def gen(template)
24 return [template] unless template.include? :X
25 i = template.index :X
26 gen(template.dup.tap { |d| d[i] = 0 }) + gen(template.dup.tap { |d| d[i] = 1 })
27end
28
29INPUT.each do |line|
30 case line
31 when /^mask = ([01X]+)$/
32 $mask = $1.chars
33 when /^mem\[(\d+)\] = (\d+)$/
34 index = $1.to_i
35 value = $2.to_i
36 bits, bits2 = [value, index].map { _1.to_s(2).chars.map(&:to_i) }
37 masked = apply_mask bits, $mask
38 masked2 = apply_mask2 bits2, $mask
39 indices = gen(masked2)
40 MEMORY[index] = masked.join.to_i(2)
41 indices.each { |i| MEMORY2[i] = value }
42 end
43end
44
45puts MEMORY.values.sum
46puts MEMORY2.values.sum