Code for the Advent of Code event
aoc advent-of-code
at rust 94 lines 2.0 kB view raw
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