Ostatnio aktywny 2 days ago

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

Day2Part1.cs Surowy
1using BenTek.AdventOfCode.TwentyTwentyFive.Interfaces;
2
3namespace BenTek.AdventOfCode.TwentyTwentyFive.Days;
4
5public 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 Surowy
1using BenTek.AdventOfCode.TwentyTwentyFive.Interfaces;
2
3namespace BenTek.AdventOfCode.TwentyTwentyFive.Days;
4
5public 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}