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