Skip to content

Instantly share code, notes, and snippets.

@therubyhound
Created December 5, 2024 23:09
Show Gist options
  • Save therubyhound/2e7c5c4d868d7b2bda84741fe376accb to your computer and use it in GitHub Desktop.
Save therubyhound/2e7c5c4d868d7b2bda84741fe376accb to your computer and use it in GitHub Desktop.
Advent of Code 2024, Day 5
require "miNitest/autorun"
require "debug"
class SafetyManual
attr_reader :rules, :pages
def initialize(input)
@rules, @pages = parse input
end
def sum
middle_pages(valid_updates).sum
end
def fixed_sum
middle_pages(fixed_updates).sum
end
def middle_pages(updates)
updates.map { |update| update[update.length / 2] }
end
def valid_updates
pages.select { |update| valid_update?(update) }
end
def fixed_updates
invalid_updates.map { |update| fix(update) }
end
def fix(update)
hash = rule_hash(update)
sorted_update = update.sort_by do |item|
depth = hash.keys.count { |key| hash[key]&.include?(item) }
depth
end
sorted_update
end
def invalid_updates
pages.reject { |update| valid_update?(update) }
end
def valid_update?(update)
relevant_rules(update).all? { |rule| valid?(rule, update) }
end
def valid?(rule, update)
update.find_index(rule[0]) < update.find_index(rule[1])
end
def relevant_rules(update)
rules & update.product(update)
end
private
def parse(input)
rules, pages = input.split("\n\n")
[
rules.lines.map { |line| line.split("|").map(&:to_i) },
pages.lines.map { |line| line.split(",").map(&:to_i) }
]
end
def rule_hash(update)
hash = {}
relevant_rules(update).each do |p1, p2|
hash[p1] ||= []
hash[p1] << p2
end
hash
end
end
BLUE = "\e[34m"
YELLOW = "\e[33m"
RESET = "\e[0m"
safety_manual = SafetyManual.new(File.read(ARGV[0]))
puts "#{BLUE}Sum:#{RESET} #{YELLOW}#{safety_manual.sum}#{RESET}"
puts "#{BLUE}Fixed Sum:#{RESET} #{YELLOW}#{safety_manual.fixed_sum}#{RESET}"
INPUT = DATA.read
class SafetyManualTest < Minitest::Test
def setup
@safety_manual = SafetyManual.new(INPUT)
end
def fixed_sum
assert_equal 123, @safety_manual.sum
end
def test_sum
assert_equal 143, @safety_manual.sum
end
def test_middle_pages
updates = [
[75,47,61,53,29],
[97,61,53,29,13],
[75,29,13]
]
assert_equal [61, 53, 29], @safety_manual.middle_pages(updates)
end
def test_valid_updates
expected = [
[75,47,61,53,29],
[97,61,53,29,13],
[75,29,13]
]
assert_equal expected, @safety_manual.valid_updates
end
def test_fix
assert_equal [97,75,47,61,53], @safety_manual.fix([75,97,47,61,53])
assert_equal [61,29,13], @safety_manual.fix([61,13,29])
assert_equal [97,75,47,29,13], @safety_manual.fix([97,13,75,29,47])
end
def test_fixed_updates
expected = [
[97,75,47,61,53],
[61,29,13],
[97,75,47,29,13]
]
assert_equal expected, @safety_manual.fixed_updates
end
def test_invalid_updates
expected = [
[75,97,47,61,53],
[61,13,29],
[97,13,75,29,47]
]
assert_equal expected, @safety_manual.invalid_updates
end
def test_valid?
assert @safety_manual.valid?([75,29], [75,47,61,53,29])
end
def test_valid_update?
assert @safety_manual.valid_update?([75,47,61,53,29])
refute @safety_manual.valid_update?([75,97,47,61,53])
end
def test_relevant_rules
expected = [
[75, 29],
[75, 53],
[75, 47],
[75, 61],
[47, 53],
[47, 61],
[47, 29],
[61, 53],
[61, 29],
[53, 29]
]
assert equal_array(expected, @safety_manual.relevant_rules([75,47,61,53,29]))
end
def test_rules
expected = [
[47, 53],
[97, 13],
[97, 61],
[97, 47],
[75, 29],
[61, 13],
[75, 53],
[29, 13],
[97, 29],
[53, 29],
[61, 53],
[97, 53],
[61, 29],
[47, 13],
[75, 47],
[97, 75],
[47, 61],
[75, 61],
[47, 29],
[75, 13],
[53, 13],
]
assert_equal expected, @safety_manual.rules
end
def test_pages
expected = [
[75,47,61,53,29],
[97,61,53,29,13],
[75,29,13],
[75,97,47,61,53],
[61,13,29],
[97,13,75,29,47],
]
assert_equal expected, @safety_manual.pages
end
def equal_array(expected, result)
expected.count == result.count && result.all? { |x| expected.include?(x) }
end
end
__END__
47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13
75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment