diff --git a/day13.sh b/day13.sh new file mode 100644 index 0000000..15b37b6 --- /dev/null +++ b/day13.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +unset PATH +readonly PATH +source ./utils/main.sh +source ./utils/array.sh + +solve() { + local ax="$1" ay="$2" bx="$3" by="$4" px="$5" py="$6" tokens=0 + + a="$((px * by - py * bx))" + b="$((py * ax - px * ay))" + c="$((ax * by - ay * bx))" + + ((a % c == 0 && b % c == 0)) && tokens="$((3 * (a / c) + (b / c)))" + echo "$tokens" +} + +do_part() { + local offset="$1" ax ay bx by result=0 + + while read -r line; do + [[ -z "$line" ]] && continue + [[ "$line" =~ Button\ A:\ X\+([0-9]*),\ Y\+([0-9]*) ]] && read -r ax ay <<<"${BASH_REMATCH[@]:1}" && continue + [[ "$line" =~ Button\ B:\ X\+([0-9]*),\ Y\+([0-9]*) ]] && read -r bx by <<<"${BASH_REMATCH[@]:1}" && continue + [[ "$line" =~ Prize:\ X=([0-9]*),\ Y=([0-9]*) ]] && ((result += $(solve "$ax" "$ay" "$bx" "$by" "$((BASH_REMATCH[1] + offset))" "$((BASH_REMATCH[2] + offset))"))) + done + + printf '%s' "$result" + +} + +p1() { + do_part 0 <<<"$1" +} + +p2() { + do_part 10000000000000 <<<"$1" +} + +main "$@" diff --git a/utils/grid.sh b/utils/grid.sh new file mode 100644 index 0000000..339766c --- /dev/null +++ b/utils/grid.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash + +declare -a __GRID__PERPENDICULAR_DIRECTIONS=( + '1 0' + '0 1' + '0 -1' + '-1 0' +) + +grid.coord_to_index() { + local width="$1" x="$2" y="$3" + printf '%d' "$((y * width + x))" +} + +grid.index_to_coord() { + local width="$1" index="$2" + printf '%d %d\n' "$((index % width))" "$((index / width))" +} + +grid.text_to_grid() { + local -n __grid_text_to_grid_grid="$1" + local text="$2" width=0 height=0 c=0 + + __grid_text_to_grid_grid=() + + while read -r line; do + ((height++)) + [[ "$width" ]] && width="${#line}" + while IFS= read -rd '' -n 1 char; do + [[ "$char" == $'\n' ]] && continue + __grid_text_to_grid_grid+=(["$c"]="$char") + ((c++)) + done <<<"$line" + done <<<"$text" + + __grid_text_to_grid_grid+=([width]="$width") + __grid_text_to_grid_grid+=([height]="$height") +} + +grid.perpendicular_neighbors() { + local -n __grid_perpendicular_neighbors_grid="$1" + local x="$2" y="$3" + + for dir in "${__GRID__PERPENDICULAR_DIRECTIONS[@]}"; do + local dx dy nx ny + read -r dx dy <<<"$dir" + nx="$(( x + dx ))" + ny="$(( y + dy ))" + (( nx >= 0 && nx < __grid_perpendicular_neighbors_grid[width] && ny >= 0 && ny < __grid_perpendicular_neighbors_grid[height] )) || continue + printf '%d %d\n' "$nx" "$ny" + done +} + +grid.get() { + local -n __grid_get_grid="$1" + local x="$2" y="$3" width="${__grid_get_grid[width]}" + + (( x >= 0 && x < __grid_get_grid[width] && y >= 0 && y < __grid_get_grid[height] )) || { + echo "($x,$y) is out of bounds for grid of size (${__grid_get_grid[width]},${__grid_get_grid[height]})" >&2 + return 1 + } + + printf '%s\n' "${__grid_get_grid["$((y * width + x))"]}" +} + +grid.set() { + local -n __grid_set_grid="$1" + local x="$2" y="$3" value="$4" width="${__grid_set_grid[width]}" + + (( x >= 0 && x < __grid_set_grid[width] && y >= 0 && y < __grid_set_grid[height] )) || { + echo "($x,$y) is out of bounds for grid of size (${__grid_set_grid[width]},${__grid_set_grid[height]})" >&2 + return 1 + } + __grid_set_grid["$((y * width + x))"]="$value" +}