Code for the Advent of Code event
aoc advent-of-code
at rust 90 lines 2.0 kB view raw
1# frozen_string_literal: true 2 3require 'matrix' 4 5class Grid 6 attr_reader :width, :height 7 8 def initialize(width, height, walls = nil) 9 @width = width 10 @height = height 11 @walls = Set.new 12 self.walls = walls if walls 13 end 14 15 def in_bounds?(pos) 16 x, y = pos.to_a 17 x >= 0 && x < width && y >= 0 && y < height 18 end 19 20 def passable?(pos) 21 !@walls.include? pos 22 end 23 24 def add_wall(pos) 25 @walls.add pos 26 end 27 28 def walls=(positions) 29 positions.each { add_wall _1 } 30 end 31 32 def neighbors(pos) 33 x, y = pos.to_a 34 adjacent = [[x + 1, y], [x - 1, y], [x, y - 1], [x, y + 1]].map { Vector[*_1] } 35 adjacent.reverse! if (x + y).even? 36 adjacent.select { in_bounds?(_1) && passable?(_1) } 37 end 38 39 def draw(**opts) 40 puts '___' * width 41 (0...height).each do |y| 42 (0...width).each do |x| 43 print draw_tile(Vector[x, y], opts) 44 end 45 puts 46 end 47 puts '~~~' * width 48 end 49 50 protected 51 52 def draw_tile(pos, opts) 53 return '###' unless passable?(pos) 54 return ' Z ' if opts.key?(:goal) && opts[:goal] == pos 55 return ' A ' if opts.key?(:start) && opts[:start] == pos 56 return ' @ ' if opts.key?(:path) && opts[:path].include?(pos) 57 if opts.key?(:point_to) && !opts[:point_to][pos].nil? 58 x1, y1 = pos.to_a 59 x2, y2 = opts[:point_to][pos].to_a 60 return ' ↑ ' if y2 == y1 - 1 61 return ' ↓ ' if y2 == y1 + 1 62 return ' ← ' if x2 == x1 - 1 63 return ' → ' if x2 == x1 + 1 64 end 65 return sprintf(' %-2d', opts[:number][pos]) if opts.key?(:number) && opts[:number].key?(pos) 66 ' . ' 67 end 68end 69 70class GridWithWeights < Grid 71 def initialize(width, height, walls = nil) 72 super 73 @weights = Hash.new(1) 74 end 75 76 def add_weight(pos, weight) 77 @weights[pos] = weight 78 end 79 80 def cost(_source, destination) 81 @weights[destination] 82 end 83 84 protected 85 86 def draw_tile(pos, opts) 87 return sprintf(' %-2d', @weights[pos]) if opts[:weights] 88 super 89 end 90end