initial commit, day 10
This commit is contained in:
263
dotnet/07/07a.cs
Normal file
263
dotnet/07/07a.cs
Normal file
@@ -0,0 +1,263 @@
|
||||
void Main1()
|
||||
{
|
||||
var eqs = LoadEqs(Path.Join("..", "..", "07a.txt"));
|
||||
long total = 0;
|
||||
foreach (var eq in eqs)
|
||||
{
|
||||
if (eq.Test1())
|
||||
{
|
||||
total += eq.Target;
|
||||
}
|
||||
}
|
||||
Console.WriteLine($"Solution {total}");
|
||||
}
|
||||
|
||||
void Main2()
|
||||
{
|
||||
var eqs = LoadEqs(Path.Join("..", "..", "07a.txt"));
|
||||
long total = 0;
|
||||
foreach (var eq in eqs)
|
||||
{
|
||||
if (eq.Test2())
|
||||
{
|
||||
total += eq.Target;
|
||||
}
|
||||
}
|
||||
Console.WriteLine($"Solution1 {total}");
|
||||
}
|
||||
|
||||
void Main2_take2()
|
||||
{
|
||||
var eqs = LoadEqs(Path.Join("..", "..", "07a.txt"));
|
||||
long total = 0;
|
||||
foreach (var eq in eqs)
|
||||
{
|
||||
if (eq.Test3())
|
||||
{
|
||||
total += eq.Target;
|
||||
}
|
||||
}
|
||||
Console.WriteLine($"Solution (exp) {total}");
|
||||
}
|
||||
|
||||
void Main2_take3()
|
||||
{
|
||||
var eqs = LoadEqs(Path.Join("..", "..", "07a.txt"));
|
||||
long total = 0;
|
||||
foreach (var eq in eqs)
|
||||
{
|
||||
if (eq.Test4())
|
||||
{
|
||||
total += eq.Target;
|
||||
}
|
||||
}
|
||||
Console.WriteLine($"Solution {total}");
|
||||
}
|
||||
|
||||
void Main2_take2and3()
|
||||
{
|
||||
var eqs = LoadEqs(Path.Join("..", "..", "07a.txt"));
|
||||
long total = 0;
|
||||
foreach (var eq in eqs)
|
||||
{
|
||||
var t3 = eq.Test3();
|
||||
var t4 = eq.Test4();
|
||||
if (t3 != t4)
|
||||
{
|
||||
Console.WriteLine((t4 ? "Pass " : "Fail ") + eq.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main1();
|
||||
Main2();
|
||||
// Main2_take2();
|
||||
// Main2_take3();
|
||||
// Main2_take2and3();
|
||||
|
||||
List<EQ> LoadEqs(string filepath)
|
||||
{
|
||||
var lines = File.ReadAllLines(filepath).ToList();
|
||||
if (string.IsNullOrWhiteSpace(lines.Last()))
|
||||
lines.RemoveAt(lines.Count()-1);
|
||||
List<EQ> eqs = new();
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var parts = line.Split(':');
|
||||
eqs.Add(new(
|
||||
long.Parse(parts[0]),
|
||||
parts[1].Trim().Split(' ').Select(long.Parse)
|
||||
));
|
||||
}
|
||||
return eqs;
|
||||
}
|
||||
|
||||
class EQ
|
||||
{
|
||||
public long Target;
|
||||
public List<long> Terms;
|
||||
public EQ(long target, IEnumerable<long> terms)
|
||||
{
|
||||
Target = target;
|
||||
Terms = terms.ToList();
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Target}: {string.Join(' ', Terms)}";
|
||||
}
|
||||
public bool Test1()
|
||||
{
|
||||
return InnerTest1(Target, Terms.First(), Terms.Skip(1));
|
||||
}
|
||||
private static bool InnerTest1(long target, long current, IEnumerable<long> terms)
|
||||
{
|
||||
if (current > target)
|
||||
return false;
|
||||
var term = terms.Cast<long?>().FirstOrDefault();
|
||||
if (term is long _term)
|
||||
{
|
||||
return InnerTest1(target, current + _term, terms.Skip(1))
|
||||
|| InnerTest1(target, current * _term, terms.Skip(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
return target == current;
|
||||
}
|
||||
}
|
||||
public bool Test2()
|
||||
{
|
||||
return InnerTest2(Target, Terms.First(), Terms, 1);
|
||||
}
|
||||
private static bool InnerTest2(long target, long current, IList<long> terms, int index)
|
||||
{
|
||||
if (current > target)
|
||||
return false;
|
||||
if (index >= terms.Count())
|
||||
return target == current;
|
||||
var term = terms[index];
|
||||
return InnerTest2(target, current + term, terms, index + 1)
|
||||
|| InnerTest2(target, current * term, terms, index + 1)
|
||||
|| InnerTest2(target, Concat(current, term), terms, index + 1);
|
||||
}
|
||||
public bool Test3()
|
||||
{
|
||||
return InnerTest3(Target, Terms.First(), Terms.Skip(1)) == Result.Success;
|
||||
}
|
||||
private static Result InnerTest3(long target, long current, IEnumerable<long> terms)
|
||||
{
|
||||
if (current > target)
|
||||
return Result.AllOverflow;
|
||||
var term = terms.Cast<long?>().FirstOrDefault();
|
||||
var remaining = terms.Skip(1);
|
||||
if (term is long _term)
|
||||
{
|
||||
return current switch
|
||||
{
|
||||
1 => InnerTest3(target, _term, remaining) switch
|
||||
{
|
||||
Result.MixedFailures => InnerTest3(target, 1 + _term, remaining) switch
|
||||
{
|
||||
Result.Success => Result.Success,
|
||||
Result.AllOverflow => Result.MixedFailures,
|
||||
_ => InnerTest3(target, Concat(1, _term), remaining) switch
|
||||
{
|
||||
Result.Success => Result.Success,
|
||||
_ => Result.MixedFailures,
|
||||
},
|
||||
},
|
||||
Result res => res,
|
||||
},
|
||||
0 => InnerTest3(target, 0, remaining) switch
|
||||
{
|
||||
Result.MixedFailures => InnerTest3(target, _term, remaining) switch
|
||||
{
|
||||
Result.Success => Result.Success,
|
||||
_ => Result.MixedFailures,
|
||||
},
|
||||
Result res => res,
|
||||
},
|
||||
long _current => _term switch
|
||||
{
|
||||
1 => InnerTest3(target, _current, remaining) switch
|
||||
{
|
||||
Result.MixedFailures => InnerTest3(target, _current + 1, remaining) switch
|
||||
{
|
||||
Result.Success => Result.Success,
|
||||
Result.MixedFailures => InnerTest3(target, _current * 10 + 1, remaining) switch
|
||||
{
|
||||
Result.Success => Result.Success,
|
||||
_ => Result.MixedFailures,
|
||||
},
|
||||
_ => Result.MixedFailures,
|
||||
},
|
||||
Result res => res,
|
||||
},
|
||||
_ => InnerTest3(target, _current + _term, remaining) switch
|
||||
{
|
||||
Result.MixedFailures => InnerTest3(target, _current * _term, remaining) switch
|
||||
{
|
||||
Result.Success => Result.Success,
|
||||
Result.AllOverflow => Result.MixedFailures,
|
||||
_ => InnerTest3(target, Concat(_current, _term), remaining) switch
|
||||
{
|
||||
Result.Success => Result.Success,
|
||||
_ => Result.MixedFailures,
|
||||
},
|
||||
},
|
||||
Result res => res,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
return (target - current) switch
|
||||
{
|
||||
//should be impossible due to earlier check
|
||||
< 0 => Result.AllOverflow,
|
||||
0 => Result.Success,
|
||||
> 0 => Result.MixedFailures,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static long Concat(long first, long second)
|
||||
{
|
||||
return first * Shift(second) + second;
|
||||
}
|
||||
public bool Test4()
|
||||
{
|
||||
return InnerTest4(Target, Terms, Terms.Count() - 1);
|
||||
}
|
||||
private static bool InnerTest4(long current, IList<long> terms, int index)
|
||||
{
|
||||
long term = terms[index];
|
||||
if (index == 0)
|
||||
return current == term;
|
||||
if (InnerTest4(current - term, terms, index - 1))
|
||||
return true;
|
||||
if (current % term == 0 && InnerTest4(current / term, terms, index - 1))
|
||||
return true;
|
||||
var shift = Shift(term);
|
||||
if ((current % shift == term) && InnerTest4(current / shift, terms, index - 1))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
private static long Shift(long num)
|
||||
{
|
||||
var digits = ((long)Math.Log10(num+0.5)) + 1;
|
||||
long shift = 1;
|
||||
while (digits > 0)
|
||||
{
|
||||
shift *= 10;
|
||||
digits--;
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
enum Result
|
||||
{
|
||||
AllOverflow,
|
||||
MixedFailures,
|
||||
Success,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user