Last active 2 days ago

My implementation of solving Day 2 of 2025's Advent of Code.

ben revised this gist 2 days ago. Go to revision

No changes

ben revised this gist 2 days ago. Go to revision

No changes

ben revised this gist 2 days ago. Go to revision

2 files changed, 267 insertions

Day2Part1.cs(file created)

@@ -0,0 +1,111 @@
1 + using BenTek.AdventOfCode.TwentyTwentyFive.Interfaces;
2 +
3 + namespace BenTek.AdventOfCode.TwentyTwentyFive.Days;
4 +
5 + public class Day2Part1 : IPuzzle
6 + {
7 + private class Bounds
8 + {
9 + public long Upper { get; }
10 + public long Lower { get; }
11 +
12 + public Bounds(long lower, long upper)
13 + {
14 + Upper = upper;
15 + Lower = lower;
16 + }
17 +
18 + public Bounds(string range)
19 + {
20 + string[] bounds = range.Split('-');
21 + Lower = long.Parse(bounds[0]);
22 + Upper = long.Parse(bounds[1]);
23 + }
24 + }
25 +
26 + /// <inheritdoc />
27 + public string ExpectedTestValue1 => "1227775554";
28 +
29 + public string TestDataPath =>
30 + Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data", "Day2", "sample_input.txt");
31 + public string RealDataPath =>
32 + Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data", "Day2", "input.txt");
33 +
34 + /// <inheritdoc />
35 + public bool Test()
36 + {
37 + string input = Utilities.FileLoader.LoadFile(TestDataPath);
38 + string result = Logic(input);
39 + bool passing = result == ExpectedTestValue1;
40 + if (!passing)
41 + {
42 + Console.WriteLine($"Expected {ExpectedTestValue1} but got {result}");
43 + }
44 + return passing;
45 + }
46 +
47 + /// <inheritdoc />
48 + public string Run()
49 + {
50 + string input = Utilities.FileLoader.LoadFile(RealDataPath);
51 + string result = Logic(input);
52 + return result;
53 + }
54 +
55 + /// <inheritdoc />
56 + public string Logic(string input)
57 + {
58 + List<Bounds> boundsList = new List<Bounds>();
59 + string[] ranges = input.Split(',');
60 + foreach (string range in ranges)
61 + {
62 + boundsList.Add(new Bounds(range));
63 + }
64 +
65 + List<long> invalidIDs = new List<long>();
66 +
67 + for (int i = 0; i < boundsList.Count; i++)
68 + {
69 + Bounds bounds = boundsList[i];
70 +
71 + for (long j = bounds.Lower; j <= bounds.Upper; j++) // Inclusive
72 + {
73 + if (!IsValid(j))
74 + {
75 + invalidIDs.Add(j);
76 + }
77 + }
78 + }
79 +
80 + long total = 0;
81 +
82 + foreach (long invalidID in invalidIDs)
83 + {
84 + total += invalidID;
85 + }
86 +
87 + return total.ToString();
88 + }
89 +
90 + private bool IsValid(long id)
91 + {
92 + string idStr = id.ToString();
93 + int length = idStr.Length;
94 + if (length % 2 == 1)
95 + {
96 + return true;
97 + }
98 +
99 + int subSize = length / 2;
100 +
101 + string left = idStr.Substring(0, subSize);
102 + string right = idStr.Substring(subSize);
103 +
104 + if (left.Length != right.Length)
105 + {
106 + Console.WriteLine($"Error: {left} is a different length to {right}");
107 + }
108 +
109 + return left != right;
110 + }
111 + }

Day2Part2.cs(file created)

@@ -0,0 +1,156 @@
1 + using BenTek.AdventOfCode.TwentyTwentyFive.Interfaces;
2 +
3 + namespace BenTek.AdventOfCode.TwentyTwentyFive.Days;
4 +
5 + public class Day2Part2 : IPuzzle
6 + {
7 + private class Bounds
8 + {
9 + public long Upper { get; }
10 + public long Lower { get; }
11 +
12 + public Bounds(long lower, long upper)
13 + {
14 + Upper = upper;
15 + Lower = lower;
16 + }
17 +
18 + public Bounds(string range)
19 + {
20 + string[] bounds = range.Split('-');
21 + Lower = long.Parse(bounds[0]);
22 + Upper = long.Parse(bounds[1]);
23 + }
24 + }
25 +
26 + /// <inheritdoc />
27 + public string ExpectedTestValue1 => "4174379265";
28 +
29 + public string TestDataPath =>
30 + Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data", "Day2", "sample_input.txt");
31 + public string RealDataPath =>
32 + Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data", "Day2", "input.txt");
33 +
34 + private string[] WrongAnswers => ["31210613313"];
35 +
36 + /// <inheritdoc />
37 + public bool Test()
38 + {
39 + string input = Utilities.FileLoader.LoadFile(TestDataPath);
40 + string result = Logic(input);
41 + bool passing = result == ExpectedTestValue1;
42 + if (!passing)
43 + {
44 + Console.WriteLine($"Expected {ExpectedTestValue1} but got {result}");
45 + }
46 + return passing;
47 + }
48 +
49 + /// <inheritdoc />
50 + public string Run()
51 + {
52 + string input = Utilities.FileLoader.LoadFile(RealDataPath);
53 + string result = Logic(input);
54 + if (!CheckAnswer(result))
55 + {
56 + return $" - {result} is the wrong answer";
57 + }
58 + return result;
59 + }
60 +
61 + /// <inheritdoc />
62 + public string Logic(string input)
63 + {
64 + List<Bounds> boundsList = new List<Bounds>();
65 + string[] ranges = input.Split(',');
66 + foreach (string range in ranges)
67 + {
68 + boundsList.Add(new Bounds(range));
69 + }
70 +
71 + List<long> invalidIDs = new List<long>();
72 +
73 + for (int i = 0; i < boundsList.Count; i++)
74 + {
75 + Bounds bounds = boundsList[i];
76 +
77 + for (long j = bounds.Lower; j <= bounds.Upper; j++) // Inclusive
78 + {
79 + if (!IsValid(j))
80 + {
81 + invalidIDs.Add(j);
82 + }
83 + }
84 + }
85 +
86 + long total = 0;
87 +
88 + foreach (long invalidID in invalidIDs)
89 + {
90 + total += invalidID;
91 + }
92 +
93 + return total.ToString();
94 + }
95 +
96 + private bool IsValid(long id)
97 + {
98 + string idStr = id.ToString();
99 + int length = idStr.Length;
100 +
101 + for (int i = 2; i <= length; i++)
102 + {
103 + float strideFloat = length / (float)i;
104 +
105 + if (strideFloat % 1f > 0)
106 + {
107 + continue;
108 + }
109 +
110 + int stride = (int)strideFloat;
111 +
112 + List<string> substrings = new List<string>();
113 + for (int j = 0; j < length / stride; j++)
114 + {
115 + substrings.Add(idStr.Substring(j * stride, stride));
116 + }
117 +
118 + if (!UniformSubstrings(substrings))
119 + {
120 + continue;
121 + }
122 +
123 + return false;
124 + }
125 +
126 + return true;
127 + }
128 +
129 + private bool UniformSubstrings(List<string> substrings)
130 + {
131 + string prototype = substrings[0];
132 +
133 + for (int j = 1; j < substrings.Count; j++)
134 + {
135 + if (substrings[j] != prototype)
136 + {
137 + return false;
138 + }
139 + }
140 +
141 + return true;
142 + }
143 +
144 + private bool CheckAnswer(string answer)
145 + {
146 + foreach (string wrongAnswer in WrongAnswers)
147 + {
148 + if (answer == wrongAnswer)
149 + {
150 + return false;
151 + }
152 + }
153 +
154 + return true;
155 + }
156 + }
Newer Older