2023 Day 21 Part 1
This commit is contained in:
parent
680e168478
commit
57f8147867
1 changed files with 100 additions and 0 deletions
100
2023/day21.rb
Normal file
100
2023/day21.rb
Normal 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')
|
||||
Loading…
Reference in a new issue