Day 03 part two
Signed-off-by: Christopher Arndt <chris@chrisarndt.de>
This commit is contained in:
parent
098ab3f9c8
commit
6267bb6dd9
|
@ -1,18 +1,6 @@
|
||||||
import std/[cmdline, sequtils, strformat, strutils]
|
import std/[cmdline, sequtils, strformat, strutils, sugar]
|
||||||
|
|
||||||
var fn: string
|
proc isAdjacentToCond(grid: seq[seq[char]], row, col: int, cond: (char) -> bool): bool =
|
||||||
|
|
||||||
if paramCount() > 0:
|
|
||||||
fn = paramStr(1)
|
|
||||||
else:
|
|
||||||
fn = "input_03.txt"
|
|
||||||
|
|
||||||
var result = 0
|
|
||||||
var lines = readFile(fn).strip.splitLines
|
|
||||||
var grid = newSeqWith(lines.len, newSeq[char](lines[0].strip.len))
|
|
||||||
|
|
||||||
|
|
||||||
proc isAdjacentToSymbol(row, col: int): bool =
|
|
||||||
for i in @[row - 1, row, row + 1]:
|
for i in @[row - 1, row, row + 1]:
|
||||||
if i < 0 or i >= grid.len:
|
if i < 0 or i >= grid.len:
|
||||||
continue
|
continue
|
||||||
|
@ -22,11 +10,17 @@ proc isAdjacentToSymbol(row, col: int): bool =
|
||||||
if j < 0 or j >= grid[i].len:
|
if j < 0 or j >= grid[i].len:
|
||||||
continue
|
continue
|
||||||
var ch = grid[i][j]
|
var ch = grid[i][j]
|
||||||
if not ch.isDigit and ch != '.':
|
if cond(ch):
|
||||||
return true
|
return true
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
|
||||||
|
var fn = if paramCount() > 0: paramStr(1) else: "input_03.txt"
|
||||||
|
|
||||||
|
var result = 0
|
||||||
|
var lines = readFile(fn).strip.splitLines
|
||||||
|
var grid = newSeqWith(lines.len, newSeq[char](lines[0].strip.len))
|
||||||
|
|
||||||
for i, line in lines:
|
for i, line in lines:
|
||||||
for j, ch in line.strip:
|
for j, ch in line.strip:
|
||||||
grid[i][j] = ch
|
grid[i][j] = ch
|
||||||
|
@ -41,19 +35,26 @@ for i, row in grid:
|
||||||
for j, ch in row:
|
for j, ch in row:
|
||||||
if ch.isDigit:
|
if ch.isDigit:
|
||||||
number &= ch
|
number &= ch
|
||||||
if isAdjacentToSymbol(i, j):
|
if isAdjacentToCond(grid, i, j, (c) => not c.isDigit and c != '.'):
|
||||||
isPartNumber = true
|
isPartNumber = true
|
||||||
else:
|
else:
|
||||||
if isPartNumber:
|
if isPartNumber:
|
||||||
#echo number.parseInt
|
#echo number.parseInt
|
||||||
result += number.parseInt
|
result += number.parseInt
|
||||||
elif number.len > 0:
|
#elif number.len > 0:
|
||||||
echo &"Not a part number: {number.parseInt} (row {i}, col {j})"
|
# echo &"Not a part number: {number.parseInt} (row {i}, col {j})"
|
||||||
|
|
||||||
number = ""
|
number = ""
|
||||||
isPartNumber = false
|
isPartNumber = false
|
||||||
|
|
||||||
# account for numbers going untl the end of the row
|
# account for numbers going until the end of the row
|
||||||
if isPartNumber:
|
if isPartNumber:
|
||||||
result += number.parseInt
|
result += number.parseInt
|
||||||
|
|
||||||
echo &"Result: {result}"
|
echo &"Result: {result}"
|
||||||
|
|
||||||
|
case fn:
|
||||||
|
of "input_03.txt":
|
||||||
|
assert result == 559667
|
||||||
|
of "sample_input_03.txt":
|
||||||
|
assert result == 4361
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
import std/[cmdline, sequtils, strformat, strutils, sugar, tables]
|
||||||
|
|
||||||
|
type Position = tuple
|
||||||
|
row: int
|
||||||
|
col: int
|
||||||
|
|
||||||
|
## Check if any of the grid cells adjacent to position (i, j) match condition cond.
|
||||||
|
proc isAdjacentToCond(grid: seq[seq[char]], row, col: int, cond: (char) -> bool): Position =
|
||||||
|
for i in @[row - 1, row, row + 1]:
|
||||||
|
if i < 0 or i >= grid.len:
|
||||||
|
continue
|
||||||
|
for j in @[col - 1, col, col + 1]:
|
||||||
|
if i == row and j == col:
|
||||||
|
continue
|
||||||
|
if j < 0 or j >= grid[i].len:
|
||||||
|
continue
|
||||||
|
var ch = grid[i][j]
|
||||||
|
if cond(ch):
|
||||||
|
return (i, j)
|
||||||
|
return (-1, -1)
|
||||||
|
|
||||||
|
|
||||||
|
var fn = if paramCount() > 0: paramStr(1) else: "input_03.txt"
|
||||||
|
var result = 0
|
||||||
|
# read input file as seq of lines
|
||||||
|
var lines = readFile(fn).strip.splitLines
|
||||||
|
# allocate 2-D seq to hold ros and colums of characters
|
||||||
|
var grid = newSeqWith(lines.len, newSeq[char](lines[0].strip.len))
|
||||||
|
# table to save positions of gears and parts connected to it
|
||||||
|
var gears = initTable[Position, seq[int]]()
|
||||||
|
|
||||||
|
# Parse input
|
||||||
|
for i, line in lines:
|
||||||
|
for j, ch in line.strip:
|
||||||
|
grid[i][j] = ch
|
||||||
|
|
||||||
|
#echo &"Rows: {grid.len}"
|
||||||
|
#echo &"Cols: {grid[0].len}"
|
||||||
|
|
||||||
|
# Go through grid and find positions of gears
|
||||||
|
for i, row in grid:
|
||||||
|
var
|
||||||
|
isConnectedToGear = false
|
||||||
|
gear: Position
|
||||||
|
number = ""
|
||||||
|
|
||||||
|
for j, ch in row:
|
||||||
|
if ch.isDigit:
|
||||||
|
number &= ch
|
||||||
|
# Scan adjacent grid cells gor a gear ('*')
|
||||||
|
var symbol = isAdjacentToCond(grid, i, j, (c) => c == '*')
|
||||||
|
|
||||||
|
if symbol != (-1, -1):
|
||||||
|
# It's a number adjacent to a gear!
|
||||||
|
isConnectedToGear = true
|
||||||
|
gear = symbol
|
||||||
|
if not gears.hasKey(gear):
|
||||||
|
# save gear position in table
|
||||||
|
gears[gear] = newSeq[int]()
|
||||||
|
else:
|
||||||
|
if isConnectedToGear:
|
||||||
|
# add part to gear position saved above
|
||||||
|
# we can save an infinite amount of parts per gear
|
||||||
|
# but we assume that at most two parts are connected to a gear
|
||||||
|
gears[gear].add(number.parseInt)
|
||||||
|
|
||||||
|
number = ""
|
||||||
|
isConnectedToGear = false
|
||||||
|
|
||||||
|
# account for numbers going until the end of the row
|
||||||
|
if isConnectedToGear:
|
||||||
|
# add part to gear position saved above
|
||||||
|
gears[gear].add(number.parseInt)
|
||||||
|
|
||||||
|
# Sum up gear ratios
|
||||||
|
for pos, parts in gears:
|
||||||
|
# Ignore gears conencted to only one part
|
||||||
|
if parts.len > 1:
|
||||||
|
result += parts[0] * parts[1]
|
||||||
|
|
||||||
|
echo &"Result: {result}"
|
||||||
|
|
||||||
|
case fn:
|
||||||
|
of "input_03.txt":
|
||||||
|
assert result == 86841457
|
||||||
|
of "sample_input_03.txt":
|
||||||
|
assert result == 467835
|
Loading…
Reference in New Issue