Day 13
[advent-of-code-2021.git] / day13 / fold.sh
1 #!/bin/bash
2
3 set -u
4
5 declare -a points=()
6 declare -a folds=()
7
8 filename="${1:-example.txt}"
9 exec 3<"$filename"
10
11 max_x=0
12 max_y=0
13
14 while read -u 3 line; do
15     if [ "$line" == "" ]; then
16         break
17     fi
18     x=${line%,*}
19     y=${line#*,}
20     if [ $x -gt $max_x ]; then
21         max_x=$x
22     fi
23     if [ $y -gt $max_y ]; then
24         max_y=$y
25     fi
26     points+=($line)
27 done
28
29 ((max_x+=1))
30 ((max_y+=1))
31
32 while read -u 3 line; do
33     folds+=(${line#fold along })
34 done
35
36 display_map() {
37     for (( y=0; y<$max_y; y++ )); do
38         for (( x=0; x<$max_x; x++ )); do
39             offset=$(((y*$max_x) + $x))
40             case "${map[$offset]}" in
41                 0)
42                     echo -n "."
43                     ;;
44                 1)
45                     echo -n "#"
46                     ;;
47             esac
48         done
49         echo
50     done
51 }
52
53 declare -a map
54
55 # now build a map
56 for (( a=0; a<$(($max_x * $max_y)); a++ )); do
57     map[$a]=0
58 done
59
60 for point in "${points[@]}"; do
61     x=${point%,*}
62     y=${point#*,}
63     offset=$((($y*$max_x)+$x))
64     map[$offset]=1
65 done
66
67 fold() {
68     local line="$1"
69     local axis=${line%=*}
70     local point=${line#*=}
71     local dot="."
72
73     declare -a new_map=()
74
75     case $axis in
76         x)
77             local new_max_x=$(($max_x - $point - 1))
78             if [ $point -gt $new_max_x ]; then
79                 new_max_x=$point
80             fi
81             local adj=$((max_x % 2))
82             for (( y=0; y<$max_y; y++ )); do
83                 for (( x=0; x<$new_max_x; x++ )); do
84                     x_1=$(($point - $new_max_x + $x))
85                     x_2=$(($max_x - ($new_max_x - $point) - $x - $adj))
86                     offset_1=$((($y * $max_x) + $x_1))
87                     offset_2=$((($y * $max_x) + $x_2))
88                     if [ $x_1 -lt 0 ]; then
89                         offset_1=$offset_2
90                     fi
91                     if [ $x_2 -ge $max_x  ]; then
92                         offset_2=$offset_1
93                     fi
94                     new_map+=($((${map[$offset_1]} | ${map[$offset_2]})))
95                 done
96             done
97             map=("${new_map[@]}")
98             max_x=$new_max_x
99             ;;
100         y)
101             local new_max_y=$(($max_y - $point - 1))
102             if [ $point -gt $new_max_y ]; then
103                 new_max_y=$point
104             fi
105             local adj=$((max_y % 2))
106             for (( y=0; y<$new_max_y; y++ )); do
107                 # do the y offsets here
108                 y_1=$(($point - $new_max_y + $y))
109                 y_2=$(($max_y - ($new_max_y - $point) - $y - $adj))
110                 offset_1=$(($y_1 * $max_x))
111                 offset_2=$(($y_2 * $max_x))
112                 if [ $y_1 -lt 0 ]; then
113                     offset_1=$offset_2
114                 fi
115                 if [ $y_2 -ge $max_y  ]; then
116                     offset_2=$offset_1
117                 fi
118                 for (( x=0; x<$max_x; x++ )); do
119                     off_1=$(($offset_1+$x))
120                     off_2=$(($offset_2+$x))
121                     new_map+=($((${map[$off_1]} | ${map[$off_2]})))
122                 done
123             done
124             map=("${new_map[@]}")
125             max_y=$new_max_y
126             ;;
127     esac
128 }
129
130 get_points_count() {
131     local count=0
132     for point in "${map[@]}"; do
133         ((count+=$point))
134     done
135
136     echo $count
137 }
138
139 #display_map
140
141 # do first fold
142 fold "${folds[0]}"
143 echo
144 #display_map
145 echo
146 echo "There are $(get_points_count) dots visible after first fold"
147 for (( f=1; f<${#folds[@]}; f++ )); do
148     echo "Doing fold $((f+1)) of ${#folds[@]}"
149     fold "${folds[$f]}"
150 done
151 echo
152 echo "After all folds:"
153 display_map