-
Notifications
You must be signed in to change notification settings - Fork 10
/
Day09.cs
74 lines (64 loc) · 2.38 KB
/
Day09.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
using AdventOfCode.CSharp.Common;
using System;
using System.Collections.Generic;
using System.Text;
namespace AdventOfCode.CSharp.Y2015.Solvers;
public class Day09 : ISolver
{
public static void Solve(ReadOnlySpan<byte> input, Solution solution)
{
// get list of towns and edges from input
var townSet = new HashSet<string>();
var distances = new Dictionary<(string From, string To), int>();
foreach (Range lineRange in input.SplitLines())
{
ParseLine(input[lineRange], out int distance, out string fromName, out string toName);
townSet.Add(fromName);
townSet.Add(toName);
distances[(fromName, toName)] = distance;
distances[(toName, fromName)] = distance;
}
// convert adjacency list to adjacency matrix
string[] townNames = [.. townSet];
int numTowns = townNames.Length;
int[,] adjMatrix = new int[numTowns, numTowns];
int[] towns = new int[numTowns];
for (int a = 0; a < numTowns; a++)
{
towns[a] = a;
for (int b = 0; b < numTowns; b++)
{
if (a != b)
{
adjMatrix[a, b] = distances[(townNames[a], townNames[b])];
}
}
}
int minDistance = int.MaxValue;
int maxDistance = int.MinValue;
foreach (ReadOnlySpan<int> perm in towns.AsSpan().GetPermutations())
{
int pathDistance = 0;
int prevTown = perm[0];
for (int j = 1; j < numTowns; j++)
{
int town = perm[j];
pathDistance += adjMatrix[prevTown, town];
prevTown = town;
}
minDistance = Math.Min(minDistance, pathDistance);
maxDistance = Math.Max(maxDistance, pathDistance);
}
solution.SubmitPart1(minDistance);
solution.SubmitPart2(maxDistance);
}
private static void ParseLine(ReadOnlySpan<byte> line, out int distance, out string fromName, out string toName)
{
var reader = new SpanReader(line);
fromName = Encoding.ASCII.GetString(reader.ReadUntil(' '));
reader.SkipLength("to ".Length);
toName = Encoding.ASCII.GetString(reader.ReadUntil(' '));
reader.SkipLength("= ".Length);
distance = reader.ReadPosIntUntilEnd();
}
}