import 2017 solutions I found in my github gists
This commit is contained in:
parent
fc0f216511
commit
568a43b115
4
2017/README.md
Normal file
4
2017/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
# 2017
|
||||
While going through my Github gists, I found a few AoC days from 2017, so I decided to include them here for later reference.
|
||||
|
||||
Apparently, I got a total of 15 stars that year, but I have no idea where my code for most of the solutions is.
|
69
2017/day08.nim
Normal file
69
2017/day08.nim
Normal file
@ -0,0 +1,69 @@
|
||||
import tables
|
||||
import nre
|
||||
import strutils
|
||||
|
||||
|
||||
let pattern = re"(?<target>\w+)\s(?<opcode>(inc|dec))\s(?<value>-?\d+)\sif\s(?<comptarget>\w+)\s(?<compop>(<|>|==|!=|<=|>=))\s(?<comp2>-?\d+)"
|
||||
|
||||
var registers = initTable[string, int]();
|
||||
|
||||
|
||||
proc parseLine(li: string): RegexMatch =
|
||||
let found = nre.find(li, pattern)
|
||||
if found.isNone:
|
||||
echo("mismatch")
|
||||
return
|
||||
return found.get()
|
||||
|
||||
|
||||
proc compare(target: string, val2: int, op: string): bool =
|
||||
# text parsing done right ヽ( ゚ヮ・)ノ
|
||||
let val1 = registers[target]
|
||||
case op
|
||||
of "<":
|
||||
return val1 < val2;
|
||||
of ">":
|
||||
return val1 > val2;
|
||||
of "==":
|
||||
return val1 == val2;
|
||||
of "!=":
|
||||
return val1 != val2;
|
||||
of "<=":
|
||||
return val1 <= val2;
|
||||
of ">=":
|
||||
return val1 >= val2;
|
||||
else: discard
|
||||
|
||||
|
||||
proc changeRegister(r: string, op: string, val: int): void =
|
||||
# only ‘inc’ and ‘dec’ are possible
|
||||
if op == "inc":
|
||||
registers[r] += val
|
||||
else:
|
||||
registers[r] -= val
|
||||
|
||||
|
||||
proc executeLine(ins: Table): void =
|
||||
# set registers to 0 if they haven’t been initialized
|
||||
if not registers.hasKey(ins["comptarget"]):
|
||||
registers[ins["comptarget"]] = 0
|
||||
if not registers.hasKey(ins["target"]):
|
||||
registers[ins["target"]] = 0
|
||||
# do math... or don’t
|
||||
if compare(ins["comptarget"], parseInt(ins["comp2"]), ins["compop"]):
|
||||
changeRegister(ins["target"], ins["opcode"], parseInt(ins["value"]))
|
||||
|
||||
|
||||
for line in lines "day8.txt":
|
||||
let parsed = parseLine(line)
|
||||
executeLine(parsed.captures.toTable())
|
||||
|
||||
|
||||
# returning a list like with python’s dict.values doesn’t seem to work.
|
||||
# is there a way to convert iterables to arrays?
|
||||
var maximum = 0
|
||||
for v in values(registers):
|
||||
if v > maximum:
|
||||
maximum = v
|
||||
|
||||
echo(maximum)
|
83
2017/day19.nim
Normal file
83
2017/day19.nim
Normal file
@ -0,0 +1,83 @@
|
||||
import sequtils
|
||||
import future
|
||||
import nre except toSeq
|
||||
|
||||
|
||||
|
||||
type
|
||||
Direction = enum
|
||||
up = 0, left = 1, down = 2, right = 3
|
||||
Grid = seq[seq[char]]
|
||||
|
||||
const directions = [up, left, down, right]
|
||||
|
||||
proc indexOf(hay: seq[char], needle: char): int =
|
||||
# It almost seems weird that this doesn’t already exist...
|
||||
# It probably does, and I just missed it. Whatever, no error handling because :lul:
|
||||
var i = 0
|
||||
while hay[i] != needle:
|
||||
i += 1
|
||||
return i
|
||||
|
||||
|
||||
proc gridGet(g: Grid, p: array[2, int]): char =
|
||||
return g[p[0]][p[1]]
|
||||
|
||||
|
||||
proc changePosition(current: array[2, int], dir: Direction): array[2, int] =
|
||||
if dir == up:
|
||||
return [current[0]-1, current[1]]
|
||||
if dir == left:
|
||||
return [current[0], current[1]-1]
|
||||
if dir == down:
|
||||
return [current[0]+1, current[1]]
|
||||
if dir == right:
|
||||
return [current[0], current[1]+1]
|
||||
|
||||
|
||||
proc oppositeDirection(d: Direction): Direction =
|
||||
# the better solution would be something like
|
||||
# mod(getEnumOrdinal(direction, $direction) + 2, 4)
|
||||
# but that doesn’t quite work because I’m bad at this whole thing
|
||||
case d
|
||||
of up: return down
|
||||
of left: return right
|
||||
of down: return up
|
||||
of right: return left
|
||||
else: discard
|
||||
|
||||
proc changeDirection(g: Grid, pos: array[2, int], direction: Direction): Direction =
|
||||
for d in directions:
|
||||
if d != oppositeDirection(direction) and gridGet(g, changePosition(pos, d)) != ' ':
|
||||
return d
|
||||
|
||||
|
||||
let grid = lc[toSeq(line.items()) | (line <- lines("input.txt")), seq[char]]
|
||||
|
||||
var position = [0, indexOf(grid[0], '|')]
|
||||
var direction = down
|
||||
var done = false
|
||||
var visited = ""
|
||||
var newchar: char
|
||||
var steps = 1
|
||||
|
||||
while not done:
|
||||
#echo position[0], ", ", position[1]
|
||||
#echo direction
|
||||
var newpos = changePosition(position, direction)
|
||||
newchar = gridGet(grid, newpos)
|
||||
#echo(newchar)
|
||||
if newchar in ['|', '-']:
|
||||
inc steps
|
||||
elif newchar == '+':
|
||||
inc steps
|
||||
direction = changeDirection(grid, newpos, direction)
|
||||
elif nre.contains($newchar, re"[A-Z]"):
|
||||
inc steps
|
||||
visited &= newchar
|
||||
elif newchar == ' ':
|
||||
done = true
|
||||
position = newpos
|
||||
|
||||
echo(visited)
|
||||
echo(steps)
|
108
2017/day20.nim
Normal file
108
2017/day20.nim
Normal file
@ -0,0 +1,108 @@
|
||||
import strutils
|
||||
import future
|
||||
import nre
|
||||
|
||||
|
||||
# 3-dimensional vector type with attributes for x, y, and z
|
||||
# Mainly used for readability
|
||||
type Vector = object
|
||||
x, y, z: int
|
||||
|
||||
# Are there proper constructors in nim?
|
||||
# I guess this is... something.
|
||||
proc newVector(x: int, y: int, z: int): Vector =
|
||||
var v: Vector
|
||||
v.x = x
|
||||
v.y = y
|
||||
v.z = z
|
||||
return v
|
||||
|
||||
# Manhattan Distance. Should be self-explanatory
|
||||
method manhattan(this: Vector): int {.base.} =
|
||||
return abs(this.x) + abs(this.y) + abs(this.z)
|
||||
|
||||
proc countZeros(v: Vector): int =
|
||||
var z = 0
|
||||
for c in [v.x, v.y, v.z]:
|
||||
if c == 0:
|
||||
inc z
|
||||
return z
|
||||
|
||||
proc `$`(v: Vector): string =
|
||||
return $v.x & ", " & $v.y & ", " & $v.z
|
||||
|
||||
proc `<`(a: Vector, b:Vector): bool =
|
||||
if manhattan(a) == manhattan(b):
|
||||
return countZeros(a) < countZeros(b)
|
||||
return manhattan(a) < manhattan(b)
|
||||
|
||||
proc `>`(a: Vector, b:Vector): bool =
|
||||
if a == b:
|
||||
return countZeros(a) > countZeros(b)
|
||||
return manhattan(a) > manhattan(b)
|
||||
|
||||
proc `==`(a: Vector, b:Vector): bool =
|
||||
return a.x == b.x and a.y == b.y and a.z == b.z
|
||||
|
||||
proc `!=`(a: Vector, b:Vector): bool =
|
||||
return not (a == b)
|
||||
|
||||
|
||||
type Particle = object
|
||||
number: int
|
||||
velocity: Vector
|
||||
acceleration: Vector
|
||||
position: Vector
|
||||
|
||||
proc newParticle(n: int, vel: Vector, acc: Vector, pos: Vector): Particle =
|
||||
var p: Particle
|
||||
p.number = n
|
||||
p.velocity = vel
|
||||
p.acceleration = acc
|
||||
p.position = pos
|
||||
return p
|
||||
|
||||
proc `>`(a: Particle, b: Particle): bool =
|
||||
if a.acceleration == b.acceleration:
|
||||
if a.velocity == b.velocity:
|
||||
return a.position > b.position
|
||||
return a.velocity > b.velocity
|
||||
return a.acceleration > b.acceleration
|
||||
|
||||
proc `<`(a: Particle, b: Particle): bool =
|
||||
if a.acceleration == b.acceleration:
|
||||
if a.velocity == b.velocity:
|
||||
return a.position < b.position
|
||||
return a.velocity < b.velocity
|
||||
return a.acceleration < b.acceleration
|
||||
|
||||
proc min(arr: seq[Particle]): Particle =
|
||||
var m = arr[0]
|
||||
for p in arr:
|
||||
if p < m:
|
||||
m = p
|
||||
return m
|
||||
|
||||
|
||||
|
||||
let input = lc[line | (line <- lines("input.txt")), string]
|
||||
var particles: seq[Particle] = @[]
|
||||
|
||||
# p=<-1027,-979,-188>, v=<7,60,66>, a=<9,1,-7>
|
||||
for i in 0..(len(input)-1):
|
||||
let line = input[i]
|
||||
let parsed = nre.match(line, re"p=.(?<px>-?\d+),(?<py>-?\d+),(?<pz>-?\d+).,\sv=.(?<vx>-?\d+),(?<vy>-?\d+),(?<vz>-?\d+).,\sa=.(?<ax>-?\d+),(?<ay>-?\d+),(?<az>-?\d+)")
|
||||
if parsed.isNone():
|
||||
echo("Could not parse ", line)
|
||||
continue
|
||||
let matched = parsed.get().captures
|
||||
# echo(i, ": ", line)
|
||||
particles.add(
|
||||
newParticle(i,
|
||||
newVector(parseInt(matched["vx"]), parseInt(matched["vy"]), parseInt(matched["vz"])),
|
||||
newVector(parseInt(matched["ax"]), parseInt(matched["ay"]), parseInt(matched["az"])),
|
||||
newVector(parseInt(matched["px"]), parseInt(matched["py"]), parseInt(matched["pz"]))
|
||||
)
|
||||
)
|
||||
|
||||
echo(min(particles).number)
|
Loading…
Reference in New Issue
Block a user