2022 day 10: Bash parts 1 & 2

This commit is contained in:
2022-12-17 16:05:49 +01:00
parent ef29ca28a1
commit 02a1dda786
3 changed files with 246 additions and 0 deletions

View File

@@ -195,3 +195,23 @@ aoc.bash: res=2376
aoc-c: res=2376
time: 0:00.00 real, 0.00 user, 0.00 sys
context-switch: 0+1, page-faults: 0+131
=========================================
================= day10 =================
=========================================
+++++++++++++++++ part 1
aoc.bash: res=13220
time: 0:00.00 real, 0.00 user, 0.00 sys
context-switch: 1+1, page-faults: 0+261
+++++++++++++++++ part 2
aoc.bash: res=
###..#..#..##..#..#.#..#.###..####.#..#.
#..#.#..#.#..#.#.#..#..#.#..#.#....#.#..
#..#.#..#.#..#.##...####.###..###..##...
###..#..#.####.#.#..#..#.#..#.#....#.#..
#.#..#..#.#..#.#.#..#..#.#..#.#....#.#..
#..#..##..#..#.#..#.#..#.###..####.#..#.
time: 0:00.01 real, 0.00 user, 0.00 sys
context-switch: 0+1, page-faults: 0+263

View File

@@ -229,3 +229,161 @@ The sum of these signal strengths is =13140=.
Find the signal strength during the 20th, 60th, 100th, 140th, 180th, and
220th cycles. /What is the sum of these six signal strengths?/
Your puzzle answer was =13220=.
** --- Part Two ---
It seems like the =X= register controls the horizontal position of a
[[https://en.wikipedia.org/wiki/Sprite_(computer_graphics)][sprite]].
Specifically, the sprite is 3 pixels wide, and the =X= register sets the
horizontal position of the /middle/ of that sprite. (In this system,
there is no such thing as "vertical position": if the sprite's
horizontal position puts its pixels where the CRT is currently drawing,
then those pixels will be drawn.)
You count the pixels on the CRT: 40 wide and 6 high. This CRT screen
draws the top row of pixels left-to-right, then the row below that, and
so on. The left-most pixel in each row is in position =0=, and the
right-most pixel in each row is in position =39=.
Like the CPU, the CRT is tied closely to the clock circuit: the CRT
draws /a single pixel during each cycle/. Representing each pixel of the
screen as a =#=, here are the cycles during which the first and last
pixel in each row are drawn:
#+begin_example
Cycle 1 -> ######################################## <- Cycle 40
Cycle 41 -> ######################################## <- Cycle 80
Cycle 81 -> ######################################## <- Cycle 120
Cycle 121 -> ######################################## <- Cycle 160
Cycle 161 -> ######################################## <- Cycle 200
Cycle 201 -> ######################################## <- Cycle 240
#+end_example
So, by [[https://en.wikipedia.org/wiki/Racing_the_Beam][carefully]]
[[https://www.youtube.com/watch?v=sJFnWZH5FXc][timing]] the CPU
instructions and the CRT drawing operations, you should be able to
determine whether the sprite is visible the instant each pixel is drawn.
If the sprite is positioned such that one of its three pixels is the
pixel currently being drawn, the screen produces a /lit/ pixel (=#=);
otherwise, the screen leaves the pixel /dark/ (=.=).
The first few pixels from the larger example above are drawn as follows:
#+begin_example
Sprite position: ###.....................................
Start cycle 1: begin executing addx 15
During cycle 1: CRT draws pixel in position 0
Current CRT row: #
During cycle 2: CRT draws pixel in position 1
Current CRT row: ##
End of cycle 2: finish executing addx 15 (Register X is now 16)
Sprite position: ...............###......................
Start cycle 3: begin executing addx -11
During cycle 3: CRT draws pixel in position 2
Current CRT row: ##.
During cycle 4: CRT draws pixel in position 3
Current CRT row: ##..
End of cycle 4: finish executing addx -11 (Register X is now 5)
Sprite position: ....###.................................
Start cycle 5: begin executing addx 6
During cycle 5: CRT draws pixel in position 4
Current CRT row: ##..#
During cycle 6: CRT draws pixel in position 5
Current CRT row: ##..##
End of cycle 6: finish executing addx 6 (Register X is now 11)
Sprite position: ..........###...........................
Start cycle 7: begin executing addx -3
During cycle 7: CRT draws pixel in position 6
Current CRT row: ##..##.
During cycle 8: CRT draws pixel in position 7
Current CRT row: ##..##..
End of cycle 8: finish executing addx -3 (Register X is now 8)
Sprite position: .......###..............................
Start cycle 9: begin executing addx 5
During cycle 9: CRT draws pixel in position 8
Current CRT row: ##..##..#
During cycle 10: CRT draws pixel in position 9
Current CRT row: ##..##..##
End of cycle 10: finish executing addx 5 (Register X is now 13)
Sprite position: ............###.........................
Start cycle 11: begin executing addx -1
During cycle 11: CRT draws pixel in position 10
Current CRT row: ##..##..##.
During cycle 12: CRT draws pixel in position 11
Current CRT row: ##..##..##..
End of cycle 12: finish executing addx -1 (Register X is now 12)
Sprite position: ...........###..........................
Start cycle 13: begin executing addx -8
During cycle 13: CRT draws pixel in position 12
Current CRT row: ##..##..##..#
During cycle 14: CRT draws pixel in position 13
Current CRT row: ##..##..##..##
End of cycle 14: finish executing addx -8 (Register X is now 4)
Sprite position: ...###..................................
Start cycle 15: begin executing addx 13
During cycle 15: CRT draws pixel in position 14
Current CRT row: ##..##..##..##.
During cycle 16: CRT draws pixel in position 15
Current CRT row: ##..##..##..##..
End of cycle 16: finish executing addx 13 (Register X is now 17)
Sprite position: ................###.....................
Start cycle 17: begin executing addx 4
During cycle 17: CRT draws pixel in position 16
Current CRT row: ##..##..##..##..#
During cycle 18: CRT draws pixel in position 17
Current CRT row: ##..##..##..##..##
End of cycle 18: finish executing addx 4 (Register X is now 21)
Sprite position: ....................###.................
Start cycle 19: begin executing noop
During cycle 19: CRT draws pixel in position 18
Current CRT row: ##..##..##..##..##.
End of cycle 19: finish executing noop
Start cycle 20: begin executing addx -1
During cycle 20: CRT draws pixel in position 19
Current CRT row: ##..##..##..##..##..
During cycle 21: CRT draws pixel in position 20
Current CRT row: ##..##..##..##..##..#
End of cycle 21: finish executing addx -1 (Register X is now 20)
Sprite position: ...................###..................
#+end_example
Allowing the program to run to completion causes the CRT to produce the
following image:
#+begin_example
##..##..##..##..##..##..##..##..##..##..
###...###...###...###...###...###...###.
####....####....####....####....####....
#####.....#####.....#####.....#####.....
######......######......######......####
#######.......#######.......#######.....
#+end_example
Render the image given by your program. /What eight capital letters
appear on your CRT?/
Your puzzle answer was =RUAKHBEK=.
Both parts of this puzzle are complete! They provide two gold stars: **

68
2022/day10/aoc.bash Executable file
View File

@@ -0,0 +1,68 @@
#!/usr/bin/env bash
#
# aoc.bash: Advent of Code 2022, day 10
#
# Copyright (C) 2022 Bruno Raoult ("br")
# Licensed under the GNU General Public License v3.0 or later.
# Some rights reserved. See COPYING.
#
# You should have received a copy of the GNU General Public License along with this
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
#
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
. common.bash
declare -i cycle=0 regx=1
draw() {
local -i pos
if (( cycle % 40 )); then
(( pos = cycle % 40 - regx - 1, pos = pos < 0? -pos: pos ))
(( pos < 2 )) && res+="#" || res+="."
else
res+=.$'\n'
fi
}
tick() {
(( cycle ++ ))
if (( part == 1 )); then
(( (cycle + 20) % 40 )) || (( res += cycle * regx ))
else
draw
fi
}
do_noop() {
tick
}
do_add() {
tick
tick
(( regx += $1 ))
}
parse() {
while read -r instr value; do
# not too hacky, to prepare for next puzzles ;-)
case "$instr" in
"addx")
do_add "$value"
;;
"noop")
do_noop
;;
esac
done
}
solve() {
# remove last '\n', add starting '\n'
(( part == 2 )) && res=$'\n'${res::-1}
}
main "$@"
exit 0