pladcl day6 and day7

This commit is contained in:
m
2024-12-07 15:55:33 +08:00
parent 5dbf437175
commit 559fb2514a
7 changed files with 1767 additions and 0 deletions

View File

@@ -0,0 +1,131 @@
state start
if streq(0, "^") == 1 then
`lisp`
end
end
interrupt program_start
`0sw`
`0sh`
end
interrupt newline
# if the width hasn't been recorded yet
if `lw` == 0 then
# width is here
`li1+sw`
end
# inc height
`lh1+sh`
end
interrupt program_end
# print board size
`[board is ]nlwn[ x ]nlhn10an`
`0sd` # current direction
# 0 is up, 1 is right, 2 is down, 3 is left
# calculate x and y dir from found position of ^
`lplw~sxsy`
while 0 == 0 do
#`[current pos is (]nlxn[, ]nlyn[) dir is ]nldn10an`
if out_of_bounds() == 1 then
break
end
# mark us as here
mark_visited()
do_movement()
#`[value at next_pos is ]n`
#value_at_cursor()
#`an10an`
value_at_cursor()
`sv`
if `lv` != '#' then
# move there
`l1sx`
`l2sy`
end
# else turn
if `lv` == '#' then
# d = (d + 1) % 4
`ld1+4%sd`
end
end
# sum all visited
0
for '!' in 0 to `lwlh1-*` do
`l!;Vsv`
if `lv` == 0 then
`l!;Ian`
end
if `lv` != 0 then
`[X]n`
end
`lv+`
end
`[visited: ]np`
end
# takes x, y, d and puts it into 1, 2
function do_movement
if `ld` == 0 then
`lxs1`
`ly1-s2`
end
if `ld` == 1 then
`lx1+s1`
`lys2`
end
if `ld` == 2 then
`lxs1`
`ly1+s2`
end
if `ld` == 3 then
`lx1-s1`
`lys2`
end
end
# finds the char at (1, 2)
function value_at_cursor
`l2lw*l1+;I`
end
# mark (x, y) as visited
function mark_visited
`1lylw*lx+:V`
end
# if (x, y) is out of bounds
function out_of_bounds
if `lx` < 0 then
return 1
end
if `ly` < 0 then
return 1
end
if `lx` >= `lw1-` then
return 1
end
if `ly` >= `lh1-` then
return 1
end
0
end

View File

@@ -0,0 +1,194 @@
state start
if streq(0, "^") == 1 then
`lisp`
end
end
interrupt program_start
`0sw`
`0sh`
end
interrupt newline
# if the width hasn't been recorded yet
if `lw` == 0 then
# width is here
`li1+sw`
end
# inc height
`lh1+sh`
end
interrupt program_end
# print board size
`[board is ]nlwn[ x ]nlhn10an`
`11sd` # current direction
# 2 is up, 3 is right, 5 is down, 7 is left
# max size
`lwlh1-*sm`
`lpsx`
while 0 == 0 do
#`[start]n`
`1lx:X`
#`[marked]n`
do_movement()
#`[moved]n`
if out_of_bounds() == 1 then
break
end
#`[oobchecked]n`
`l1;I`
`sv`
if `lv` != '#' then
#`[move]n`
`l1sx`
end
if `lv` == '#' then
#`[next_dir]n`
next_dir()
end
end
`[initial movement check done]n10an`
`0so`
`0s)`
for '-' in 0 to `lwlh1-*` do
#`6 lw * 3 + s-`
if `l-;X` == 1 then
if `l-;I` == '.' then
`l)p1+s)`
#`l-lw~sxsy`
#`[(]nlxn[, ]nlyn[)]n10an`
`l-;Isi` # load the replacement value of I for safekeeping
'#'
`l-:I` # replce it with '#'
# check
for '?' in 0 to `lm` do
`1l?:V`
end
if test_escape() == 0 then
`lo1+so`
end
'.'
`l-:I` # replace the value back to what it was
end
end
#break
end
`[done]p`
`lop`
end
function test_escape
# calculate x and y dir from found position of ^
`lpsx`
`11sd`
`[`
if check_and_mark_visited() == 1 then
`0q`
end
do_movement()
if out_of_bounds() == 1 then
`1q`
end
`l1;I`
`sv`
if `lv` != '#' then
`l1sxl2sy`
end
if `lv` == '#' then
next_dir()
end
`llx]dslx`
end
# takes x, y, d and puts it into 1, 2
function do_movement
if `ld` == 11 then
`lxlw-s1`
end
if `ld` == 17 then
`lx1+s1`
end
if `ld` == 23 then
`lxlw+s1`
end
if `ld` == 29 then
`lx1-s1`
end
end
# return 1 if already visited in this dir, return 0 and else mark (x, y) as visited
function check_and_mark_visited
# get value of
`lx;Vsv`
if `lvld%` == 0 then
#`[wow]n`
return 1
end
# multiply in d
`lvld*`
# store in array
`lx:V`
0
end
function next_dir
if `ld` == 29 then
`11sd`
return
end
`ld6+sd`
end
# if (x, y) is out of bounds
function out_of_bounds
if `l1` < 0 then
return 1
end
if `l11+lw%` == 0 then
return 1
end
if `l11+` > `lm` then
return 1
end
0
end

View File

@@ -0,0 +1,206 @@
state start
if streq(0, "^") == 1 then
`lisp`
end
end
interrupt program_start
`0sw`
`0sh`
end
interrupt newline
# if the width hasn't been recorded yet
if `lw` == 0 then
# width is here
`li1+sw`
end
# inc height
`lh1+sh`
end
interrupt program_end
# print board size
`[board is ]nlwn[ x ]nlhn10an`
`11sd` # current direction
# 2 is up, 3 is right, 5 is down, 7 is left
`lplw~sxsy`
`lxs1lys2`
while 0 == 0 do
if out_of_bounds() == 1 then
break
end
mark_visited()
do_movement()
value_at_cursor()
`sv`
if `lv` != '#' then
`l1sxl2sy`
end
if `lv` == '#' then
next_dir()
end
end
`[initial movement check done]n10an`
`0so`
`0s)`
for '-' in 0 to `lwlh1-*` do
#`6 lw * 3 + s-`
if `l-;X` == 1 then
if `l-;I` == '.' then
`l)p1+s)`
#`l-lw~sxsy`
#`[(]nlxn[, ]nlyn[)]n10an`
`l-;Isi` # load the replacement value of I for safekeeping
'#'
`l-:I` # replce it with '#'
# check
clear_visited()
if test_escape() == 0 then
`lo1+so`
end
'.'
`l-:I` # replace the value back to what it was
end
end
#break
end
`[done]p`
`lop`
end
function test_escape
# calculate x and y dir from found position of ^
`lplw~sxsy`
`11sd`
while 0 == 0 do
#`[a]nf`
#`[current pos is (]nlxn[, ]nlyn[) dir is ]nldn10an`
#`[b]nf`
if check_and_mark_visited() == 1 then
return 0
end
#`[c]nf`
do_movement()
if out_of_bounds() == 1 then
return 1
end
value_at_cursor()
`sv`
if `lv` != '#' then
`l1sxl2sy`
end
if `lv` == '#' then
next_dir()
end
end
end
function clear_visited
for '?' in 0 to `lwlh1-*` do
`1l?:V`
end
end
# takes x, y, d and puts it into 1, 2
function do_movement
if `ld` == 11 then
`lxs1`
`ly1-s2`
end
if `ld` == 17 then
`lx1+s1`
`lys2`
end
if `ld` == 23 then
`lxs1`
`ly1+s2`
end
if `ld` == 29 then
`lx1-s1`
`lys2`
end
end
# finds the char at (1, 2)
function value_at_cursor
`l2lw*l1+;I`
end
# return 1 if already visited in this dir, return 0 and else mark (x, y) as visited
function check_and_mark_visited
# index
`lylw*lx+s.`
# get value of
`l.;Vsv`
if `lvld%` == 0 then
#`[wow]n`
return 1
end
# multiply in d
`lvld*`
# store in array
`l.:V`
0
end
function mark_visited
# index
`1lylw*lx+:X`
end
function next_dir
if `ld` == 29 then
`11sd`
return
end
`ld6+sd`
end
# if (x, y) is out of bounds
function out_of_bounds
if `l1` < 0 then
return 1
end
if `l2` < 0 then
return 1
end
if `l1` >= `lw1-` then
return 1
end
if `l2` >= `lh1-` then
return 1
end
0
end