-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day18.cs
70 lines (57 loc) · 2.47 KB
/
Day18.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
using System;
using System.Linq;
using System.Text.RegularExpressions;
using Aoc2020Net.Utilities;
namespace Aoc2020Net.Days
{
internal sealed class Day18 : Day
{
public override object SolvePart1() => GetEvaluatedExpressionsSum(EvaluateSimpleExpression);
public override object SolvePart2() => GetEvaluatedExpressionsSum(EvaluateSimpleExpressionWithAdditionFirst);
private long GetEvaluatedExpressionsSum(Func<string, long> evaluateSimpleExpression) =>
InputData.GetInputLines().Select(line => EvaluateExpression(line, evaluateSimpleExpression)).Sum();
private static long EvaluateExpression(string expression, Func<string, long> evaluateSimpleExpression)
{
var subExpressionRegex = new Regex(@"\([^()]+?\)");
var subExpressionsCount = expression.CountValue('(');
for (var i = 0; i < subExpressionsCount; i++)
{
expression = subExpressionRegex.Replace(expression, m => evaluateSimpleExpression(m.Value.Trim('(', ')')).ToString());
}
return evaluateSimpleExpression(expression);
}
private static long EvaluateSimpleExpressionWithAdditionFirst(string expression)
{
var expressionWithAdditionsInParentheses = Regex.Replace(expression, @"[\d\s+]+", m => $" ({m.Value.Trim()}) ");
return EvaluateExpression(expressionWithAdditionsInParentheses, EvaluateSimpleExpression);
}
private static long EvaluateSimpleExpression(string expression)
{
const char noOperation = ' ';
const string noNumber = "";
var result = 0L;
var operation = noOperation;
var numberString = noNumber;
foreach (var symbol in $"{expression}.".Where(c => c != ' '))
{
if (char.IsDigit(symbol))
numberString += symbol;
else
{
var number = long.Parse(numberString);
result = operation == noOperation
? number
: operation switch
{
'+' => result + number,
'*' => result * number,
_ => result
};
operation = symbol;
numberString = noNumber;
}
}
return result;
}
}
}