Re: FizzBuzz
  Home FAQ Contact Sign in
comp.lang.forth only
 
Advanced search
POPULAR GROUPS

more...

 Up
Re: FizzBuzz         

Group: comp.lang.forth · Group Profile
Author: Gerry
Date: Mar 3, 2007 06:37

On 2 Mar, 15:48, "J Thomas" gmail.com> wrote:
> On Mar 2, 7:29 am, Andrew Haley
> wrote:
>
>> Cesar Rabak yahoo.com.br> wrote:
>>> keo...@gmail.com escreveu:
>>> [snipped]
>>>> As I am interested but not yet very proficient in stack based
>>>> programming languages, I ask you: how would you solve this problem in
>>>> FORTH?
>
>>> Did you study the solution given in the post # 53?
>
>> The code is over-factored, making it hard to read. There is also too
>> much stack noise: this problem really doesn't need DUP SWAP etc.
>
> I don't see any problem with that code. It looks fine to me.
>
>> A simple solution is
>
>> : bang
>> 100 1 do
>> i 15 mod 0= if ." FizzBuzz " else
>> i 3 mod 0= if ." Fizz " else
>> i 5 mod 0= if ." Buzz " else
>> i . then then then
>> loop ;
>
> Your solution looks fine to me too.
>
> Your code brings up something for me. I notice those three then then
> thens. Forth doesn't usually have a way to skip over the rest of a
> loop and then repeat. We have ways to break out of the loop, but not a
> command to skip to the end of the loop. So we have ugly things like
> then then then to do it, both in DO loops and in BEGIN loops.
>
> I've never felt the need for an improvement there. Multiple THENs
> don't actually cause a performance hit, only a very slight compile-
> time hit. Wil Baden made his THENS command which palliates it.
>
> Somehow I never noticed until now that you can get a similar result
> with multiple BEGINs.
>
> : bang1
> 0 BEGIN BEGIN 1+ cr
> dup 3 mod DUP 0= if ." Fizz" then
> over 5 mod dup 0= if ." Buzz" then
> or 0= UNTIL
> dup .
> dup 100 >
> UNTIL ;
>
> I certainly don't want to propose this as clear writing or even
> adequate code (like, the method would run over if you changed the
> limit to 99BEG), it's just that I never thought of this as a single
> loop with a continuation. If you had a word that was just like UNTIL
> except it left a copy of the dest, it would effectively skip to (but
> not past) the end of the loop on failure or execute the rest of the
> loop on success.
>
> BEGIN ... SKIP-TO-REPEAT ... SKIP-TO-REPEAT ... SKIP-TO-REPEAT ...
> WHILE ... REPEAT
>
> Again, I've never felt the need to have something like this, I've
> always just accepted THEN THEN THEN as good enough.
>
> Additional control structure words might someimes make the flow of
> control clearer, provided we all remembered what they did. What we
> already have is adequate.
>
> : bang2
> 101 0 do
> i 3 mod 0= 1 and
> i 5 mod 0= 2 and or
> case
> 0 of i . endof
> 1 of Fizz endof
> 2 of Buzz endof
> 3 of FizzBuzz endof
> endcase
> loop ;
>
> This one doesn't read better either, but at least the most common
> cases are tested the most often. A jump table might be more efficient
> but also less readable.
>
> : DUP. dup . ;
>
> CREATE TABLE
> ' DUP. ,
> ' Fizz ,
> ' Buzz ,
> ' FizzBuzz ,
>
> : do-it
> CELLS TABLE + @ EXECUTE ;
>
> : which-action ( n -- n 0|1|2|3 )
> dup
> i 3 mod 0= 1 and
> i 5 mod 0= 2 and or ;
>
> : Bang3
> 0 begin
> 1+ dup 101 <
> while
> which-action do-it
> repeat drop ;
>
> I guess when the first methods I learned give a result that isn't too
> long, then that's the most readable. There's nothing hard to
> understand about nested IF THENs. Just, if they get too complex you
> can lose track of how deeply they're nested and which places which
> result happens.

Nothing wrong with other solutions but a simple solution avoiding
nested ifs etc uses bit vectors. The constants can be stuck in line

hex
1249 constant 3vec
0421 constant 5vec
4000 constant probe
3vec 5vec or constant 3or5vec
decimal

: bang
cr 0 101 1
do
?dup 0= if probe then
3or5vec over and 0= if i . then
3vec over and if ." fizz" then
5vec over and if ." buzz" then
1 rshift cr
loop
drop
;
no comments
diggit! del.icio.us! reddit!