commit 2d9273f4c47376b4ad83cf6b336587c1162e76ae
parent fb16f0f694ec44b9c4a127e0939cfb72fdaee6b9
Author: alex wennerberg <alex@alexwennerberg.com>
Date: Sat, 26 Nov 2022 19:54:24 -0800
add new sols 2021
update readme
Diffstat:
11 files changed, 186 insertions(+), 125 deletions(-)
diff --git a/2021/01.f b/2021/01.f
@@ -1,55 +0,0 @@
-h# 5000 constant filespace
-
-: initfile s" input01.txt" filename ;
-
-: readnum
- 0 ( return val )
- begin
- ( push char to stack [awkward] )
- filespace 1 fileread filespace c@
- swap over h# 0a <> and while ( not [newline or eof] )
- h# 30 - swap 10 * + ( convert ascii val )
- repeat
- drop
-;
-
-
-: solvea
- initfile
- 0
- readnum
- 2000 1 do
- readnum dup -rot > 0<> 1+ rot
- + swap
- loop
- drop
-;
-
-: 3dup 2 pick 2 pick 2 pick ;
-
-variable total
-variable last
-
-: solveb
- initfile
- readnum readnum readnum \ read 3 nums
- 2000 3 do
- 3dup + + dup \ sum
- last @
- swap < 0<> negate total +!
- last ! \ store variable
- rot drop \ remove oldest value
- readnum
- loop
- total @
-;
-
-
-: boot
- s" input01.txt" filename
- solvea . cr
- solveb .
- bye
-;
-save 01.rom \ Replace with soln number
-bye
diff --git a/2021/01a.f b/2021/01a.f
@@ -0,0 +1,7 @@
+variable last
+: to-num ( a u -- n ) 0 -rot 0 do dup r@ + c@ h# 30 - rot 10 * + swap loop drop ;
+: read-num ( -- n ) pad pad 10 accept to-num ;
+: get-first-depth read-num last ! ;
+: ?deeper dup last @ u> swap last ! ;
+: count-deepers 1999 0 do read-num ?deeper if 1+ then loop ;
+get-first-depth 0 count-deepers . cr bye
diff --git a/2021/01b.f b/2021/01b.f
@@ -0,0 +1,11 @@
+variable last
+variable total
+: to-num ( a u -- n ) 0 -rot 0 do dup r@ + c@ h# 30 - rot 10 * + swap loop drop ;
+: read-num ( -- n ) pad pad 10 accept to-num ;
+: 3dup 2 pick 2 pick 2 pick ;
+: read-first-3 3 0 do read-num loop ;
+: solve read-first-3 2000 3 do
+3dup + + dup \ sum
+last @ swap < 0<> negate total +! last !
+rot drop read-num loop total @ ;
+solve . cr bye
diff --git a/2021/02.f b/2021/02.f
@@ -1,57 +0,0 @@
-h# 5000 constant filespace
-
-: chartonum h# 30 - ;
-
-: readline \ read a line to filespace
- 0 begin dup
- filespace + dup 1 fileread
- swap c@ h# 0a <> and while ( not [newline or eof] )
- 1+ repeat drop
-;
-
-variable xpos
-variable ydepth
-variable aim
-
-: getcommand
- filespace c@ \ get direction
- filespace 20 32 scan drop 1+ \ read until space
- c@ chartonum swap \ get number
-;
-: solvea
- 1000 0 do readline getcommand
- dup 102 = if \ 'f'
- over xpos +!
- then dup 100 = if \ 'd'
- over ydepth +!
- then dup 117 = if \ 'u'
- over negate ydepth +!
- then
- 2drop loop
- xpos @ ydepth @ um*
-;
-
-: solveb \ TODO figure out how to store double
- s" input02.txt" filename
- 1000 0 do readline getcommand
- dup 102 = if \ 'f'
- over xpos +!
- over aim @ * ydepth +!
- then dup 100 = if \ 'd'
- over aim +!
- then dup 117 = if \ 'u'
- over negate aim +!
- then
- xpos @ ydepth @ aim @ . . . cr
- 2drop loop
- xpos @ ydepth @ .s um*
-;
-
-: boot
- s" input02.txt" filename
- solvea d. cr \ TODO double math??
- 0 xpos ! 0 ydepth !
- solveb d. cr
- bye ;
-save 02.rom \ Replace with soln number
-bye
diff --git a/2021/02a.f b/2021/02a.f
@@ -0,0 +1,16 @@
+\ doesnt need stdin, reads from file named "input.txt"
+include dmath.f
+
+variable horiz 0 horiz !
+variable depth 0 depth !
+
+: to-num ( a u -- n ) 0 -rot 0 do dup r@ + c@ h# 30 - rot 10 * + swap loop drop ;
+: get-n bl parse to-num ;
+: forward ( "N" -- ) get-n horiz +! ;
+: down ( "N" -- ) get-n depth +! ;
+: up ( "N" -- ) get-n negate depth +! ;
+: solve horiz @ depth @ um* ;
+
+include input.txt
+
+solve d. cr bye
diff --git a/2021/02b.f b/2021/02b.f
@@ -0,0 +1,18 @@
+\ doesnt need stdin, reads from file named "input.txt"
+\ copied mostly from peter to learn metaprogramming stuff
+include dmath.f
+
+variable horiz 0 horiz !
+2variable depth 0 0 depth 2!
+variable aim 0 aim !
+
+: to-num ( a u -- n ) 0 -rot 0 do dup r@ + c@ h# 30 - rot 10 * + swap loop drop ;
+: get-n bl parse to-num ;
+: forward ( "N" -- ) get-n dup horiz +! aim @ * 0 depth 2@ d+ depth 2! ;
+: down ( "N" -- ) get-n aim +! ;
+: up ( "N" -- ) get-n negate aim +! ;
+: solve depth 2@ horiz @ 1 m*/ ;
+
+include input.txt
+
+solve d. cr bye
diff --git a/2021/03a.f b/2021/03a.f
@@ -0,0 +1,7 @@
+variable 0 n 0 !
+variable bit 0 bit !
+: read-char pad pad 1 accept c@ ;
+: rate create here 12 cells dup allot fill
+ does> ( -- a ) bit @ cell+ 1 bit +!
+;
+: solve 5 0 do r@ ;
diff --git a/2021/README.md b/2021/README.md
@@ -0,0 +1,11 @@
+Experimenting with aoc-2021. My plan is to do advent of code 2022 LIVE on twitch and upload the VODs to youtube.
+
+Many of these are "inspired" by peter fidelman's [solutions](https://gitlab.cs.washington.edu/fidelp/advent-of-code-2021)
+
+many of these won't run on the sample input
+
+Easiest way to run:
+
+```
+cat ##.f input.txt | uxncli [or uxnemu for solutions with visualizations] ufx.rom
+```
diff --git a/2021/dmath.f b/2021/dmath.f
@@ -0,0 +1,106 @@
+\ mostly taken from:
+\ https://web.archive.org/web/20181118215700/http://excamera.com/files/j1demo/docforth/nuc.fs.html
+
+: d= ( a b c d -- f )
+ >r \ a b c
+ rot xor \ b a^c
+ swap r> xor \ a^c b^d
+ or 0= ;
+: d+ ( augend . addend . -- sum . )
+ rot + >r ( augend addend)
+ over + ( augend sum)
+ dup rot ( sum sum augend)
+ u< if ( sum)
+ r> 1+
+ else
+ r>
+ then ; ( sum . )
+: s>d dup 0< if -1 else 0 then ;
+: dnegate
+ invert swap invert swap
+ 1 0 d+ ;
+: dabs ( d -- ud ) dup 0< if dnegate then ;
+: d- dnegate d+ ;
+: d< \ ( al ah bl bh -- flag )
+ rot \ al bl bh ah
+ 2dup =
+ if
+ 2drop u<
+ else
+ 2nip >
+ then ;
+: d0= or 0= ;
+: d0< 0 0 d< ;
+: d2* 2dup d+ ;
+: d2/ dup 31 lshift >r 2/ swap 2/ r> or swap ;
+: dmax 2over 2over d< if 2swap then 2drop ;
+: dmin 2over 2over d< 0= if 2swap then 2drop ;
+: tf if -1 else 0 then ;
+
+variable scratch
+: um* ( u1 u2 -- ud )
+ scratch !
+ 0 0
+ 16 0 do
+ 2dup d+
+ rot dup 0< if
+ 2* -rot
+ scratch @ 0 d+
+ else
+ 2* -rot
+ then
+ loop
+ rot drop ;
+: abssgn ( a b -- |a| |b| negf )
+ 2dup xor 0< tf >r abs swap abs swap r> ;
+: m* abssgn >r um* r> if dnegate then ;
+: divstep
+ ( divisor dq hi )
+ 2*
+ over 0< if 1+ then
+ swap 2* swap
+ rot ( dq hi divisor )
+ 2dup >= if
+ tuck ( dq divisor hi divisor )
+ -
+ swap ( dq hi divisor )
+ rot 1+ ( hi divisor dq )
+ rot ( divisor dq hi )
+ else
+ -rot
+ then ;
+
+: um/mod ( ud u1 -- u2 u3 )
+ -rot 16 0 do divstep loop
+ rot drop swap ;
+: sm/rem ( d n -- r q ) ( symmetric )
+ over >r >r dabs r@ abs um/mod
+ r> r@ xor 0< if negate then r> 0< if >r negate r> then ;
+: */mod >r m* r> sm/rem ;
+: */ */mod nip ;
+: t2* over >r >r d2* r> 2* r> 0< tf 1 and + ;
+
+variable divisor
+: m*/mod
+ divisor !
+ tuck um* 2swap um* ( hi. lo. )
+ ( m0 h l m1 )
+ swap >r 0 d+ r> ( m h l )
+ -rot ( l m h )
+ 32 0 do
+ t2*
+ dup divisor @ >= if
+ divisor @ -
+ rot 1+ -rot
+ then
+ loop ;
+: m*/ ( d1 n1 +n2 -- d2 ) m*/mod drop ;
+
+\ double printing
+: (digit) ( u -- c ) 9 over < 7 and + [char] 0 + ;
+: (d#) ( d1 -- d2 )
+ 0 base @ um/mod >r base @ um/mod swap (digit) hold r> ;
+: d#s ( d1 -- d2 ) begin (d#) 2dup or 0= until ;
+: d#> ( d -- a u ) drop #> ;
+: (d.) ( d -- a n ) 2dup dabs <# d#s 2swap nip sign d#> ;
+: d. ( n -- ) (d.) type space ;
diff --git a/2021/utils.f b/2021/utils.f
@@ -0,0 +1 @@
+: is-num ( c -- f ) dup 48 >= swap 57 <= and ;
diff --git a/README.md b/README.md
@@ -1,27 +1,23 @@
# Forth AOC
-Advent of Code solutions in [UF
+**Watch me live on [twitch](https://twitch.tv/0000) each day at Midnight EST trying to do this challenge!**
+
+[Advent of Code](https://adventofcode.com/) solutions in [UF
forth](http://www.call-with-current-continuation.org/uf/uf.html)
Forth is a stack-based programming language. It is extremely small. UF is a Forth targeting the
[uxn/varvara](https://100r.co/site/uxn.html) virtual computer.
-I am going to try to work through 2021 using this language/environment as an exercise, and
-in preparation for 2022.
+2021 was me playing around. Doing 2022 live
-A notable challenge will be that I only have access to 64kb of memory. May have to
-use swap space of some sort.
+A notable challenge will be that I only have access to 64kb of memory.
-To run each solution (after building or acquiring ufx.rom from the `uf` repo):
+To run each solution (after building or acquiring uxn and the ufx.rom from the `uf` repo):
```
-# make sure input is in inputN.txt (TODO: make a CLI arg)
-uxncli ufx.rom < N.fs
-uxnemu N.rom
+cat ##[a/b].f input.txt | uxncli ufx.rom
```
-Working on different ways of importing things, some days require helper functions
-
-Some solutions have visualizations, others do not. For those that don't, you can use uxncli
+Each day is split into two parts for simplicity. Code may be heavily duplicated.
-part 1 and part 2 solutions will be printed to the console, newline separated
+Use `uxnemu` for visual solutions (I'll call them out)