/// <summary> /// Parse an incoming line based on '->' /// </summary> private Day7Operation ParseLine(string line) { var parts = line.Split("->", StringSplitOptions.TrimEntries); if (parts.Length != 2) { throw new Exception($"Invalid split: {line}"); } // Start our return object var ret = new Day7Operation() { outputRegister = parts[1] }; // 2 params: // AND // OR // LSHIFT // RSHIFT // NOT = 1 param // SET (1234 -> abc) = No params-ish var matches = (new Regex("^([a-z0-9]+) (AND|OR|LSHIFT|RSHIFT) ([a-z0-9]+)$")).Match(parts[0]); if (matches.Success) { ret.inA = matches.Groups[1].Value; ret.operation = matches.Groups[2].Value; ret.inB = matches.Groups[3].Value; UInt16 o; if (UInt16.TryParse(ret.inA, out o)) { ret.inA = string.Empty; ret.inAVal = o; } if (UInt16.TryParse(ret.inB, out o)) { ret.inB = string.Empty; ret.inBVal = o; } return(ret); } matches = (new Regex("^(NOT) ([a-z]+)$")).Match(parts[0]); if (matches.Success) { ret.inA = matches.Groups[2].Value; ret.operation = matches.Groups[1].Value; return(ret); } matches = (new Regex("^([0-9a-z]+)$")).Match(parts[0]); if (matches.Success) { ret.inA = matches.Groups[1].Value; ret.operation = "SET"; // If this is a hard-coded integer, this is a starting point UInt16 o; if (UInt16.TryParse(ret.inA, out o)) { ret.setValue = o; ret.order = 0; } return(ret); } // No results throw new Exception($"Unable to find a match for: {line}"); }
private void ProcessOperation(Day7Operation operation) { UInt16 value = 0; switch (operation.operation) { case "SET": { if (operation.setValue < UInt16.MaxValue) { value = operation.setValue; } else { value = GetRegister(operation.inA); } break; } case "AND": { UInt16 a = operation.inAVal < UInt16.MaxValue ? operation.inAVal : GetRegister(operation.inA); UInt16 b = operation.inBVal < UInt16.MaxValue ? operation.inBVal : GetRegister(operation.inB); value = (UInt16)(a & b); break; } case "OR": { UInt16 a = operation.inAVal < UInt16.MaxValue ? operation.inAVal : GetRegister(operation.inA); UInt16 b = operation.inBVal < UInt16.MaxValue ? operation.inBVal : GetRegister(operation.inB); value = (UInt16)(a | b); break; } case "NOT": { UInt16 a = operation.inAVal < UInt16.MaxValue ? operation.inAVal : GetRegister(operation.inA); value = (UInt16)(~a); break; } case "LSHIFT": { UInt16 a = operation.inAVal < UInt16.MaxValue ? operation.inAVal : GetRegister(operation.inA); UInt16 b = operation.inBVal < UInt16.MaxValue ? operation.inBVal : GetRegister(operation.inB); value = (UInt16)(a << b); break; } case "RSHIFT": { UInt16 a = operation.inAVal < UInt16.MaxValue ? operation.inAVal : GetRegister(operation.inA); UInt16 b = operation.inBVal < UInt16.MaxValue ? operation.inBVal : GetRegister(operation.inB); value = (UInt16)(a >> b); break; } } SaveRegister(operation.outputRegister, value); }