This commit is contained in:
parent
0ff6053926
commit
5e5192c9a3
|
@ -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}"
|
|
@ -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}"
|
Loading…
Reference in New Issue