Skip to content

Commit 25305e7

Browse files
11-2023
1 parent db6872b commit 25305e7

File tree

6 files changed

+439
-23
lines changed

6 files changed

+439
-23
lines changed

2023/Day11/README.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
original source: [https://adventofcode.com/2023/day/11](https://adventofcode.com/2023/day/11)
2+
## --- Day 11: Cosmic Expansion ---
3+
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.
4+
5+
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.
6+
7+
Maybe you can help him with the analysis to speed things up?
8+
9+
The researcher has collected a bunch of data and compiled the data into a single giant <em>image</em> (your puzzle input). The image includes <em>empty space</em> (<code>.</code>) and <em>galaxies</em> (<code>#</code>). For example:
10+
11+
<pre>
12+
<code>...#......
13+
.......#..
14+
#.........
15+
..........
16+
......#...
17+
.#........
18+
.........#
19+
..........
20+
.......#..
21+
#...#.....
22+
</code>
23+
</pre>
24+
25+
The researcher is trying to figure out the sum of the lengths of the <em>shortest path between every pair of galaxies</em>. However, there's a catch: the universe expanded in the time it took the light from those galaxies to reach the observatory.
26+
27+
Due to something involving gravitational effects, <em>only some space expands</em>. In fact, the result is that <em>any rows or columns that contain no galaxies</em> should all actually be twice as big.
28+
29+
In the above example, three columns and two rows contain no galaxies:
30+
31+
<pre>
32+
<code> v v v
33+
...#......
34+
.......#..
35+
#.........
36+
>..........<
37+
......#...
38+
.#........
39+
.........#
40+
>..........<
41+
.......#..
42+
#...#.....
43+
^ ^ ^
44+
</code>
45+
</pre>
46+
47+
These rows and columns need to be <em>twice as big</em>; the result of cosmic expansion therefore looks like this:
48+
49+
<pre>
50+
<code>....#........
51+
.........#...
52+
#............
53+
.............
54+
.............
55+
........#....
56+
.#...........
57+
............#
58+
.............
59+
.............
60+
.........#...
61+
#....#.......
62+
</code>
63+
</pre>
64+
65+
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:
66+
67+
<pre>
68+
<code>....1........
69+
.........2...
70+
3............
71+
.............
72+
.............
73+
........4....
74+
.5...........
75+
............6
76+
.............
77+
.............
78+
.........7...
79+
8....9.......
80+
</code>
81+
</pre>
82+
83+
In these 9 galaxies, there are <em>36 pairs</em>. 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 <code>.</code> or <code>#</code> at a time. (The shortest path between two galaxies is allowed to pass through another galaxy.)
84+
85+
For example, here is one of the shortest paths between galaxies <code>5</code> and <code>9</code>:
86+
87+
<pre>
88+
<code>....1........
89+
.........2...
90+
3............
91+
.............
92+
.............
93+
........4....
94+
.5...........
95+
.##.........6
96+
..##.........
97+
...##........
98+
....##...7...
99+
8....9.......
100+
</code>
101+
</pre>
102+
103+
This path has length <code><em>9</em></code> because it takes a minimum of <em>nine steps</em> to get from galaxy <code>5</code> to galaxy <code>9</code> (the eight locations marked <code>#</code> plus the step onto galaxy <code>9</code> itself). Here are some other example shortest path lengths:
104+
105+
106+
- Between galaxy <code>1</code> and galaxy <code>7</code>: 15
107+
- Between galaxy <code>3</code> and galaxy <code>6</code>: 17
108+
- Between galaxy <code>8</code> and galaxy <code>9</code>: 5
109+
110+
In this example, after expanding the universe, the sum of the shortest path between all 36 pairs of galaxies is <code><em>374</em></code>.
111+
112+
Expand the universe, then find the length of the shortest path between every pair of galaxies. <em>What is the sum of these lengths?</em>
113+
114+
115+
## --- Part Two ---
116+
The galaxies are much <em>older</em> (and thus much <em>farther apart</em>) than the researcher initially estimated.
117+
118+
Now, instead of the expansion you did before, make each empty row or column <em>one million times</em> larger. That is, each empty row should be replaced with <code>1000000</code> empty rows, and each empty column should be replaced with <code>1000000</code> empty columns.
119+
120+
(In the example above, if each empty row or column were merely <code>10</code> times larger, the sum of the shortest paths between every pair of galaxies would be <code><em>1030</em></code>. If each empty row or column were merely <code>100</code> times larger, the sum of the shortest paths between every pair of galaxies would be <code><em>8410</em></code>. However, your universe will need to expand far beyond these values.)
121+
122+
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. <em>What is the sum of these lengths?</em>
123+
124+

2023/Day11/Solution.cs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
namespace AdventOfCode.Y2023.Day11;
6+
7+
[ProblemName("Cosmic Expansion")]
8+
class Solution : Solver
9+
{
10+
private const char GalaxySymbol = '#';
11+
12+
public object PartOne(string input)
13+
{
14+
var lines = ParseLines(input);
15+
var emptyLineIndexes = GetEmptyLineIndexes(lines);
16+
var emptyColumnIndexes = GetEmptyColumnIndexes(lines);
17+
18+
var galaxies = GetGalaxies(lines);
19+
var pairs = GetPairs(galaxies, emptyColumnIndexes, emptyLineIndexes);
20+
21+
return pairs.Sum(pair => pair.Distance + pair.NumberOfEmptySpacesToBeExpandedCrossed);
22+
}
23+
24+
public object PartTwo(string input)
25+
{
26+
var lines = ParseLines(input);
27+
var emptyLineIndexes = GetEmptyLineIndexes(lines);
28+
var emptyColumnIndexes = GetEmptyColumnIndexes(lines);
29+
30+
var galaxies = GetGalaxies(lines);
31+
var pairs = GetPairs(galaxies, emptyColumnIndexes, emptyLineIndexes);
32+
33+
return pairs.Sum(pair => pair.Distance + (999_999 * pair.NumberOfEmptySpacesToBeExpandedCrossed));
34+
}
35+
36+
private static IEnumerable<Pair> GetPairs(
37+
IReadOnlyList<Position> galaxies,
38+
IReadOnlyList<int> emptyColumnIndexes,
39+
IReadOnlyList<int> emptyLineIndexes)
40+
{
41+
List<Pair> pairs = [];
42+
for (var index = 0; index < galaxies.Count; index++)
43+
{
44+
var galaxy = galaxies[index];
45+
for (var j = index + 1; j < galaxies.Count; j++)
46+
{
47+
var otherGalaxy = galaxies[j];
48+
var distance = ComputeDistance(galaxy, otherGalaxy);
49+
var numberOfEmptySpacesToBeExpandedCrossed =
50+
emptyColumnIndexes.Count(emptyColumnIndex => IsBetween(emptyColumnIndex, galaxy.X, otherGalaxy.X)) +
51+
emptyLineIndexes.Count(emptyLineIndex => IsBetween(emptyLineIndex, galaxy.Y, otherGalaxy.Y));
52+
53+
pairs.Add(new Pair(distance, numberOfEmptySpacesToBeExpandedCrossed));
54+
}
55+
}
56+
57+
return pairs;
58+
}
59+
60+
private static bool IsBetween(int value, int end1, int end2) =>
61+
value > Math.Min(end1, end2) && value < Math.Max(end1, end2);
62+
63+
private static List<Position> GetGalaxies(IReadOnlyList<string> linesList)
64+
{
65+
List<Position> galaxies = [];
66+
for (var i = 0; i < linesList.Count; i++)
67+
{
68+
var line = linesList[i];
69+
for (var j = 0; j < line.Length; j++)
70+
{
71+
if (line[j] == GalaxySymbol)
72+
{
73+
galaxies.Add(new Position(j, i));
74+
}
75+
}
76+
}
77+
78+
return galaxies;
79+
}
80+
81+
private static List<int> GetEmptyColumnIndexes(IReadOnlyList<string> lines)
82+
{
83+
List<int> emptyColumnIndexes = [];
84+
for (var j = 0; j < lines[0].Length; j++)
85+
{
86+
var emptyColumn = lines.All(line => line[j] != GalaxySymbol);
87+
88+
if (emptyColumn)
89+
{
90+
emptyColumnIndexes.Add(j);
91+
}
92+
}
93+
94+
return emptyColumnIndexes;
95+
}
96+
97+
private static List<int> GetEmptyLineIndexes(IReadOnlyList<string> lines)
98+
{
99+
List<int> emptyLineIndexes = [];
100+
101+
for (var i = 0; i < lines.Count; i++)
102+
{
103+
if (!lines[i].Contains(GalaxySymbol))
104+
{
105+
emptyLineIndexes.Add(i);
106+
}
107+
}
108+
109+
return emptyLineIndexes;
110+
}
111+
112+
private static double ComputeDistance(Position galaxy, Position otherGalaxy)
113+
{
114+
return Math.Abs(galaxy.X - otherGalaxy.X) + Math.Abs(galaxy.Y - otherGalaxy.Y);
115+
}
116+
117+
118+
private static List<string> ParseLines(string input)
119+
{
120+
return input.Split("\n").ToList();
121+
}
122+
}
123+
124+
internal readonly struct Position(int x, int y)
125+
{
126+
public int X { get; } = x;
127+
public int Y { get; } = y;
128+
}
129+
130+
internal readonly struct Pair(
131+
double distance,
132+
double numberOfEmptySpacesToBeExpandedCrossed)
133+
{
134+
public double Distance { get; } = distance;
135+
public double NumberOfEmptySpacesToBeExpandedCrossed { get; } = numberOfEmptySpacesToBeExpandedCrossed;
136+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy