6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 23, 2024 9:13 pm

All times are UTC




Post new topic Reply to topic  [ 87 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next
Author Message
PostPosted: Mon Jul 31, 2017 5:21 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
I watched this video this morning https://www.youtube.com/watch?v=QPZ0pIK_wsc and realized it was the perfect example of a CS-101 Forth problem. So below is my first attempt.

Code:
: FIZZ?  ( n -- flag)
  3 MOD 0= ;

: BUZZ?   ( n -- flag)
  5 MOD 0= ;

: .FIZZ   ( n -- flag)
  FIZZ? DUP
  IF ." Fizz " THEN ;

: .BUZZ   ( n -- flag)
  BUZZ? DUP
  IF ." Buzz " THEN ;

: FIZZBUZZ   ( --)
  101 1 DO
    I .FIZZ I .BUZZ
    OR 0= IF I . THEN
    CR
  LOOP ;

FIZZBUZZ


Last edited by Martin_H on Tue Aug 01, 2017 12:26 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 01, 2017 4:54 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
Stack comments?

Mike B.


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 01, 2017 4:58 am 
Offline

Joined: Sun Jul 28, 2013 12:59 am
Posts: 235
A variation, tested in gforth; the use of MOD is probably painful on some implementations:
Code:
: .FIZZ ." Fizz " DROP ;
: .BUZZ ." Buzz " DROP ;
: .FIZZBUZZ ." Fizzbuzz " DROP ;

HERE
' .FIZZBUZZ , ' . , ' . , ' .FIZZ , ' . ,
' .BUZZ , ' .FIZZ , ' . , ' . , ' .FIZZ ,
' .BUZZ , ' . , ' .FIZZ , ' . , ' . ,
CONSTANT BEES

: FIZZBUZZ
  101 1 DO
    I BEES I 15 MOD CELLS + @ EXECUTE
    CR
  LOOP ;

FIZZBUZZ

This is somewhat off-the-cuff, so I didn't bother trying to come up with a better name than "BEES" for the fizzing, buzzing array of execution tokens.


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 01, 2017 12:29 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
barrym95838 wrote:
Stack comments?

Mike B.

I updated the program, but I'm not sure how valuable they are given that all functions except the main one have the same stack footprint.

@nyef, that's a really Forthy Forth program.


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 01, 2017 2:47 pm 
Offline

Joined: Sun Jul 28, 2013 12:59 am
Posts: 235
Martin_H wrote:
@nyef, that's a really Forthy Forth program.

Thanks, I think?

Ordinarily I would not have used a DO loop, it simply isn't part of my normal mental toolkit (or even implemented in my current Forth), but since I started by hacking up a given example, I just left the iteration control alone.

Is it at least obvious how and why it works?


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 01, 2017 3:05 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
nyef wrote:
Is it at least obvious how and why it works?

It looks like you are indexing into a list of execution tokens based upon the remainder. The token determines the output, and most of them are the TOS, but the exceptions output text and drop TOS. It's extensible just by changing the execution token table.

I called it forthy since it uses a number some of the more powerful features of Forth that a novice wouldn't know. I am tempted to rework it using Create Does> which should do the same thing, but bury the complexity.


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 01, 2017 3:07 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
To me it's obvious, in a kinky sort of way. :D You're using a custom-tailored constant array of execution tokens that works great for Fizz=3 and Buzz=5, but it could get a bit unwieldy if you were later tasked to revise it with more "buzz-words". It appears to be efficient in what it does.

Mike B.


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 01, 2017 3:39 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
I changed nyef's program to use create does> to bury the access to the address of BEES.

Code:
: .FIZZ ( unused --)
  ." Fizz " DROP ;

: .BUZZ ( unused --)
  ." Buzz " DROP ;

: .FIZZBUZZ ( unused --)
  ." Fizz Buzz " DROP ;

CREATE BEES
  ' .FIZZBUZZ , ' . , ' . , ' .FIZZ , ' . ,
  ' .BUZZ , ' .FIZZ , ' . , ' . , ' .FIZZ ,
  ' .BUZZ , ' . , ' .FIZZ , ' . , ' . ,
DOES>  ( i addr --)
  SWAP TUCK
  15 MOD CELLS + @ EXECUTE ;

: FIZZBUZZ
  101 1 DO
    I BEES
    CR
  LOOP ;


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 01, 2017 3:50 pm 
Offline

Joined: Sun Jul 28, 2013 12:59 am
Posts: 235
Martin_H wrote:
It looks like you are indexing into a list of execution tokens based upon the remainder. The token determines the output, and most of them are the TOS, but the exceptions output text and drop TOS. It's extensible just by changing the execution token table.

Yes, that's the mechanism.

Martin_H wrote:
I called it forthy since it uses a number some of the more powerful features of Forth that a novice wouldn't know. I am tempted to rework it using Create Does> which should do the same thing, but bury the complexity.

I... fail to see how CREATE DOES> would help here? We're trying to make one word with a specific behaviour, not multiple words with similar (parameterizable) behaviour.

Martin_H wrote:
Code:
CREATE BEES
  ' .FIZZBUZZ , ' . , ' . , ' .FIZZ , ' . ,
  ' .BUZZ , ' .FIZZ , ' . , ' . , ' .FIZZ ,
  ' .BUZZ , ' . , ' .FIZZ , ' . , ' . ,
DOES>  ( i addr --)
  SWAP TUCK
  15 MOD CELLS + @ EXECUTE ;

DOES> outside of a colon definition is not defined by the ANS standard. Easy enough to implement, now that I'm thinking about it, but not defined by the standard.

barrym95838 wrote:
To me it's obvious, in a kinky sort of way. :D You're using a custom-tailored constant array of execution tokens that works great for Fizz=3 and Buzz=5, but it could get a bit unwieldy if you were later tasked to revise it with more "buzz-words". It appears to be efficient in what it does.

Yes, it could get unwieldy very quickly, but since the sequence repeats every ( 3 5 * => 15 ) elements this was easy enough. If the sequence length was in the 17 - 24 range, it'd be a bit iffier, and if it were longer or MOD were expensive, then I might look for another solution.


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 01, 2017 8:24 pm 
Offline

Joined: Tue Jun 08, 2004 11:51 pm
Posts: 213
I might write it like this for a 6502.

Code:
5 constant BuzzMax
3 constant FuzzMax

0 value FuzzCnt
0 value BuzzCnt

: FuzzBuzz
   cr
   0 !> BuzzCnt
   0 !> FuzzCnt
   101 1 do
     FuzzCnt dup 0= if
       ." Fuzz" FuzzMax !> FuzzCnt
     then
     BuzzCnt dup 0= if
       ." Buzz" BuzzMax !> BuzzCnt
     then
     or  if
       I .
     then
     -1 +!> BuzzCnt
     -1 +!> FuzzCnt
     cr
   loop ;
     


untested
Dwight


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 01, 2017 9:05 pm 
Offline

Joined: Sun Jul 28, 2013 12:59 am
Posts: 235
Clearly untested: You got the initialization wrong, so the first result is Fizzbuzz, which shouldn't occur until the fifteenth.

Also note that, unlike the other solutions, this one must be run iteratively. Yes, that's part of the problem statement, but the other versions can easily be refactored (in one case is already refactored) to have a word which takes a number and prints it as though it were part of the fizzbuzz sequence, thus the lower limit on the DO loop is arbitrary, not so here.

!> and +!> are non-standard, as well, FWIW. !> is clearly TO by any other name, but I see no standard equivalent of +!>.


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 01, 2017 9:59 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
I think Dwight's idea is to avoid the use of the mod operator which is probably expensive on an eight bit machine.

I've never seen !> and +!> before. I didn't know create does> outside of a word definition wasn't standard as most Forth implementations I have used included it.


Top
 Profile  
Reply with quote  
PostPosted: Wed Aug 02, 2017 12:34 am 
Offline

Joined: Tue Jun 08, 2004 11:51 pm
Posts: 213
Ok, a little off.
I don't do much with ANSI standard so I miss some.
Most of the Forths I use have !>, =: or TO. They
all do the same thing.
I didn't realize that there was no +TO. It is most useful.


Code:
5 constant BuzzMax
3 constant FuzzMax

0 value FuzzCnt
0 value BuzzCnt

: FuzzBuzz
   BuzzMax to BuzzCnt
   FuzzMax to FuzzCnt
   101 1 do
     BuzzCnt 1- to BuzzCnt
     FuzzCnt 1- to FuzzCnt
     FuzzCnt dup 0= if
       ." Fuzz" FuzzMax to FuzzCnt
     then
     BuzzCnt dup 0= if
       ." Buzz" BuzzMax to BuzzCnt
     then
     or if
       I .
     then
     cr
   loop ;



Yes, I was writing it to avoid MOD that is slow on a 6502.

I'm not sure what is meant by "this one must be run iteratively"?
What makes any of the solutions iteratively and mine not?

Do you mean it should be run like:
Bees ( EndCount StartCount - )
That is a minor change.
Dwight


Top
 Profile  
Reply with quote  
PostPosted: Wed Aug 02, 2017 2:16 am 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
@Dwight, what does !> and +!> do? They are impervious to Google as I can't find a Forth word list that contains them.


Top
 Profile  
Reply with quote  
PostPosted: Wed Aug 02, 2017 2:22 am 
Offline

Joined: Sun Jul 28, 2013 12:59 am
Posts: 235
Martin_H wrote:
@Dwight, what does !> and +!> do? They are impervious to Google as I can't find a Forth word list that contains them.

From context, !> is another name for TO, and +!> would be +TO if such a word existed (add the value at the top of the stack to the following VALUE word).

I'm really not sure if I like VALUE and TO or not.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 87 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: