From: Pillsy on 28 Feb 2007 15:01 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 28 Feb 2007 15:22 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 28 Feb 2007 17:05 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 28 Feb 2007 17:12 + 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 28 Feb 2007 17:39
"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 |