Skip to content

Instantly share code, notes, and snippets.

@skammer
Created December 1, 2023 22:31
Show Gist options
  • Save skammer/c907122abf7ca79772b889d9e25d7402 to your computer and use it in GitHub Desktop.
Save skammer/c907122abf7ca79772b889d9e25d7402 to your computer and use it in GitHub Desktop.
include ffl/str.fs
0 Variable cnt
0 Value fd-in
256 Constant max-line
Create line-buffer max-line 2 + allot
str-create buffer
str-create buffer-inverted
str-create buffer-tmp
: SPACE ( -- ) BL EMIT ;
: open-input ( addr u -- ) r/o open-file throw to fd-in ;
: swap-chars ( len idx str -- )
>r 2dup - 1- buffer-tmp str-get-char
swap r> str-set-char drop ;
: invert-string ( str -- )
>r
r@ str-get buffer-tmp str-set
r@ str-length@ 0
begin
2dup >
while
2dup r@ swap-chars
1+
repeat
2drop
rdrop
;
: read-one-line
line-buffer max-line fd-in read-line throw
over line-buffer swap buffer str-set
over line-buffer swap buffer-inverted str-set
buffer-inverted invert-string
;
: ctype ( addr -- ) begin dup c@ dup while emit 1 + repeat drop drop ;
\ 48 is 0 in ascii
: ascii-to-int ( c -- int ) 48 - ;
: is-number ( c -- bool )
ascii-to-int dup 0 >= swap 9 <= and ;
: first-number ( str -- number )
>r 0
begin
dup r@ str-length@ <
over r@ str-data@ + c@ is-number invert
and
while
\ line-buffer over + c@ emit cr
1+
repeat
r@ str-data@ + c@ ascii-to-int
rdrop
\ dup . cr
;
: last-number ( str -- number )
>r r@ str-length@
begin
1-
dup 0 >
over r@ str-data@ swap + c@ is-number invert
and
while
\ r@ str-data@ over + c@ emit cr
repeat
r@ str-data@ swap + c@ ascii-to-int
rdrop
\ dup . cr
;
: number-spelled-out-somewhere ( str -- bool )
>r
s" one" 0 r@ str-find 0>=
s" two" 0 r@ str-find 0>= or
s" three" 0 r@ str-find 0>= or
s" four" 0 r@ str-find 0>= or
s" five" 0 r@ str-find 0>= or
s" six" 0 r@ str-find 0>= or
s" seven" 0 r@ str-find 0>= or
s" eight" 0 r@ str-find 0>= or
s" nine" 0 r@ str-find 0>= or
rdrop
;
: number-spelled-out-somewhere-inv ( str -- bool )
>r
s" eno" 0 r@ str-find 0>=
s" owt" 0 r@ str-find 0>= or
s" eerht" 0 r@ str-find 0>= or
s" ruof" 0 r@ str-find 0>= or
s" evif" 0 r@ str-find 0>= or
s" xis" 0 r@ str-find 0>= or
s" neves" 0 r@ str-find 0>= or
s" thgie" 0 r@ str-find 0>= or
s" enin" 0 r@ str-find 0>= or
rdrop
;
: str-replace-first ( c-addr1 u1 c-addr2 u2 str -- = Replace first occurence of the string c-addr2 u2 with the string c-addr1 u1 in the string )
>r 0
dup r@ str-length@ < dup IF \ If index is lower than the length
drop
>r 2dup r>
r@ str-find \ Find the search string in the string
dup -1 <>
THEN IF
>r 2swap 2dup r>
r@ over
>r str-insert-string dup r> + \ Insert the new string in the string
>r 2swap dup r>
r@ over
>r str-delete r> \ Delete the search string
THEN
drop 2drop 2drop
rdrop
;
: starts-with-at-index ( s1 u1 idx str -- bool )
>r
dup 2swap rot r> str-find = ;
: maybe-replace ( str_r u_r str_f u_f n_idx str -- bool )
2>r 2dup 2r@ starts-with-at-index if
2r@ swap drop str-replace-first
-1
else
2drop 2drop
0
then
2rdrop
;
: replace-number-at-index ( n str -- n = returns bool if something has been replaced)
2>r
s" 1" s" one" 2r@ maybe-replace
s" 2" s" two" 2r@ maybe-replace or
s" 3" s" three" 2r@ maybe-replace or
s" 4" s" four" 2r@ maybe-replace or
s" 5" s" five" 2r@ maybe-replace or
s" 6" s" six" 2r@ maybe-replace or
s" 7" s" seven" 2r@ maybe-replace or
s" 8" s" eight" 2r@ maybe-replace or
s" 9" s" nine" 2r@ maybe-replace or
2rdrop
;
: replace-number-at-index-inv ( n str -- n = returns bool if something has been replaced)
2>r
s" 1" s" eno" 2r@ maybe-replace
s" 2" s" owt" 2r@ maybe-replace or
s" 3" s" eerht" 2r@ maybe-replace or
s" 4" s" ruof" 2r@ maybe-replace or
s" 5" s" evif" 2r@ maybe-replace or
s" 6" s" xis" 2r@ maybe-replace or
s" 7" s" neves" 2r@ maybe-replace or
s" 8" s" thgie" 2r@ maybe-replace or
s" 9" s" enin" 2r@ maybe-replace or
2rdrop
;
: print-buffer buffer str-get type cr ;
: numberify-buffer ( str -- )
>r 0
begin
dup r@ str-length@ <
r@ number-spelled-out-somewhere
and
while
dup r@ replace-number-at-index if
drop 0
else
1+
then
repeat
drop
rdrop
;
: numberify-buffer-inv ( str -- )
>r 0
begin
dup r@ str-length@ <
r@ number-spelled-out-somewhere-inv
and
while
dup r@ replace-number-at-index-inv if
drop 0
else
1+
then
repeat
drop
rdrop
;
: count-lines
begin
read-one-line
while
buffer numberify-buffer
buffer-inverted numberify-buffer-inv
buffer first-number
\ dup . space
10 *
buffer-inverted first-number
\ dup . space
+
\ dup . space buffer str-get type space buffer-inverted str-get type cr
cnt @ swap + cnt !
repeat
s" Total: " type
cnt @ . cr ;
s" input.txt" open-input
\ read-one-line
cr cr
count-lines
\ 37165 + 16935
\ 54100
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment