95 lines
2.4 KiB
Nim
95 lines
2.4 KiB
Nim
|
import std/strutils
|
||
|
import std/sequtils
|
||
|
import system
|
||
|
|
||
|
type Pos = object
|
||
|
X: int
|
||
|
Y: int
|
||
|
|
||
|
type Rope = object
|
||
|
Head: Pos
|
||
|
Tail: Pos
|
||
|
|
||
|
proc move_rope(input: Rope, vec: Pos): Rope =
|
||
|
var rope = input
|
||
|
rope.Head.X += vec.X
|
||
|
rope.Head.Y += vec.Y
|
||
|
|
||
|
let deltaX = rope.Head.X - rope.Tail.X
|
||
|
let deltaY = rope.Head.Y - rope.Tail.Y
|
||
|
|
||
|
if not (abs(deltaX) >= 2 or abs(deltaY) >= 2): return rope
|
||
|
|
||
|
if deltaX > 0:
|
||
|
rope.Tail.X += 1
|
||
|
elif deltaX < 0:
|
||
|
rope.Tail.X -= 1
|
||
|
|
||
|
if deltaY > 0:
|
||
|
rope.Tail.Y += 1
|
||
|
elif deltaY < 0:
|
||
|
rope.Tail.Y -= 1
|
||
|
|
||
|
return rope
|
||
|
|
||
|
proc print_rope(r: Rope, width: int, height: int) =
|
||
|
for y in -height .. height:
|
||
|
for x in -width .. width:
|
||
|
let ishead = (x == r.Head.X and y == r.Head.Y)
|
||
|
let istail = (x == r.Tail.X and y == r.Tail.Y)
|
||
|
let iszero = (x == 0 and y == 0 )
|
||
|
if ishead and istail:
|
||
|
io.stdout.write "@"
|
||
|
elif ishead:
|
||
|
io.stdout.write "H"
|
||
|
elif istail:
|
||
|
io.stdout.write "T"
|
||
|
elif iszero:
|
||
|
io.stdout.write "s"
|
||
|
else:
|
||
|
io.stdout.write "."
|
||
|
io.stdout.write "\n"
|
||
|
io.stdout.write "\n"
|
||
|
|
||
|
proc run09_1(): string =
|
||
|
const input = staticRead"../input/day09.txt"
|
||
|
|
||
|
let lines = splitLines(input).filter(proc(p: string): bool = p != "")
|
||
|
|
||
|
var rope = Rope(Head: Pos(X: 0, Y: 0), Tail: Pos(X: 0, Y: 0))
|
||
|
|
||
|
var tailposmap = @[rope.Tail]
|
||
|
|
||
|
# print_rope(rope, 200, 200)
|
||
|
|
||
|
for line in lines:
|
||
|
let dir = case line.split(" ")[0][0]:
|
||
|
of 'U': Pos(X: 00, Y: -1)
|
||
|
of 'D': Pos(X: 00, Y: +1)
|
||
|
of 'L': Pos(X: -1, Y: 00)
|
||
|
of 'R': Pos(X: +1, Y: 00)
|
||
|
else: Pos(X: 00, Y: 00)
|
||
|
|
||
|
let cnt = parseInt(line.split(" ")[1])
|
||
|
|
||
|
for _ in 0 ..< cnt:
|
||
|
# echo "== ", line, " ==", " (dir: [", dir.X, "|", dir.Y, "] )"
|
||
|
|
||
|
rope = move_rope(rope, dir)
|
||
|
|
||
|
tailposmap.add(rope.Tail)
|
||
|
|
||
|
# print_rope(rope, 100, 100)
|
||
|
#echo "[", rope.Tail.X, ";", rope.Tail.Y, "] -> [", rope.Head.X, ";", rope.Head.Y, "]"
|
||
|
|
||
|
# echo tailposmap.deduplicate()
|
||
|
|
||
|
return tailposmap.deduplicate().len().intToStr()
|
||
|
|
||
|
|
||
|
when not defined(js):
|
||
|
echo run09_1()
|
||
|
else:
|
||
|
proc js_run09_1(): cstring {.exportc.} =
|
||
|
return cstring(run09_1())
|