Created
December 2, 2024 21:45
-
-
Save therubyhound/823eb525011b79eb71232cfd1cbea2d2 to your computer and use it in GitHub Desktop.
Advent of Code 2024, Day 2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "minitest/autorun" | |
class Reactor | |
attr_reader :data | |
def initialize(input) | |
@data = parse input | |
end | |
def safe_count | |
data.count { |levels| safe?(levels) } | |
end | |
def dampened_safe_count | |
data.count { |levels| safe?(levels) || safely_dampen?(levels) } | |
end | |
def safe?(row) | |
difference_data = differences(row) | |
same_sign?(difference_data) && within_limits?(difference_data) | |
end | |
def safely_dampen?(row) | |
row.each_index.any? { |index| safe?(row[0...index] + row[index+1..]) } | |
end | |
def differences(row) | |
row.each_cons(2).map { |x, y| x - y } | |
end | |
def same_sign?(differences) | |
differences.all?(&:positive?) || differences.all?(&:negative?) | |
end | |
def within_limits?(differences) | |
differences.map(&:abs).all? { |number| number.between?(1, 3) } | |
end | |
private | |
def parse(input) | |
input.split("\n").map { |row| row.split.map(&:to_i) } | |
end | |
end | |
BLUE = "\e[34m" | |
YELLOW = "\e[33m" | |
RESET = "\e[0m" | |
reactor = Reactor.new(File.read(ARGV[0])) | |
puts "#{BLUE}Safety Count:#{RESET} #{YELLOW}#{reactor.safe_count}#{RESET}" | |
puts "#{BLUE}Dampened Safety Count:#{RESET} #{YELLOW}#{reactor.dampened_safe_count}#{RESET}" | |
INPUT = DATA.read | |
class ReactorTest < Minitest::Test | |
def setup | |
@reactor = Reactor.new(INPUT) | |
end | |
def test_data | |
expected = [ | |
[7, 6, 4, 2, 1], | |
[1, 2, 7, 8, 9], | |
[9, 7, 6, 2, 1], | |
[1, 3, 2, 4, 5], | |
[8, 6, 4, 4, 1], | |
[1, 3, 6, 7, 9] | |
] | |
assert_equal expected, @reactor.data | |
end | |
def test_safe_count | |
assert_equal 2, @reactor.safe_count | |
end | |
def test_dampened_safe_count | |
assert_equal 4, @reactor.dampened_safe_count | |
end | |
def test_safe? | |
assert @reactor.safe?([7, 6, 4, 2, 1]) | |
refute @reactor.safe?([1, 2, 7, 8, 9]) | |
refute @reactor.safe?([9, 7, 6, 2, 1]) | |
refute @reactor.safe?([1, 3, 2, 4, 5]) | |
refute @reactor.safe?([8, 6, 4, 4, 1]) | |
assert @reactor.safe?([1, 3, 6, 7, 9]) | |
end | |
def test_safely_dampen? | |
refute @reactor.safely_dampen?([1, 2, 7, 8, 9]) | |
refute @reactor.safely_dampen?([9, 7, 6, 2, 1]) | |
assert @reactor.safely_dampen?([1, 3, 2, 4, 5]) | |
assert @reactor.safely_dampen?([8, 6, 4, 4, 1]) | |
end | |
def test_differences | |
expected = [1, 2, 2, 1] | |
input = [7, 6, 4, 2, 1] | |
assert_equal expected, @reactor.differences(input) | |
end | |
def test_same_sign? | |
assert @reactor.same_sign?([1, 2, 2, 1]) | |
refute @reactor.same_sign?([-1, 2, 2, 1]) | |
end | |
def test_within_limits? | |
assert @reactor.within_limits?([1, 2, 2, 1]) | |
assert @reactor.within_limits?([-1, -3, -2, -1]) | |
refute @reactor.within_limits?([1, 3, 5, 1]) | |
refute @reactor.within_limits?([1, 3, 0, 1]) | |
end | |
end | |
__END__ | |
7 6 4 2 1 | |
1 2 7 8 9 | |
9 7 6 2 1 | |
1 3 2 4 5 | |
8 6 4 4 1 | |
1 3 6 7 9 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment