164 lines
2.9 KiB
Forth
164 lines
2.9 KiB
Forth
|
variable input-fd
|
||
|
|
||
|
: open-input r/o open-file throw input-fd ! ;
|
||
|
|
||
|
256 constant MAX_LINE
|
||
|
create line MAX_LINE allot
|
||
|
|
||
|
: fill-line line line MAX_LINE input-fd @ read-line throw ;
|
||
|
|
||
|
: start s" input.txt" open-input ;
|
||
|
: hint s" hint.txt" open-input ;
|
||
|
|
||
|
( c c-addr u -- c-addr' u' ) \ Search string for char `c`
|
||
|
: find-char
|
||
|
begin
|
||
|
\ Read character
|
||
|
over c@
|
||
|
\ Pick c from stack and compare
|
||
|
3 pick = if
|
||
|
\ Drop off c
|
||
|
rot drop
|
||
|
exit
|
||
|
then
|
||
|
\ Next character
|
||
|
swap 1+ swap 1-
|
||
|
again ;
|
||
|
|
||
|
( c-addr u -- c-addr' u' )
|
||
|
: skip-card-number
|
||
|
': rot rot find-char
|
||
|
\ Skip past ": "
|
||
|
swap 2 + swap 2 - ;
|
||
|
|
||
|
( c-addr u -- c-addr' u' )
|
||
|
: find-pipe
|
||
|
'| rot rot find-char
|
||
|
\ Skip past "| "
|
||
|
swap 2 + swap 2 - ;
|
||
|
|
||
|
2variable winning_nums
|
||
|
2variable my_nums
|
||
|
|
||
|
( c-addr u -- ) \ Splits input line and stores in winning_nums and my_nums
|
||
|
: split-line
|
||
|
|
||
|
\ Skip past card number
|
||
|
skip-card-number
|
||
|
|
||
|
\ Find the pipe
|
||
|
2dup find-pipe
|
||
|
\ This is the start of my_nums
|
||
|
2dup my_nums 2!
|
||
|
|
||
|
\ (win_addr win_len my_addr my_len)
|
||
|
\ Subtract lens then -3 to remove the " | "
|
||
|
swap drop - 3 -
|
||
|
winning_nums 2! ;
|
||
|
|
||
|
( c-addr u -- c-addr' u' ) \ Increment string until a non space is found
|
||
|
: skip-spaces
|
||
|
begin
|
||
|
dup
|
||
|
while
|
||
|
over
|
||
|
c@ bl <> if
|
||
|
exit
|
||
|
then
|
||
|
swap 1+ swap 1-
|
||
|
repeat ;
|
||
|
|
||
|
\ 11/10 pow()
|
||
|
: ** swap dup rot 1- 0 do over * loop swap drop ;
|
||
|
|
||
|
\ Fuck it, we copy paste now. I'm tired
|
||
|
2variable cur2
|
||
|
( n -- w ) \ w = 1 if win
|
||
|
: check-win
|
||
|
winning_nums 2@ cur2 2!
|
||
|
|
||
|
begin
|
||
|
cur2 2@
|
||
|
swap drop
|
||
|
while
|
||
|
\ Preserve `n` passed in
|
||
|
dup
|
||
|
0 0 cur2 2@ skip-spaces >number
|
||
|
\ Stack now has address of rest of string, skip past the spaces and save to cur
|
||
|
skip-spaces
|
||
|
cur2 2!
|
||
|
|
||
|
\ Drop upper part of dint from >number
|
||
|
drop
|
||
|
|
||
|
= if
|
||
|
." Win " .S . cr
|
||
|
true
|
||
|
exit
|
||
|
then
|
||
|
repeat
|
||
|
drop
|
||
|
false
|
||
|
;
|
||
|
|
||
|
2variable cur
|
||
|
variable wins
|
||
|
( -- w ) \ w = 1 if win
|
||
|
: check-mine
|
||
|
0 wins !
|
||
|
my_nums 2@ cur 2!
|
||
|
|
||
|
begin
|
||
|
cur 2@
|
||
|
swap drop
|
||
|
while
|
||
|
0 0 cur 2@ skip-spaces >number
|
||
|
\ Stack now has address of rest of string, skip past the spaces and save to cur
|
||
|
skip-spaces
|
||
|
cur 2!
|
||
|
|
||
|
\ Drop upper part of dint from >number
|
||
|
drop
|
||
|
|
||
|
." Passed to check-win" .S cr
|
||
|
check-win
|
||
|
if
|
||
|
wins @ 1+ wins !
|
||
|
then
|
||
|
repeat
|
||
|
;
|
||
|
|
||
|
: calc-points
|
||
|
wins @ 1 > if
|
||
|
2 wins @ **
|
||
|
2 /
|
||
|
exit
|
||
|
else
|
||
|
wins @ 0 = if
|
||
|
0 exit
|
||
|
then
|
||
|
then
|
||
|
1 ;
|
||
|
|
||
|
variable points
|
||
|
: do-all
|
||
|
begin
|
||
|
\ Read in a line
|
||
|
fill-line
|
||
|
while
|
||
|
split-line
|
||
|
winning_nums 2@ type cr
|
||
|
my_nums 2@ type cr
|
||
|
|
||
|
check-mine cr
|
||
|
." Wins " wins @ . cr
|
||
|
calc-points points @ + points !
|
||
|
repeat ;
|
||
|
|
||
|
start
|
||
|
do-all
|
||
|
cr ." Done ?!@# " points @ . cr
|
||
|
|
||
|
quit
|
||
|
( bye )
|