~deciduously/aoc2020

9a84bd97a3fc82718f34ce8cdfbb0f185cddc7de — Ben Lovy 1 year, 6 months ago 7541b95
Create runner
23 files changed, 126 insertions(+), 72 deletions(-)

D 1/day1
D 2/day2
D 3/day3
D 4/day4
D 5/day5
M README.md
A aoc
A aoc.nim
R 1/day1.nim => day1.nim
R 2/day2.nim => day2.nim
R 3/day3.nim => day3.nim
R 4/day4.nim => day4.nim
R 5/day5.nim => day5.nim
A helpers.nim
R 1/day1part1 => puzzles/day1.txt
R 2/day2puzzle => puzzles/day2.txt
R 3/puzzle => puzzles/day3.txt
R 4/puzzle => puzzles/day4.txt
R 5/puzzle => puzzles/day5.txt
R 1/day1sample => samples/day1.txt
R 2/day2sample => samples/day2.txt
R 3/sample => samples/day3.txt
R 4/sample => samples/day4.txt
D 1/day1 => 1/day1 +0 -0
D 2/day2 => 2/day2 +0 -0
D 3/day3 => 3/day3 +0 -0
D 4/day4 => 4/day4 +0 -0
D 5/day5 => 5/day5 +0 -0
M README.md => README.md +5 -1
@@ 1,3 1,7 @@
# aoc2020

Advent of Code 2020 in Nim.
\ No newline at end of file
Advent of Code 2020 in Nim.

## Usage

Install [Nim](https://nim-lang.org/install.html).  Run `nim compile --run aoc.nim 1`.  Pass the desired day to execute.  It will place the `aoc` binary in the current directio for subsequent runs with, e.g. `./aoc 1`.
\ No newline at end of file

A aoc => aoc +0 -0
A aoc.nim => aoc.nim +56 -0
@@ 0,0 1,56 @@
# This file is the main interface.
import day1, day2, day3, day4, day5
import os, strutils

proc getDay(): int =
    let params = commandLineParams()
    if len(params) != 1:
        stderr.writeLine("Usage: <aoc> X - please pass exactly one number.  Pass 0 to run all")
        quit(1)

    parseInt(params[0])

proc runDay(day: int) =
    let min = 0
    let max = 5
    if day < min or day > max:
        stderr.writeLine("Must pass day in ", min, " to ", max, " inclusive.")
        quit(1)
    
    case day:
        of 0:
            # TODO can this be automated?  A macro, perhaps...
            echo "Day 1:"
            day1()
            echo "\nDay 2:"
            day2()
            echo "\nDay 3:"
            day3()
            echo "\nDay 4:"
            day4()
            echo "\nDay 5:"
            day5()
        of 1:
            day1()
        of 2:
            day2()
        of 3:
            day3()
        of 4:
            day4()
        of 5:
            day5()
        else: echo "Unreachable..."

proc main() =
    echo "Advent of Code 2020!\n"
    let day = getDay()
    if day == 0:
        echo "Running all days..."
    else:
        echo "Running day ", day, "..."
    echo()
    runDay(day)
    quit(0)
    
main()
\ No newline at end of file

R 1/day1.nim => day1.nim +13 -23
@@ 1,15 1,5 @@
import strutils

proc readFile(name: string): seq[int] =
    let f = open(name)
    defer: f.close()

    var ret: seq[int] = @[]

    for line in f.lines:
        ret.add(parseInt(line))

    ret
import helpers
import sequtils, strutils

proc findPair(target: int, vals: openArray[int]): (int, int) =
    for idx, x in vals:


@@ 34,16 24,16 @@ proc findThree(target: int, vals: openArray[int]): (int, int, int) =
    # what on fail
    (-1, -1, -1)

proc part1() =
    let ret = readFile("day1part1")
    let (x, y) = findPair(2020, ret)        
    echo "Results: ", x, " and ", y, ". Multiplied: ", x * y

part1()
proc part1(input: openArray[int]) =
    let (x, y) = findPair(2020, input)        
    echo "Part 1: ", x, " and ", y, ". Multiplied: ", x * y

proc part2() = 
    let ret = readFile("day1part1")
    let (x, y, z) = findThree(2020, ret)        
    echo "Results: ", x, ", ", y, ", and ", z, ". Multiplied: ", x * y * z
proc part2(input: openArray[int]) =
    let (x, y, z) = findThree(2020, input)        
    echo "Part 2: ", x, ", ", y, ", and ", z, ". Multiplied: ", x * y * z

part2()
\ No newline at end of file
proc day1*() =
    let raw = readLinesToStrSeq("puzzles/day1.txt")
    let input = map(raw, proc(s: string): int = parseInt(s))
    part1(input)
    part2(input)
\ No newline at end of file

R 2/day2.nim => day2.nim +12 -16
@@ 1,16 1,6 @@
import helpers
import strutils

proc readLines(name: string): seq[string] =
    let f = open(name)
    defer: f.close()

    var ret: seq[string] = @[]

    for line in f.lines:
        ret.add(line)

    ret

proc part1(str: string): bool =
    # split into parts
    # store min, max, char


@@ 64,8 54,14 @@ proc part2(str: string): bool =
    if pos1res and pos2res: return false
    pos1res or pos2res

let lines = readLines("day2puzzle")
var total = 0
for line in lines:
    if part2(line): total += 1
echo total
\ No newline at end of file
proc day2*() =
    let lines = readLinesToStrSeq("puzzles/day2.txt")
    var total = 0
    for line in lines:
        if part1(line): total += 1
    echo "Part 1: ", total

    total = 0
    for line in lines:
        if part2(line): total += 1
    echo "Part 2: ", total
\ No newline at end of file

R 3/day3.nim => day3.nim +12 -13
@@ 1,13 1,4 @@
proc readLines(name: string): seq[string] =
    let f = open(name)
    defer: f.close()

    var ret: seq[string] = @[]

    for line in f.lines:
        ret.add(line)

    ret
import helpers

type
    Row = seq[bool]


@@ 42,7 33,7 @@ type

proc newMap(filename: string): Map =
    Map(
        grid: inputToGrid(readLines(filename)),
        grid: inputToGrid(readLinesToStrSeq(filename)),
        position: (0, 0)
    )



@@ 72,5 63,13 @@ proc traverse(map: Map, right: int, down: int): int =
proc tryAllSlopes(map: Map): int =
    map.traverse(1, 1) * map.traverse(3, 1) * map.traverse(5, 1) * map.traverse(7, 1) * map.traverse(1, 2)

var map = newMap("puzzle")
echo map.tryAllSlopes()
\ No newline at end of file
proc part1(input: Map) =
    echo "Part 1: ", input.traverse(3, 1)

proc part2(input: Map) =
    echo "Part 2: ", input.tryAllSlopes()

proc day3*() =
    var map = newMap("puzzles/day3.txt")
    part1(map)
    part2(map)
\ No newline at end of file

R 4/day4.nim => day4.nim +13 -15
@@ 1,6 1,7 @@
import options, re, strutils

proc readLines(name: string): seq[string] =
# Don't use the helper for this one - different delimiiter.
proc readLinesToSeqStr(name: string): seq[string] =
    var ret: seq[string] = @[]

    # Delimiter is two newlines for this


@@ 22,12 23,6 @@ type
        pid: Option[string]
        cid: Option[string]

proc `$`(p: Passport): string =
    if p.pid.isSome:
        p.pid.get()
    else:
        "No ID"

proc newPassport(): Passport =
    Passport(byr: none(string), iyr: none(string), eyr: none(string), hgt: none(
            string), hcl: none(string), ecl: none(string), pid: none(string),


@@ 94,16 89,19 @@ proc isValidPartTwo(p: Passport): bool =
    validateHcl(p.hcl) and validateEcl(p.ecl) and validatePid(p.pid)

proc generatePassports(filename: string): seq[Passport] =
    let strs = readLines(filename)
    let strs = readLinesToSeqStr(filename)
    var ret = newSeq[Passport]()
    for str in strs:
        ret.add(passportFromString(str))
    ret

let passports = generatePassports("puzzle")
echo passports
var res = 0
for pass in passports:
    if pass.isValidPartTwo(): res += 1

echo res
proc day4*() =
    let passports = generatePassports("puzzles/day4.txt")
    var res = 0
    for pass in passports:
        if pass.isValidPartOne(): res += 1
    echo "Part 1: ", res
    res = 0
    for pass in passports:
        if pass.isValidPartTwo(): res += 1
    echo "Part 2: ", res

R 5/day5.nim => day5.nim +5 -4
@@ 56,7 56,7 @@ proc findSeat(str: string): int =


proc getAllIds(): seq[int] =
    let allPasses = readLines("puzzle")
    let allPasses = readLines("puzzles/day5.txt")
    map(allPasses, proc(s: string): int = findSeat(s))

proc findHighest(allIds: openArray[int]): int =


@@ 68,9 68,10 @@ proc findMissing(allIds: seq[int]): int =
    for idx, n in a:
        if a[idx + 1] != n + 1: return n + 1

var allIds = getAllIds()
echo findHighest(allIds)
echo findMissing(allIds)
proc day5*() =
    var allIds = getAllIds()
    echo "Part 1: ", findHighest(allIds)
    echo "Part 2: ", findMissing(allIds)

# echo findSeat("FBFBBFFRLR") # (44, 5) - 357
# echo findSeat("BFFFBBFRRR") # (70, 7) - 567

A helpers.nim => helpers.nim +10 -0
@@ 0,0 1,10 @@
proc readLinesToStrSeq*(name: string): seq[string] =
    let f = open(name)
    defer: f.close()

    var ret: seq[string] = @[]

    for line in f.lines:
        ret.add(line)

    ret
\ No newline at end of file

R 1/day1part1 => puzzles/day1.txt +0 -0
R 2/day2puzzle => puzzles/day2.txt +0 -0
R 3/puzzle => puzzles/day3.txt +0 -0
R 4/puzzle => puzzles/day4.txt +0 -0
R 5/puzzle => puzzles/day5.txt +0 -0
R 1/day1sample => samples/day1.txt +0 -0
R 2/day2sample => samples/day2.txt +0 -0
R 3/sample => samples/day3.txt +0 -0
R 4/sample => samples/day4.txt +0 -0