From 0ff60539267c2eaf9af4897ab06eec1a2ae9edb0 Mon Sep 17 00:00:00 2001 From: Danny Harpigny Date: Thu, 30 Dec 2021 16:31:29 +0100 Subject: [PATCH] --- .gitignore | 2 ++ 2021/1/first.nim | 20 +++++++++++++++++++ 2021/1/second.nim | 22 ++++++++++++++++++++ 2021/2/first.nim | 22 ++++++++++++++++++++ 2021/2/second.nim | 24 ++++++++++++++++++++++ 2021/3/first.nim | 26 ++++++++++++++++++++++++ 2021/3/second.nim | 38 +++++++++++++++++++++++++++++++++++ 2021/4/first.nim | 50 ++++++++++++++++++++++++++++++++++++++++++++++ 2021/4/x/board.nim | 40 +++++++++++++++++++++++++++++++++++++ adventofcode.nim | 24 ++++++++++++++++++++++ 10 files changed, 268 insertions(+) create mode 100644 .gitignore create mode 100644 2021/1/first.nim create mode 100644 2021/1/second.nim create mode 100644 2021/2/first.nim create mode 100644 2021/2/second.nim create mode 100644 2021/3/first.nim create mode 100644 2021/3/second.nim create mode 100644 2021/4/first.nim create mode 100644 2021/4/x/board.nim create mode 100644 adventofcode.nim diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b228c15 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# input files +input.txt diff --git a/2021/1/first.nim b/2021/1/first.nim new file mode 100644 index 0000000..f02b20b --- /dev/null +++ b/2021/1/first.nim @@ -0,0 +1,20 @@ +import + ../../adventofcode, + sequtils, + strformat, + strutils + +let input = adventofcode.getInput(2021, 1) +let lines = input.splitLines()[0 .. ^2].mapIt(it.parseInt()) + +var depths = 0 +var prevResult = lines[0] + +for line in lines[1 .. ^1]: + let currResult = line + if prevResult < currResult: + depths += 1 + + prevResult = currResult + +echo fmt"Answer: {depths}" \ No newline at end of file diff --git a/2021/1/second.nim b/2021/1/second.nim new file mode 100644 index 0000000..d864021 --- /dev/null +++ b/2021/1/second.nim @@ -0,0 +1,22 @@ +import + ../../adventofcode, + sequtils, + strformat, + strutils + +let input = adventofcode.getInput(2021, 1) +let lines = input.splitLines()[0 .. ^2].mapIt(it.parseInt()) + +var depths = 0 +var prevSum = lines[0] + lines[1] + lines[2] + +for idx in 0 .. lines.high(): + if idx + 2 > lines.high(): break + + let currSum = lines[idx] + lines[idx + 1] + lines[idx + 2] + if prevSum < currSum: + depths += 1 + + prevSum = currSum + +echo fmt"Answer: {depths}" \ No newline at end of file diff --git a/2021/2/first.nim b/2021/2/first.nim new file mode 100644 index 0000000..b0805c1 --- /dev/null +++ b/2021/2/first.nim @@ -0,0 +1,22 @@ +import + ../../adventofcode, + strutils, + strformat + +let input = adventofcode.getInput(2021, 2) +let lines = input.splitLines()[0 .. ^2] + +var horizontalPosition = 0 +var depth = 0 + +for line in lines: + var command = line.split(" ") + case command[0]: + of "forward": + horizontalPosition += command[1].parseInt() + of "up": + depth -= command[1].parseInt() + of "down": + depth += command[1].parseInt() + +echo fmt"Answer: {horizontalPosition * depth}" \ No newline at end of file diff --git a/2021/2/second.nim b/2021/2/second.nim new file mode 100644 index 0000000..52f6fca --- /dev/null +++ b/2021/2/second.nim @@ -0,0 +1,24 @@ +import + ../../adventofcode, + strutils, + strformat + +let input = adventofcode.getInput(2021, 2) +let lines = input.splitLines()[0 .. ^2] + +var horizontalPosition = 0 +var depth = 0 +var aim = 0 + +for line in lines: + var command = line.split(" ") + case command[0]: + of "forward": + horizontalPosition += command[1].parseInt() + depth += aim * command[1].parseInt() + of "up": + aim -= command[1].parseInt() + of "down": + aim += command[1].parseInt() + +echo fmt"Answer: {horizontalPosition * depth}" \ No newline at end of file diff --git a/2021/3/first.nim b/2021/3/first.nim new file mode 100644 index 0000000..3a34fec --- /dev/null +++ b/2021/3/first.nim @@ -0,0 +1,26 @@ +import + ../../adventofcode, + sequtils, + strutils, + strformat + +let input = adventofcode.getInput(2021, 3) +let lines = input.splitLines()[0 .. ^2] + +var gammaRateBinary = "" +var epsilonRateBinary = "" + +for idx in 0 .. lines[0].high(): + let a = lines.countIt(it[idx] == '0') + let b = lines.countIt(it[idx] == '1') + if a > b: + gammaRateBinary.add '0' + epsilonRateBinary.add '1' + else: + gammaRateBinary.add '1' + epsilonRateBinary.add '0' + +let gammaRate = gammaRateBinary.parseBinInt() +let epsilonRate = epsilonRateBinary.parseBinInt() + +echo fmt"Answer: {gammaRate * epsilonRate}" \ No newline at end of file diff --git a/2021/3/second.nim b/2021/3/second.nim new file mode 100644 index 0000000..8a9eee6 --- /dev/null +++ b/2021/3/second.nim @@ -0,0 +1,38 @@ +import + ../../adventofcode, + sequtils, + strutils, + strformat + +let input = adventofcode.getInput(2021, 3) +let lines = input.splitLines()[0 .. ^2] + +var oxygenGenRateValues = lines +var co2ScrubberRateValues = lines + +while oxygenGenRateValues.len() > 1: + for idx in 0 .. oxygenGenRateValues[0].high(): + let a = oxygenGenRateValues.countIt(it[idx] == '0') + let b = oxygenGenRateValues.countIt(it[idx] == '1') + if a == b or a < b: + oxygenGenRateValues = oxygenGenRateValues.filterIt(it[idx] == '1') + else: + oxygenGenRateValues = oxygenGenRateValues.filterIt(it[idx] == '0') + + if oxygenGenRateValues.len() == 1: break + +while co2ScrubberRateValues.len() > 1: + for idx in 0 .. co2ScrubberRateValues[0].high(): + let a = co2ScrubberRateValues.countIt(it[idx] == '0') + let b = co2ScrubberRateValues.countIt(it[idx] == '1') + if a == b or a < b: + co2ScrubberRateValues = co2ScrubberRateValues.filterIt(it[idx] == '0') + else: + co2ScrubberRateValues = co2ScrubberRateValues.filterIt(it[idx] == '1') + + if co2ScrubberRateValues.len() == 1: break + +let o2GenRate = oxygenGenRateValues[0].parseBinInt() +let co2ScrubberRate = co2ScrubberRateValues[0].parseBinInt() + +echo fmt"Answer: {o2GenRate * co2ScrubberRate}" \ No newline at end of file diff --git a/2021/4/first.nim b/2021/4/first.nim new file mode 100644 index 0000000..e8a374b --- /dev/null +++ b/2021/4/first.nim @@ -0,0 +1,50 @@ +import + ../../adventofcode, + math, + sequtils, + strutils, + strformat + +import + x/board + +let input = adventofcode.getInput(2021, 4) +let lines = input.splitLines()[0 .. ^2] + +let drawn = lines[0].split(",").mapIt(it.parseInt()) +var currentlyDrawn: seq[int] = @[] +var boards: seq[Board] = @[] + +# Determinate boards from our input +var currBoard = newBoard() +for line in lines[2 .. ^1]: + if line.len() != 0: + currBoard.grid.add line.split(" ").filterIt(it.len() > 0).mapIt(it.parseInt()) + + else: + boards.add currBoard + currBoard = newBoard() + +var determinatedWinner = false +var winningBoard: Board +while not determinatedWinner: + if currentlyDrawn.len() == drawn.len(): + # We run out of numbers to draw + break + + let next = drawn[currentlyDrawn.len()] + currentlyDrawn.add next + + for board in boards: + board.markNumber next + + if board.winning: + winningBoard = board + determinatedWinner = true + break + +echo $winningBoard +let winningBoardScore = currentlyDrawn[^1] * math.sum winningBoard.getUnmarkedNumbers() + +echo fmt"Boards: {boards.len()}" +echo fmt"Answer: {winningBoardScore}" \ No newline at end of file diff --git a/2021/4/x/board.nim b/2021/4/x/board.nim new file mode 100644 index 0000000..acd77d6 --- /dev/null +++ b/2021/4/x/board.nim @@ -0,0 +1,40 @@ +import + sequtils, + strutils + +type + Board* = ref object + grid*: seq[seq[int]] + marks*: seq[seq[bool]] + +proc newBoard*(): Board = + result = Board( + marks: @[ + @[false, false, false, false, false], + @[false, false, false, false, false], + @[false, false, false, false, false], + @[false, false, false, false, false], + @[false, false, false, false, false] + ] + ) + +proc `$`*(this: Board): string = this.grid.mapIt(it.mapIt($it).join(" ")).join("\n") + +proc winning*(this: Board): bool = + for i in 0 .. 4: + if this.marks.allIt(it[i] == true): + return true + if this.marks[i].allIt(it == true): + return true + +proc markNumber*(this: Board, number: int) = + for i in 0 .. 4: + for j in 0 .. 4: + if this.grid[i][j] == number: + this.marks[i][j] = true + +proc getUnmarkedNumbers*(this: Board): seq[int] = + for i in 0 .. 4: + for j in 0 .. 4: + if this.marks[i][j] == false: + result.add this.grid[i][j] \ No newline at end of file diff --git a/adventofcode.nim b/adventofcode.nim new file mode 100644 index 0000000..f057b72 --- /dev/null +++ b/adventofcode.nim @@ -0,0 +1,24 @@ +import + httpclient, + os, + strformat + +let session = os.getEnv("SESSION") +if session == "": + echo "Missing SESSION environment variable." + quit 1 + +proc getInput*(year, day: int): string = + try: + let input = readFile(getCurrentDir() / "input.txt") + + return input + except IOError: + let client = newHttpClient() + client.headers = newHttpHeaders({ "Cookie": fmt"session={session}" }) + + let input = client.getContent fmt"https://adventofcode.com/{year}/day/{day}/input" + + writeFile(getCurrentDir() / "input.txt", input) + + return input \ No newline at end of file