2023 Day 13 Part 1
This commit is contained in:
parent
73a7104f8f
commit
a4588253ba
1 changed files with 98 additions and 0 deletions
98
2023/day13.nim
Normal file
98
2023/day13.nim
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import std/algorithm
|
||||
import std/deques
|
||||
import std/enumerate
|
||||
import std/math
|
||||
import std/options
|
||||
import std/sequtils
|
||||
import std/sets
|
||||
import std/strscans
|
||||
import std/strutils
|
||||
import std/sugar
|
||||
import std/tables
|
||||
import std/terminal
|
||||
|
||||
proc dbg[T](v: T): T = (echo(v); v)
|
||||
|
||||
func empty[T](v: seq[T]): bool = v.len == 0
|
||||
|
||||
type Point = tuple
|
||||
r: int
|
||||
c: int
|
||||
|
||||
type Pattern = object
|
||||
height: int
|
||||
width: int
|
||||
|
||||
grid: Table[Point, char]
|
||||
|
||||
rows: seq[seq[char]]
|
||||
cols: seq[seq[char]]
|
||||
|
||||
func parsePattern(text: string): Pattern =
|
||||
let lines = text.strip.splitLines()
|
||||
result.height = lines.len
|
||||
result.width = lines[0].len
|
||||
|
||||
for r in 0 ..< result.height:
|
||||
result.rows.add @[]
|
||||
|
||||
for c in 0 ..< result.width:
|
||||
result.cols.add @[]
|
||||
|
||||
for (r, line) in enumerate(lines):
|
||||
for (c, sym) in enumerate(line):
|
||||
result.grid[(r, c)] = sym
|
||||
result.rows[r] &= @[sym]
|
||||
result.cols[c] &= @[sym]
|
||||
|
||||
func parsePatterns(text: string): seq[Pattern] =
|
||||
text.strip.split("\n\n").map(parsePattern)
|
||||
|
||||
func col(p: Pattern, c: int): (seq[char], bool) =
|
||||
if c in p.cols.low .. p.cols.high:
|
||||
(p.cols[c], true)
|
||||
else:
|
||||
(@[], false)
|
||||
|
||||
func row(p: Pattern, r: int): (seq[char], bool) =
|
||||
if r in p.rows.low .. p.rows.high:
|
||||
(p.rows[r], true)
|
||||
else:
|
||||
(@[], false)
|
||||
|
||||
proc reflectAtV(p: Pattern, c: int): bool =
|
||||
for dc in 0 .. c:
|
||||
let (l, okL) = p.col(c-dc - 1)
|
||||
let (r, okR) = p.col(c+dc)
|
||||
if okL and okR and l != r:
|
||||
return false
|
||||
true
|
||||
|
||||
proc reflectAtH(p: Pattern, r: int): bool =
|
||||
for dr in 0 ..< r:
|
||||
let (u, okU) = p.row(r-dr - 1)
|
||||
let (d, okD) = p.row(r+dr)
|
||||
if okU and okD and d != u:
|
||||
return false
|
||||
true
|
||||
|
||||
proc reflectVertical(p: Pattern): int =
|
||||
for c in 1 ..< p.width:
|
||||
if p.reflectAtV(c):
|
||||
return c
|
||||
|
||||
proc reflectHorizontal(p: Pattern): int =
|
||||
for r in 1 ..< p.height:
|
||||
if p.reflectAtH(r):
|
||||
return r
|
||||
|
||||
proc part1(input: string): int =
|
||||
let text = readFile(input)
|
||||
let patterns = parsePatterns(text)
|
||||
|
||||
for pattern in patterns:
|
||||
result.inc pattern.reflectVertical
|
||||
result.inc 100 * pattern.reflectHorizontal
|
||||
|
||||
echo part1("input/test.txt")
|
||||
echo part1("input/day13.txt")
|
||||
Loading…
Reference in a new issue