C# - no regex, 235ms for part 2. down to 51ms when I put each range on its own thread
spoiler
public class Day2
{
public void Go()
{
//var input = File.ReadAllText("Day2/ExampleData.txt");
var input = File.ReadAllText("Day2/RealData.txt");
var inputs = input.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
var pairs = inputs.Select(s =>
s.Split('-', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
.Select(s => new Tuple<Int64,Int64>(Int64.Parse(s[0]), Int64.Parse(s[1])));
Int64 sum = 0;
foreach (var pair in pairs)
{
sum += CheckPair2(pair);
}
Console.WriteLine($"Total invalid sum: {sum}");
}
public Int64 CheckPair(Tuple<Int64, Int64> pair)
{
Int64 sum = 0;
for (Int64 i = pair.Item1; i <= pair.Item2; i++)
{
var s = i.ToString();
if (s.Length%2 == 1)
{
continue;
}
var p1 = s.Substring(0, s.Length/2);
var p2 = s.Substring(s.Length/2);
if (p1 == p2)
{
Console.WriteLine($"INVALID PAIR: {s} is made up of {p1} and {p2}");
sum += i;
}
}
return sum;
}
public Int64 CheckPair2(Tuple<Int64, Int64> pair)
{
Int64 sum = 0;
for (Int64 id = pair.Item1; id <= pair.Item2; id++)
{
var s = id.ToString();
for (int searchLength = 1; searchLength <= s.Length/2; searchLength++)
{
if (s.Length%searchLength != 0)
{
continue;
}
var valid = true;
var firstSet = s.Substring(0, searchLength);
for (int repeatPosition = 1; repeatPosition < s.Length/searchLength; repeatPosition++)
{
var checkSet = s.Substring(searchLength*repeatPosition, searchLength);
if (firstSet != checkSet)
{
valid = false;
break;
}
}
if (valid)
{
Console.WriteLine($"INVALID ID: {s} is made up of {firstSet} {s.Length/searchLength} times");
sum += id;
break;
}
}
}
return sum;
}
}