-
Notifications
You must be signed in to change notification settings - Fork 0
/
09.sh
138 lines (120 loc) · 3.07 KB
/
09.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!bin/bash
makeQ () {
local line=$1
local curr=0
local res=()
i=0
while (( i < ${#line} )); do
num=${line:$i:1}
j=0
if (( i % 2 == 0 )); then
while (( j < num )); do
res+=("$curr")
(( j++ ))
done
(( curr++ ))
else
while (( j < num )); do
res+=(".")
(( j++ ))
done
fi
(( i++ ))
done
echo "${res[@]}"
}
p2() {
local Q=($(makeQ "$1"))
echo "B/init ${Q[*]}" >&2 # init
local N=${#Q[@]}
echo "len/ $N" >&2
local SPACE=()
declare -A IDS
local highest=-1
local i=0
while :; do
if [[ ${Q[i]} == "." ]]; then
local count=0
local spaceleft=$i
while (( i < N )) && [[ ${Q[i]} == "." ]]; do
(( count++ ))
(( i++ ))
done
if (( count != 0 )); then
SPACE+=("$spaceleft,$count")
fi
if (( i >= N )); then
break
fi
else
local count=0
local spaceleft=$i
local curr=${Q[i]}
while (( i < N )) && [[ ${Q[i]} == $curr ]]; do
(( count++ ))
(( i++ ))
done
if (( count != 0 )); then
IDS[$curr]="$spaceleft,$count"
fi
highest=$curr # Track the highest value
if (( i >= N )); then
break
fi
fi
done
# moving tiles
while (( highest > -1 )); do
IFS=',' read -r IDleft IDsize <<< "${IDS[$highest]}"
for i in "${!SPACE[@]}"; do
IFS=',' read -r spaceleft spacesize <<< "${SPACE[$i]}"
if (( spaceleft > IDleft )); then
break
fi
if (( IDsize == spacesize )); then
IDS[$highest]="$spaceleft,$IDsize"
SPACE[$i]="$(( spaceleft + IDsize )),0"
break
fi
if (( IDsize < spacesize )); then
IDS[$highest]="$spaceleft,$IDsize"
SPACE[$i]="$(( spaceleft + IDsize )),$((spacesize - IDsize))"
break
fi
done
(( highest-- ))
done
local res=0
for key in "${!IDS[@]}"; do
IFS=',' read -r L N <<< "${IDS[$key]}"
for (( i = L; i < L + N; i++ )); do
(( res += i * key ))
done
done
echo "$res"
}
p1() {
local Q=($(makeQ "$1"))
echo "A/init ${Q[*]}" >&2 # init
i=0
while (( i < ${#Q[@]} ));do
if [[ ${Q[i]} == "." ]];then
Q[i]=${Q[-1]}
unset 'Q[-1]'
else
(( i++ ))
fi
done
echo "A/last ${Q[*]}" >&2 # end state
local res=0
for idx in "${!Q[@]}"; do
(( res += idx * Q[idx] ))
done
echo "$res"
}
read -r line
res1=$(p1 "$line")
echo "part 1:" $res1
res2=$(p2 "$line");echo
echo "part 1:" $res1 "shouldbe/ 1928 - 6258319840548"
echo "part 2:" $res2 "shouldbe/ 2858 - 6286182965311"