diff options
author | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2023-11-30 22:46:45 -0700 |
---|---|---|
committer | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2023-11-30 22:46:45 -0700 |
commit | 3d57434c04a669610d5f15bd2a7713e6928cdef7 (patch) | |
tree | a0f1f04a335bbc808369d6492f4fee2ff06a0bdb /aoc_2022 | |
parent | 59966ade163a39fc03f07a9d905e0bd87a98d60c (diff) | |
download | aoc-3d57434c04a669610d5f15bd2a7713e6928cdef7.tar.gz aoc-3d57434c04a669610d5f15bd2a7713e6928cdef7.zip |
add aoc2023
Diffstat (limited to 'aoc_2022')
43 files changed, 1010 insertions, 0 deletions
diff --git a/aoc_2022/README.md b/aoc_2022/README.md new file mode 100644 index 0000000..5ce862f --- /dev/null +++ b/aoc_2022/README.md @@ -0,0 +1,32 @@ +# AOC 2022 + +## Goal Languages + +- [x] BASH + - [Day 0](./day-00) +- [x] C + - [Day 1](./day-01) +- [x] Clojure + - [Day 2](./day-02) +- [x] Common LISP + - [Day 3](./day-03) +- [x] C++ + - [Day 4](./day-04) +- [] Dart +- [x] Elixir + - [Day 5](./day-05) +- [] Emacs Lisp +- [x] Haskell + - [Day 7](./day-07) +- [x] Java + - [Day 13](./day-13) +- [x] JavaScript + - [Day 6](./day-06) +- [] Kotlin +- [] PHP +- [x] Python + - [Day 11](./day-11) +- [] Ruby +- [x] TypeScript + - [Day 12](./day-12) + diff --git a/aoc_2022/day-00/.gitkeep b/aoc_2022/day-00/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-00/.gitkeep diff --git a/aoc_2022/day-00/sol.sh b/aoc_2022/day-00/sol.sh new file mode 100755 index 0000000..441efb2 --- /dev/null +++ b/aoc_2022/day-00/sol.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +# USAGE: ./sol.sh (n: top elves) + +NUM_ELVES=${1:-3} + +declare -a ELVES=() +for (( i = 0; i<$NUM_ELVES; i++)) +do + ELVES+=(0) +done + + +add_to_elves () { + local max=$1 + for (( i = 0; i<${NUM_ELVES}; i++)); + do + local tmp="${ELVES[$i]}"; + if [[ $max -ge $tmp ]]; + then + ELVES[$i]=$max + max=$tmp + fi + done +} + +CURRENT_ELF=0 +while read -r line +do + if [[ -z "$line" ]]; + then + add_to_elves $CURRENT_ELF + CURRENT_ELF=0 + else + CURRENT_ELF=$((CURRENT_ELF+line)) + fi +done < input + +echo "MAX ELF = ${ELVES[0]}" +echo "sum(TOP $NUM_ELVES ELVES) = $(printf "%s\n" $(echo "${ELVES[*]}") | paste -sd+ - | bc)" diff --git a/aoc_2022/day-01/.gitkeep b/aoc_2022/day-01/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-01/.gitkeep diff --git a/aoc_2022/day-01/sol.c b/aoc_2022/day-01/sol.c new file mode 100644 index 0000000..612692a --- /dev/null +++ b/aoc_2022/day-01/sol.c @@ -0,0 +1,74 @@ +#include <stdio.h> + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +/* + USAGE: ./sol <inputfile> +*/ + +int get_my_score(char elf, char me) +{ + int elf_choice = (int)(elf - 'A') + 1; + int my_choice = (int)(me - 'X') + 1; + int i_won = 0; + if (elf_choice == my_choice) + return my_choice + 3; + + switch (elf_choice + my_choice) + { + case 3: + i_won = (elf_choice == 1); + break; + case 4: + i_won = (elf_choice == 3); + break; + case 5: + i_won = (elf_choice == 2); + break; + } + + return my_choice + i_won * 6; +} + +const int wins[3] = {2, 3, 1}; +const int loss[3] = {3, 1, 2}; + +int get_my_score_2(char elf, char me) +{ + int elf_choice = (int)(elf - 'A') + 1; + int outcome = (int)(me - 'X') + 1; + + if (outcome == 2) + return elf_choice + 3; + + if (outcome == 1) + return loss[elf_choice - 1]; + return 6 + wins[elf_choice - 1]; +} + +int main(int argc, char *argv[]) +{ + char *fileName = argv[1]; + + FILE *file = fopen(fileName, "r"); + char line[256]; + char elf, me; + + int score1 = 0; + int score2 = 0; + while (1) + { + int i = fscanf(file, "%c %c\n", &elf, &me); + if (i == EOF) + break; + score1 += get_my_score(elf, me); + score2 += get_my_score_2(elf, me); + } + + printf("Score one: %d\n", score1); + printf("Score two: %d\n", score2); + + fclose(file); + return 0; +} diff --git a/aoc_2022/day-02/.gitkeep b/aoc_2022/day-02/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-02/.gitkeep diff --git a/aoc_2022/day-02/sol.clj b/aoc_2022/day-02/sol.clj new file mode 100644 index 0000000..99783cc --- /dev/null +++ b/aoc_2022/day-02/sol.clj @@ -0,0 +1,34 @@ +(require '[clojure.java.io]) + +(defn find-recurring-characters [strs] + (reduce (fn [a x] + (into #{} (filter #(contains? a %) x))) + (into #{} (first strs)) + strs)) + +(defn get-priority [c] + (if (>= c 97) + (- c 96) + (- c 38))) + +(defn obtain-total-priorities [rucksacks] + (reduce + (map (fn [line] + (let [half (/ (count line) 2)] + (get-priority (int + (first (find-recurring-characters + (list (subs line 0 half) + (subs line half)))))))) + rucksacks))) + +(defn obtain-total-priorities-2 [rucksacks] + (reduce + (map (fn [lines] + (get-priority (int (first (find-recurring-characters lines))))) + (partition 3 rucksacks)))) + +(defn main [] + (with-open [rdr (clojure.java.io/reader "input")] + (println (obtain-total-priorities (line-seq rdr)))) + (with-open [rdr (clojure.java.io/reader "input")] + (println (obtain-total-priorities-2 (line-seq rdr)))) + (System/exit 0)) +(main)
\ No newline at end of file diff --git a/aoc_2022/day-03/.gitkeep b/aoc_2022/day-03/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-03/.gitkeep diff --git a/aoc_2022/day-03/sol.lisp b/aoc_2022/day-03/sol.lisp new file mode 100644 index 0000000..7f9ba90 --- /dev/null +++ b/aoc_2022/day-03/sol.lisp @@ -0,0 +1,33 @@ +(ql:quickload "cl-ppcre") + +(defun get-ranges (line) + (ppcre:register-groups-bind ((#'parse-integer first second third fourth)) + ("(\\d+)-(\\d+),(\\d+)-(\\d+)" line :sharedp t) + `((,first ,second) (,third ,fourth)))) + +(defun ranges-may-subset-of-one (a b) + (member-if + (lambda (r) + (and + (>= (caar r) (caadr r)) + (<= (cadar r) (cadadr r)))) + `((,a ,b) (,b ,a)))) + +(defun range-is-contained-at-all (a b) + (and + (<= (car a) (cadr b)) + (>= (cadr a) (car b)))) + +(defun main () + (let ((lines (uiop:read-file-lines "input"))) + (print + (mapcar (lambda (f) + (reduce (lambda (a x) + (if (apply f (get-ranges x)) + (1+ a) + a)) + lines + :initial-value 0)) + '(range-is-contained range-may-be-subset-of-one))))) + +(main) diff --git a/aoc_2022/day-04/.gitkeep b/aoc_2022/day-04/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-04/.gitkeep diff --git a/aoc_2022/day-04/a.out b/aoc_2022/day-04/a.out Binary files differnew file mode 100755 index 0000000..d31e159 --- /dev/null +++ b/aoc_2022/day-04/a.out diff --git a/aoc_2022/day-04/sol.cpp b/aoc_2022/day-04/sol.cpp new file mode 100644 index 0000000..d7847da --- /dev/null +++ b/aoc_2022/day-04/sol.cpp @@ -0,0 +1,103 @@ +#include <tuple> +#include <iostream> +#include <fstream> +#include <string> +#include <sstream> +#include <stack> +#include <cmath> +#include <array> +#include <algorithm> +#include <cstdint> +#include <vector> + +using stack_type = std::stack<char>; + +enum PROBLEM +{ + PROBLEM_1 = 1, + PROBLEM_2 = 2 +}; + +std::tuple<std::vector<stack_type>, int> build_stacks(std::vector<std::string> &lines) +{ + int num_stacks = std::ceil(lines[0].size() / 4.0); + + std::vector<stack_type> stacks(num_stacks); + + std::vector<int> stack_positions(num_stacks, 0); + int lines_of_stacks = 0; + for (std::string line : lines) + { + char l = '1'; + for (int i = 0; i < line.size(); ++i) + if (line[i] == l) + { + stack_positions[l - '1'] = i; + l++; + } + if (l == num_stacks + '1') + break; + lines_of_stacks++; + } + + for (int i = lines_of_stacks - 1; i >= 0; i--) + for (int j = 0; j < num_stacks; ++j) + if (lines[i][stack_positions[j]] != ' ') + stacks[j].push(lines[i][stack_positions[j]]); + + return std::make_tuple(stacks, lines_of_stacks); +} + +std::string solve(std::vector<stack_type> &stacks, std::vector<std::string> &lines, int start_from, PROBLEM problem) +{ + stack_type curr; + for (auto line = lines.begin() + start_from; line != lines.end(); ++line) + { + std::istringstream iss(*line); + std::string word; + int from = 0, to = 0, amount = 0; + + while (iss >> word >> amount >> word >> from >> word >> to) + ; + + if (problem == PROBLEM_1) + for (int i = 0; i < amount; ++i) + { + stacks[to - 1].push(stacks[from - 1].top()); + stacks[from - 1].pop(); + } + else + { + for (int i = 0; i < amount; ++i) + { + curr.push(stacks[from - 1].top()); + stacks[from - 1].pop(); + } + for (int i = 0; i < amount; ++i) + { + stacks[to - 1].push(curr.top()); + curr.pop(); + } + } + } + + std::string result; + for (auto &stack : stacks) + result += stack.top(); + return result; +} + +int main() +{ + std::ifstream input("input"); + std::vector<std::string> lines; + for (std::string line; std::getline(input, line);) + lines.push_back(line); + + auto [stacks, start_from] = build_stacks(lines); + std::cout << "Solve 1: " << solve(stacks, lines, start_from + 1, PROBLEM_1) << std::endl; + auto [stacks2, start_from2] = build_stacks(lines); + std::cout << "Solve 2: " << solve(stacks2, lines, start_from2 + 1, PROBLEM_2) << std::endl; + + return 0; +} diff --git a/aoc_2022/day-05/.gitkeep b/aoc_2022/day-05/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-05/.gitkeep diff --git a/aoc_2022/day-05/sol.exs b/aoc_2022/day-05/sol.exs new file mode 100644 index 0000000..e1dab2b --- /dev/null +++ b/aoc_2022/day-05/sol.exs @@ -0,0 +1,28 @@ +defmodule Solution do + def solve(input, chunk) do + (String.split(input, "", trim: true) + |> Enum.chunk_every(chunk, 1, :discard) + |> Enum.map(fn window -> + Enum.reduce(window, %{}, fn char, acc -> + Map.put(acc, char, Map.get(acc, char, 0) + 1) + end) + end) + |> Enum.find_index(fn letter_counts -> + Enum.all?(letter_counts, fn {_key, value} -> + value == 1 + end) + end)) + chunk + end + + def main do + input = File.read!("input") + + solve(input, 4) + |> IO.inspect() + + solve(input, 14) + |> IO.inspect() + end +end + +Solution.main() diff --git a/aoc_2022/day-06/.gitkeep b/aoc_2022/day-06/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-06/.gitkeep diff --git a/aoc_2022/day-06/package.json b/aoc_2022/day-06/package.json new file mode 100644 index 0000000..3dbc1ca --- /dev/null +++ b/aoc_2022/day-06/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/aoc_2022/day-06/sol.js b/aoc_2022/day-06/sol.js new file mode 100644 index 0000000..28b7b0d --- /dev/null +++ b/aoc_2022/day-06/sol.js @@ -0,0 +1,115 @@ +import input from "fs"; + +class File { + constructor(name, size, parent) { + this.name = name; + this.fileSize = size; + this.parent = parent; + } + + size() { + return this.fileSize; + } +} + +class Directory { + constructor(name, parent) { + this.children = []; + this.name = name; + this.parent = parent; + } + + add(child) { + this.children.push(child); + } + + size() { + return this.children.reduce((acc, child) => acc + child.size(), 0); + } + + searchDirectoresOfSizePredicate(sizeP) { + const dirs = []; + for (const child of this.children) { + if (child instanceof Directory) { + if (sizeP(child.size())) { + dirs.push(child); + } + dirs.push(...child.searchDirectoresOfSizePredicate(sizeP)); + } + } + return dirs; + } +} + +class OS { + constructor() { + this.root = new Directory("/", null); + + this.current = this.root; + } + + cd(path) { + if (path === "/") { + this.current = this.root; + } else if (path === ".." && this.current.parent) { + this.current = this.current.parent; + } else { + this.current = this.current.children.find((child) => child.name === path); + } + } + + printFs() { + const print = (dir, depth) => { + for (const child of dir.children) { + console.log(" ".repeat(depth) + child.name); + if (child instanceof Directory) { + print(child, depth + 1); + } + } + }; + + print(this.root, 0); + } +} + +const main = () => { + const os = new OS(); + const lines = input.readFileSync("input", "utf8").split("\n"); + + let currentCommand = null; + for (const line of lines) { + if (line.startsWith("$")) { + const [command, path] = line.split(" ").splice(1); + if (command == "cd") os.cd(path); + currentCommand = command; + } else if (currentCommand == "ls") { + const [dirOrSize, name] = line.split(" "); + if (dirOrSize === "dir") { + const dir = new Directory(name, os.current); + os.current.add(dir); + } else { + const file = new File(name, parseInt(dirOrSize), os.current); + os.current.add(file); + } + } + } + + //os.printFs(); + + console.log( + os.root + .searchDirectoresOfSizePredicate((size) => size <= 100000) + .reduce((a, x) => a + x.size(), 0) + ); + + const rootSize = os.root.size(); + const freeSpace = 70000000 - rootSize; + console.log( + [...os.root.searchDirectoresOfSizePredicate(() => true), os.root] + .map((x) => x.size()) + .filter((x) => freeSpace + x >= 30000000) + .reduce((a, x) => Math.min(a, x), Infinity) + ); +}; + +main(); diff --git a/aoc_2022/day-07/.gitkeep b/aoc_2022/day-07/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-07/.gitkeep diff --git a/aoc_2022/day-07/sol.hs b/aoc_2022/day-07/sol.hs new file mode 100644 index 0000000..c6b8c35 --- /dev/null +++ b/aoc_2022/day-07/sol.hs @@ -0,0 +1,114 @@ +import Data.List (find, transpose) +import qualified Data.Set as Set +import qualified Data.Text as Text +import qualified Data.Text.IO as Text + +countVisibleTrees :: + [[Int]] -> [Int] -> Int -> (Set.Set (Int, Int)) -> (Set.Set (Int, Int)) +countVisibleTrees [] _ _ seen = seen +countVisibleTrees (row:rows) maxTrees depth seen = + countVisibleTrees + rows + (zipWith (\x y -> max x y) row maxTrees) + (depth + 1) + (foldl + (\acc x -> Set.insert x acc) + seen + (zipWith + (\i x -> + if x == 1 + then (depth, i) + else (0, 0)) + [0 ..] + (zipWith + (\x y -> + if x > y + then 1 + else 0) + row + maxTrees))) + +treeScore :: [[Int]] -> (Int, Int) -> Int -> Int -> [Int] +treeScore digits (x, y) width height = + let currentHeight = ((digits !! y) !! x) + in [ (case (find + (\x -> (digits !! y) !! x >= currentHeight) + [(x + 1) .. (width - 1)]) of + Just value -> (value - x) + Nothing -> (width - x - 1)) + , (case (find + (\x -> (digits !! y) !! x >= currentHeight) + (reverse [0 .. (x - 1)])) of + Just value -> (x - value) + Nothing -> x) + , (case (find + (\y -> (digits !! y) !! x >= currentHeight) + (reverse [0 .. (y - 1)])) of + Just value -> (y - value) + Nothing -> y) + , (case (find + (\y -> (digits !! y) !! x >= currentHeight) + [(y + 1) .. (height - 1)]) of + Just value -> (value - y) + Nothing -> (height - y - 1)) + ] + +getDigitsFromString :: String -> [Int] +getDigitsFromString = map (read . (: "")) + +rotl :: [[Int]] -> [[Int]] +rotl = reverse . transpose + +rotr :: [[Int]] -> [[Int]] +rotr = transpose . reverse + +main = do + ls <- fmap Text.lines (Text.readFile "input") + let digits = map (getDigitsFromString . Text.unpack) ls + let height = length digits + let width = length (head digits) + let topDownSeen = + countVisibleTrees digits (take width (repeat (-1))) 0 Set.empty + let rightLeftSeen = + Set.map + (\x -> ((snd x), width - (fst x) - 1)) + (countVisibleTrees + (rotl digits) + (take height (repeat (-1))) + 0 + Set.empty) + let downTopSeen = + Set.map + (\x -> (height - (fst x) - 1, (snd x))) + (countVisibleTrees + (reverse digits) + (take width (repeat (-1))) + 0 + Set.empty) + let leftRightSeen = + Set.map + (\x -> (height - (snd x) - 1, (fst x))) + (countVisibleTrees + (rotr digits) + (take height (repeat (-1))) + 0 + Set.empty) + let allSeen = + (foldl + (\acc x -> Set.union acc x) + Set.empty + [topDownSeen, rightLeftSeen, downTopSeen, leftRightSeen]) + print (Set.size allSeen) + print + (maximum + (map + (\y -> + maximum + (map + (\x -> + (foldl + (\acc x -> acc * x) + 1 + (treeScore digits (x, y) width height))) + [0 .. (width - 1)])) + [0 .. (height - 1)])) diff --git a/aoc_2022/day-08/.gitkeep b/aoc_2022/day-08/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-08/.gitkeep diff --git a/aoc_2022/day-09/.gitkeep b/aoc_2022/day-09/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-09/.gitkeep diff --git a/aoc_2022/day-10/.gitkeep b/aoc_2022/day-10/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-10/.gitkeep diff --git a/aoc_2022/day-11/.gitkeep b/aoc_2022/day-11/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-11/.gitkeep diff --git a/aoc_2022/day-11/sol.py b/aoc_2022/day-11/sol.py new file mode 100644 index 0000000..9da8cec --- /dev/null +++ b/aoc_2022/day-11/sol.py @@ -0,0 +1,67 @@ + +def get_neighbors(grid, current): + neighbors = [] + y, x = current + cur_height = ord(grid[y][x]) + if (grid[y][x] == "S"): + cur_height = ord("a") + for i in range(-1, 2): + for j in range(-1, 2): + if i == 0 and j == 0 or (i != 0 and j != 0): + continue + if (y + i) < 0 or (y + i) >= len(grid): + continue + if (x + j) < 0 or (x + j) >= len(grid[y + i]): + continue + new_height = ord(grid[y + i][x + j]) + if (grid[y + i][x + j] == "E"): + new_height = ord("z") + if abs(new_height - cur_height) <= 1 or new_height <= cur_height: + neighbors.append((y + i, x + j)) + return neighbors + +def bfs(grid, start, end): + queue = [] + queue.append(start) + visited = {} + visited[start] = 0 + while queue: + current = queue.pop(0) + if current == end: + return visited[current] + for neighbor in get_neighbors(grid, current): + if neighbor not in visited: + queue.append(neighbor) + visited[neighbor] = visited[current] + 1 + return False + +def main(): + file = open("input", "r") + grid = file.readlines() + file.close() + + start = (0, 0) + end = (0, 0) + + for i in range(len(grid)): + for j in range(len(grid[i])): + if grid[i][j] == "S": + start = (i, j) + elif grid[i][j] == "E": + end = (i, j) + + best = bfs(grid, start, end) + print(best) + + for i in range(len(grid)): + for j in range(len(grid[i])): + if grid[i][j] == "a": + this_as_start = bfs(grid, (i, j), end) + if this_as_start and this_as_start < best: + best = this_as_start + + print(best) + + +if __name__ == "__main__": + main() diff --git a/aoc_2022/day-12/.gitignore b/aoc_2022/day-12/.gitignore new file mode 100644 index 0000000..5bf19b0 --- /dev/null +++ b/aoc_2022/day-12/.gitignore @@ -0,0 +1,3 @@ +build/ +sol.js +node_modules/ diff --git a/aoc_2022/day-12/.gitkeep b/aoc_2022/day-12/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-12/.gitkeep diff --git a/aoc_2022/day-12/package-lock.json b/aoc_2022/day-12/package-lock.json new file mode 100644 index 0000000..15123cd --- /dev/null +++ b/aoc_2022/day-12/package-lock.json @@ -0,0 +1,46 @@ +{ + "name": "day-12", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "devDependencies": { + "@types/node": "^18.11.14", + "typescript": "^4.9.4" + } + }, + "node_modules/@types/node": { + "version": "18.11.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.14.tgz", + "integrity": "sha512-0KXV57tENYmmJMl+FekeW9V3O/rlcqGQQJ/hNh9r8pKIj304pskWuEd8fCyNT86g/TpO0gcOTiLzsHLEURFMIQ==", + "dev": true + }, + "node_modules/typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + } + }, + "dependencies": { + "@types/node": { + "version": "18.11.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.14.tgz", + "integrity": "sha512-0KXV57tENYmmJMl+FekeW9V3O/rlcqGQQJ/hNh9r8pKIj304pskWuEd8fCyNT86g/TpO0gcOTiLzsHLEURFMIQ==", + "dev": true + }, + "typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "dev": true + } + } +} diff --git a/aoc_2022/day-12/package.json b/aoc_2022/day-12/package.json new file mode 100644 index 0000000..cfc736a --- /dev/null +++ b/aoc_2022/day-12/package.json @@ -0,0 +1,9 @@ +{ + "devDependencies": { + "@types/node": "^18.11.14", + "typescript": "^4.9.4" + }, + "scripts": { + "build": "tsc" + } +} diff --git a/aoc_2022/day-12/sol.ts b/aoc_2022/day-12/sol.ts new file mode 100644 index 0000000..7143403 --- /dev/null +++ b/aoc_2022/day-12/sol.ts @@ -0,0 +1,59 @@ +import * as input from "fs"; + +type NestedNumbers = Array<NestedNumbers | number>; + +const compare = ( + a: NestedNumbers | number, + b: NestedNumbers | number +): boolean => { + if (typeof a === typeof b && typeof b === "number") return a < b; + if (Array.isArray(a) && Array.isArray(b)) { + for (let i = 0; i < a.length; i++) { + if (i >= b.length) return false; + if (compare(a[i], b[i])) return true; + if (compare(b[i], a[i])) return false; + } + return compare(a.length, b.length); + } + return compare(Array.isArray(b) ? [a] : a, Array.isArray(a) ? [b] : b); +}; + +const main = (): void => { + const lines: NestedNumbers[] = input + .readFileSync("input", "utf-8") + .split("\n") + .filter((x) => x) + .map((x) => JSON.parse(x)); + + const pairs: [NestedNumbers, NestedNumbers][] = []; + for (let i = 0; i < lines.length; i += 2) { + const pair: [NestedNumbers, NestedNumbers] = [lines[i], lines[i + 1]]; + pairs.push(pair); + } + + console.log( + pairs.reduce((acc, [a, b], i) => acc + (compare(a, b) ? i + 1 : 0), 0) + ); + + lines.push([[2]]); + lines.push([[6]]); + + const sorted = lines.sort((a, b) => { + if (compare(a, b)) return -1; + if (compare(b, a)) return 1; + return 0; + }); + + const isPacket = (num: number) => (x: NestedNumbers) => + Array.isArray(x) && + x.length === 1 && + Array.isArray(x[0]) && + x[0].length === 1 && + x[0][0] === num; + + console.log( + (sorted.findIndex(isPacket(6)) + 1) * (sorted.findIndex(isPacket(2)) + 1) + ); +}; + +main(); diff --git a/aoc_2022/day-12/tsconfig.json b/aoc_2022/day-12/tsconfig.json new file mode 100644 index 0000000..75dcaea --- /dev/null +++ b/aoc_2022/day-12/tsconfig.json @@ -0,0 +1,103 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/aoc_2022/day-13/.gitkeep b/aoc_2022/day-13/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-13/.gitkeep diff --git a/aoc_2022/day-13/sol.java b/aoc_2022/day-13/sol.java new file mode 100644 index 0000000..7613dcd --- /dev/null +++ b/aoc_2022/day-13/sol.java @@ -0,0 +1,147 @@ +import java.io.File; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Scanner; +import java.awt.Point; +import java.util.Set; + +public class sol { + enum PROBLEM { + PROBLEM_1, PROBLEM_2 + } + + class Grid { + private Set<Point> sand; + private Set<Point> filled; + private Point source; + private int maxYP2; + + public Grid(Point source, ArrayList<ArrayList<Point>> paths) { + this.sand = new HashSet<Point>(); + this.filled = new HashSet<Point>(); + this.source = source; + + for (ArrayList<Point> path : paths) + for (int i = 1; i < path.size(); i++) { + Point p1 = path.get(i - 1); + Point p2 = path.get(i); + for (int x = Math.min(p1.x, p2.x); x <= Math.max(p1.x, p2.x); x++) + for (int y = Math.min(p1.y, p2.y); y <= Math.max(p1.y, p2.y); y++) + this.filled.add(new Point(x, y)); + } + + maxYP2 = bottomRight().y + 1; + } + + public boolean addSandGrain(PROBLEM problem) { + Point p = new Point(this.source.x, this.source.y); + while (true) { + if (this.filled.contains(p) || (problem == PROBLEM.PROBLEM_2 && p.y >= maxYP2)) { + if (problem == PROBLEM.PROBLEM_2 && p.x == this.source.x && p.y == this.source.y) + return false; + + p.y--; + filled.add(p); + sand.add(p); + return true; + } + + if (problem == PROBLEM.PROBLEM_1 && p.y >= bottomRight().y) + return false; + + p.y++; + if (this.filled.contains(new Point(p.x, p.y))) { + if (!this.filled.contains(new Point(p.x - 1, p.y))) + p.x--; + else if (!this.filled.contains(new Point(p.x + 1, p.y))) + p.x++; + } + } + } + + public Point topLeft() { + return new Point( + filled.stream().min((p1, p2) -> p1.x - p2.x).get().x, + filled.stream().min((p1, p2) -> p1.y - p2.y).get().y); + } + + public Point bottomRight() { + return new Point( + filled.stream().max((p1, p2) -> p1.x - p2.x).get().x, + filled.stream().max((p1, p2) -> p1.y - p2.y).get().y); + } + + public void print() { + Point topLeft = topLeft(); + Point bottomRight = bottomRight(); + + Point curr = new Point(topLeft.x, topLeft.y); + for (; curr.y <= bottomRight.y; curr.y++) { + for (; curr.x <= bottomRight.x; curr.x++) { + if (sand.contains(curr)) + System.out.print("o"); + else if (filled.contains(curr)) + System.out.print("#"); + else + System.out.print("."); + } + curr.x = topLeft.x; + System.out.println(); + } + } + } + + public static ArrayList<ArrayList<Point>> parsePaths(ArrayList<String> inputList) { + ArrayList<ArrayList<Point>> paths = new ArrayList<ArrayList<Point>>(); + for (String line : inputList) { + ArrayList<Point> path = new ArrayList<Point>(); + + String[] points = line.split(" -> "); + for (String point : points) { + String[] coords = point.split(","); + path.add(new Point(Integer.parseInt(coords[0]), Integer.parseInt(coords[1]))); + } + + paths.add(path); + } + return paths; + } + + public static ArrayList<String> getInputLines(String file) { + ArrayList<String> inputList = new ArrayList<String>(); + + try { + File input = new File(file); + Scanner sc = new Scanner(input); + + while (sc.hasNextLine()) + inputList.add(sc.nextLine()); + + sc.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + return inputList; + } + + public static void main(String[] args) { + ArrayList<ArrayList<Point>> paths = parsePaths(getInputLines("input")); + + sol s = new sol(); + Grid gridP1 = s.new Grid(new Point(500, 0), paths); + int i = 0; + for (; gridP1.addSandGrain(PROBLEM.PROBLEM_1); i++) { + // gridP1.print(); + } + System.out.println(i); + + Grid gridP2 = s.new Grid(new Point(500, 0), paths); + i = 0; + for (; gridP2.addSandGrain(PROBLEM.PROBLEM_2); i++) { + // gridP2.print(); + } + System.out.println(i); + } +}
\ No newline at end of file diff --git a/aoc_2022/day-14/.gitkeep b/aoc_2022/day-14/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-14/.gitkeep diff --git a/aoc_2022/day-15/.gitkeep b/aoc_2022/day-15/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-15/.gitkeep diff --git a/aoc_2022/day-16/.gitkeep b/aoc_2022/day-16/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-16/.gitkeep diff --git a/aoc_2022/day-17/.gitkeep b/aoc_2022/day-17/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-17/.gitkeep diff --git a/aoc_2022/day-18/.gitkeep b/aoc_2022/day-18/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-18/.gitkeep diff --git a/aoc_2022/day-19/.gitkeep b/aoc_2022/day-19/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-19/.gitkeep diff --git a/aoc_2022/day-20/.gitkeep b/aoc_2022/day-20/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-20/.gitkeep diff --git a/aoc_2022/day-21/.gitkeep b/aoc_2022/day-21/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-21/.gitkeep diff --git a/aoc_2022/day-22/.gitkeep b/aoc_2022/day-22/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-22/.gitkeep diff --git a/aoc_2022/day-23/.gitkeep b/aoc_2022/day-23/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-23/.gitkeep diff --git a/aoc_2022/day-24/.gitkeep b/aoc_2022/day-24/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aoc_2022/day-24/.gitkeep |