changeset 27:6b58ddfaed38

Add Day 18 part 1 solution using line crossing
author IBBoard <dev@ibboard.co.uk>
date Tue, 02 Jan 2024 16:04:33 +0000
parents eb6c3a7d2f72
children 5ba34a851816
files day18.rb day18.txt
diffstat 2 files changed, 177 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/day18.rb	Tue Jan 02 16:04:33 2024 +0000
@@ -0,0 +1,131 @@
+#! /usr/bin/env ruby
+
+if ARGV.length < 1 or ARGV.length > 2
+        abort("Incorrect arguments - needs input file and optional 'b' for part 2")
+elsif not File.exist? (ARGV[0])
+	abort("File #{ARGV[0]} did not exist")
+end
+
+file = ARGV[0]
+
+instructions = File.open(file, "r").each_line(chomp: true).map(&:split)
+
+Coord = Struct.new(:x,:y, :values)
+
+trench = [Coord.new(0,0, [])]
+
+if ARGV.length == 1
+	def decode(instruction)
+		[instruction[0], instruction[1]]
+	end
+else
+	def decode(instruction)
+		# Offset of 2 because of brackets and hash
+		dir_char = case instruction[2][7]
+			when "0" then "R"
+			when "1" then "D"
+			when "2" then "L"
+			when "3" then "U"
+		end
+		num_steps = instruction[2][2,5].to_i(16)
+		[dir_char, num_steps]
+	end
+end
+
+instructions.reduce(trench[0]) do |pos, instruction|
+	dir_char, num_steps = decode(instruction)
+	# Map to cardinal directions so that we can use the day 10 border crossing algorithm
+	# for finding "inside" nodes
+	case dir_char
+		when "R"
+			x_change = 1
+			y_change = 0
+			prev_dir = :east
+			next_dir = :west
+		when "L"
+			x_change = -1
+			y_change = 0
+			prev_dir = :west
+			next_dir = :east
+		when "U"
+			x_change = 0
+			y_change = -1
+			prev_dir = :north
+			next_dir = :south
+		when "D"
+			x_change = 0
+			y_change = 1
+			prev_dir = :south
+			next_dir = :north
+	end
+
+	num_steps.to_i.times do |i|
+		pos.values << prev_dir
+		pos = Coord.new(pos.x + x_change, pos.y + y_change, [next_dir])
+		trench << pos
+	end
+	pos
+end
+
+x_min, x_max = trench.map(&:x).minmax
+y_min, y_max = trench.map(&:y).minmax
+
+puts x_min, y_min
+
+if ARGV.length > 1
+	puts "We can't brute force this. Answers online suggest shoelace formula and Pick's theorem"
+	puts "So we'll call it quits and skip this"
+	return
+end
+
+dig_map = Hash.new
+trench.each do |pos|
+	new_x = pos.x - x_min
+	new_y = pos.y - y_min
+	coords = [new_x, new_y]
+	if dig_map.key? (coords)
+		dig_map[coords] += pos.values
+	else
+		dig_map[coords] = pos.values
+	end
+	dig_map[coords].sort!
+end
+
+
+State = Struct.new(:crossed_lines, :inside_count, :last_switch)
+in_out_transition = [:north, :south]
+
+state = State.new(0,0,nil)
+
+cells_inside = (y_max - y_min + 1).times do |y|
+	state.last_switch = nil
+	(x_max - x_min + 1).times do |x|
+		cell = dig_map[[x,y]]
+		if cell
+			#puts "#{x},#{y} - #{cell}"
+			# Same algorithm as Day 10 EXCEPT we count the trench/border as well
+			state.inside_count += 1
+			if cell == in_out_transition
+				state.crossed_lines += 1
+			elsif cell != [:east, :west]
+				this_switch = (cell & in_out_transition)
+				if state.last_switch.nil?
+					state.last_switch = this_switch
+				else
+					if this_switch != state.last_switch
+						state.crossed_lines += 1
+					end
+					state.last_switch = nil
+				end
+			end
+		elsif state.crossed_lines % 2.0 != 0
+			#puts "#{x},#{y} - inside"
+			state.inside_count += 1
+		else
+			#puts "#{x},#{y} - crossed #{state.crossed_lines} lines"
+		end
+		state
+	end
+	state
+end
+puts state.inside_count
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/day18.txt	Tue Jan 02 16:04:33 2024 +0000
@@ -0,0 +1,46 @@
+--- Day 18: Lavaduct Lagoon ---
+
+You have a set of instructions - directions, distance and hex colour
+
+R 6 (#70c710)
+D 5 (#0dc571)
+L 2 (#5713f0)
+D 2 (#d2c081)
+R 2 (#59c680)
+D 2 (#411b91)
+L 5 (#8ceee2)
+U 2 (#caa173)
+L 1 (#1b58a2)
+U 2 (#caa171)
+R 2 (#7807d2)
+U 3 (#a77fa3)
+L 2 (#015232)
+U 2 (#7a21e3)
+
+This creates a trench:
+
+#######
+#.....#
+###...#
+..#...#
+..#...#
+###.###
+#...#..
+##..###
+.#....#
+.######
+
+This is 38 dug spaces. The inside can then be dug out:
+
+#######
+#######
+#######
+..#####
+..#####
+#######
+#####..
+#######
+.######
+.######
+
+This is now 62 dug spaces.
\ No newline at end of file