About
My main solutions are in Rust, but this document holds other solutions, mostly in AWK so far
Table of Contents
Day 1
Bash (mostly awk)
just change 1q to 3q for part 2
awk '/^$/ {print sum; sum = 0}; {sum += $1}; END {print sum}' day1/input \
| sort -nr | sed 1q | paste -sd+ | bc -l
Just awk
s - 1
to s - 3
for part 2
/^$/ {
sums[s++] = sum;
sum = 0
}
{
sum += $1
}
END {
asort(sums)
for (i = s; i > s - 1; i--) tot += sums[i]
print tot
}
Day 2
my awk
BEGIN {
hand["A"] = 1 # rock
hand["B"] = 2 # paper
hand["C"] = 3 # scissors
hand["X"] = 1 # rock
hand["Y"] = 2 # paper
hand["Z"] = 3 # scissors
}
function score(a, b) {
o = 0
t = 0
if (a == b) {
# draw
o += 3
t += 3;
} else if (a == 1 && b == 2) {
t += 6
} else if (a == 1 && b == 3) {
o += 6
} else if (a == 2 && b == 1) {
o += 6
} else if (a == 2 && b == 3) {
t += 6
} else if (a == 3 && b == 1) {
t += 6
} else if (a == 3 && b == 2) {
o += 6
}
o += a
t += b
return o" "t
}
{
# t"h"eirs
h = hand[$1]
# o"u"tcome
u = hand[$2]
switch (h" "u) {
case "2 2":
case "1 2":
case "3 2":
ours = h
break;
case "1 1":
ours = 3
break;
case "2 1":
ours = 1
break;
case "3 1":
ours = 2
break;
case "1 3":
ours = 2
break;
case "2 3":
ours = 3
break;
case "3 3":
ours = 1
break;
}
theirs = h
s = score(ours, theirs)
split(s, a, " ")
o = a[1]
t = a[2]
# print ours, theirs, o, t
tot += o
}
END { print tot }
you can just write down all of the possible options and look up the answer.
it could be even shorter if we could initialize a literal array without all
of the assignments. you can translate this straight to Rust with a
HashMap::from([...])
BEGIN {
part1["A X"] = 1 + 3; part1["A Y"] = 2 + 6; part1["A Z"] = 3 + 0;
part1["B X"] = 1 + 0; part1["B Y"] = 2 + 3; part1["B Z"] = 3 + 6;
part1["C X"] = 1 + 6; part1["C Y"] = 2 + 0; part1["C Z"] = 3 + 3;
part2["A X"] = 3 + 0; part2["A Y"] = 1 + 3; part2["A Z"] = 2 + 6;
part2["B X"] = 1 + 0; part2["B Y"] = 2 + 3; part2["B Z"] = 3 + 6;
part2["C X"] = 2 + 0; part2["C Y"] = 3 + 3; part2["C Z"] = 1 + 6;
}
{
p1 += part1[$1" "$2]
p2 += part2[$1" "$2]
}
END { print p1; print p2 }
Day 3
BEGIN {
# build a table mapping characters to priorities
FS = ""
c = 27
for (n = 65; n <= 90; n++) priority[sprintf("%c", n)] = c++
c = 1
for (n = 97; n <= 122; n++) priority[sprintf("%c", n)] = c++
}
{
# part 1
delete a
for (i = 1; i <= NF/2; i++) a[$i] = 1
for (i = NF/2 + 1; i <= NF; i++)
if (a[$i]) {
tot1 += priority[$i]
break;
}
# part 2
if (NR % 3 == 0) {
for (i = 1; i <= NF; i++)
if (r1[$i] && r2[$i]) {
tot2 += priority[$i]
break;
}
delete r1
delete r2
} else if (NR % 3 == 1 ) {
for (i = 1; i <= NF; i++) r1[$i] = 1
} else if (NR % 3 == 2) {
for (i = 1; i <= NF; i++) r2[$i] = 1
}
}
END { print tot1, tot2 }
Day 4
BEGIN { FS = "," }
function contains(a, b) {return a[1] >= b[1] && a[2] <= b[2]}
function contains_any(a, b) {return !(a[1] > b[2] || a[2] < b[1])}
{
split($1, a, "-");
split($2, b, "-");
sum1 += (contains(a, b) || contains(b, a)) ? 1 : 0
sum2 += (contains_any(a, b) || contains_any(b, a)) ? 1 : 0
}
END { print sum1, sum2 }
Day 6
BEGIN { FS = ""; width = 14 }
{
for (i = 1; i <= NF-width; i++) {
for (j = i; j < i+width; j++) {
hold[$j] = 1;
}
if (length(hold) == width) {
print i+width-1
exit
}
delete hold
}
}
Day 7
Not my solution, but the top person’s (betaveros) from the leaderboard in his language noulith is pretty cool. I expected that you could ignore constructing a real directory tree, but I didn’t think actually explore that option in the code. It looks like under the assumption that you only list each directory’s contents once, you can treat the current directory as a stack and push the file’s size to every directory on the stack. With this, betaveros finished the challenge in just over 5 minutes compared to the more than 2 hours in my Rust video. I translate his noulith solution to awk here:
BEGIN {
# stack pointer since we can't push/pop in awk
stack[1] = "/"
p = 2
}
$2 ~ /^ls$/ { next }
$1 ~ /^dir$/ { next }
$2 ~ /^cd$/ {
if ($3 == "/") {
stack[1] = "/"
p = 2
}
else if ($3 == "..") p--
else stack[p++] = $3
next
}
{
# otherwise we're in a file
for (i = p-1; i >= 1; i--) {
if (stack[i] == "ddhfvv") print $0, "adding", sizes[stack[i]]
sizes[stack[i]] += $1
}
}
END {
print "missing: ", sizes["ddhfvv"]
print "missing: ", sizes["jjshzrhd"]
for (key in sizes) {
size = sizes[key]
if (size <= 100000) {
print size, key
tot += size
}
}
print tot
}