From 5657157ffa2c63c62bddcfda068eb82685f47ab0 Mon Sep 17 00:00:00 2001 From: Greg Woods Date: Fri, 15 Dec 2023 09:32:56 -0500 Subject: [PATCH] Day 15 --- examples/15.txt | 1 + lib/days/15.rb | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ test/15_test.rb | 18 +++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 examples/15.txt create mode 100644 lib/days/15.rb create mode 100644 test/15_test.rb diff --git a/examples/15.txt b/examples/15.txt new file mode 100644 index 0000000..4f58f74 --- /dev/null +++ b/examples/15.txt @@ -0,0 +1 @@ +rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7 diff --git a/lib/days/15.rb b/lib/days/15.rb new file mode 100644 index 0000000..2d1eade --- /dev/null +++ b/lib/days/15.rb @@ -0,0 +1,54 @@ +class Day15 + + def part1(input) + input.split(',').map { |s| compute_hash(s) }.sum + end + + def compute_hash(str) + str.chars.reduce(0) do |value, char| + code = char.ord + value += code + value *= 17 + value %= 256 + value + end + end + + Lens = Struct.new(:label, :focal_length) + + def part2(input) + boxes = {} + + input.split(',').each do |step| + if step.include?('=') + label, value = step.split('=') + box_num = compute_hash(label) + + boxes[box_num] ||= [] + new_lens = Lens.new(label, value.to_i) + + index = boxes[box_num].index { |b| b.label == label } + if index + boxes[box_num][index] = new_lens + else + boxes[box_num] << new_lens + end + else + label = step[0...-1] + box_num = compute_hash(label) + + if boxes[box_num] + index = boxes[box_num].index { |b| b.label == label } + boxes[box_num].delete_at(index) if index + end + end + end + + boxes.sum do |box_num, box| + box.each_with_index.sum do |lens, index| + (box_num + 1) * (index + 1) * lens.focal_length + end + end + end + +end diff --git a/test/15_test.rb b/test/15_test.rb new file mode 100644 index 0000000..9fcab55 --- /dev/null +++ b/test/15_test.rb @@ -0,0 +1,18 @@ +require 'minitest/autorun' +require 'minitest/pride' +require_relative '../app' + +class TestDay15 < Minitest::Test + def setup + @data = File.read(File.join(APP_ROOT, 'examples', '15.txt')).rstrip + @day = Day15.new + end + + def test_part1 + assert_equal @day.part1(@data), 1320 + end + + def test_part2 + assert_equal @day.part2(@data), 145 + end +end