From: Pillsy on
On Feb 28, 8:03 am, Ken Tilton <kentil...(a)gmail.com> wrote:
> Tim Bradshaw wrote:
[...]
> > Incidentally, I'm deeply disappointed in the quality of answers in
> > this thread. In the elder days there would have been at least a few
> > followups showing how to do this in the proper "FORMAT string
> > indistinguishable from line noise" way.

> Oh, absolutely, long overdue in this thread. Is this going to become a
> lost art? The village elders need to step up, methinks. I started
> playing with it, but I am just an elder, not a Lisp elder. Screams for a
> nested thingy, yes?

Well, if you're going to throw down the gauntlet like that, I'm
just going to have to respond in the hopes of provoking someone
into besting my wimpy attempt.

(apply #'format t "~@{ ~2@{~D ~}~^~*Fizz ~D ~*Buzz~
~*Fizz ~2@{~D ~} ~*Buzz ~D ~*Fizz~
~2@{~D ~} ~*FizzBuzz ~%~}"
(loop
:for i :from 1 to 100
:collect i))

Cheers,
Pillsy


From: Richard M Kreuter on
Tim Bradshaw <tfb(a)tfeb.org> writes:
> On 2007-02-28 17:38:48 +0000, Richard M Kreuter <kreuter(a)progn.net> said:

> I'm unhappy about the explicit looping however. I can see two
> solutions to this:
>
> * something really gratuitous involving GO
> * something equally gratuitous involving a lot of LAMBDAs.

I'm sorry, but here's the best I can do for now.

(unwind-protect
(prog ((i 0) mod3 mod5)
(declare (special i mod3 mod5))
(setf (symbol-function 'cl-user::format-eval)
(lambda (stream thing colon atsign)
(declare (ignore stream colon atsign))
(handler-bind ((warning #'muffle-warning))
(eval thing))))
(setf mod3 (mod i 3)
mod5 (mod i 5))
format
(ecase
(catch 'go
(format
t
"~&~[~[~3@*~A~A~:;~3@*~A~*~]~:;~[~4@*~A~:;~D~2*~]~]~%~/CL-USER::FORMAT-EVAL/"
mod3 mod5 i "Fizz" "Buzz"
'(progn
(incf i)
(setf
mod3 (mod i 3)
mod5 (mod i 5))
(if (> i 100)
(throw 'go 'quit)
(throw 'go 'format)))))
(format (go format))
(quit (go quit)))
quit nil)
(fmakunbound 'cl-user::format-eval))

I know, it doesn't have enough LAMBDAs.

--
RmK
From: Harald Hanche-Olsen on
You want squiggles? How about

(format t "~&~:{ ~@[~A~]~@[~A~]~2:*~:[~:[~D~;~]~;~]~}~%"
(loop for n from 1 to 100
for fizz in '#3=(nil nil "Fizz" . #3#)
for buzz in '#5=(nil nil nil nil "Buzz" . #5#)
collect (list fizz buzz n)))

Or, if loop is for weenies, perhaps this one, with a few gratuitous
MAPs and NCONCs thrown in.

(format t "~&~:{ ~@[~A~]~@[~A~]~2:*~:[~:[~@[~C~]~C~;~]~;~]~}~%"
(cdr
(nconc
(map 'list
(lambda (ij f b) (cons f (cons b ij)))
(apply #'nconc
(map 'list
(lambda (i)
(map 'list
(lambda (j)
(list (if (eql i #\0) nil i) j))
#1="0123456789"))
#1#))
'#3=("Fizz" nil nil . #3#)
'#5=("Buzz" nil nil nil nil . #5#)))))

--
* Harald Hanche-Olsen <URL:http://www.math.ntnu.no/~hanche/>
- It is undesirable to believe a proposition
when there is no ground whatsoever for supposing it is true.
-- Bertrand Russell
From: Harald Hanche-Olsen on
+ Harald Hanche-Olsen <hanche(a)math.ntnu.no>:

| for fizz in '#3=(nil nil "Fizz" . #3#)
| for buzz in '#5=(nil nil nil nil "Buzz" . #5#)

But I hadn't read the whole thread and missed Rob Warnock's use of
this same trick in <zZSdnVArCY40vHjYnZ2dnUVZ_ruknZ2d(a)speakeasy.net>.

--
* Harald Hanche-Olsen <URL:http://www.math.ntnu.no/~hanche/>
- It is undesirable to believe a proposition
when there is no ground whatsoever for supposing it is true.
-- Bertrand Russell
From: Thomas A. Russ on
"Tim Bradshaw" <tfb+google(a)tfeb.org> writes:
>
> Incidentally, I'm deeply disappointed in the quality of answers in
> this thread. In the elder days there would have been at least a few
> followups showing how to do this in the proper "FORMAT string
> indistinguishable from line noise" way. No true CL programmer ever
> uses any other construct when the problem can be solved with a
> combination of FORMAT, LOOP & GO (FORMAT being always preferable,
> obviously). There may yet be those reading cll who know this, though
> I suspect they have all gone into the west now.

Well, OK -- I have gone into the West, but I stopped just short of the
Pacific Ocean. Obviously this requires some finesse since we don't want
to have to specify arguments more than once. So we do need to obscurely
move back and forth along the argument list:

(dotimes (i 20)
(format t "~[Fizz~:;~]~[Buzz~*~:;~2:*~[~2*~:;~*~D~]~]~%"
(mod i 3) (mod i 5) i))

Now this is just way too obscure for me -- and it looks vaguely like
Perl code ;)

My real preference for doing it using format would be for a solution
more like:

(dotimes (i 20)
(let ((divisible-by-3-p (zerop (mod i 3)))
(divisible-by-5-p (zerop (mod i 5))))
(format t "~@[Fizz~*~]~@[Buzz~*~]~:[~D~:;~*~]~%"
divisible-by-3-p divisible-by-5-p
(or divisible-by-3-p divisible-by-5-p)
i)))



Although for production code I would take one of the cond-based
programming solutions over trying to do this with format




--
Thomas A. Russ, USC/Information Sciences Institute