import std/[strutils, sequtils, math] import aoc proc parseInstruction(i: string): (int, int) = let s = i.split(',') assert s.len == 2 result = (parseInt(s[0]), parseInt(s[1])) proc parseInput(input: string): seq[(int, int)] = var i: int while i < input.len: case input[i] of 'm': # ul(x,y) # not enough space so bail if i > (input.len - 6): return else: var instruction: string if input[i .. i+3] == "mul(": i += 4 while true: let c = input[i] case c: of '0'..'9': instruction.add c; inc i of ')': result.add parseInstruction instruction break of ',': instruction.add c; inc i else: break inc i else: inc i proc partOne*(input: string): int = let instructions = parseInput(input) instructions.mapIt(it[0] * it[1]).sum() proc parseInput2(input: string): seq[(int, int)] = var i: int var working = true while i < input.len: case input[i] of 'd': # check for enough room for don't() if i > (input.len - 6): inc i else: if input[i .. i + 3] == "do()": working = true i += 3 elif input[i .. i + 6] == "don't()": working = false i += 6 inc i of 'm': # ul(x,y) # not enough space for instruction so bail if i > (input.len - 6): return else: var instruction: string if input[i .. i+3] == "mul(": i += 4 while true: let c = input[i] case c: of '0'..'9': instruction.add c; inc i of ')': if working: result.add parseInstruction instruction break of ',': instruction.add c; inc i else: break inc i else: inc i proc partTwo*(input: string): int = let instructions = parseInput2(input) instructions.mapIt(it[0] * it[1]).sum() solve: "example.txt": partOne: 161 "example2.txt": partTwo: 48 "input.txt": partOne: 164730528 partTwo: 70478672