Watch
1
0
Fork
You've already forked advent-of-code
0

2023 Day 21 Part 1

This commit is contained in:
Jeremy Kaplan 2023-12-20 21:33:30 -08:00
commit 57f8147867

100
2023/day21.rb Normal file
View file

@ -0,0 +1,100 @@
# frozen_string_literal: true
# typed: true
require 'set'
require 'sorbet-runtime'
require 'sorbet-struct-comparable'
extend T::Sig
class Cell < T::Struct
extend T::Sig
include T::Struct::ActsAsComparable
const :r, Integer
const :c, Integer
class << self
extend T::Sig
sig { params(r: Integer, c: Integer).returns(Cell) }
def at(r, c) = Cell::new(r: r, c: c)
end
sig { returns(Cell) }
def north = Cell::at(r - 1, c)
sig { returns(Cell) }
def south = Cell::at(r + 1, c)
sig { returns(Cell) }
def west = Cell::at(r, c - 1)
sig { returns(Cell) }
def east = Cell::at(r, c + 1)
sig { returns(T::Array[Cell]) }
def neighbors = [north, south, west, east]
end
class Garden
extend T::Sig
sig { returns(Cell) }
attr_reader :start
def initialize(text)
@grid = T.let({}, T::Hash[Cell, String])
text.strip.each_line.each_with_index do |line, r|
line.strip.each_char.each_with_index do |char, c|
@grid[Cell::at(r, c)] = char
@start = Cell::at(r, c) if char == ?S
end
end
end
sig { params(cell: Cell).returns(T.nilable(String)) }
def char(cell) = @grid[cell]
sig { params(cell: Cell).returns(T::Boolean) }
def is_plot?(cell)
sym = char(cell) or return false
sym != '#'
end
end
class Gardener
extend T::Sig
sig { params(garden: Garden).void }
def initialize(garden)
@garden = garden
end
sig { params(starts: T::Set[Cell]).returns(T::Set[Cell]) }
def step_hypothetically(starts)
dests = Set::new
starts.each do |start|
dests.merge start.neighbors.select { |c| @garden.is_plot?(c) }
end
dests
end
end
sig { params(path: String).returns(Integer) }
def part1(path)
text = File.read(path)
garden = Garden::new(text)
gardener = Gardener::new(garden)
pos = Set[garden.start]
64.times do
pos = gardener.step_hypothetically(pos)
end
pos.size
end
puts part1 File.join(__dir__, 'input/test.txt')
puts part1 File.join(__dir__, 'input/day21.txt')