Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.forth > #47061 > unrolled thread

fizzbuzz problem in forth

Started bymurphy.darin@gmail.com
First post2016-05-12 16:17 -0700
Last post2016-05-20 23:51 +0000
Articles 20 on this page of 30 — 11 participants

Back to article view | Back to comp.lang.forth

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  fizzbuzz problem in forth murphy.darin@gmail.com - 2016-05-12 16:17 -0700
    Re: fizzbuzz problem in forth Paul Rubin <no.email@nospam.invalid> - 2016-05-12 16:43 -0700
      Re: fizzbuzz problem in forth murphy.darin@gmail.com - 2016-05-12 17:22 -0700
      Re: fizzbuzz problem in forth anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-05-13 12:52 +0000
        Re: fizzbuzz problem in forth Paul Rubin <no.email@nospam.invalid> - 2016-05-16 15:09 -0700
          Re: fizzbuzz problem in forth anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-05-17 13:49 +0000
            Re: fizzbuzz problem in forth Paul Rubin <no.email@nospam.invalid> - 2016-05-17 11:14 -0700
              Re: fizzbuzz problem in forth anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-05-18 12:36 +0000
                Re: fizzbuzz problem in forth Paul Rubin <no.email@nospam.invalid> - 2016-05-20 21:55 -0700
                Re: fizzbuzz problem in forth julian.fondren@endurance.com - 2016-06-20 20:20 -0700
          Re: fizzbuzz problem in forth hughaguilar96@gmail.com - 2016-05-17 12:26 -0700
      Re: fizzbuzz problem in forth Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2016-05-15 21:42 +0100
        Re: fizzbuzz problem in forth hughaguilar96@gmail.com - 2016-05-15 14:41 -0700
          Re: fizzbuzz problem in forth hughaguilar96@gmail.com - 2016-05-15 15:15 -0700
            Re: fizzbuzz problem in forth hughaguilar96@gmail.com - 2016-05-15 17:38 -0700
              Re: fizzbuzz problem in forth murphy.darin@gmail.com - 2016-05-15 19:01 -0700
                Re: fizzbuzz problem in forth hughaguilar96@gmail.com - 2016-05-15 19:51 -0700
                  Re: fizzbuzz problem in forth murphy.darin@gmail.com - 2016-05-15 20:48 -0700
                    Re: fizzbuzz problem in forth hughaguilar96@gmail.com - 2016-05-16 07:51 -0700
            Re: fizzbuzz problem in forth "WJ" <w_a_x_man@yahoo.com> - 2016-05-25 08:31 +0000
              Re: fizzbuzz problem in forth "WJ" <w_a_x_man@yahoo.com> - 2016-05-27 19:06 +0000
      Re: fizzbuzz problem in forth humptydumpty <ouatubi@gmail.com> - 2016-05-18 13:19 -0700
        Re: fizzbuzz problem in forth hughaguilar96@gmail.com - 2016-05-18 17:49 -0700
          Re: fizzbuzz problem in forth humptydumpty <ouatubi@gmail.com> - 2016-05-18 21:17 -0700
            Re: fizzbuzz problem in forth hughaguilar96@gmail.com - 2016-05-19 07:38 -0700
              Re: fizzbuzz problem in forth "Kerr Mudd-John" <admin@127.0.0.1> - 2016-06-20 19:24 -0100
                Re: fizzbuzz problem in forth endlessboomcapitalism@gmail.com - 2016-06-20 15:03 -0700
          Re: fizzbuzz problem in forth Albert van der Horst <albert@cherry.spenarnc.xs4all.nl> - 2016-05-19 13:07 +0000
            Re: fizzbuzz problem in forth Paul Rubin <no.email@nospam.invalid> - 2016-05-19 12:22 -0700
              Re: fizzbuzz problem in forth Albert van der Horst <albert@cherry.spenarnc.xs4all.nl> - 2016-05-20 23:51 +0000

Page 1 of 2  [1] 2  Next page →


#47061 — fizzbuzz problem in forth

Frommurphy.darin@gmail.com
Date2016-05-12 16:17 -0700
Subjectfizzbuzz problem in forth
Message-ID<f2c2561c-5208-452d-97b7-3aff17789c02@googlegroups.com>
Here's my version (very, very forth newbie!):

: test   ( -- ) dup 3 mod 0= swap dup 5 mod 0= rot and if ." fizzbuzz" drop else
                                  dup 5 mod 0= if ." buzz" drop else
                                  dup 3 mod 0= if ." fizz" drop else
                                  . then then then ;  

: fizzbuzz   ( -- ) 101 1 do cr i test loop ;

I know it's probaby very sloppy and wasteful, but just finised reading chapter 5 of "Starting forth" and haven't gotten factoring (distilling) down yet, but I will improve! Take care now.

[toc] | [next] | [standalone]


#47063

FromPaul Rubin <no.email@nospam.invalid>
Date2016-05-12 16:43 -0700
Message-ID<871t566dwf.fsf@jester.gateway.pace.com>
In reply to#47061
murphy.darin@gmail.com writes:
> I know it's probaby very sloppy and wasteful, but just finised reading
> chapter 5 of "Starting forth" and haven't gotten factoring
> (distilling) down yet, but I will improve! Take care now.

You did fine.  That fizzbuzz problem attracts so many solutions not
because it's difficult, but because it has annoying edges that draw
people irresistably to look for ways to smooth them down.

http://dave.fayr.am/posts/2012-10-4-finding-fizzbuzz.html
(not Forth related) expands on that thought.

[toc] | [prev] | [next] | [standalone]


#47064

Frommurphy.darin@gmail.com
Date2016-05-12 17:22 -0700
Message-ID<a444923d-4372-4556-80a8-9447b83d9ea1@googlegroups.com>
In reply to#47063
Thank you for your encouraging words, Paul.  I tried not to peek at the other solutions until after I posted my own because I wanted to see if I understood the problem and was able to take what limited knowledge I had to come up with a solution. I am sure with more knowledge and experience my solutions will be smaller, faster and clearer, but for right now I'm just glad to come up with a working solution without bugs or at least bugs I am aware of.  When I work on a problem I try to spend as much time as I can testing each piece to make sure it works the way I expect it too, before moving on to the next, than once I have it all together, I test again to make sure one piece didn't unexpectedly bug another.  Right now, I'm trying not to over optimize/factor because I still have a long way to go in understanding how each piece of the puzzle works on it's own and with other pieces. "Starting Forth" is a great read so far and I've really enjoyed working through the problems presented, once I'm finished with it, I'm going to start working through "Thinking Forth" as I'm sure it will help me learn how to break problem down easier and more efficiently. Take care now.

[toc] | [prev] | [next] | [standalone]


#47085

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2016-05-13 12:52 +0000
Message-ID<2016May13.145248@mips.complang.tuwien.ac.at>
In reply to#47063
Paul Rubin <no.email@nospam.invalid> writes:
>That fizzbuzz problem attracts so many solutions not
>because it's difficult, but because it has annoying edges that draw
>people irresistably to look for ways to smooth them down.
>
>http://dave.fayr.am/posts/2012-10-4-finding-fizzbuzz.html
>(not Forth related) expands on that thought.

I remember that someone presented a nice, concise solution one of the
last times this came up.  Anyway, the article you linked to inspired
the following solution:

: fizzbuzz1 ( n -- )
    dup 3 mod 0= if ." fizz" then
    dup 5 mod 0= if ." buzz" then
    drop ;

: fizzbuzz ( n -- )
    cr dup ['] fizzbuzz1 >string-execute dup if
        2dup type drop free throw drop
    else
        drop free throw . then ;

: main ( -- )
    101 1 ?do i fizzbuzz loop ;

(unveiled a bug in RESIZE, and I cannot commit the fix at the moment).
Of course, using >STRING-EXECUTE to find out if the output of
FIZZBUZZ1 is empty is very heavyweight.  A more Forth-like solution
is:

: fizzbuzz1 ( n -- f )
    true
    over 3 mod 0= if ." fizz" drop false then
    over 5 mod 0= if ." buzz" drop false then
    nip ;

: fizzbuzz ( n -- )
    cr dup fizzbuzz1 if . else drop then ;

: main ( -- )
    101 1 ?do i fizzbuzz loop ;

Simpler, faster, takes a little more effort than the earlier variant
to add more cases, but that's in the Forth spirit of not
overgeneralizing.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2016: http://www.euroforth.org/ef16/

[toc] | [prev] | [next] | [standalone]


#47221

FromPaul Rubin <no.email@nospam.invalid>
Date2016-05-16 15:09 -0700
Message-ID<8760udodtl.fsf@jester.gateway.pace.com>
In reply to#47085
anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
> Of course, using >STRING-EXECUTE to find out if the output of
> FIZZBUZZ1 is empty is very heavyweight.

Yes, and also mathematically unsatisfying imho.  The pattern in
generalized fizzbuzz is "IF this-divisor THEN that-string" and making
the empty string special is a code smell.  I've seen a number of
e.g. Python solutions like that, which don't seem great for the same
reason.

>  A more Forth-like solution is:
> : fizzbuzz1 ( n -- f )
>     true
>     over 3 mod 0= if ." fizz" drop false then
>     over 5 mod 0= if ." buzz" drop false then
>     nip ;     ...

Here's my solution from some time back:

: fout ( addr u n d -- flag ) mod 0= if type 0 else 2drop 1 then ;
: fb.1 ( n -- flag ) >r
    s" Fizz" r@ 3 fout
    s" Buzz" r> 5 fout
    and ;
: fb ( n -- ) dup fb.1 if . else drop then cr ;
: run ( -- ) 20 1 do i fb loop ;

[toc] | [prev] | [next] | [standalone]


#47251

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2016-05-17 13:49 +0000
Message-ID<2016May17.154948@mips.complang.tuwien.ac.at>
In reply to#47221
Paul Rubin <no.email@nospam.invalid> writes:
>anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>> Of course, using >STRING-EXECUTE to find out if the output of
>> FIZZBUZZ1 is empty is very heavyweight.
>
>Yes, and also mathematically unsatisfying imho.  The pattern in
>generalized fizzbuzz is "IF this-divisor THEN that-string" and making
>the empty string special is a code smell.

It's the equivalent of the Maybe stuff in the Haskell solution you
linked to <http://dave.fayr.am/posts/2012-10-4-finding-fizzbuzz.html>,
only more direct: Why have a separate Nothing value, when you can
clearly differentiate between empty and non-empty strings already.
And concatenating strings has exactly the same properties for
non-emptyness as mappend has for Nothing in Maybe values.

The problem is stated (simplified) "Print the numbers, but for some
cases, print something else".  Both the >STRING-EXECUTE and the
Haskell version turn this into:

 In some cases, print something else; if you don't print something
 else, print the number.

Not sure why you smell something here.  The nice thing compared to our
solutions with explicit flags is that there is no redundancy.  E.g.,
it cannot happen that it outputs something else and yet prints a
number.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2016: http://www.euroforth.org/ef16/

[toc] | [prev] | [next] | [standalone]


#47258

FromPaul Rubin <no.email@nospam.invalid>
Date2016-05-17 11:14 -0700
Message-ID<87k2ismu0z.fsf@jester.gateway.pace.com>
In reply to#47251
anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>  In some cases, print something else; if you don't print something
>  else, print the number.
> Not sure why you smell something here.

Because that description is wrong.  It's more like "in some cases, print
some specified string.  Otherwise, print the number".  The trouble is
that the specified string might be the empty string.  So you hit that
case and print the empty string as requested.  But then examine the
print buffer and see that you haven't printed anything, so you
erroneously conclude that you're in the "otherwise" case, so you print
the number when you shouldn't.  That's why you want a Maybe value
instead of checking whether you've printed anything.

[toc] | [prev] | [next] | [standalone]


#47277

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2016-05-18 12:36 +0000
Message-ID<2016May18.143614@mips.complang.tuwien.ac.at>
In reply to#47258
Paul Rubin <no.email@nospam.invalid> writes:
>anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>>  In some cases, print something else; if you don't print something
>>  else, print the number.
>> Not sure why you smell something here.
>
>Because that description is wrong.  It's more like "in some cases, print
>some specified string.  Otherwise, print the number".  The trouble is
>that the specified string might be the empty string.

Not in the original task and not in the extended versions suggested by
<http://dave.fayr.am/posts/2012-10-4-finding-fizzbuzz.html> nor those
discussed in other postings I found, either.

So, ok, your solution, my "more Forth-like solution" and the Haskell
Maybe variant are prepared for the case when the extended task says:
"In some cases, print nothing."  But is it worth complicating the
solution with Maybe and (up-to-now) redundant flags in order to be
prepared for this?  What about other potential changes?  Say, skipping
the next number on some condition; or changing the condition for
printing "buzz" when some condition holds.

Anyway, one of Chuck Moore's principles is "Do what is needed, don't
generalize", and this discussion is a good example for that.  Whatever
solution you write, the interviewer (or, in real life, the customer)
can give you a change request for which it does not work well.  And
you can "smell" that, so every solution will have a smell if you are
thinking in terms of what-ifs.

Back to the >STRING-EXECUTE implementation.  I thought about a simpler
way (as far as implementation is concerned).  Fig-Forth has a user
variable OUT that is incremented whenever EMIT is called (or, by
extension, TYPE).  If a Forth system has OUT (and it works that way),
there is no need to collect the output in a string to determine it's
length, you can use OUT for it.  The solution would look as follows:

: fizzbuzz1 ( n -- )
    dup 3 mod 0= if ." fizz" then
    dup 5 mod 0= if ." buzz" then
    drop ;

: fizzbuzz ( n -- )
    cr 0 out ! dup fizzbuzz1 out @ if drop else . then ;

: main ( -- )
    101 1 ?do i fizzbuzz loop ;

Works nicely on VFXlin.  However, Gforth and SwiftForth don't have
OUT.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2016: http://www.euroforth.org/ef16/

[toc] | [prev] | [next] | [standalone]


#47392

FromPaul Rubin <no.email@nospam.invalid>
Date2016-05-20 21:55 -0700
Message-ID<87futcc8mp.fsf@jester.gateway.pace.com>
In reply to#47277
anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>>The trouble is that the specified string might be the empty string.
> Not in the original task and not in the extended versions suggested by
> <http://dave.fayr.am/posts/2012-10-4-finding-fizzbuzz.html> nor those
> discussed in other postings I found, either.

The original task was just 3->Fizz, 5->Buzz.  The extended versions
suggested additional numbers like 7, and additional strings like Bazz.
I don't remember it mentioning the empty string specifically, but the
empty string is a perfectly good string just like 0 is a perfectly good
number.  Neither should make programs misbehave.

> So, ok, your solution, my "more Forth-like solution" and the Haskell
> Maybe variant are prepared for the case when the extended task says:
> "In some cases, print nothing."  

Well here there's again a code smell, or maybe a specification smell,
where the word "nothing" is overloaded.  It's cleaner to say that the
empty string is not nothing.  It's a string, whose length happens to be
zero.  That is something rather than nothing.  

> But is it worth complicating the solution with Maybe and (up-to-now)
> redundant flags in order to be prepared for this?

The extra flags in the Forth examples do complicate the code, but I
think one point of the blog post is that Maybe doesn't complicate things
as much, because of how Maybe's monoid instance lifts the string
concatenation operation into the Maybe String type.  That is, the post
is a bit of Haskell advocacy, saying Haskell's built-in abstractions
make this stuff work automatically.  The Maybe type also makes the
difference between "the empty string" and "nothing" explicit, which
helps clear thinking.

> Anyway, one of Chuck Moore's principles is "Do what is needed, don't
> generalize", and this discussion is a good example for that.

OTOH, one of the principles from "The Elements of Programming Style"
from the same era was

   33. Make sure your code does "nothing" gracefully.
    ( https://en.wikipedia.org/wiki/The_Elements_of_Programming_Style )

If my system has a word INCREASE-FOO:

  VARIABLE foo
  : INCREASE-FOO ( n -- ) ... ; \ make foo larger by n 

and it somehow doesn't work when n=0, that's broken code even if none of
the examples in the specification had n=0.  Making it work properly for
n=0 is not overgeneralization by any means.

> Whatever solution you write, the interviewer (or, in real life, the
> customer) can give you a change request for which it does not work
> well.  And you can "smell" that, so every solution will have a smell
> if you are thinking in terms of what-ifs.

There's a big enough body of experience in programming by now that we
have identified lots of valuable practices, re-usable abstractions, etc.
Handling do-nothing cases properly is so basic good practice that even
the the Programming Style book from the 1970's documented it explicitly.
"Maybe" values might have originated in ML in the 1980s, but are finally
catching on in the wider world.

> Back to the >STRING-EXECUTE implementation.  I thought about a simpler
> way (as far as implementation is concerned).  Fig-Forth has a user
> variable OUT ...

IMHO this is still way ugly compared with remembering whether any of the
tests succeeded, or alternatively, remembering whether the string
printer has been called (possibly with the empty string as argument).

[toc] | [prev] | [next] | [standalone]


#48413

Fromjulian.fondren@endurance.com
Date2016-06-20 20:20 -0700
Message-ID<ebe16470-cd29-40e5-a849-4d5d690a9b25@googlegroups.com>
In reply to#47277
On Wednesday, May 18, 2016 at 10:20:27 AM UTC-5, Anton Ertl wrote:
> : fizzbuzz1 ( n -- )
>     dup 3 mod 0= if ." fizz" then
>     dup 5 mod 0= if ." buzz" then
>     drop ;
> 
> : fizzbuzz ( n -- )
>     cr 0 out ! dup fizzbuzz1 out @ if drop else . then ;
> 
> : main ( -- )
>     101 1 ?do i fizzbuzz loop ;
> 
> Works nicely on VFXlin.  However, Gforth and SwiftForth don't have
> OUT.

A natural place to have, maybe not OUT exactly, but some kind of way
to see if output happened, is in an output-to-string facility.

In SwiftForth:

  package buffio
  public
  aka buf buf  \ expose the address of the end of the output buffer
  end-package

  : fizzbuzz1 ( n -- )
      dup 3 mod 0= if ." fizz" then
      dup 5 mod 0= if ." buzz" then
      drop ;

  : fizzbuzz ( n -- )
    [buf cr buf @ over fizzbuzz1 buf @ <> if drop else . then buf] @buf type ;                        

  : main ( -- )
      101 1 ?do i fizzbuzz loop ;


-- Julian

[toc] | [prev] | [next] | [standalone]


#47260

Fromhughaguilar96@gmail.com
Date2016-05-17 12:26 -0700
Message-ID<a6a1dc69-7df9-4740-b73f-ad872d7f1ac1@googlegroups.com>
In reply to#47221
On Monday, May 16, 2016 at 3:09:11 PM UTC-7, Paul Rubin wrote:
> anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
> >  A more Forth-like solution is:
> > : fizzbuzz1 ( n -- f )
> >     true
> >     over 3 mod 0= if ." fizz" drop false then
> >     over 5 mod 0= if ." buzz" drop false then
> >     nip ;     ...

Anton Ertl is too concerned with telling everybody what is "Forth-like" and implying that they aren't Forth programmers at all. 

> Here's my solution from some time back:
> 
> : fout ( addr u n d -- flag ) mod 0= if type 0 else 2drop 1 then ;
> : fb.1 ( n -- flag ) >r
>     s" Fizz" r@ 3 fout
>     s" Buzz" r> 5 fout
>     and ;
> : fb ( n -- ) dup fb.1 if . else drop then cr ;
> : run ( -- ) 20 1 do i fb loop ;

This is a pretty good solution. Very "Forth-like" (whatever that means).

I find Paul's code to somewhat hard to read. Here is a slightly cleaned up version (even more "Forth-like"):

: fout ( adr cnt n denominator -- displayed? )
    mod 0= if  type  true exit then
    2drop  false ;

: fb.1 { n -- displayed? }
    s" Fizz "  n 3 fout
    s" Buzz "  n 5 fout or ;
    
: fb ( n -- )   \ only display the number if we did not display anything else
    cr
    dup fb.1 0= if  .  exit then
    drop ;

: run ( -- )
    20 1 do  I fb  loop 
    cr ;

I found it confusing that his FOUT returned a TRUE when it did not display anything, and FALSE when it did display the string. I changed the flag to be TRUE when the string is displayed.

I also don't like the use of ELSE when it is not necessary, so I got rid of that.

This code, derived from Paul's code, is the most readable so far --- it is more readable than my version earlier --- my version did have the advantage of not using MOD, but that is only an advantage if you assume that MOD is bad.

[toc] | [prev] | [next] | [standalone]


#47159

FromGerry Jackson <gerry@jackson9000.fsnet.co.uk>
Date2016-05-15 21:42 +0100
Message-ID<nhamor$q5i$1@dont-email.me>
In reply to#47063
On 13/05/2016 00:43, Paul Rubin wrote:
> murphy.darin@gmail.com writes:
>> I know it's probaby very sloppy and wasteful, but just finised reading
>> chapter 5 of "Starting forth" and haven't gotten factoring
>> (distilling) down yet, but I will improve! Take care now.
>
> You did fine.  That fizzbuzz problem attracts so many solutions not
> because it's difficult, but because it has annoying edges that draw
> people irresistably to look for ways to smooth them down.
>
> http://dave.fayr.am/posts/2012-10-4-finding-fizzbuzz.html
> (not Forth related) expands on that thought.
>

In 2007 (yes that long ago) I posted a solution that didn't involve 
using MOD. Slightly re-worked this was:

hex
1249 constant fizzers      \ Bits 3i set, i = 0 to 4
0421 constant buzzers      \ Bits 5i set, i = 0 to 2
4000 constant reset-probe  \ Bit 14 set
decimal

: fizzbuzz
    cr 0 101 1
    do
       ?dup 0= if reset-probe then      ( -- probe )
       [ fizzers buzzers or ] literal over and 0= if i . then
       fizzers over and if ." fizz" then
       buzzers over and if ." buzz" then
       1 rshift cr                      ( -- probe' )
    loop drop
;


-- 
Gerry

[toc] | [prev] | [next] | [standalone]


#47166

Fromhughaguilar96@gmail.com
Date2016-05-15 14:41 -0700
Message-ID<7bc3a74c-01a4-4db5-936d-e75f2f01e67c@googlegroups.com>
In reply to#47159
On Sunday, May 15, 2016 at 1:42:27 PM UTC-7, Gerry wrote:
> On 13/05/2016 00:43, Paul Rubin wrote:
> > murphy.darin@gmail.com writes:
> >> I know it's probaby very sloppy and wasteful, but just finised reading
> >> chapter 5 of "Starting forth" and haven't gotten factoring
> >> (distilling) down yet, but I will improve! Take care now.
> >
> > You did fine.  That fizzbuzz problem attracts so many solutions not
> > because it's difficult, but because it has annoying edges that draw
> > people irresistably to look for ways to smooth them down.
> >
> > http://dave.fayr.am/posts/2012-10-4-finding-fizzbuzz.html
> > (not Forth related) expands on that thought.
> >
> 
> In 2007 (yes that long ago) I posted a solution that didn't involve 
> using MOD. Slightly re-worked this was:
> 
> hex
> 1249 constant fizzers      \ Bits 3i set, i = 0 to 4
> 0421 constant buzzers      \ Bits 5i set, i = 0 to 2
> 4000 constant reset-probe  \ Bit 14 set
> decimal

I told you then to use binary for your bit-masks --- bit-masks only make sense in binary --- using hex or any other base is just obfuscation.
 
> : fizzbuzz
>     cr 0 101 1
>     do
>        ?dup 0= if reset-probe then      ( -- probe )
>        [ fizzers buzzers or ] literal over and 0= if i . then
>        fizzers over and if ." fizz" then
>        buzzers over and if ." buzz" then
>        1 rshift cr                      ( -- probe' )
>     loop drop
> ;

Your solution is pretty good --- you do avoid using MOD which everybody else uses.

Your solution doesn't scale up very well though. What if the interview asks you to upgrade to FIZZ-BUZZ-BURP, with BURP being printed every 7th time? Bit masks were reasonable when they were (3*5=15) bits long --- not so reasonable when they are (3*5*7=105) bits long.

[toc] | [prev] | [next] | [standalone]


#47167

Fromhughaguilar96@gmail.com
Date2016-05-15 15:15 -0700
Message-ID<3519332a-ed11-4629-a6e3-b3fca8730bb0@googlegroups.com>
In reply to#47166
On Sunday, May 15, 2016 at 2:41:53 PM UTC-7, hughag...@gmail.com wrote:
> Your solution is pretty good --- you do avoid using MOD which everybody else uses.
> 
> Your solution doesn't scale up very well though. What if the interview asks you to upgrade to FIZZ-BUZZ-BURP, with BURP being printed every 7th time? Bit masks were reasonable when they were (3*5=15) bits long --- not so reasonable when they are (3*5*7=105) bits long.

Here is my solution that also does not involve MOD. Mine however can be upgraded easily to support the FIZZ-BUZZ-BURP problem.

3 constant top-fizz
5 constant top-buzz

: fizz-buzz ( -- )
    top-fizz top-buzz { fizz buzz -- }
    101 1 do
        -1 +to fizz
        -1 +to buzz
        cr
        fizz 0=  buzz 0=  or if  8 spaces  else  I 5 .r  3 spaces  then
        fizz 0= if  ." fizz "  top-fizz to fizz  then
        buzz 0= if  ." buzz "  top-buzz to buzz  then
        loop ;

[toc] | [prev] | [next] | [standalone]


#47171

Fromhughaguilar96@gmail.com
Date2016-05-15 17:38 -0700
Message-ID<76a26350-2230-437b-bcd9-42fe1caabea5@googlegroups.com>
In reply to#47167
On Sunday, May 15, 2016 at 3:15:21 PM UTC-7, hughag...@gmail.com wrote:
> On Sunday, May 15, 2016 at 2:41:53 PM UTC-7, hughag...@gmail.com wrote:
> > Your solution is pretty good --- you do avoid using MOD which everybody else uses.
> > 
> > Your solution doesn't scale up very well though. What if the interview asks you to upgrade to FIZZ-BUZZ-BURP, with BURP being printed every 7th time? Bit masks were reasonable when they were (3*5=15) bits long --- not so reasonable when they are (3*5*7=105) bits long.
> 
> Here is my solution that also does not involve MOD. Mine however can be upgraded easily to support the FIZZ-BUZZ-BURP problem.
> 
> 3 constant top-fizz
> 5 constant top-buzz
> 
> : fizz-buzz ( -- )
>     top-fizz top-buzz { fizz buzz -- }
>     101 1 do
>         -1 +to fizz
>         -1 +to buzz
>         cr
>         fizz 0=  buzz 0=  or if  8 spaces  else  I 5 .r  3 spaces  then
>         fizz 0= if  ." fizz "  top-fizz to fizz  then
>         buzz 0= if  ." buzz "  top-buzz to buzz  then
>         loop ;

Here is a more clearly written version that does the same thing:

3 constant top-fizz
5 constant top-buzz

: fizz-buzz ( -- )
    top-fizz top-buzz { fizz buzz -- }
    101 1 do
        -1 +to fizz
        -1 +to buzz
        cr
        fizz 0<>  buzz 0<>  and if  I 5 .r  3 spaces  then
        fizz 0= if  ." fizz "  top-fizz to fizz  then
        buzz 0= if  ." buzz "  top-buzz to buzz  then
        loop ;

So, here is a job-interview question for everybody --- could I get rid of the 0<> in the above and still get the same result?

Here is the code:

3 constant top-fizz
5 constant top-buzz

: fizz-buzz ( -- )
    top-fizz top-buzz { fizz buzz -- }
    101 1 do
        -1 +to fizz
        -1 +to buzz
        cr
        fizz buzz and if  I 5 .r  3 spaces  then
        fizz 0= if  ." fizz "  top-fizz to fizz  then
        buzz 0= if  ." buzz "  top-buzz to buzz  then
        loop ;

[toc] | [prev] | [next] | [standalone]


#47173

Frommurphy.darin@gmail.com
Date2016-05-15 19:01 -0700
Message-ID<5bb77957-6c79-4a5c-8701-44c7270fac3c@googlegroups.com>
In reply to#47171
Can't wake to see everyone else's solution to your question Hughag. Right now I'm going over "starting forth" chapter 5 & 6 again. Fix-point and loops are still a little fuzzy for me right now, so I'm not going to try and work this question out just yet. When something is fuzzy to me, I prefer to repeat it, over and over giving myself some break from it now and again until I digest it better. So far though I'm loving forth! I can't wait till I've completed both forth books by Leo then I'm really going to have a blast! Take care now.

[toc] | [prev] | [next] | [standalone]


#47176

Fromhughaguilar96@gmail.com
Date2016-05-15 19:51 -0700
Message-ID<a4b5c883-c799-497d-81f5-6e2500cbe14f@googlegroups.com>
In reply to#47173
On Sunday, May 15, 2016 at 7:01:39 PM UTC-7, murphy...@gmail.com wrote:
> Can't wake to see everyone else's solution to your question Hughag. Right now I'm going over "starting forth" chapter 5 & 6 again. Fix-point and loops are still a little fuzzy for me right now, so I'm not going to try and work this question out just yet. When something is fuzzy to me, I prefer to repeat it, over and over giving myself some break from it now and again until I digest it better. So far though I'm loving forth! I can't wait till I've completed both forth books by Leo then I'm really going to have a blast! Take care now.

It is necessary to learn about fixed-point arithmetic, especially the scalar */ (star-slash). This is pretty easy though, so you'll understand it quickly.

DO loops are actually quite confusing though. I recommend that you ignore them for now --- just use BEGIN loops, and get some experience writing programs, because you can't learn by reading books but you need hands-on experience --- go back to DO loops later on, and only use DO loops going upwards (I still get confused myself when using them going downwards).

DO loops are confusing for these reasons:
1.) Going downwards does make sense, but it is non-intuitive. This relies on using the overflow-flag internally, and it is pretty tricky programming. Also, it is not possible on processors (such as the MiniForth) that don't have an overflow-flag --- yet another example of ANS-Forth standardizing implementation rather than behavior.
2.) The I and the J are like a half-step toward local variables --- DO loops predate the introduction of local variables to Forth --- it would have been much better to just use local variables. I and J are confusing because in a nested loop, J is the index for the outer loop and I is the index for the inner loop, but in the outer loop the index is called I (the same index that is called J inside of the inner loop). 
3.) >R data that is pushed outside of a DO loop is not available inside of the loop, and >R data that is pushed inside of a DO loop if not removed will crash the computer at the LOOP. This is very confusing because nobody would expect >R and DO loops to be clashing like this. It would be much better to have >R data and DO loops use different stacks. Once again, ANS-Forth has standardized implementation rather than behavior --- ANS-Forth is standardizing the PDP-11 implementation in which there wasn't any register available for another stack pointer, and so DO loops had to just use the return-stack and clash with >R etc..

In my own Forth I'm getting rid of DO loops altogether --- this is 1970s cruft.

[toc] | [prev] | [next] | [standalone]


#47178

Frommurphy.darin@gmail.com
Date2016-05-15 20:48 -0700
Message-ID<a461ce90-5ae8-4604-969f-f616f3ec16da@googlegroups.com>
In reply to#47176
Thanks hughag.  I have a question about "+to". I looked in gforth and it's not located anywhere, though "to" is. Are they related? Thanks as always for your help. Take care now.

[toc] | [prev] | [next] | [standalone]


#47197

Fromhughaguilar96@gmail.com
Date2016-05-16 07:51 -0700
Message-ID<8f651ec4-5172-4307-8779-971c733c9056@googlegroups.com>
In reply to#47178
On Sunday, May 15, 2016 at 8:48:22 PM UTC-7, murphy...@gmail.com wrote:
> Thanks hughag.  I have a question about "+to". I looked in gforth and it's not located anywhere, though "to" is. Are they related? Thanks as always for your help. Take care now.

Its in the novice-package. Note that my +TO works for both VALUE and local variables --- somebody on the Forth-200x committee (I think it was Anton Ertl) wrote +TO but it only worked on VALUE and not local variables (most likely, this is what will get put in the Forth-200x Standard because it was written by a committee member).

Also, { is in the novice-package --- that is used in the above code as well --- this has been common practice since prior to ANS-Forth, but Forth-200x changed the name to {: and also screwed up the implementation (the locals to the right of the | get initialized to whatever happened to be in memory, rather than initialized to zero as mine are) --- {: was written by Anton Ertl according to spec (the spec presumably provided by Leon Wagne), so this is what gets put in the Forth-200x Standard.

Everything in the novice-package is ANS-Forth --- tested on SwiftForth, gForth, Win32Forth and VFX.

BTW: my name is Hugh Aguilar --- the hughag you see is the first 6 chars of my email address.

[toc] | [prev] | [next] | [standalone]


#47502

From"WJ" <w_a_x_man@yahoo.com>
Date2016-05-25 08:31 +0000
Message-ID<ni3ns5$i3b$1@dont-email.me>
In reply to#47167
hughaguilar96@gmail.com wrote:

> > Your solution is pretty good --- you do
> > avoid using MOD which everybody else uses.
> > 
> > Your solution doesn't scale up very well
> > though. What if the interview asks you to
> > upgrade to FIZZ-BUZZ-BURP, with BURP being
> > printed every 7th time? Bit masks were
> > reasonable when they were (3*5=15) bits long
> > --- not so reasonable when they are
> > (3*5*7=105) bits long.
> 
> Here is my solution that also does not
> involve MOD. Mine however can be
> upgraded easily to support the
> FIZZ-BUZZ-BURP problem.
> 
> 3 constant top-fizz
> 5 constant top-buzz
> 
> : fizz-buzz ( -- )
>     top-fizz top-buzz { fizz buzz -- }
>     101 1 do
>         -1 +to fizz
>         -1 +to buzz
>         cr
>         fizz 0=  buzz 0=  or if  8 spaces  else  I 5 .r  3 spaces  then
>         fizz 0= if  ." fizz "  top-fizz to fizz  then
>         buzz 0= if  ." buzz "  top-buzz to buzz  then
>         loop ;


OCaml:

open List ;;

let rotate (x::xs) = xs @ [x] ;;

let init (n,str) = Array.to_list (Array.make (n - 1) "") @ [str] ;;

let stuff =
  ref (map init [3,"fizz"; 5,"buzz"; 7,"hum"; 11,"thrum"; 13,"yelp"]) ;;

for i = 1 to 100 do
  let s = String.concat "" (map hd !stuff) in
  if "" = s then print_int i else print_string s ;
  print_newline () ;
  stuff := map rotate !stuff
done ;;

1
2
fizz
4
buzz
fizz
hum
8
fizz
buzz
thrum
fizz
yelp
hum
fizzbuzz
16
17
fizz
19
buzz
fizzhum
thrum
23
fizz
buzz
yelp
fizz
hum
29
fizzbuzz
31
32
fizzthrum
34
buzzhum
fizz
37
38
fizzyelp
buzz
41
fizzhum
43
thrum
fizzbuzz
46
47
fizz
hum
buzz
fizz
yelp
53
fizz
buzzthrum
hum
fizz
58
59
fizzbuzz
61
62
fizzhum
64
buzzyelp
fizzthrum
67
68
fizz
buzzhum
71
fizz
73
74
fizzbuzz
76
humthrum
fizzyelp
79
buzz
fizz
82
83
fizzhum
buzz
86
fizz
thrum
89
fizzbuzz
humyelp
92
fizz
94
buzz
fizz
97
hum
fizzthrum
buzz

-- 
The former leader of the National Front Jean-Marie Le Pen was fined 30,000
euros for exposing the Jews Holocaust gas chamber hoax.
infostormer.com/jean-marie-le-pen-fined-30000-euros-for-exposing-jewish-holocaust-gas-chamber-hoax

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.forth


csiph-web