about summary refs log tree commit diff
path: root/aoc/2022
diff options
context:
space:
mode:
Diffstat (limited to 'aoc/2022')
-rwxr-xr-xaoc/2022/01/part-one.sh2
-rwxr-xr-xaoc/2022/01/part-two.sh3
-rw-r--r--aoc/2022/02/part-one.ha30
-rw-r--r--aoc/2022/02/part-two.ha30
-rw-r--r--aoc/2022/03/part-one.nim19
-rw-r--r--aoc/2022/03/part-two.nim16
-rwxr-xr-xaoc/2022/04/part-one.jl8
-rwxr-xr-xaoc/2022/04/part-two.jl8
-rwxr-xr-xaoc/2022/05/part-one.rb10
-rwxr-xr-xaoc/2022/05/part-two.rb10
-rw-r--r--aoc/2022/06/part-one.d24
-rw-r--r--aoc/2022/06/part-two.d26
-rwxr-xr-xaoc/2022/07/part-one.janet58
-rwxr-xr-xaoc/2022/07/part-two.janet60
-rw-r--r--aoc/2022/08/part-one.f9047
-rw-r--r--aoc/2022/08/part-two.f9053
-rwxr-xr-xaoc/2022/09/part-one.tcl25
-rwxr-xr-xaoc/2022/09/part-two.tcl30
-rwxr-xr-xaoc/2022/10/part-one.awk8
-rwxr-xr-xaoc/2022/10/part-two.awk10
20 files changed, 477 insertions, 0 deletions
diff --git a/aoc/2022/01/part-one.sh b/aoc/2022/01/part-one.sh
new file mode 100755
index 0000000..a0e0095
--- /dev/null
+++ b/aoc/2022/01/part-one.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+sed 's/$/+/' | { echo 0; sed 's/^+$/p0/'; echo p; } | dc | sort -n | tail -1
diff --git a/aoc/2022/01/part-two.sh b/aoc/2022/01/part-two.sh
new file mode 100755
index 0000000..a5a4d77
--- /dev/null
+++ b/aoc/2022/01/part-two.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+sed 's/$/+/' | { echo 0; sed 's/^+$/p0/'; echo p; } | dc |
+  sort -n | tail -n 3 | { echo 0; sed 's/$/+/'; echo p; } | dc
diff --git a/aoc/2022/02/part-one.ha b/aoc/2022/02/part-one.ha
new file mode 100644
index 0000000..7a49de0
--- /dev/null
+++ b/aoc/2022/02/part-one.ha
@@ -0,0 +1,30 @@
+use bufio;
+use fmt;
+use io;
+use os;
+
+fn scanbyte(file: io::handle) u8 = {
+	match (bufio::scanbyte(os::stdin)!) {
+	case let byte: u8 =>
+		return byte;
+	case io::EOF =>
+		fmt::fatal("Unexpected EOF");
+	};
+};
+
+export fn main() void = {
+	let score: u16 = 0;
+	for (true) {
+		const them = 'D' - (match (bufio::scanbyte(os::stdin)!) {
+		case let byte: u8 =>
+			yield byte;
+		case io::EOF =>
+			break;
+		});
+		scanbyte(os::stdin);
+		const us = scanbyte(os::stdin) - 'W';
+		scanbyte(os::stdin);
+		score += us + (us + them) % 3 * 3;
+	};
+	fmt::println(score)!;
+};
diff --git a/aoc/2022/02/part-two.ha b/aoc/2022/02/part-two.ha
new file mode 100644
index 0000000..da7ab52
--- /dev/null
+++ b/aoc/2022/02/part-two.ha
@@ -0,0 +1,30 @@
+use bufio;
+use fmt;
+use io;
+use os;
+
+fn scanbyte(file: io::handle) u8 = {
+	match (bufio::scanbyte(os::stdin)!) {
+	case let byte: u8 =>
+		return byte;
+	case io::EOF =>
+		fmt::fatal("Unexpected EOF");
+	};
+};
+
+export fn main() void = {
+	let score: u16 = 0;
+	for (true) {
+		const opponent = match (bufio::scanbyte(os::stdin)!) {
+		case let byte: u8 =>
+			yield byte;
+		case io::EOF =>
+			break;
+		} - '?';
+		scanbyte(os::stdin);
+		const outcome = scanbyte(os::stdin) - 'X';
+		scanbyte(os::stdin);
+		score += (opponent + outcome) % 3 + 1 + outcome * 3;
+	};
+	fmt::println(score)!;
+};
diff --git a/aoc/2022/03/part-one.nim b/aoc/2022/03/part-one.nim
new file mode 100644
index 0000000..0f16754
--- /dev/null
+++ b/aoc/2022/03/part-one.nim
@@ -0,0 +1,19 @@
+import math
+import sequtils
+import sets
+import strutils
+
+func priority(item: int): int =
+  result = item - 96
+  if result < 0:
+    result += 58
+
+func examine(sack: string): int =
+  let
+    size = sack.len div 2
+    other = to_hash_set sack[0 ..< size]
+  for c in sack[size .. ^1]:
+    if c in other:
+      return priority ord c
+
+echo sum stdin.read_all.strip.split_lines.map examine
diff --git a/aoc/2022/03/part-two.nim b/aoc/2022/03/part-two.nim
new file mode 100644
index 0000000..ef27011
--- /dev/null
+++ b/aoc/2022/03/part-two.nim
@@ -0,0 +1,16 @@
+import math
+import sequtils
+import sets
+import strutils
+
+func priority(group: seq[string]): int =
+  let sets = group.map_it it.to_hash_set
+  var common = sets.foldl a * b
+  result = common.pop.ord - 96
+  if result < 0:
+    result += 58
+
+let
+  elves = split_lines strip read_all stdin
+  groups = elves.distribute elves.len div 3
+echo sum groups.map priority
diff --git a/aoc/2022/04/part-one.jl b/aoc/2022/04/part-one.jl
new file mode 100755
index 0000000..3f409ea
--- /dev/null
+++ b/aoc/2022/04/part-one.jl
@@ -0,0 +1,8 @@
+#!/usr/bin/env julia
+function containing(line)
+  (a, b), (c, d) = map(r -> map(i -> parse(Int16, i),
+                                split(r, '-')),
+                       split(line, ','))
+  (c - a) * (d - b) <= 0
+end
+println(sum(map(containing, readlines(stdin))))
diff --git a/aoc/2022/04/part-two.jl b/aoc/2022/04/part-two.jl
new file mode 100755
index 0000000..9f4dbaf
--- /dev/null
+++ b/aoc/2022/04/part-two.jl
@@ -0,0 +1,8 @@
+#!/usr/bin/env julia
+function overlapping(line)
+  (a, b), (c, d) = map(r -> map(i -> parse(Int16, i),
+                                split(r, '-')),
+                       split(line, ','))
+  !(b < c || d < a)
+end
+println(sum(map(overlapping, readlines(stdin))))
diff --git a/aoc/2022/05/part-one.rb b/aoc/2022/05/part-one.rb
new file mode 100755
index 0000000..4e11ce9
--- /dev/null
+++ b/aoc/2022/05/part-one.rb
@@ -0,0 +1,10 @@
+#!/usr/bin/env ruby
+drawing, procedure = ARGF.read.split /\n.*\n\n/
+first, *rest = (drawing.split "\n").map { |line| (line.scan /.(.). ?/) }
+stacks = (first.zip *rest).map { |stack| stack.join.strip.reverse }
+for line in procedure.split "\n"
+  n, from, to = (line.scan /\d+/).map &:to_i
+  stacks[to - 1] << stacks[from - 1][-n..].reverse
+  stacks[from - 1].slice! -n..
+end
+puts (stacks.map { |stack| stack[-1] }).join
diff --git a/aoc/2022/05/part-two.rb b/aoc/2022/05/part-two.rb
new file mode 100755
index 0000000..1cabf1b
--- /dev/null
+++ b/aoc/2022/05/part-two.rb
@@ -0,0 +1,10 @@
+#!/usr/bin/env ruby
+drawing, procedure = ARGF.read.split /\n.*\n\n/
+first, *rest = (drawing.split "\n").map { |line| (line.scan /.(.). ?/) }
+stacks = (first.zip *rest).map { |stack| stack.join.strip.reverse }
+for line in procedure.split "\n"
+  n, from, to = (line.scan /\d+/).map &:to_i
+  stacks[to - 1] << stacks[from - 1][-n..]
+  stacks[from - 1].slice! -n..
+end
+puts (stacks.map { |stack| stack[-1] }).join
diff --git a/aoc/2022/06/part-one.d b/aoc/2022/06/part-one.d
new file mode 100644
index 0000000..c914704
--- /dev/null
+++ b/aoc/2022/06/part-one.d
@@ -0,0 +1,24 @@
+import core.stdc.stdio : getchar, printf;
+
+extern(C) void main()
+{
+    slide: for (auto q = 0u, i = 1u; q & 0xffu ^ '\n'; ++i)
+    {
+        q <<= 8u;
+        q |= getchar();
+        if (i < 4)
+          continue;
+
+        auto p = cast(ubyte*) &q;
+        for (auto s = 0u, j = 0u; j < 4u; ++j)
+        {
+            auto b = 1u << (p[j] & 0x1fu);
+            if (s & b)
+                continue slide;
+            s |= b;
+        }
+
+        printf("%d\n", i);
+        break;
+    }
+}
diff --git a/aoc/2022/06/part-two.d b/aoc/2022/06/part-two.d
new file mode 100644
index 0000000..4465e38
--- /dev/null
+++ b/aoc/2022/06/part-two.d
@@ -0,0 +1,26 @@
+import core.int128 : Cent, and, or, shl, tst, xor;
+import core.stdc.stdio : getchar, printf;
+
+extern(C) void main()
+{
+    slide: for (auto q = cast(Cent) 0u, i = 1u;
+                tst(xor(and(q, cast(Cent) 0xff), cast(Cent) '\n'));
+                ++i)
+    {
+        q = or(shl(q, 8u), cast(Cent) getchar());
+        if (i < 14)
+          continue;
+
+        auto p = cast(ubyte*) &q;
+        for (auto s = 0u, j = 0u; j < 14u; ++j)
+        {
+            auto b = 1u << (p[j] & 0x1fu);
+            if (s & b)
+                continue slide;
+            s |= b;
+        }
+
+        printf("%d\n", i);
+        break;
+    }
+}
diff --git a/aoc/2022/07/part-one.janet b/aoc/2022/07/part-one.janet
new file mode 100755
index 0000000..fba92e5
--- /dev/null
+++ b/aoc/2022/07/part-one.janet
@@ -0,0 +1,58 @@
+#!/usr/bin/env janet
+(def grammar
+  ~{:filename (<- (some :S))
+    :dirname (+ (/ "/" :root)
+                (/ ".." :parent)
+                :filename)
+    :cd (* "$ cd " (constant :cd)
+           :dirname
+           "\n")
+    :file (* (<- :d+)
+             " "
+             (constant :name)
+             :filename)
+    :dir (* (constant :dir)
+            "dir "
+            (constant :name)
+            :dirname)
+    :ls (* "$ ls\n" (constant :ls)
+           (group (any (/ (* (constant :stat)
+                             (+ :file :dir)
+                             "\n")
+                          ,struct))))
+    :main (some (/ (+ :cd :ls)
+                   ,tuple))})
+
+(defn du [fs]
+  (if (number? fs)
+    [fs]
+    (reduce (fn [[parent & children] [child & grandchildren]]
+                [(+ parent child)
+                 (splice children)
+                 (if (empty? grandchildren)
+                   []
+                   [child (splice grandchildren)])])
+            [0]
+            (map du (values fs)))))
+
+(var path nil)
+(let [fs (table)]
+  (each [cmd rest]
+        (peg/match grammar (:read stdin :all))
+        (cond (= cmd :ls) (each {:name name :stat stat}
+                            rest
+                            (set ((array/peek path)
+                                  name)
+                                 (if (= stat :dir)
+                                   (table)
+                                   (scan-number stat))))
+              (= rest :root) (set path (array fs))
+              (= rest :parent) (array/pop path)
+              (let [last (array/peek path)]
+                (unless (last rest)
+                  (set (last rest)
+                       (table)))
+                (array/push path (last rest)))))
+  (print (+ (splice (filter (fn [n]
+                              (<= n 100_000))
+                            (flatten (du fs)))))))
diff --git a/aoc/2022/07/part-two.janet b/aoc/2022/07/part-two.janet
new file mode 100755
index 0000000..36c25f1
--- /dev/null
+++ b/aoc/2022/07/part-two.janet
@@ -0,0 +1,60 @@
+#!/usr/bin/env janet
+(def grammar
+  ~{:filename (<- (some :S))
+    :dirname (+ (/ "/" :root)
+                (/ ".." :parent)
+                :filename)
+    :cd (* "$ cd " (constant :cd)
+           :dirname
+           "\n")
+    :file (* (<- :d+)
+             " "
+             (constant :name)
+             :filename)
+    :dir (* (constant :dir)
+            "dir "
+            (constant :name)
+            :dirname)
+    :ls (* "$ ls\n" (constant :ls)
+           (group (any (/ (* (constant :stat)
+                             (+ :file :dir)
+                             "\n")
+                          ,struct))))
+    :main (some (/ (+ :cd :ls)
+                   ,tuple))})
+
+(defn du [fs]
+  (if (number? fs)
+    [fs]
+    (reduce (fn [[parent & children] [child & grandchildren]]
+                [(+ parent child)
+                 (splice children)
+                 (if (empty? grandchildren)
+                   []
+                   [child (splice grandchildren)])])
+            [0]
+            (map du (values fs)))))
+
+(var path nil)
+(let [fs (table)]
+  (each [cmd rest]
+        (peg/match grammar (:read stdin :all))
+        (cond (= cmd :ls) (each {:name name :stat stat}
+                            rest
+                            (set ((array/peek path)
+                                  name)
+                                 (if (= stat :dir)
+                                   (table)
+                                   (scan-number stat))))
+              (= rest :root) (set path (array fs))
+              (= rest :parent) (array/pop path)
+              (let [last (array/peek path)]
+                (unless (last rest)
+                  (set (last rest)
+                       (table)))
+                (array/push path (last rest)))))
+  (let [usages (flatten (du fs))]
+    (print (min (splice (filter (fn [n]
+                                  (>= (+ n 40_000_000)
+                                      (first usages)))
+                                usages))))))
diff --git a/aoc/2022/08/part-one.f90 b/aoc/2022/08/part-one.f90
new file mode 100644
index 0000000..a339f48
--- /dev/null
+++ b/aoc/2022/08/part-one.f90
@@ -0,0 +1,47 @@
+PROGRAM one
+  implicit none
+  integer, parameter :: WIDTH = 99, HEIGHT = 99
+  character(WIDTH), dimension(HEIGHT) :: lines
+  integer :: i, j
+  integer, dimension(HEIGHT, WIDTH) :: grid, tmp
+  logical, dimension(HEIGHT, WIDTH) :: visible
+
+  read (*, *) lines
+  do i = 1, HEIGHT
+    do j = 1, WIDTH
+      read (lines(i)(j:j), '(I1)') grid(i, j)
+    end do
+  end do
+
+  visible(:, :) = .false.
+  visible(1, :) = .true.
+  visible(HEIGHT, :) = .true.
+  visible(:, 1) = .true.
+  visible(:, WIDTH) = .true.
+
+  tmp = grid
+  do i = 2, HEIGHT-1
+    visible(i, :) = visible(i, :) .or. tmp(i-1, :) < grid(i, :)
+    tmp(i, :) = max(tmp(i-1, :), grid(i, :))
+  end do
+
+  tmp = grid
+  do i = HEIGHT-1, 2, -1
+    visible(i, :) = visible(i, :) .or. tmp(i+1, :) < grid(i, :)
+    tmp(i, :) = max(tmp(i+1, :), grid(i, :))
+  end do
+
+  tmp = grid
+  do i = 2, WIDTH-1
+    visible(:, i) = visible(:, i) .or. tmp(:, i-1) < grid(:, i)
+    tmp(:, i) = max(tmp(:, i-1), grid(:, i))
+  end do
+
+  tmp = grid
+  do i = WIDTH-1, 2, -1
+    visible(:, i) = visible(:, i) .or. tmp(:, i+1) < grid(:, i)
+    tmp(:, i) = max(tmp(:, i+1), grid(:, i))
+  end do
+
+  print *, sum(merge(1, 0, visible))
+end program one
diff --git a/aoc/2022/08/part-two.f90 b/aoc/2022/08/part-two.f90
new file mode 100644
index 0000000..a313638
--- /dev/null
+++ b/aoc/2022/08/part-two.f90
@@ -0,0 +1,53 @@
+PROGRAM two
+  implicit none
+  integer, parameter :: WIDTH = 99, HEIGHT = 99
+  integer, parameter :: ID(0:9) = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+  integer, parameter :: COL(HEIGHT, 0:9) = spread(ID, 1, HEIGHT)
+  integer, parameter :: ROW(WIDTH, 0:9) = spread(ID, 1, WIDTH)
+  character(WIDTH) :: lines(HEIGHT)
+  integer :: i, j
+  integer, dimension(HEIGHT, WIDTH) :: grid, score
+  integer, dimension(HEIGHT, WIDTH, 0:9) :: tmp
+
+  read (*, *) lines
+  do i = 1, HEIGHT
+    do j = 1, WIDTH
+      read (lines(i)(j:j), '(I1)') grid(i, j)
+    end do
+  end do
+
+  score = 0
+  tmp = 0
+  do i = 2, HEIGHT-1
+    tmp(i, :, :) = merge(tmp(i-1, :, :)+1, 1, spread(grid(i-1, :), 2, 10) < ROW)
+    do j = 2, WIDTH-1
+      score(i, j) = tmp(i, j, grid(i, j))
+    end do
+  end do
+
+  tmp = 0
+  do i = 2, WIDTH-1
+    tmp(:, i, :) = merge(tmp(:, i-1, :)+1, 1, spread(grid(:, i-1), 2, 10) < COL)
+    do j = 2, WIDTH-1
+      score(j, i) = score(j, i) * tmp(j, i, grid(j, i))
+    end do
+  end do
+
+  tmp = 0
+  do i = HEIGHT-1, 2, -1
+    tmp(i, :, :) = merge(tmp(i+1, :, :)+1, 1, spread(grid(i+1, :), 2, 10) < ROW)
+    do j = 2, WIDTH-1
+      score(i, j) = score(i, j) * tmp(i, j, grid(i, j))
+    end do
+  end do
+
+  tmp = 0
+  do i = WIDTH-1, 2, -1
+    tmp(:, i, :) = merge(tmp(:, i+1, :)+1, 1, spread(grid(:, i+1), 2, 10) < COL)
+    do j = 2, WIDTH-1
+      score(j, i) = score(j, i) * tmp(j, i, grid(j, i))
+    end do
+  end do
+
+  print *, maxval(score)
+end program two
diff --git a/aoc/2022/09/part-one.tcl b/aoc/2022/09/part-one.tcl
new file mode 100755
index 0000000..3e7716a
--- /dev/null
+++ b/aoc/2022/09/part-one.tcl
@@ -0,0 +1,25 @@
+#!/usr/bin/env tclsh
+proc vec x {list [expr {abs($x)}] [expr {($x>0)-($x<0)}]}
+set tx [set hx 0]
+set ty [set hy 0]
+while {1} {
+    set line [gets stdin]
+    if {[eof stdin] || $line == ""} then break
+    lassign [split $line] d n
+    for {set i 0} {$i < $n} {incr i} {
+        switch $d {
+            R {incr hx 1}
+            U {incr hy 1}
+            L {incr hx -1}
+            D {incr hy -1}
+        }
+        lassign [vec [expr {$hx-$tx}]] mx dx
+        lassign [vec [expr {$hy-$ty}]] my dy
+        if {$mx == 2 || $my == 2} {
+            incr tx $dx
+            incr ty $dy
+        }
+        set v($tx,$ty) 1
+    }
+}
+puts [array size v]
diff --git a/aoc/2022/09/part-two.tcl b/aoc/2022/09/part-two.tcl
new file mode 100755
index 0000000..e3d539f
--- /dev/null
+++ b/aoc/2022/09/part-two.tcl
@@ -0,0 +1,30 @@
+#!/usr/bin/env tclsh
+proc vec x {list [expr {abs($x)}] [expr {($x>0)-($x<0)}]}
+for {set i 0} {$i < 10} {incr i} {
+    set kx($i) 0
+    set ky($i) 0
+}
+while {1} {
+    set line [gets stdin]
+    if {[eof stdin] || $line == ""} then break
+    lassign [split $line] d n
+    for {set i 0} {$i < $n} {incr i} {
+        switch $d {
+            R {incr kx(0) 1}
+            U {incr ky(0) 1}
+            L {incr kx(0) -1}
+            D {incr ky(0) -1}
+        }
+        for {set j 1} {$j < 10} {incr j} {
+            set p [expr {$j-1}]
+            lassign [vec [expr {$kx($p)-$kx($j)}]] mx dx
+            lassign [vec [expr {$ky($p)-$ky($j)}]] my dy
+            if {$mx == 2 || $my == 2} {
+                incr kx($j) $dx
+                incr ky($j) $dy
+            }
+        }
+        set v($kx(9),$ky(9)) 1
+    }
+}
+puts [array size v]
diff --git a/aoc/2022/10/part-one.awk b/aoc/2022/10/part-one.awk
new file mode 100755
index 0000000..756464e
--- /dev/null
+++ b/aoc/2022/10/part-one.awk
@@ -0,0 +1,8 @@
+#!/usr/bin/env -S awk -f
+BEGIN { cycle = x = 1 }
+{ cycle++ }
+cycle % 40 == 20 { strength += cycle * x }
+{ x += $2 }
+/^addx/ { cycle++ }
+/^addx/ && cycle % 40 == 20 { strength += cycle * x }
+END { print strength }
diff --git a/aoc/2022/10/part-two.awk b/aoc/2022/10/part-two.awk
new file mode 100755
index 0000000..9126306
--- /dev/null
+++ b/aoc/2022/10/part-two.awk
@@ -0,0 +1,10 @@
+#!/usr/bin/env -S awk -f
+function cycle (c, x) {
+  printf x - 2 < c && c < x + 2 ? "#" : "."
+  printf c == 39 ? "\n" : ""
+  return (c + 1) % 40
+}
+BEGIN { x = 1 }
+{ c = cycle(c, x) }
+/^addx/ { c = cycle(c, x) }
+{ x += $2 }