diff --git a/2021/4/second.nim b/2021/4/second.nim new file mode 100644 index 0000000..5247cc1 --- /dev/null +++ b/2021/4/second.nim @@ -0,0 +1,43 @@ +import + ../../adventofcode, + math, + sequtils, + strutils, + strformat + +import + x/board + +let input = adventofcode.getInput(2021, 4) +let lines = input.splitLines()[0 .. ^2] + +let drawn = lines[0].split(",").mapIt(it.parseInt()) +var currentlyDrawn: seq[int] = @[] +var boards: seq[Board] = @[] + +# Determinate boards from our input +var currBoard = newBoard() +for line in lines[2 .. ^1]: + if line.len() != 0: + currBoard.grid.add line.split(" ").filterIt(it.len() > 0).mapIt(it.parseInt()) + + else: + boards.add currBoard + currBoard = newBoard() + +var winningBoards: seq[Board] +while currentlyDrawn.len() != drawn.len() and winningBoards.len() < boards.len(): + let next = drawn[currentlyDrawn.len()] + currentlyDrawn.add next + + for board in boards: + board.markNumber next + + if board.winning and not winningBoards.contains board: + winningBoards.add board + +let lastWinningBoard = winningBoards[^1] +let lastWinningBoardScore = currentlyDrawn[^1] * math.sum lastWinningBoard.getUnmarkedNumbers() + +echo fmt"Boards: {boards.len()}" +echo fmt"Answer: {lastWinningBoardScore}" \ No newline at end of file diff --git a/2021/5/both.nim b/2021/5/both.nim new file mode 100644 index 0000000..1d7cb69 --- /dev/null +++ b/2021/5/both.nim @@ -0,0 +1,92 @@ +import + ../../adventofcode, + hashes, + sequtils, + strutils, + strformat, + tables + +type + Grid = TableRef[Point, int] + + HydrothermalVent = object + x1, x2, y1, y2: int + + Point = object + x, y: int + +## https://stackoverflow.com/questions/919612/mapping-two-integers-to-one-in-a-unique-and-deterministic-way +#[ +A = a >= 0 ? 2 * a : -2 * a - 1; +B = b >= 0 ? 2 * b : -2 * b - 1; +A >= B ? A * A + A + B : A + B * B; +]# +proc hash(p: Point): Hash = + let A = + if p.x >= 0: 2 * p.x + else: -2 * p.x - 1 + let B = + if p.y >= 0: 2 * p.y + else: -2 * p.y - 1 + return + if A >= B: A * A + A + B + else: A + B * B + +proc getPoints(v: HydrothermalVent): seq[Point] = + let xd = max(v.x1, v.x2) - min(v.x1, v.x2) + let yd = max(v.y1, v.y2) - min(v.y1, v.y2) + when defined(second): + let xoffset = v.x2 - v.x1 + let yoffset = v.y2 - v.y1 + + if xd != 0 and v.y1 == v.y2: + for i in 0 .. xd: + result.add Point(x: min(v.x1, v.x2) + i, y: v.y1) + + elif yd != 0 and v.x1 == v.x2: + for i in 0 .. yd: + result.add Point(x: v.x1, y: min(v.y1, v.y2) + i) + + else: + when defined(second): + # TODO: + if xoffset < 0: + for i in 0 .. xd: + result.add Point( + x: min(v.x1, v.x2) + i, + y: max(v.y1, v.y2) - i + ) + + else: + for i in 0 .. yd: + result.add Point( + x: max(v.x1, v.x2) + i, + y: min(v.y1, v.y2) + i + ) + +proc parseInput(input: string): seq[HydrothermalVent] = + for line in input.splitLines()[0 .. ^2]: + let coords = line.split(" -> ").mapIt(it.split(",").mapIt(it.parseInt())) + result.add HydrothermalVent( + x1: coords[0][0], y1: coords[0][1], x2: coords[1][0], y2: coords[1][1] + ) + +static: + let dummyVent = HydrothermalVent(x1: 9, y1: 7, x2: 7, y2: 9) + for point in dummyVent.getPoints(): + echo $point + +let input = adventofcode.getInput(2021, 5) +let vents = input.parseInput() +let grid = Grid() + +for vent in vents: + let points = vent.getPoints() + for point in points: + if not grid.hasKey point: + grid[point] = 1 + else: + grid[point] += 1 + +let overlappingPoints = toSeq(grid.values).countIt(it > 1) +echo fmt"Answer: {overlappingPoints}" \ No newline at end of file