Day 03 part two

Signed-off-by: Christopher Arndt <chris@chrisarndt.de>
This commit is contained in:
Christopher Arndt 2023-12-03 13:33:19 +01:00
parent 098ab3f9c8
commit 6267bb6dd9
2 changed files with 107 additions and 19 deletions

View File

@ -1,18 +1,6 @@
import std/[cmdline, sequtils, strformat, strutils]
import std/[cmdline, sequtils, strformat, strutils, sugar]
var fn: string
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 =
proc isAdjacentToCond(grid: seq[seq[char]], row, col: int, cond: (char) -> bool): bool =
for i in @[row - 1, row, row + 1]:
if i < 0 or i >= grid.len:
continue
@ -22,11 +10,17 @@ proc isAdjacentToSymbol(row, col: int): bool =
if j < 0 or j >= grid[i].len:
continue
var ch = grid[i][j]
if not ch.isDigit and ch != '.':
if cond(ch):
return true
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 j, ch in line.strip:
grid[i][j] = ch
@ -41,19 +35,26 @@ for i, row in grid:
for j, ch in row:
if ch.isDigit:
number &= ch
if isAdjacentToSymbol(i, j):
if isAdjacentToCond(grid, i, j, (c) => not c.isDigit and c != '.'):
isPartNumber = true
else:
if isPartNumber:
#echo number.parseInt
result += number.parseInt
elif number.len > 0:
echo &"Not a part number: {number.parseInt} (row {i}, col {j})"
#elif number.len > 0:
# echo &"Not a part number: {number.parseInt} (row {i}, col {j})"
number = ""
isPartNumber = false
# account for numbers going untl the end of the row
# account for numbers going until the end of the row
if isPartNumber:
result += number.parseInt
echo &"Result: {result}"
case fn:
of "input_03.txt":
assert result == 559667
of "sample_input_03.txt":
assert result == 4361

87
day_03/solution_03b.nim Normal file
View File

@ -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