+#!/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