Day 13 (start)
[advent-of-code-2021.git] / day13 / fold.sh
diff --git a/day13/fold.sh b/day13/fold.sh
new file mode 100755 (executable)
index 0000000..83e1585
--- /dev/null
@@ -0,0 +1,157 @@
+#!/bin/bash
+
+set -u
+
+declare -a points=()
+declare -a folds=()
+
+filename="${1:-example.txt}"
+exec 3<"$filename"
+
+max_x=0
+max_y=0
+
+while read -u 3 line; do
+    if [ "$line" == "" ]; then
+        break
+    fi
+    x=${line%,*}
+    y=${line#*,}
+    if [ $x -gt $max_x ]; then
+        max_x=$x
+    fi
+    if [ $y -gt $max_y ]; then
+        max_y=$y
+    fi
+    points+=($line)
+done
+
+((max_x+=1))
+((max_y+=1))
+
+while read -u 3 line; do
+    folds+=(${line#fold along })
+done
+
+display_map() {
+    for (( y=0; y<$max_y; y++ )); do
+        for (( x=0; x<$max_x; x++ )); do
+            offset=$(((y*$max_x) + $x))
+            case "${map[$offset]}" in
+                0)
+                    echo -n "."
+                    ;;
+                1)
+                    echo -n "#"
+                    ;;
+            esac
+        done
+        echo
+    done
+}
+
+declare -a map
+
+# now build a map
+for (( a=0; a<$(($max_x * $max_y)); a++ )); do
+    map[$a]=0
+done
+
+for point in "${points[@]}"; do
+    x=${point%,*}
+    y=${point#*,}
+    offset=$((($y*$max_x)+$x))
+    map[$offset]=1
+done
+
+fold() {
+    local line="$1"
+    local axis=${line%=*}
+    local point=${line#*=}
+    local dot="."
+
+    declare -a new_map=()
+
+    case $axis in
+        x)
+            local new_max_x=$(($max_x - $point - 1))
+            if [ $point -gt $new_max_x ]; then
+                new_max_x=$point
+            fi
+            local adj=$((max_x % 2))
+            for (( y=0; y<$max_y; y++ )); do
+                for (( x=0; x<$new_max_x; x++ )); do
+                    x_1=$(($point - $new_max_x + $x))
+                    x_2=$(($max_x - ($new_max_x - $point) - $x - $adj))
+                    offset_1=$((($y * $max_x) + $x_1))
+                    offset_2=$((($y * $max_x) + $x_2))
+                    if [ $x_1 -lt 0 ]; then
+                        offset_1=$offset_2
+                    fi
+                    if [ $x_2 -ge $max_x  ]; then
+                        offset_2=$offset_1
+                    fi
+                    new_map+=("$dot")
+                    new_offset=$((($y * $new_max_x) + $x))
+                    new_map[$new_offset]=$((${map[$offset_1]} | ${map[$offset_2]}))
+                done
+            done
+            map=("${new_map[@]}")
+            max_x=$new_max_x
+            ;;
+        y)
+            local new_max_y=$(($max_y - $point - 1))
+            if [ $point -gt $new_max_y ]; then
+                new_max_y=$point
+            fi
+            local adj=$((max_y % 2))
+            for (( y=0; y<$new_max_y; y++ )); do
+                # do the y offsets here
+                y_1=$(($point - $new_max_y + $y))
+                y_2=$(($max_y - ($new_max_y - $point) - $y - $adj))
+                offset_1=$(($y_1 * $max_x))
+                offset_2=$(($y_2 * $max_x))
+                if [ $y_1 -lt 0 ]; then
+                    offset_1=$offset_2
+                fi
+                if [ $y_2 -ge $max_y  ]; then
+                    offset_2=$offset_1
+                fi
+                for (( x=0; x<$max_x; x++ )); do
+                    off_1=$(($offset_1+$x))
+                    off_2=$(($offset_2+$x))
+                    new_map+=("$dot")
+                    new_offset=$((($y * $max_x) + $x))
+                    new_map[$new_offset]=$((${map[$off_1]} | ${map[$off_2]}))
+                done
+            done
+            map=("${new_map[@]}")
+            max_y=$new_max_y
+            ;;
+    esac
+}
+
+get_points_count() {
+    local count=0
+    for point in "${map[@]}"; do
+        ((count+=$point))
+    done
+
+    echo $count
+}
+
+#display_map
+
+# do first fold
+fold "${folds[0]}"
+echo
+#display_map
+echo
+echo "There are $(get_points_count) dots visible after first fold"
+for (( f=1; f<${#folds[@]}; f++ )); do
+    echo "Doing fold $((f+1)) of ${#folds[@]}"
+    fold "${folds[$f]}"
+done
+echo
+echo "After all folds:"
+display_map