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


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

Fizz Buzz Zoom

Started byPaul Rubin <no.email@nospam.invalid>
First post2012-10-07 09:19 -0700
Last post2012-10-08 10:15 -0700
Articles 17 on this page of 37 — 12 participants

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


Contents

  Fizz Buzz Zoom Paul Rubin <no.email@nospam.invalid> - 2012-10-07 09:19 -0700
    Re: Fizz Buzz Zoom mhx@iae.nl (Marcel Hendrix) - 2012-10-07 20:33 +0200
      Re: Fizz Buzz Zoom Paul Rubin <no.email@nospam.invalid> - 2012-10-07 11:43 -0700
        Re: Fizz Buzz Zoom mhx@iae.nl (Marcel Hendrix) - 2012-10-07 21:09 +0200
          Re: Fizz Buzz Zoom Paul Rubin <no.email@nospam.invalid> - 2012-10-07 12:18 -0700
            Re: Fizz Buzz Zoom ouatubi@gmail.com - 2012-10-08 01:15 -0700
              Re: Fizz Buzz Zoom Paul Rubin <no.email@nospam.invalid> - 2012-10-08 09:37 -0700
                Re: Fizz Buzz Zoom ouatubi@gmail.com - 2012-10-09 01:16 -0700
    Re: Fizz Buzz Zoom Doug Hoffman <glidedog@gmail.com> - 2012-10-07 14:45 -0400
      Re: Fizz Buzz Zoom Paul Rubin <no.email@nospam.invalid> - 2012-10-07 12:28 -0700
        Re: Fizz Buzz Zoom Doug Hoffman <glidedog@gmail.com> - 2012-10-07 21:06 -0400
          Re: Fizz Buzz Zoom Paul Rubin <no.email@nospam.invalid> - 2012-10-07 21:32 -0700
            Re: Fizz Buzz Zoom Doug Hoffman <glidedog@gmail.com> - 2012-10-08 06:06 -0400
              Re: Fizz Buzz Zoom Mark Wills <forthfreak@gmail.com> - 2012-10-08 05:24 -0700
    Re: Fizz Buzz Zoom anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2012-10-08 14:02 +0000
      Re: Fizz Buzz Zoom Paul Rubin <no.email@nospam.invalid> - 2012-10-08 08:38 -0700
        Re: Fizz Buzz Zoom Paul Rubin <no.email@nospam.invalid> - 2012-10-08 08:43 -0700
        Re: Fizz Buzz Zoom "A. K." <akk@nospam.org> - 2012-10-08 18:03 +0200
        Re: Fizz Buzz Zoom anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2012-10-08 16:08 +0000
          Re: Fizz Buzz Zoom Paul Rubin <no.email@nospam.invalid> - 2012-10-08 09:23 -0700
            Re: Fizz Buzz Zoom anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2012-10-08 17:11 +0000
              Re: Fizz Buzz Zoom Bernd Paysan <bernd.paysan@gmx.de> - 2012-10-08 22:12 +0200
              Re: Fizz Buzz Zoom Paul Rubin <no.email@nospam.invalid> - 2012-10-08 13:16 -0700
                Re: Fizz Buzz Zoom Hannu Vuolasaho <hannu.vuolasaho@nospam.tut.fi.invalid> - 2012-10-08 21:06 +0000
                  Re: Fizz Buzz Zoom "Elizabeth D. Rather" <erather@forth.com> - 2012-10-08 11:57 -1000
                    Re: Fizz Buzz Zoom Mark Wills <forthfreak@gmail.com> - 2012-10-09 01:26 -0700
                      Re: Fizz Buzz Zoom George Hubert <georgeahubert@yahoo.co.uk> - 2012-10-09 08:38 -0700
                        Re: Fizz Buzz Zoom Paul Rubin <no.email@nospam.invalid> - 2012-10-09 09:03 -0700
                      Re: Fizz Buzz Zoom "Elizabeth D. Rather" <erather@forth.com> - 2012-10-09 08:44 -1000
                Re: Fizz Buzz Zoom anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2012-10-10 12:32 +0000
                  Re: Fizz Buzz Zoom Bernd Paysan <bernd.paysan@gmx.de> - 2012-10-10 16:59 +0200
                    Re: Fizz Buzz Zoom anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2012-10-10 16:42 +0000
                  Re: Fizz Buzz Zoom Paul Rubin <no.email@nospam.invalid> - 2012-10-12 21:18 -0700
                    Re: Fizz Buzz Zoom "Elizabeth D. Rather" <erather@forth.com> - 2012-10-12 21:06 -1000
        Re: Fizz Buzz Zoom Doug Hoffman <glidedog@gmail.com> - 2012-10-10 09:02 -0400
    Re: Fizz Buzz Zoom Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2012-10-08 17:50 +0100
      Re: Fizz Buzz Zoom Paul Rubin <no.email@nospam.invalid> - 2012-10-08 10:15 -0700

Page 2 of 2 — ← Prev page 1 [2]


#16060

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2012-10-08 17:11 +0000
Message-ID<2012Oct8.191146@mips.complang.tuwien.ac.at>
In reply to#16055
Paul Rubin <no.email@nospam.invalid> writes:
>anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>> Given the separate case in the spec for Fizz Buzz, having a separate
>> case in the program looks pretty natural to me.
>
>Since you've already done both tests (mod 3 and mod 5), doing them again
>has a DRY problem.

What's a "DRY problem"?

>> |multiples of five print "Buzz". For numbers which are multiples of
>> |both three and five print "FizzBuzz". ...
>> Anyway, what is the specification of Fizz Buzz Zoom?
>
>Same thing, except additionally, if n is divisible by 7, print "Zoom".
>So for example, for n=21 you'd print FizzZoom, for n=35 you'd print
>BuzzZoom, and for n=105 you'd print FizzBuzzZoom.

Now maybe someone should write a blog posting about writing
specifications.  Let me have a go at that.  What you mean is probably:

  Write a program that prints the numbers from 1 to 121. But for
  multiples of three print "Fizz" instead of the number and for the
  multiples of five print "Buzz". For numbers which are multiples of
  both three and five print "FizzBuzz".  For numbers which are multiples
  of seven, print "Zoom".  For numbers which are multiples of three and
  seven, print "FizzZoom".  For numbers which are multiples of five and
  seven, print "BuzzZoom".  For numbers which are multiples of three,
  five and seven, print "FizzBuzzZoom".

Why did I write it that way?  Because it's closest to the FizzBuzz
spec and also the way you wrote the incomplete spec for FizzBuzzZoom.

That spec naturally leads to a solution you consider "ugly".  Now
maybe someone can write a less ugly specification, and maybe that
naturally leads to a less ugly program.

- 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 2012: http://www.euroforth.org/ef12/

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


#16066

FromBernd Paysan <bernd.paysan@gmx.de>
Date2012-10-08 22:12 +0200
Message-ID<3036043.EYBWDeqreq@sunwukong.fritz.box>
In reply to#16060
Anton Ertl wrote:
> That spec naturally leads to a solution you consider "ugly".  Now
> maybe someone can write a less ugly specification, and maybe that
> naturally leads to a less ugly program.

The only ugly think is that you somehow have to track your decision to 
prevent printing the number.  A slight variation of Doug Hoffman's code 
doesn't look that ugly.

: mod? ( flag i n -- flag' flagp )
  mod 0= tuck or swap ;

: fizzbuzzzoom ( n -- ) 1 ?DO  false
      i 3 mod? IF ." Fizz" THEN
      i 5 mod? IF ." Buzz" THEN
      i 7 mod? IF ." Zoom" THEN
      0= IF i 0 .r THEN space \ or cr, if you prefer
  LOOP ;

If you think this is not enough DSL, try this:

: mod? ( flag i n -- flag' flagp )
  mod 0= tuck or swap ;

: ?" ( flag n "string"<"> -- flag' )
  ]] i swap mod? IF ." THEN [[ ; immediate

: fizzbuzzzoom ( n -- ) 1 ?DO  false
      3 ?" Fizz"  5 ?" Buzz"  7 ?" Zoom"
      0= IF i 0 .r THEN space \ or cr, if you prefer
  LOOP ;

-- 
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://bernd-paysan.de/

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


#16067

FromPaul Rubin <no.email@nospam.invalid>
Date2012-10-08 13:16 -0700
Message-ID<7x626k90t2.fsf@ruckus.brouhaha.com>
In reply to#16060
anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
> What's a "DRY problem"?

DRY = Don't Repeat Yourself.  Basically, "this should be factored some
more".

>   Write a program that prints the numbers from 1 to 121. But for
>   multiples of three print "Fizz" instead of the number and for the
>   multiples of five print "Buzz". For numbers which are multiples of
>   both three and five print "FizzBuzz".  For numbers which are multiples
>   of seven, print "Zoom".  For numbers which are multiples of three and
>   seven, print "FizzZoom".  For numbers which are multiples of five and
>   seven, print "BuzzZoom".  For numbers which are multiples of three,
>   five and seven, print "FizzBuzzZoom".

This seems like a messy specification to me, and also an incorrect or
ambiguous one, since (e.g.) for n=15 it allows printing "Fizz Buzz
FizzBuzz".  Its size also grows exponentially in the number of divisors.
Here's another attempt:

   Write a program that prints the numbers from 1 to 120 (inclusive) in
   FBZ (Fizz-Buzz-Zoom) notation, one per line.  For a natural number n
   that is coprime to 3, 5, and 7, the FBZ notation for n is the same as
   the decimal representation of n.  For other natural numbers n, the
   FBZ notation for n is the concatenation of the F, B, and Z notations
   for n.  The F notation for natural n is the string "Fizz" if n is a
   multiple of 3, otherwise it is the empty string.  The B notation for
   natural n is the string "Buzz" if n is a multiple of 5, otherwise it
   is the empty string.  The Z notation for natural n is the string
   "Zoom" if n is a multiple of 7, otherwise it is the empty string.

That is also a messy spec, but most ways I see to clean it up involve
introducing more machinery that in other ways makes it worse.  I do
think the monoid implementation

   fbz n = fromMaybe (show n) (mconcat [f 3 "Fizz", f 5 "Buzz", f 7 "Zoom"])
     where f d s = if n`mod`d==0 then Just s else Nothing
   main = map (putStrLn . fbz) [1..120]

is the most conceptually explicit reflection of how I see the problem,
even though in actual code I like the list-based version better due to
it having fewer implementation artifacts (library dependencies etc.)

Anyway, as someone in the earlier clf thread mentioned, it's an
interview question rather than a "program from spec" problem.  In that
situation, some ambiguity can be a good thing since it lets you see the
candidate's approach to resolving it.  

There is a formal specification language called Z-notation (nothing to
do with the "Z notation" above) that some Ada projects use.  Now I'm
sort of wondering what a Z-notation spec for this problem would look
like.

> That spec naturally leads to a solution you consider "ugly".  Now
> maybe someone can write a less ugly specification, and maybe that
> naturally leads to a less ugly program.

Even with a formal spec, it's still appropriate to identify the patterns
inherent in the spec and reflect them in the code.

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


#16072

FromHannu Vuolasaho <hannu.vuolasaho@nospam.tut.fi.invalid>
Date2012-10-08 21:06 +0000
Message-ID<slrnk76g2q.nb.hannu.vuolasaho@haikara.cs.tut.fi>
In reply to#16067
On 2012-10-08, Paul Rubin <no.email@nospam.invalid> wrote:
>
> Anyway, as someone in the earlier clf thread mentioned, it's an
> interview question rather than a "program from spec" problem.  In that
> situation, some ambiguity can be a good thing since it lets you see the
> candidate's approach to resolving it.  

Indeed. This is interview test. There are many ways to answer it. It 
gives idea what kind of code applicant writes and it reveals how 
applicant handdles problems.

I was given this kind of question after a short interview. The task was 
given on paper "Solve this problem." and there was the place to paper 
code it. I had said that I knew some forth so I solved it quite fast 
with forth. And I failed.

My program would work. I had even a stack comment for those three words.
What I missed was documenting what the code did, who wrote it and so on.

So far all solutions suffer the same problem. Very good programmers 
here don't bother to document.

--
Hannu Vuolasaho

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


#16075

From"Elizabeth D. Rather" <erather@forth.com>
Date2012-10-08 11:57 -1000
Message-ID<Q4mdnTdd_MjX0e7NnZ2dnUVZ_sudnZ2d@supernews.com>
In reply to#16072
On 10/8/12 11:06 AM, Hannu Vuolasaho wrote:
> On 2012-10-08, Paul Rubin <no.email@nospam.invalid> wrote:
>>
>> Anyway, as someone in the earlier clf thread mentioned, it's an
>> interview question rather than a "program from spec" problem.  In that
>> situation, some ambiguity can be a good thing since it lets you see the
>> candidate's approach to resolving it.
>
> Indeed. This is interview test. There are many ways to answer it. It
> gives idea what kind of code applicant writes and it reveals how
> applicant handdles problems.
>
> I was given this kind of question after a short interview. The task was
> given on paper "Solve this problem." and there was the place to paper
> code it. I had said that I knew some forth so I solved it quite fast
> with forth. And I failed.
>
> My program would work. I had even a stack comment for those three words.
> What I missed was documenting what the code did, who wrote it and so on.
>
> So far all solutions suffer the same problem. Very good programmers
> here don't bother to document.

People who "don't bother to document" are *not* "very good programmers" 
in my book.

That said, expectations when you're writing code in a job interview 
situation are significantly different than when tossing off a little 
code to illustrate a point in a newsgroup discussion. In an interview, 
it pays to bust a gut to provide clear documentation, especially when 
you're using a language the interviewer isn't familiar with.

All things considered, in this thread I like Doug Hoffman's code best:

: run'
   120 1 do
      cr i 3 mod 0= dup if ." Fizz" then
         i 5 mod 0= dup if ." Buzz" then or
         i 7 mod 0= dup if ." Zoom" then or
         0= if i . then
      loop ;

(although I really think he should have included an empty stack 
comment). All the detailed factoring in other approaches is 
inappropriate for a problem this simple. In a job interview, a brief 
discussion of the approach here would be important.

Cheers,
Elizabeth

-- 
==================================================
Elizabeth D. Rather   (US & Canada)   800-55-FORTH
FORTH Inc.                         +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com

"Forth-based products and Services for real-time
applications since 1973."
==================================================

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


#16088

FromMark Wills <forthfreak@gmail.com>
Date2012-10-09 01:26 -0700
Message-ID<d3018eb4-db19-4e32-8ed1-67392f3ac45c@d17g2000vbv.googlegroups.com>
In reply to#16075
On Oct 8, 10:57 pm, "Elizabeth D. Rather" <erat...@forth.com> wrote:
> On 10/8/12 11:06 AM, Hannu Vuolasaho wrote:
>
>
>
>
>
> > On 2012-10-08, Paul Rubin <no.em...@nospam.invalid> wrote:
>
> >> Anyway, as someone in the earlier clf thread mentioned, it's an
> >> interview question rather than a "program from spec" problem.  In that
> >> situation, some ambiguity can be a good thing since it lets you see the
> >> candidate's approach to resolving it.
>
> > Indeed. This is interview test. There are many ways to answer it. It
> > gives idea what kind of code applicant writes and it reveals how
> > applicant handdles problems.
>
> > I was given this kind of question after a short interview. The task was
> > given on paper "Solve this problem." and there was the place to paper
> > code it. I had said that I knew some forth so I solved it quite fast
> > with forth. And I failed.
>
> > My program would work. I had even a stack comment for those three words.
> > What I missed was documenting what the code did, who wrote it and so on.
>
> > So far all solutions suffer the same problem. Very good programmers
> > here don't bother to document.
>
> People who "don't bother to document" are *not* "very good programmers"
> in my book.
>
> That said, expectations when you're writing code in a job interview
> situation are significantly different than when tossing off a little
> code to illustrate a point in a newsgroup discussion. In an interview,
> it pays to bust a gut to provide clear documentation, especially when
> you're using a language the interviewer isn't familiar with.
>
> All things considered, in this thread I like Doug Hoffman's code best:
>
> : run'
>    120 1 do
>       cr i 3 mod 0= dup if ." Fizz" then
>          i 5 mod 0= dup if ." Buzz" then or
>          i 7 mod 0= dup if ." Zoom" then or
>          0= if i . then
>       loop ;
>
> (although I really think he should have included an empty stack
> comment). All the detailed factoring in other approaches is
> inappropriate for a problem this simple. In a job interview, a brief
> discussion of the approach here would be important.
>
> Cheers,
> Elizabeth
>
> --
> ==================================================
> Elizabeth D. Rather   (US & Canada)   800-55-FORTH
> FORTH Inc.                         +1 310.999.6784
> 5959 West Century Blvd. Suite 700
> Los Angeles, CA 90045http://www.forth.com
>
> "Forth-based products and Services for real-time
> applications since 1973."
> ==================================================- Hide quoted text -
>
> - Show quoted text -

I agree. And I think that, having submitted the above example in
Forth, if you were criticised in an interview for not commenting the
code, my counter would be that it is self describing to anyone with a
passing familiarity with the language to render comments superfluous.

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


#16099

FromGeorge Hubert <georgeahubert@yahoo.co.uk>
Date2012-10-09 08:38 -0700
Message-ID<39463685-08ae-45d5-aee3-4908bf2e7862@googlegroups.com>
In reply to#16088
On Tuesday, October 9, 2012 9:26:21 AM UTC+1, M.R.W Wills wrote:
> On Oct 8, 10:57 pm, "Elizabeth D. Rather" <erat...@forth.com> wrote: > On 10/8/12 11:06 AM, Hannu Vuolasaho wrote: > > > > > > > On 2012-10-08, Paul Rubin <no.em...@nospam.invalid> wrote: > > >> Anyway, as someone in the earlier clf thread mentioned, it's an > >> interview question rather than a "program from spec" problem.  In that > >> situation, some ambiguity can be a good thing since it lets you see the > >> candidate's approach to resolving it. > > > Indeed. This is interview test. There are many ways to answer it. It > > gives idea what kind of code applicant writes and it reveals how > > applicant handdles problems. > > > I was given this kind of question after a short interview. The task was > > given on paper "Solve this problem." and there was the place to paper > > code it. I had said that I knew some forth so I solved it quite fast > > with forth. And I failed. > > > My program would work. I had even a stack comment for those three words. > > What I missed was documenting what the code did, who wrote it and so on. > > > So far all solutions suffer the same problem. Very good programmers > > here don't bother to document. > > People who "don't bother to document" are *not* "very good programmers" > in my book. > > That said, expectations when you're writing code in a job interview > situation are significantly different than when tossing off a little > code to illustrate a point in a newsgroup discussion. In an interview, > it pays to bust a gut to provide clear documentation, especially when > you're using a language the interviewer isn't familiar with. > > All things considered, in this thread I like Doug Hoffman's code best: > > : run' >    120 1 do >       cr i 3 mod 0= dup if ." Fizz" then >          i 5 mod 0= dup if ." Buzz" then or >          i 7 mod 0= dup if ." Zoom" then or >          0= if i . then >       loop ; > > (although I really think he should have included an empty stack > comment). All the detailed factoring in other approaches is > inappropriate for a problem this simple. In a job interview, a brief > discussion of the approach here would be important. > > Cheers, > Elizabeth > > -- > ================================================== > Elizabeth D. Rather   (US & Canada)   800-55-FORTH > FORTH Inc.                         +1 310.999.6784 > 5959 West Century Blvd. Suite 700 > Los Angeles, CA 90045http://www.forth.com > > "Forth-based products and Services for real-time > applications since 1973." > ==================================================- Hide quoted text - > > - Show quoted text - I agree. And I think that, having submitted the above example in Forth, if you were criticised in an interview for not commenting the code, my counter would be that it is self describing to anyone with a passing familiarity with the language to render comments superfluous.

Curious. I find it doesn't match the spec. One of the numbers 1 to 120 
inclusive has been left out (it's left as an exercise for the reader to
work out which one). Most other solutions have similar problems.

George Hubert

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


#16101

FromPaul Rubin <no.email@nospam.invalid>
Date2012-10-09 09:03 -0700
Message-ID<7xr4p7iqfe.fsf@ruckus.brouhaha.com>
In reply to#16099
George Hubert <georgeahubert@yahoo.co.uk> writes:
> Curious. I find it doesn't match the spec. One of the numbers 1 to 120 
> inclusive has been left out (it's left as an exercise for the reader to
> work out which one). Most other solutions have similar problems.

Well, that spec was written after the code examples were posted as
something of a separate exercise, so the mismatches are not the fault of
the programs.

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


#16111

From"Elizabeth D. Rather" <erather@forth.com>
Date2012-10-09 08:44 -1000
Message-ID<YvednSQqM-s57enNnZ2dnUVZ_vednZ2d@supernews.com>
In reply to#16088
On 10/8/12 10:26 PM, Mark Wills wrote:
> On Oct 8, 10:57 pm, "Elizabeth D. Rather" <erat...@forth.com> wrote:
...
>> That said, expectations when you're writing code in a job interview
>> situation are significantly different than when tossing off a little
>> code to illustrate a point in a newsgroup discussion. In an interview,
>> it pays to bust a gut to provide clear documentation, especially when
>> you're using a language the interviewer isn't familiar with.
>>
>> All things considered, in this thread I like Doug Hoffman's code best:
>>
>> : run'
>>     120 1 do
>>        cr i 3 mod 0= dup if ." Fizz" then
>>           i 5 mod 0= dup if ." Buzz" then or
>>           i 7 mod 0= dup if ." Zoom" then or
>>           0= if i . then
>>        loop ;
>>
>> (although I really think he should have included an empty stack
>> comment). All the detailed factoring in other approaches is
>> inappropriate for a problem this simple. In a job interview, a brief
>> discussion of the approach here would be important.
...
> I agree. And I think that, having submitted the above example in
> Forth, if you were criticised in an interview for not commenting the
> code, my counter would be that it is self describing to anyone with a
> passing familiarity with the language to render comments superfluous.
>

While that defense is technically true, it can come off sounding like 
you're blaming the interviewer for not understanding the code. In an 
interview situation, I'd recommend not necessarily trying to describe 
what each word does, but the thought process behind your design of the 
solution, along the lines of:

"Set up a loop in which, for each iteration, the current index is tested 
to see if it's evenly divisible by 3, 5, or 7. If it is, print the 
appropriate string. Otherwise, print the value."

The interviewer wants to know how you think, as well as how you write 
code. So, here's a clear explanation and some code which, given the 
explanation, looks pretty clear even to someone who's never seen Forth.

Cheers,
Elizabeth

-- 
==================================================
Elizabeth D. Rather   (US & Canada)   800-55-FORTH
FORTH Inc.                         +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com

"Forth-based products and Services for real-time
applications since 1973."
==================================================

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


#16162

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2012-10-10 12:32 +0000
Message-ID<2012Oct10.143249@mips.complang.tuwien.ac.at>
In reply to#16067
Paul Rubin <no.email@nospam.invalid> writes:
>anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>>   Write a program that prints the numbers from 1 to 121. But for
>>   multiples of three print "Fizz" instead of the number and for the
>>   multiples of five print "Buzz". For numbers which are multiples of
>>   both three and five print "FizzBuzz".  For numbers which are multiples
>>   of seven, print "Zoom".  For numbers which are multiples of three and
>>   seven, print "FizzZoom".  For numbers which are multiples of five and
>>   seven, print "BuzzZoom".  For numbers which are multiples of three,
>>   five and seven, print "FizzBuzzZoom".
>
>This seems like a messy specification to me, and also an incorrect or
>ambiguous one, since (e.g.) for n=15 it allows printing "Fizz Buzz
>FizzBuzz".

That supposed ambiguity is already there in the original
specification.  It still seems that everybody interpreted it in the
same way, following the following rule: Apply the most specific rule
of those given.  And actually this specific rule is necessary, because
otherwise there would be an ambiguity about what happens for numbers
divisible by three and by five; should we apply the three-rule, the
five rule, first three, then five or first five, then three.  And I
guess that's why you spelled out every case of this kind explicitly in
your incomplete extension of the specification, too.

>Here's another attempt:
>
>   Write a program that prints the numbers from 1 to 120 (inclusive) in
>   FBZ (Fizz-Buzz-Zoom) notation, one per line.  For a natural number n
>   that is coprime to 3, 5, and 7, the FBZ notation for n is the same as
>   the decimal representation of n.  For other natural numbers n, the
>   FBZ notation for n is the concatenation of the F, B, and Z notations
>   for n.  The F notation for natural n is the string "Fizz" if n is a
>   multiple of 3, otherwise it is the empty string.  The B notation for
>   natural n is the string "Buzz" if n is a multiple of 5, otherwise it
>   is the empty string.  The Z notation for natural n is the string
>   "Zoom" if n is a multiple of 7, otherwise it is the empty string.
>
>That is also a messy spec, but most ways I see to clean it up involve
>introducing more machinery that in other ways makes it worse.

It's also longer (10 lines instead of 8), more complicated and harder
to understand.  Let's see what program follows naturally from it:

: fbz ( -- )
  121 1 ?do
    cr i 3 mod 0<> i 5 mod 0<> i 7 mod 0<> and and if 
      i .
    else
      i 3 mod 0= if ." fizz" then
      i 5 mod 0= if ." buzz" then
      i 7 mod 0= if ." zoom" then
    then
  loop ;

>Anyway, as someone in the earlier clf thread mentioned, it's an
>interview question rather than a "program from spec" problem.  In that
>situation, some ambiguity can be a good thing since it lets you see the
>candidate's approach to resolving it.  

Not in this case, because the interviewer was interested in
correctness.  I also don't think that ambiguity lets you see a
candidates approach any better than non-ambiguity.

>Even with a formal spec, it's still appropriate to identify the patterns
>inherent in the spec and reflect them in the code.

If the point of the example is correctness (as in the original
example), staying close to the spec is a good idea, as it reduces the
opportunities for mistakes.  If the goal is to have the solution fast,
staying close to the spec is also a good idea.  If the point of the
example is to produce small or efficient code, then one should also
consider other approaches.

Concerning the goal of future-proofing the program, I find that hard
for a contrived problem; you contrive one extension of the problem,
but someone else might contrive a completely different one, and there
is no way to predict which contrived extension is more probably.
Besides, future-proofing is not the Forth way:-).

- 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 2012: http://www.euroforth.org/ef12/

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


#16164

FromBernd Paysan <bernd.paysan@gmx.de>
Date2012-10-10 16:59 +0200
Message-ID<2375326.3OPp2VNvLy@sunwukong.fritz.box>
In reply to#16162
Anton Ertl wrote:
> Concerning the goal of future-proofing the program, I find that hard
> for a contrived problem; you contrive one extension of the problem,
> but someone else might contrive a completely different one, and there
> is no way to predict which contrived extension is more probably.
> Besides, future-proofing is not the Forth way:-).

But extensibility is.  Let's say the general problem is "print some word 
if there is a rule to match, print a number if there isn't".  Typical 
application would be a calendar, where you have a date on normal days, 
and a string if there is an entry (multiple strings for multiple 
entries).

So you write

Defer check ( flag n -- flag' )  ' drop is check

: list-items ( n1 n2 -- )
  ?DO  false i check 0= IF  i 0 .r  THEN  cr  LOOP ;

\ check DSL syntactic sugar

: check[  :noname ]] dup >r [[ ['] check defer@ compile, postpone r> ;
: ]check" ]] dup IF ." THEN or ; [[ is check ; immediate

\ silly checks to test the program

check[ 3 mod 0= ]check" Fizz"
check[ 5 mod 0= ]check" Buzz"
check[ 7 mod 0= ]check" Zoom"

121 1 list-items

Being able to write a small program as test can be quite useful in a 
calendar - I could add a check for fourth Thursday in the month, but 
earlier than 24th of December with the string "Munich Forth meeting" or 
8th month, 25th day in the Chinese lunar calender (today) as "Peng 
XiuQing's birthday".  The further is almost possible in most calendars, 
with the exeption of 24th of December, the latter usually isn't, because 
the calendar makers think there is only one calendar system...

You probably want to write "Sunday" instead of "Zoom".  And to make this 
a calendar application, you will implement a few words which convert the 
index (e.g. 0=first of March of the year 1 BC, Julian calendar) to year-
month-day in various calendars.  And maybe some strings want some 
variables in it, the birthday reminder could contain the age.

A lot of flexibility comes from having source code available, so 
extensions or modifications are easy to do.  E.g. if I dedice that it is 
better to append the string to a string variable instead of printing it, 
I only have to change ]CHECK" and LIST-ITEMS.

-- 
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://bernd-paysan.de/

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


#16167

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2012-10-10 16:42 +0000
Message-ID<2012Oct10.184225@mips.complang.tuwien.ac.at>
In reply to#16164
Bernd Paysan <bernd.paysan@gmx.de> writes:
>Anton Ertl wrote:
>> Concerning the goal of future-proofing the program, I find that hard
>> for a contrived problem; you contrive one extension of the problem,
>> but someone else might contrive a completely different one, and there
>> is no way to predict which contrived extension is more probably.
>> Besides, future-proofing is not the Forth way:-).
>
>But extensibility is.  Let's say the general problem is

I actually meant Chuck Moore's way.  And I think he would not
generalize the problem and design extensibility for that on first
encounter.  Instead, he would see a more general problem and design a
more general program for it only if he encounters several similar
problems.

While I usually lean more in the direction of generalization than most
Forthers, in this case I would just follow Chuck Moore's way, because
it is a contrived problem, and any generalization would be
even more guesswork than usual.

>"print some word 
>if there is a rule to match, print a number if there isn't".

Which does not specify what happens if several rules match.  Paul
Rubin generalized the FizzBuzz problem in a way that answers that
question in a specific way, but what if the interviewer had next
asked: "Now change the program such that it prints 'boing' if the
number is divisible by three and by five".  The "ugly" program would
be easy to fix, while the generalizations along the lines that Paul
Rubin and you have in mind would require more effort.

>Defer check ( flag n -- flag' )  ' drop is check
>
>: list-items ( n1 n2 -- )
>  ?DO  false i check 0= IF  i 0 .r  THEN  cr  LOOP ;
>
>\ check DSL syntactic sugar
>
>: check[  :noname ]] dup >r [[ ['] check defer@ compile, postpone r> ;
>: ]check" ]] dup IF ." THEN or ; [[ is check ; immediate
>
>\ silly checks to test the program
>
>check[ 3 mod 0= ]check" Fizz"
>check[ 5 mod 0= ]check" Buzz"
>check[ 7 mod 0= ]check" Zoom"
>
>121 1 list-items

Cute, because it allows writing checks in different files, or
interspersed with other colon definitions; useful for allowing
extensions by several people.

>A lot of flexibility comes from having source code available, so 
>extensions or modifications are easy to do.  E.g. if I dedice that it is 
>better to append the string to a string variable instead of printing it, 
>I only have to change ]CHECK" and LIST-ITEMS.

But your approach is particularly valuable in cases where one does not
want to change the original source code.  If I can change the source
code, some of the other variants are just as easy to change and easier
to understand.

- 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 2012: http://www.euroforth.org/ef12/

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


#16229

FromPaul Rubin <no.email@nospam.invalid>
Date2012-10-12 21:18 -0700
Message-ID<7xehl357iz.fsf@ruckus.brouhaha.com>
In reply to#16162
anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
> That supposed ambiguity is already there in the original
> specification.  It still seems that everybody interpreted it in the
> same way, following the following rule: Apply the most specific rule
> of those given.

I'd say the codinghorror post isn't an actual specification, but just an
informal description.

>>That is also a messy spec...
> It's also longer (10 lines instead of 8), more complicated and harder
> to understand.  

Well, harder to understand is in the eye of the beholder.  I do think
it's more precise.

> Let's see what program follows naturally from it: ...

That program looks ok; my version basically lifted the divisor checks
to do each one once instead of twice.

> Not in this case, because the interviewer was interested in
> correctness.  I also don't think that ambiguity lets you see a
> candidates approach any better than non-ambiguity.

Part of interviewing is describing a general problem and seeing
what kind of questions the person asks.

> If the point of the example is correctness (as in the original
> example), staying close to the spec is a good idea, as it reduces the
> opportunities for mistakes.  If the goal is to have the solution fast,
> staying close to the spec is also a good idea.  If the point of the
> example is to produce small or efficient code, then one should also
> consider other approaches.

In this particular case I was taking the approach of trying to identify
a "pure" version of the problem, like that blog post I linked
("FizzBuzz, A Deep Navel to Gaze Into"), not particularly as
optimization or future-proofing.  I think your extension:

> ... "Now change the program such that it prints 'boing' if the number
> is divisible by three and by five".

still fits into that monoidal picture (the tests just become a little
more complicated), but yeah, the factored Forth implementation suffers.

It's interesting, I keep seeing Chuck's stuff saying to factor
relentlessly so I tried to do that, but per yours and other posts in the
thread, it was probably overdone.

As for following specs in general, some specs (like ITU specs) for
policy reasons (I think this means "protecting incumbents") are written
to avoid giving any implementation guidance at all.  So such a spec
might say how to recognize the correct Fizzbuzz output in a purely
syntactic, descriptive way, in this case perhaps something like EBNF
notation.  I've haven't had to deal with this type of thing directly so
far though.

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


#16232

From"Elizabeth D. Rather" <erather@forth.com>
Date2012-10-12 21:06 -1000
Message-ID<uM6dnX_AWbOMjuTNnZ2dnUVZ_hKdnZ2d@supernews.com>
In reply to#16229
On 10/12/12 6:18 PM, Paul Rubin wrote:
> anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
...
>> ... "Now change the program such that it prints 'boing' if the number
>> is divisible by three and by five".
>
> still fits into that monoidal picture (the tests just become a little
> more complicated), but yeah, the factored Forth implementation suffers.
>
> It's interesting, I keep seeing Chuck's stuff saying to factor
> relentlessly so I tried to do that, but per yours and other posts in the
> thread, it was probably overdone.
>
> As for following specs in general, some specs (like ITU specs) for
> policy reasons (I think this means "protecting incumbents") are written
> to avoid giving any implementation guidance at all.  So such a spec
> might say how to recognize the correct Fizzbuzz output in a purely
> syntactic, descriptive way, in this case perhaps something like EBNF
> notation.  I've haven't had to deal with this type of thing directly so
> far though.

Factoring isn't an abstract exercise. It should be thoroughly 
functional, identifying factors that are either usable elsewhere in the 
application or will facilitate testing in some fashion.

The excessively factored versions of FizzBuzz were abstract -- segments 
of code carved out because they *could* be. The overall result was 
*more* complex than it needed to be. The result of a *well-factored* 
program should be simpler, not more complex.

Getting the additional spec may illuminate productive additional 
factoring to avoid needless repetitive code. When an additional spec 
reveals inappropriate factoring, it's time to re-think.

Cheers,
Elizabeth

-- 
==================================================
Elizabeth D. Rather   (US & Canada)   800-55-FORTH
FORTH Inc.                         +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com

"Forth-based products and Services for real-time
applications since 1973."
==================================================

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


#16161

FromDoug Hoffman <glidedog@gmail.com>
Date2012-10-10 09:02 -0400
Message-ID<507571c5$0$286$14726298@news.sunsite.dk>
In reply to#16050
On 10/8/12 11:38 AM, Paul Rubin wrote:

> My preferred version separates the code from the data ("figure out the
> data structure, and the code takes care of itself").  First write down
> the data:
>
>       spec = [(3, "Fizz"), (5, "Buzz"), (7, "Zoom")]
>
> The following code then flows pretty easily (be aware that ''.join(...)
> is a Python idiom for concatenating a list of strings, and that a
> boolean test on a list returns true iff the list is non-empty):
>
>       def fb(n):
>          ns = [s for (d,s) in spec if n%d==0]
>          return ''.join(ns) if ns else str(n)
>
>       for i in xrange(1,121): print fb(i)
>
> This handles arbitrary numbers of divisors and does the right thing if
> one or more of the strings is empty.

There is a non-trivial degree of support required to use this kind of 
approach in Forth.  It could be approximated with some scaffolding. 
Using some (of my) library code, microFMS which is about 30-40 lines of 
code, with 3 existing library classes(var, string, and object-list):

\ record-class objects are specific to this problem
create record <super object
  ivar d  \ will contain a var obj
  ivar s  \ will contain a string obj
:m init: var >dict d !  stringc >dict s ! ;m
:m !: ( d stra len -- )
    s @ !:  d @ !: ;m
:m d: ( -- d ) d @ @: ;m
:m s: ( -- stra len ) s @ @: ;m
:m p: [char] ( emit d @ p: [char] , emit s @ p: [char] ) emit ;m
set-order

\ an object-list is a generic expandable object container
object-list >dict value spec

3 s" Fizz" record spec add!:
5 s" Buzz" record spec add!:
7 s" Zoom" record spec add!:

spec p:  \ print our list
(3 ,Fizz)(5 ,Buzz)(7 ,Zoom)

\ Finally, the main program.
\ We use the each: construct to iterate
\ over the spec list.
: fb { n | rec ns -- }
    stringc >heap to ns
    begin
      spec each:
    while
      to rec
      n rec d: mod 0= if rec s: ns add: then
    repeat
     ns size: if ns p: else n . then
     ns free: ;

: run ( n -- ) 1 do cr i fb loop ;

17 run
1
2
Fizz
4
Buzz
Fizz
Zoom
8
Fizz
Buzz
11
Fizz
13
Zoom
FizzBuzz
16 ok

This also handles arbitrary numbers of divisors and also does the right 
thing if one or more of the strings is empty.

-Doug

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


#16057

FromGerry Jackson <gerry@jackson9000.fsnet.co.uk>
Date2012-10-08 17:50 +0100
Message-ID<k4v096$lra$1@dont-email.me>
In reply to#16015
On 07/10/2012 17:19, Paul Rubin wrote:
> This works in gforth.  I'm not sure if it's valid ANS Forth, since it
> requires multiple s" ..." string literals to be alive at the same time.
> Coding and testing wasn't difficult in absolute terms, since the program
> is so small, but it still took multiple tries and head-scratching, and
> the result seems unmodular compared to a Python version.  Maybe there
> was something I could have done better.
>
>      : fb0 ( flag sa su n d -- flag )
>          mod 0= if type -1 else 2drop 0 then or ;
>
>      : fb ( n -- flag ) >r
>          0 ( flag )
>          s" Fizz" r@ 3 fb0
>          s" Buzz" r@ 5 fb0
>          s" Zoom" r> 7 fb0 ;
>
>      : f ( n -- ) dup fb ( flag ) 0= if . else drop then cr ;
>
>      : run ( -- ) \ run to 120 so that 3*5*7=105 is included
>          120 1 do i f loop ;
>

https://groups.google.com/forum/?hl=en&fromgroups=#!topic/comp.lang.forth/tLZLCc02gmk/overview

-- 
Gerry

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


#16059

FromPaul Rubin <no.email@nospam.invalid>
Date2012-10-08 10:15 -0700
Message-ID<7xwqz0navm.fsf@ruckus.brouhaha.com>
In reply to#16057
Gerry Jackson <gerry@jackson9000.fsnet.co.uk> writes:
> https://groups.google.com/forum/?hl=en&fromgroups=#!topic/comp.lang.forth/tLZLCc02gmk/overview

ZOMG.  I should have figured there would be something like that.  I
liked the Colorforth entry ;-).

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

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


csiph-web