Code for the Advent of Code event
aoc
advent-of-code
1#!/usr/bin/env ruby
2# frozen_string_literal: true
3
4require 'pry'
5
6TYPES = {
7 0 => :sum,
8 1 => :product,
9 2 => :min,
10 3 => :max,
11 4 => :literal,
12 5 => :gt,
13 6 => :lt,
14 7 => :eq
15}.freeze
16
17MODES = {
18 0 => :bits,
19 1 => :packets
20}.freeze
21
22OPS = {
23 sum: lambda(&:sum),
24 product: -> { _1.reduce :* },
25 min: lambda(&:min),
26 max: lambda(&:max),
27 gt: -> { _1.reduce(:>) ? 1 : 0 },
28 lt: -> { _1.reduce(:<) ? 1 : 0 },
29 eq: -> { _1.reduce(:==) ? 1 : 0 }
30}.freeze
31
32hex = ARGF.readline.strip
33# puts hex
34bin_width = hex.size * 4
35data = hex.to_i(16).to_s(2).rjust(bin_width, '0').chars
36# puts data.join
37
38versions = []
39
40def parse_packet(data, position, versions)
41 final_value = 0
42 version = data.shift(3).join.to_i(2)
43 versions << version
44 type = TYPES[data.shift(3).join.to_i(2)]
45 position += 6
46 # puts "V:#{version},T:#{type}"
47 case type
48 when :literal
49 value_bits = []
50 loop do
51 order = data.shift(1)[0].to_i
52 value_bits << data.shift(4).join
53 position += 5
54 break if order.zero?
55 end
56 value = value_bits.join.to_i(2)
57 final_value = value
58 else
59 mode = MODES[data.shift(1)[0].to_i]
60 position += 1
61 # print " M:#{mode}"
62 op_values = []
63 case mode
64 when :bits
65 length_bits = data.shift(15).join
66 bit_length = length_bits.to_i(2)
67 # puts ":#{bit_length}"
68 # puts " DBG:l_bits=#{length_bits}"
69 position += 15
70 bits_read = 0
71 while bits_read < bit_length
72 old_pos = position
73 position, value = parse_packet(data, position, versions)
74 bits_read += position - old_pos
75 op_values << value
76 end
77 when :packets
78 packet_count = data.shift(11).join.to_i(2)
79 # puts ":#{packet_count}"
80 position += 11
81 packet_count.times do
82 position, value = parse_packet(data, position, versions)
83 op_values << value
84 end
85 end
86 final_value = OPS[type][op_values]
87 end
88 [position, final_value]
89end
90
91_, part2 = parse_packet(data, 0, versions)
92
93puts versions.sum
94puts part2