Something went wrong. Try again.
Code for the Advent of Code event
aoc advent-of-code
Something went wrong. Try again.
2.5 kB · 109 lines
Ruby
at rust
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110#!/usr/bin/env ruby# frozen_string_literal: true
require 'matrix'
class Vector def x; self[0]; end def y; self[1]; endend
class Region EROSION_MOD = 20_183
TYPE_MAP = { 0 => :rocky, 1 => :wet, 2 => :narrow }.freeze
RISK_LEVELS = { rocky: 0, wet: 1, narrow: 2 }.freeze
DISPLAY_MAP = { rocky: '.', wet: '=', narrow: '|' }.freeze
attr_reader :position, :geological_index, :erosion_level
def initialize(pos, geo_index, depth, is_origin: false, is_target: false) @position = pos @geological_index = geo_index @erosion_level = (@geological_index + depth) % EROSION_MOD @type = TYPE_MAP[@erosion_level % 3] @is_origin = is_origin @is_target = is_target end
def risk_level RISK_LEVELS[@type] end
def to_s return 'M' if @is_origin return 'T' if @is_target DISPLAY_MAP[@type] endend
class Cave X_INDEX_MOD = 16_807
Y_INDEX_MOD = 48_271
attr_reader :depth
def initialize(depth, origin, target) @depth = depth
@origin_position = origin @target_position = target
@regions = Hash.new { |xh, x| xh[x] = Hash.new { |yh, y| yh[y] = build_region Vector[x, y] } } end
# Default value on y allows [] to be called with just a Vector def [](x, y = nil) return self[x.x, x.y] if x.is_a?(Vector) @regions[x][y] end
def display(start, stop) (start.y..stop.y).each do |y| (start.x..stop.x).each do |x| print self[x, y] end puts end end
private
def build_region(position) return Region.new position, 0, @depth, is_origin: true if position == @origin_position return Region.new position, 0, @depth, is_target: true if position == @target_position return Region.new position, position.x * X_INDEX_MOD, @depth if position.y == 0 return Region.new position, position.y * Y_INDEX_MOD, @depth if position.x == 0 previous_x_region = @regions[position.x - 1][position.y] previous_y_region = @regions[position.x][position.y - 1] Region.new position, previous_x_region.erosion_level * previous_y_region.erosion_level, @depth endend
origin = Vector[0, 0]
lines = File.readlines('input.txt')
depth = lines.first.split(':').last.to_itarget = Vector.elements lines.last.split(':').last.split(',').map(&:to_i)
cave = Cave.new depth, origin, target
risk_level = (origin.x..target.x).to_a.product((origin.y..target.y).to_a).sum { |(x, y)| cave[x, y].risk_level }
puts "Part 1: #{risk_level}"