Skip to content

Instantly share code, notes, and snippets.

@zdimension
Created December 3, 2023 19:32
Show Gist options
  • Save zdimension/0e502872aae33e8ada1f9b7a6ba4570b to your computer and use it in GitHub Desktop.
Save zdimension/0e502872aae33e8ada1f9b7a6ba4570b to your computer and use it in GitHub Desktop.
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