require_relative 'util' # --- Day 11: Hex Ed --- # Crossing the bridge, you've barely reached the other side of the # stream when a program comes up to you, clearly in distress. "It's my # child process," she says, "he's gotten lost in an infinite grid!" # Fortunately for her, you have plenty of experience with infinite grids. # Unfortunately for you, it's a hex grid. # The hexagons ("hexes") in this grid are aligned such that adjacent # hexes can be found to the north, northeast, southeast, south, # southwest, and northwest: # \ n / # nw +--+ ne # / \ # -+ +- # \ / # sw +--+ se # / s \ # You have the path the child process took. Starting where he started, # you need to determine the fewest number of steps required to reach # him. (A "step" means to move from the hex you are in to any adjacent # hex.) # For example: # - ne,ne,ne is 3 steps away. # - ne,ne,sw,sw is 0 steps away (back where you started). # - ne,ne,s,s is 2 steps away (se,se). # - se,sw,se,sw,sw is 3 steps away (s,s,sw). class HexCoord attr_accessor :x, :y, :z def initialize # NOTE: this uses the cube representation from # https://www.redblobgames.com/grids/hexagons/ @x = 0 @y = 0 @z = 0 end def n @x += 1 @z -= 1 end def ne @x += 1 @y -= 1 end def se @z += 1 @y -= 1 end def s @z += 1 @x -= 1 end def sw @y += 1 @x -= 1 end def nw @y += 1 @z -= 1 end def distance(coord) ((@x - coord.x).abs + (@y - coord.y).abs + (@z - coord.z).abs) / 2 end end input = File.open('11.txt') { |f| f.readline.chomp.split(',').map(&:to_sym) } def easy(directions) a = HexCoord.new b = HexCoord.new directions.each { |direction| b.send(direction) } b.distance(a) end assert(easy([:ne, :ne, :ne]) == 3) assert(easy([:ne, :ne, :sw, :sw]) == 0) assert(easy([:ne, :ne, :s, :s]) == 2) assert(easy([:se, :sw, :se, :sw, :sw]) == 3) puts "easy(input): #{easy(input)}" # --- Part Two --- # How many steps away is the furthest he ever got from his starting position? def hard(directions) a = HexCoord.new b = HexCoord.new max_distance = 0 directions.each do |direction| b.send(direction) max_distance = [b.distance(a), max_distance].max end max_distance end puts "hard(input): #{hard(input)}"