Mercurial > repos > other > adventofcode2023
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