Created
December 3, 2023 19:32
-
-
Save zdimension/0e502872aae33e8ada1f9b7a6ba4570b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
identification division. | |
program-id. aoc3. | |
author. zdimension | |
environment division. | |
input-output section. | |
file-control. | |
*> expects input from stdin | |
select sysin assign to keyboard organization line sequential. | |
data division. | |
file section. | |
fd sysin. | |
01 buf pic x(512). | |
working-storage section. | |
01 mat-size pic 9(3). | |
01 occurs 255 times. | |
02 state occurs 255 times pic 9(4) value 0. | |
01 input-lines occurs 255 times. | |
02 chars occurs 255 times pic X. | |
01 nums occurs 8192 times pic 9(10). | |
01 ids occurs 8192 times pic 9(4). | |
01 num-count pic 9(4) value 1. | |
01 id-count pic 9(4) value 0. | |
01 y pic 9(3). | |
01 x pic 9(3). | |
01 num-len pic 9(3) value 1. | |
01 in-number pic 1 value 0. | |
01 temp pic 9(10). | |
01 temp2 pic 9(4). | |
01 dx pic s9. | |
01 dy pic s9. | |
01 found pic 1. | |
01 sum-parts pic 9(10) value 0. | |
01 gear-ratios pic 9(10) value 0. | |
01 result-display pic z(10). | |
01 neighbs occurs 8 times pic 9(4). | |
01 neighb-count pic 9. | |
procedure division. | |
accept buf | |
*> detect matrix size | |
move function trim(buf) to buf | |
move function length(function trim(buf)) to mat-size | |
*> read numbers to state(y,x) array | |
*> nums(..) contains the list of read numbers | |
*> state(y,x) contains either 0 or the index in nums(..) of the number in that cell | |
move 1 to y | |
perform until y > mat-size | |
move buf to input-lines(y) | |
move 1 to x | |
perform until x > mat-size | |
if buf(x:num-len) is numeric | |
move 1 to in-number | |
add num-len to x giving temp | |
add 1 to y giving temp2 | |
move num-count to state(temp2, temp) | |
add 1 to num-len | |
else | |
if in-number = 1 | |
subtract 1 from num-len | |
move buf(x:num-len) to nums(num-count) | |
add 1 to num-count | |
add num-len to x | |
move 1 to num-len | |
move 0 to in-number | |
end-if | |
add 1 to x | |
end-if | |
end-perform | |
add 1 to y | |
accept buf | |
end-perform | |
move 1 to y | |
perform until y > mat-size | |
move 1 to x | |
perform until x > mat-size | |
if chars(y,x) <> "." and not chars(y,x) is numeric | |
move 0 to neighb-count | |
perform varying dy from -1 by 1 until dy > 1 | |
perform varying dx from -1 by 1 until dx > 1 | |
if dy <> 0 or dx <> 0 | |
add dx 1 to x giving temp | |
add dy 1 to y giving temp2 | |
move state(temp2, temp) to temp | |
if temp <> 0 | |
move 0 to found | |
perform varying temp2 from 1 by 1 until temp2 > id-count | |
if ids(temp2) = temp | |
move 1 to found | |
exit perform | |
end-if | |
end-perform | |
if found = 0 | |
add 1 to id-count | |
move temp to ids(id-count) | |
add nums(temp) to sum-parts | |
end-if | |
*> count neighbors for gear ratio sum computation | |
move 0 to found | |
perform varying temp2 from 1 by 1 until temp2 > neighb-count | |
if neighbs(temp2) = temp | |
move 1 to found | |
exit perform | |
end-if | |
end-perform | |
if found = 0 | |
add 1 to neighb-count | |
move temp to neighbs(neighb-count) | |
end-if | |
end-if | |
end-if | |
end-perform | |
end-perform | |
if chars(y,x) = "*" and neighb-count = 2 | |
multiply nums(neighbs(1)) by nums(neighbs(2)) giving temp | |
add temp to gear-ratios | |
end-if | |
end-if | |
add 1 to x | |
end-perform | |
add 1 to y | |
end-perform | |
move sum-parts to result-display | |
display "sum of parts numbers = ", result-display | |
move gear-ratios to result-display | |
display "sum of gear ratios = ", result-display | |
stop run. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment