From d1b87d10007c20d71f2a911323a9cb19ef937a0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Carlos=20=C3=81lvaro?=
Date: Tue, 30 Jan 2024 17:47:53 +0100
Subject: [PATCH] Advent of Code 2023 - Day 11
- Solve day 11 puzzle
---
README.md | 5 +
lib/puzzles/2023/day11/README.md | 126 +++++++++++++++++++++++
lib/puzzles/2023/day11/day11.rb | 13 +++
lib/puzzles/2023/day11/input.txt | 140 ++++++++++++++++++++++++++
lib/puzzles/2023/day11/part1.rb | 130 ++++++++++++++++++++++++
lib/puzzles/2023/day11/part2.rb | 85 ++++++++++++++++
sig/puzzles/2023/day11.rbs | 39 +++++++
sig/test/puzzles/2023/day11_test.rbs | 33 ++++++
test/puzzles/2023/day11/day11_test.rb | 81 +++++++++++++++
test/puzzles/2023/day11/test_data.txt | 10 ++
10 files changed, 662 insertions(+)
create mode 100644 lib/puzzles/2023/day11/README.md
create mode 100644 lib/puzzles/2023/day11/day11.rb
create mode 100644 lib/puzzles/2023/day11/input.txt
create mode 100644 lib/puzzles/2023/day11/part1.rb
create mode 100644 lib/puzzles/2023/day11/part2.rb
create mode 100644 sig/puzzles/2023/day11.rbs
create mode 100644 sig/test/puzzles/2023/day11_test.rbs
create mode 100644 test/puzzles/2023/day11/day11_test.rb
create mode 100644 test/puzzles/2023/day11/test_data.txt
diff --git a/README.md b/README.md
index b4f5c59..b7ff1e1 100644
--- a/README.md
+++ b/README.md
@@ -82,6 +82,11 @@ SKIP_SLOW_TESTS=1 bundle exec rake test
lib/puzzles/2023/day10 |
🌟🌟 |
+
+ 1️⃣1️⃣ Cosmic Expansion |
+ lib/puzzles/2023/day11 |
+ 🌟🌟 |
+
diff --git a/lib/puzzles/2023/day11/README.md b/lib/puzzles/2023/day11/README.md
new file mode 100644
index 0000000..fdd622b
--- /dev/null
+++ b/lib/puzzles/2023/day11/README.md
@@ -0,0 +1,126 @@
+# [Day 11: Cosmic Expansion](https://adventofcode.com/2023/day/11)
+
+## Part One
+
+You continue following signs for "Hot Springs" and eventually come across an [observatory](https://en.wikipedia.org/wiki/Observatory). The Elf within turns out to be a researcher studying cosmic expansion using the giant telescope here.
+
+He doesn't know anything about the missing machine parts; he's only visiting for this research project. However, he confirms that the hot springs are the next-closest area likely to have people; he'll even take you straight there once he's done with today's observation analysis.
+
+Maybe you can help him with the analysis to speed things up?
+
+The researcher has collected a bunch of data and compiled the data into a single giant **image** (your puzzle input). The image includes **empty space** (`.`) and **galaxies** (`#`). For example:
+
+```
+...#......
+.......#..
+#.........
+..........
+......#...
+.#........
+.........#
+..........
+.......#..
+#...#.....
+```
+
+The researcher is trying to figure out the sum of the lengths of the **shortest path between every pair of galaxies**. However, there's a catch: the universe expanded in the time it took the light from those galaxies to reach the observatory.
+
+Due to something involving gravitational effects, **only some space expands**. In fact, the result is that **any rows or columns that contain no galaxies** should all actually be twice as big.
+
+In the above example, three columns and two rows contain no galaxies:
+
+```
+ v v v
+ ...#......
+ .......#..
+ #.........
+>..........<
+ ......#...
+ .#........
+ .........#
+>..........<
+ .......#..
+ #...#.....
+ ^ ^ ^
+```
+
+These rows and columns need to be **twice as big**; the result of cosmic expansion therefore looks like this:
+
+```
+....#........
+.........#...
+#............
+.............
+.............
+........#....
+.#...........
+............#
+.............
+.............
+.........#...
+#....#.......
+```
+
+Equipped with this expanded universe, the shortest path between every pair of galaxies can be found. It can help to assign every galaxy a unique number:
+
+```
+....1........
+.........2...
+3............
+.............
+.............
+........4....
+.5...........
+............6
+.............
+.............
+.........7...
+8....9.......
+```
+
+In these 9 galaxies, there are **36 pairs**. Only count each pair once; order within the pair doesn't matter. For each pair, find any shortest path between the two galaxies using only steps that move up, down, left, or right exactly one `.` or `#` at a time. (The shortest path between two galaxies is allowed to pass through another galaxy.)
+
+For example, here is one of the shortest paths between galaxies `5` and `9`:
+
+```
+....1........
+.........2...
+3............
+.............
+.............
+........4....
+.5...........
+.##.........6
+..##.........
+...##........
+....##...7...
+8....9.......
+```
+
+This path has length `9` because it takes a minimum of **nine steps** to get from galaxy `5` to galaxy `9` (the eight locations marked `#` plus the step onto galaxy `9` itself). Here are some other example shortest path lengths:
+
+- Between galaxy `1` and galaxy `7`: 15
+- Between galaxy `3` and galaxy `6`: 17
+- Between galaxy `8` and galaxy `9`: 5
+
+In this example, after expanding the universe, the sum of the shortest path between all 36 pairs of galaxies is **`374`**.
+
+Expand the universe, then find the length of the shortest path between every pair of galaxies. **What is the sum of these lengths?**
+
+Your puzzle answer was `10313550`.
+
+**The first half of this puzzle is complete! It provides one gold star:** 🌟
+
+## Part Two
+
+The galaxies are much **older** (and thus much **farther apart**) than the researcher initially estimated.
+
+Now, instead of the expansion you did before, make each empty row or column **one million times** larger. That is, each empty row should be replaced with `1000000` empty rows, and each empty column should be replaced with `1000000` empty columns.
+
+(In the example above, if each empty row or column were merely `10` times larger, the sum of the shortest paths between every pair of galaxies would be **`1030`**. If each empty row or column were merely `100` times larger, the sum of the shortest paths between every pair of galaxies would be **`8410`**. However, your universe will need to expand far beyond these values.)
+
+Starting with the same initial image, expand the universe according to these new rules, then find the length of the shortest path between every pair of galaxies. **What is the sum of these lengths?**
+
+Your puzzle answer was `611998089572`.
+
+**Both parts of this puzzle are complete! They provide two gold stars:** 🌟🌟
diff --git a/lib/puzzles/2023/day11/day11.rb b/lib/puzzles/2023/day11/day11.rb
new file mode 100644
index 0000000..1b4ac17
--- /dev/null
+++ b/lib/puzzles/2023/day11/day11.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require_relative "part1"
+require_relative "part2"
+
+module AdventOfCode
+ module Puzzles2023
+ ##
+ # {include:file:lib/puzzles/2023/day11/README.md}
+ module Day11
+ end
+ end
+end
diff --git a/lib/puzzles/2023/day11/input.txt b/lib/puzzles/2023/day11/input.txt
new file mode 100644
index 0000000..8fbd6cf
--- /dev/null
+++ b/lib/puzzles/2023/day11/input.txt
@@ -0,0 +1,140 @@
+..#............................#....................................................................................#..........#........#...
+..........#.........................................#.......................................................................................
+...................#..........................................................................#.............................................
+.....................................................................................#.............................................#........
+.......#.......#.............#..........#......#...................#.....#..................................................................
+................................................................................#..................#..............#.........................
+....................................#.......................................................................................................
+...........#...................................................................................#......................................#.....
+.......................................................................................................................#.........#..........
+.....................#.................................................#...................#.................#..............#...............
+....#...........................................#...............#...........................................................................
+.........................#.......................................................................#..........................................
+...................................#......................#.......................................................#.......................#.
+..................#...........................................................#.......................#.................#...........#.......
+..........#........................................................#..........................................#.............................
+.............................................#.........#.....#..............................................................................
+.......................#.....................................................................#..............................#..........#....
+.............................#.......................................................#...........................#..........................
+..#...........#.......................#.....................................#...............................................................
+...........................................................#.............................................#..................................
+......#..........................................................#......#........................................................#..........
+................................#.........#...........#....................................#........#...................#..................#
+...........................#..................................................#..............................#..............................
+..............................................#.................................................#...........................................
+.#.................................................................................................................#........................
+.......................................................................#....................................................................
+...............#.............................................................................................................#..........#...
+.................................#.............................#............................................#...............................
+.....#.................#...................#................................................................................................
+....................................................#...................................................#............#......................
+...........#.....#...................................................................#............................................#.........
+..............................................#...........................................................................#.................
+...#.........................#.....................................................................#........................................
+.........................................................#...................................#........................................#.....
+.........#....................................................#........#................#.....................#.............................
+........................#..........................................................................................#........................
+..............#...................................#............................#.............................................#.....#........
+.................................#................................................................#.........................................
+..................#........................#...............#................................#.............#.............................#...
+..........#........................................................#............................................................#...........
+..#.....................................................................................#.............................#.....................
+..........................#..........#..................................#......................................#...........#................
+................................................................#...........................................................................
+................#................................#..........................#...............................................................
+...........................................#..................................................#.....#.......#...............................
+..........#............................................#.....................................................................#..............
+.......................#....................................#...........................................................#..............#....
+.....#.........................#........#..............................................#.................#........................#.........
+.................#....................................................#............................................#........................
+....................................#...............#................................................#......................................
+.........................#........................................#................#.......#...................#............................
+....................................................................................................................................#.......
+...........#...................................#...........................#......................#.........................#..............#
+..................................#......#..................................................................................................
+......#....................#.........................#..................................................#...................................
+......................#...................................#......#.....#.................................................#..................
+..............#..............................................................................#.................#.....................#......
+............................................................................................................................................
+#.............................#................#....................................................................#....................#..
+............................................................................................................................................
+........#...........................................#.......................................................................................
+...................................................................#..........#..................#..........................................
+.....................#............#........#.............................................#............#................#....................
+................#............................................................................................................#..............
+...............................................................................................................#...................#........
+........................#......#..........................#.....#......#................................................................#...
+................................................#..........................................#.............#..................................
+......................................#..............................................................................#......................
+..#.................................................................#.........#.............................................................
+..........#.....#...............................................................................................#...........#...............
+.................................#....................................................................#..............................#......
+.....................................................#........................................#........................#....................
+..........................................#..................#............#.................................................................
+......................#...............................................................#..................#.........#............#...........
+......#........................................................................#............................................................
+...................................#...................................#..................................................#.................
+...................................................#.........................................#.................#............................
+...........................#...................................#.....................................................................#......
+........................................#...................................................................................................
+................#......................................#........................#.........#.....#...........................................
+...........#......................#.....................................................................#...................................
+....#....................#...................#...................#................................................#...........#...........#.
+............................................................................................................................................
+............................................................................................................................................
+.....................................#....................................#.................................................................
+.......................#..................#........#............................#................#.............#............................
+...............#...............................................#......................#..............................................#......
+............................................................................................................................................
+.................................#...........#.....................#....................................................#...................
+............................................................................................................................................
+..#........#..........#...............#..................................................................#..........#......................#
+............................................................#............................#..................................................
+.................................................................#..........#.................................#.................#...........
+.............................#......................#.......................................................................................
+....#..................................................................................................................................#....
+...................#...............#..................................................#....................#................................
+.........................................................#......................................#...................#..............#........
+.....................................................................#...................................................#..................
+........................#...................................................................#..................#............................
+...#.....#...............................#....................#.............................................................................
+................#...............#...........................................................................................................
+.....................#........................................................#.....................................................#.......
+..............................................#.......#................#...............................................#...................#
+.........................................................................................#...............#...................#..............
+.#...........................#.......#......................................................................................................
+.............................................................................................................#........................#.....
+.................................#..........................................................................................................
+...........#........................................................................................#.............................#.........
+................#...............................................#............................#...................#..........................
+...#............................................................................#...........................................................
+....................................................#.......#.......#......#...........................................................#....
+.........................#..................................................................................................................
+....................#...............#.........................................................................................#.............
+.........................................................#....................#......................#......................................
+....#........................#...............#........................#...............#.....................................................
+..........#......#....................................................................................................................#.....
+..............................................................................................#...................#.........................
+.......................................................#...................................................#.................#..............
+..........................#....................#............................................................................................
+........................................#......................#.........#...............#.......#......................#.........#.....#...
+...............................#....................................#.......................................................................
+........#...........#.............................#.........................................................................................
+...#...........#...................................................................#..................#............#........................
+...........................#..............................#...................................#.............................................
+...................................#.............................#..........................................#...............................
+..............................................#........................#........#..........................................#................
+.......................................................................................#.............................#..............#.......
+.........................................#..................................................................................................
+.....#............#......................................#.....#............................#...............................................
+............................#...............................................................................................................
+.......................#.........#........................................#..............................#...............................#..
+..#...........#.......................................#.........................#...........................................................
+.......................................#.........................#..........................................................................
+............................................................#...............................................................................
+.......#......................#........................................#................................................#..............#....
+..............................................................................................................#.............................
+...............................................#.....................................................#......................................
+......................#..................................................................#......#.................................#.......#.
+..#.......#................#......#..................................#.......#.....................................#........................
+................#...............................................#..................#....................#..................#................
diff --git a/lib/puzzles/2023/day11/part1.rb b/lib/puzzles/2023/day11/part1.rb
new file mode 100644
index 0000000..30daf64
--- /dev/null
+++ b/lib/puzzles/2023/day11/part1.rb
@@ -0,0 +1,130 @@
+# frozen_string_literal: true
+
+module AdventOfCode
+ module Puzzles2023
+ module Day11
+ ##
+ # Class for solving Day 11 - Part 1 puzzle
+ class Part1
+ ##
+ # @param file [String] The input file
+ def initialize(file: nil)
+ file ||= "#{File.dirname(__FILE__)}/input.txt"
+ parse_file(file)
+ end
+
+ ##
+ # Get the sum of the minimum space between galaxies.
+ #
+ # @return [Integer] The sum of the space between galaxies
+ def answer
+ galaxies = find_galaxies
+ pairs = make_pairs(galaxies.size)
+ get_distances(pairs, galaxies).sum
+ end
+
+ protected
+
+ ##
+ # The symbol for a galaxy.
+ # @return [Symbol] The symbol for a galaxy
+ GALAXY_SYMBOL = :"#"
+
+ ##
+ # The space.
+ # @return [Array>] The space
+ attr_reader :space
+
+ ##
+ # Parse the input file.
+ #
+ # @param file [String] The input file
+ def parse_file(file)
+ data = []
+ File.readlines(file, chomp: true).each do |line|
+ data << line.chars.map(&:to_sym)
+ end
+
+ @space = expand_space(data)
+ end
+
+ ##
+ # Expand all empty space in the data.
+ #
+ # @param data [Array>] The data
+ #
+ # @return [Array>] The expanded data
+ def expand_space(data)
+ data = expand_empty_space(data)
+ data = expand_empty_space(data.transpose)
+ data.transpose
+ end
+
+ ##
+ # Find all of the galaxies in the space.
+ #
+ # @return [Array>] The galaxies
+ def find_galaxies
+ galaxies = []
+ space.each_with_index do |row, row_id|
+ row.each_with_index do |cell, col_id|
+ galaxies << [row_id, col_id] if cell == GALAXY_SYMBOL
+ end
+ end
+ galaxies
+ end
+
+ ##
+ # Make all of the pairs of galaxies.
+ #
+ # @param number_galaxies [Integer] The number of galaxies
+ #
+ # @return [Array>] The pairs of galaxies
+ def make_pairs(number_galaxies)
+ (0...number_galaxies).to_a.combination(2).to_a
+ end
+
+ ##
+ # Get the distances between all of the pairs of galaxies.
+ #
+ # @param pairs [Array>] The pairs of galaxies
+ # @param galaxies [Array>] The galaxies
+ #
+ # @return [Array] The distances
+ def get_distances(pairs, galaxies)
+ pairs.map do |pair|
+ get_distance(galaxies[pair[0]], galaxies[pair[1]])
+ end
+ end
+
+ ##
+ # Get the distance between two galaxies.
+ #
+ # @param galaxy1 [Array] The first galaxy
+ # @param galaxy2 [Array] The second galaxy
+ #
+ # @return [Integer] The distance between the two galaxies
+ def get_distance(galaxy1, galaxy2)
+ (galaxy2[0] - galaxy1[0]).abs + (galaxy2[1] - galaxy1[1]).abs
+ end
+
+ private
+
+ ##
+ # Expand all empty rows in the data.
+ #
+ # @param data [Array>] The data
+ #
+ # @return [Array>] The expanded data
+ def expand_empty_space(data)
+ new_data = []
+ data.each do |row|
+ new_data << row
+ new_data << row unless row.include?(GALAXY_SYMBOL)
+ end
+ new_data
+ end
+ end
+ end
+ end
+end
diff --git a/lib/puzzles/2023/day11/part2.rb b/lib/puzzles/2023/day11/part2.rb
new file mode 100644
index 0000000..b174a39
--- /dev/null
+++ b/lib/puzzles/2023/day11/part2.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+require_relative "part1"
+
+module AdventOfCode
+ module Puzzles2023
+ module Day11
+ ##
+ # Class for solving Day 11 - Part 2 puzzle
+ class Part2 < Part1
+ ##
+ # @param file [String] The input file
+ # @param expansion_rate [Integer] The expansion rate
+ def initialize(file: nil, expansion_rate: Integer(1E06))
+ super(file:)
+ @expansion_rate = expansion_rate
+ end
+
+ protected
+
+ ##
+ # The expansion rate for empty space.
+ # @return [Integer] The expansion rate for empty space
+ attr_reader :expansion_rate
+
+ ##
+ # The regions that have been expanded.
+ # @return [Hash>] The regions that have been expanded
+ attr_reader :expanded_regions
+
+ ##
+ # Expand all empty space in the data.
+ # This method does not change the data itself,
+ # but it does keep track of the expanded regions.
+ #
+ # @param data [Array>] The raw data
+ #
+ # @return [Array>] The raw data
+ def expand_space(data)
+ @expanded_regions = { rows: Set.new, columns: Set.new }
+ data.each_with_index do |row, row_id|
+ expanded_regions[:rows] << row_id unless row.include?(GALAXY_SYMBOL)
+ end
+ data.transpose.each_with_index do |column, column_id|
+ expanded_regions[:columns] << column_id unless column.include?(GALAXY_SYMBOL)
+ end
+
+ # Data remains unchanged
+ data
+ end
+
+ ##
+ # Get the distance between two galaxies.
+ # This method takes into account the expansion rate.
+ #
+ # @param galaxy1 [Array] The first galaxy
+ # @param galaxy2 [Array] The second galaxy
+ #
+ # @return [Integer] The distance between the two galaxies
+ def get_distance(galaxy1, galaxy2)
+ number_of_rows = get_1d_distance(galaxy1, galaxy2, dimension: :rows)
+ number_of_columns = get_1d_distance(galaxy1, galaxy2, dimension: :columns)
+ number_of_rows + number_of_columns
+ end
+
+ ##
+ # Get the distance between two galaxies in one dimension.
+ # This method takes into account the expansion rate.
+ #
+ # @param galaxy1 [Array] The first galaxy
+ # @param galaxy2 [Array] The second galaxy
+ # @param dimension [Symbol] The dimension to calculate the distance in
+ #
+ # @return [Integer] The distance between the two galaxies in the given dimension
+ def get_1d_distance(galaxy1, galaxy2, dimension:)
+ dim = dimension == :rows ? 0 : 1
+ min, max = [galaxy1[dim], galaxy2[dim]].minmax
+ (min...max).inject(0) do |sum, position|
+ sum + (expanded_regions[dimension].include?(position) ? expansion_rate : 1)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/sig/puzzles/2023/day11.rbs b/sig/puzzles/2023/day11.rbs
new file mode 100644
index 0000000..8ea9a69
--- /dev/null
+++ b/sig/puzzles/2023/day11.rbs
@@ -0,0 +1,39 @@
+module AdventOfCode
+ module Puzzles2023
+ module Day11
+ type galaxy = Array[Integer]
+ type data = Array[Array[Symbol]]
+ type pairs = Array[galaxy]
+ type positions = Array[galaxy]
+
+ class Part1
+ GALAXY_SYMBOL: Symbol
+
+ attr_reader space: data
+
+ def answer: -> Integer
+
+ def parse_file: (String) -> void
+
+ def expand_empty_space: (data) -> data
+
+ def expand_space: (data) -> data
+
+ def find_galaxies: -> positions
+
+ def make_pairs: (Integer) -> pairs
+
+ def get_distances: (pairs, positions) -> Array[Integer]
+
+ def get_distance: (galaxy, galaxy) -> Integer
+ end
+
+ class Part2 < Part1
+ attr_reader expansion_rate: Integer
+ attr_reader expanded_regions: Hash[Symbol, Set[Integer]]
+
+ def get_1d_distance: (galaxy, galaxy, Symbol) -> Integer
+ end
+ end
+ end
+end
diff --git a/sig/test/puzzles/2023/day11_test.rbs b/sig/test/puzzles/2023/day11_test.rbs
new file mode 100644
index 0000000..00ac6a3
--- /dev/null
+++ b/sig/test/puzzles/2023/day11_test.rbs
@@ -0,0 +1,33 @@
+module AdventOfCode
+ module Test
+ module Puzzles2023
+ module Day11
+ class Part1Test < MiniTest::Test
+ def setup: -> untyped
+
+ def teardown: -> untyped
+
+ def test_answer_test_data_set: -> untyped
+
+ def test_answer_input_set: -> untyped
+ end
+
+ class Part2Test < MiniTest::Test
+ def setup: -> untyped
+
+ def teardown: -> untyped
+
+ def test_answer_test_data_set_expansion_rate2: -> untyped
+
+ def test_answer_test_data_set_expansion_rate10: -> untyped
+
+ def test_answer_test_data_set_expansion_rate100: -> untyped
+
+ def test_answer_test_data_set_default_expansion_rate: -> untyped
+
+ def test_answer_input_set: -> untyped
+ end
+ end
+ end
+ end
+end
diff --git a/test/puzzles/2023/day11/day11_test.rb b/test/puzzles/2023/day11/day11_test.rb
new file mode 100644
index 0000000..09e28e6
--- /dev/null
+++ b/test/puzzles/2023/day11/day11_test.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+require "test_helper"
+require "puzzles/2023/day11/day11"
+
+module AdventOfCode
+ module Test
+ module Puzzles2023
+ module Day11
+ # Tests Day 11 - Part 1
+ class Part1Test < Minitest::Test
+ def setup
+ # Do nothing
+ end
+
+ def teardown
+ # Do nothing
+ end
+
+ def test_answer_test_data_set
+ input_file = "#{File.dirname(__FILE__)}/test_data.txt"
+ puzzle = AdventOfCode::Puzzles2023::Day11::Part1.new(file: input_file)
+
+ assert_equal 374, puzzle.answer
+ end
+
+ def test_answer_input_set
+ puzzle = AdventOfCode::Puzzles2023::Day11::Part1.new
+
+ assert_equal 10_313_550, puzzle.answer
+ end
+ end
+
+ # Tests Day 10 - Part 2
+ class Part2Test < Minitest::Test
+ def setup
+ # Do nothing
+ end
+
+ def teardown
+ # Do nothing
+ end
+
+ def test_answer_test_data_set_expansion_rate2
+ input_file = "#{File.dirname(__FILE__)}/test_data.txt"
+ puzzle = AdventOfCode::Puzzles2023::Day11::Part2.new(file: input_file, expansion_rate: 2)
+
+ assert_equal 374, puzzle.answer
+ end
+
+ def test_answer_test_data_set_expansion_rate10
+ input_file = "#{File.dirname(__FILE__)}/test_data.txt"
+ puzzle = AdventOfCode::Puzzles2023::Day11::Part2.new(file: input_file, expansion_rate: 10)
+
+ assert_equal 1_030, puzzle.answer
+ end
+
+ def test_answer_test_data_set_expansion_rate100
+ input_file = "#{File.dirname(__FILE__)}/test_data.txt"
+ puzzle = AdventOfCode::Puzzles2023::Day11::Part2.new(file: input_file, expansion_rate: 100)
+
+ assert_equal 8410, puzzle.answer
+ end
+
+ def test_answer_test_data_set_default_expansion_rate
+ input_file = "#{File.dirname(__FILE__)}/test_data.txt"
+ puzzle = AdventOfCode::Puzzles2023::Day11::Part2.new(file: input_file)
+
+ assert_equal 82_000_210, puzzle.answer
+ end
+
+ def test_answer_input_set
+ puzzle = AdventOfCode::Puzzles2023::Day11::Part2.new
+
+ assert_equal 611_998_089_572, puzzle.answer
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/test/puzzles/2023/day11/test_data.txt b/test/puzzles/2023/day11/test_data.txt
new file mode 100644
index 0000000..986aad4
--- /dev/null
+++ b/test/puzzles/2023/day11/test_data.txt
@@ -0,0 +1,10 @@
+...#......
+.......#..
+#.........
+..........
+......#...
+.#........
+.........#
+..........
+.......#..
+#...#.....