Skip to content

Commit 5acc2fd

Browse files
committed
15/25: Run either awk or pure bash code for slow days
PUREBASH environment variable can be set in order to run bash (50-100 times slower than awk). Day 15 optimized to run in under 20 minutes.
1 parent 83f7acc commit 5acc2fd

File tree

3 files changed

+47
-33
lines changed

3 files changed

+47
-33
lines changed

15.sh

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,42 @@
11
#! /usr/bin/env bash
22
A=($(<"${1:-15.txt}"))
3-
GIVEUP=${2:-10}
4-
#A=(0 3 6)
5-
B=(); i=0; l=""
3+
PUREBASH=${2:-$PUREBASH}
4+
declare -a B=()
5+
i=0; l=""
66
for a in "${A[@]}"; do B[a]=$((++i)); done
77
while [ $i -lt 2020 ]; do
88
n=$((i-${l:-$i})); l=${B[n]}; B[n]=$((++i))
99
done
1010
echo "15A: $n"
1111

12+
# eval is slow, but large arrays are slower
13+
# Split the higher numbers into smaller arrays
1214
sharded_swap() { # syntax: l=B[$1]; B[$1]=$2
13-
local x="B$(($1>>9))[$1&511]"
15+
local x="B$(($1>>8))[$(($1&255))]"
1416
#local x="B$(($1>>6))[$1&63]"
1517
eval "l=\${$x}; $x=$2"
1618
}
17-
SECONDS=0
18-
trap 'echo "$i: $SECONDS sec $((i/300000))%"' USR1 EXIT
19-
i=0; for a in "${A[@]}"; do sharded_swap "$a" $((++i)); done; l="";
20-
while [[ $i -lt 30000000 && $SECONDS -le $GIVEUP ]]; do
21-
n=$((i-${l:-$i})); sharded_swap $n $((++i))
22-
done
23-
if [ $i = 30000000 ]; then
19+
20+
if [ -n "$PUREBASH" ]; then
21+
trap 'echo "Giving up (i=$i, $SECONDS seconds)"; exit 1' TERM INT
22+
echo "This could take 15-20 minutes. Ctrl-C or 'kill $$' to stop."
23+
declare -a B{1..1000}
24+
for N in $(seq 1000000 1000000 30000000 ); do
25+
while ((i < N)); do
26+
n=$((i-${l:-$i}));
27+
if (( n < 2048 )); then
28+
l=${B[n]}; B[n]=$((++i))
29+
else
30+
sharded_swap $n $((++i))
31+
fi
32+
done
33+
echo "$i took $SECONDS seconds" ;
34+
done
2435
echo "15B: $n"
2536
else
26-
# The code above is painfully slow. Switch to awk
27-
echo "15B(round $i): $n (Gave up after $SECONDS seconds)"
2837
printf "%s\n" "${A[@]}" | awk '{B[$0]=++i;}
29-
END {
30-
while (i<30000000) { n=l?(i-l):0; l=B[n]; B[n]=++i; }
31-
print "15B(awk):", n;
32-
}'
38+
END {
39+
while (i<30000000) { n=l?(i-l):0; l=B[n]; B[n]=++i; }
40+
print "15B(awk):", n;
41+
}'
3342
fi

25.sh

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
#! /usr/bin/env bash
22
A=($(< "${1:-25.txt}"))
3-
declare -i k=1 e=1 key1=${A[0]} key2=${A[1]}
4-
until ((k==key1)); do
5-
((k=k*7 % 20201227, e=e*key2 % 20201227))
6-
done
7-
echo "25A: $e"
8-
echo "${A[@]}" | awk '{key1=$1; key2=$2; k=1; e=1}
9-
END {
10-
while (k != key1) { k = k*7 % 20201227; e = e*key2 % 20201227 }
11-
print "25A(awk):", e
12-
}'
3+
PUREBASH=${2:-$PUREBASH}
4+
if [ -n "$PUREBASH" ]; then
5+
trap 'echo "Giving up after $SECONDS seconds"; exit 1' INT TERM
6+
echo "This could take a minute. Ctrl-C or 'kill $$' to exit"
7+
declare -i k=1 e=1 key1=${A[0]} key2=${A[1]}
8+
until ((k==key1)); do
9+
((k=k*7 % 20201227, e=e*key2 % 20201227))
10+
done
11+
echo "25A: $e"
12+
else
13+
echo "${A[@]}" | awk '{key1=$1; key2=$2; k=1; e=1
14+
while (k != key1) { k = k*7 % 20201227; e = e*key2 % 20201227 }
15+
print "25A(awk):", e
16+
}'
17+
fi

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ https://adventofcode.com/2020/
44

55
Input not included, but can be given on the command line.
66
Defaults to *number*.txt in the same folder (no leading 0).
7+
Setting env variable PUREBASH to any value (or giving a second argument) will use slow bash instead of using faster awk in days 15 and 25.
78

89
Description of what I'm doing. Contains spoilers....
910

@@ -74,9 +75,9 @@ Description of what I'm doing. Contains spoilers....
7475

7576
### 15.sh
7677
1. Store the last known position in a sparse array. Calculate next position until done.
77-
2. Finally bash fails. Sparse arrays in bash seem to be linked lists, so accessing/adding an item is O\[Nlog(N)\] or worse.
78+
2. Finally bash fails. Sparse arrays in bash seem to be linked lists, so accessing/adding an item is O\[N\] or worse.
7879
Gave up after 20 hours getting to item 6.1M, and solved it in 10-12 seconds with awk.
79-
Using a sharded-set https://github.com/romkatv/advent-of-code-2019 solves this in about half an hour.
80+
Using a sharded-set https://github.com/romkatv/advent-of-code-2019 solves this in about 20 minutes.
8081

8182
### 16.sh
8283
1. Find the min/max of the classes, then loop through every ticket to find illegal values.
@@ -98,9 +99,8 @@ Description of what I'm doing. Contains spoilers....
9899
2. Cheat a bit and use regex{n} to denote repeated matches.
99100

100101
### 20.sh
101-
1. Slice and dice all permutations of the edges into arrays. Grep each tile against all permutations of edges.
102-
The ones with only 6 matches are corners. The ones with 7 are edges.
103-
2. Tile matching 144 pieces. Nope...
102+
1. Slice and dice all permutations of the edges into arrays. Grep each tile against all permutations of edges. Convert line number to index/rotation. The ones with only 2 matches are corners. The ones with 3 are edges. Use that to assemble the image.
103+
2. Not done yet: Once the picture is assembled, use a multi-line regex to find the monsters. Then count.
104104

105105
### 21.sh
106106
Grep, sort, count
@@ -121,5 +121,5 @@ Description of what I'm doing. Contains spoilers....
121121

122122
### 25.sh
123123
1. A couple of while loops. Yay.
124-
2. I need to complete 17, 20-2 and 24-2 to get this one. Nope.
124+
2. I need to complete 20-2 to get this one. Nope.
125125

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy