What is your FizzBuzz factor...
I was reading "Why Can't Programmers.. Program?" this morning. It is sad - but near close to true. I do not believe 199 out of 200 cannot program - but it isn't too far from the truth. It manifests itself in many ways - from the examples in that article of just not being able to come up with simple algorithms - to my biggest pet peeve. Not being able to phrase a comprehensible QUESTION.
If you don't know how to ask for help solving your problem, that is - if you cannot phrase your problem as a set of specifications, detailed specifications - you'll never get a reasonable answer except purely by luck or accident. More likely, what you get in response to a poorly framed question is an answer that appears to work (given the poorly specified requirements - typically without any of the boundary value conditions thought out), but doesn't. And the "but doesn't" part is never discovered until "too late" (when it becomes impossible to fix due to "management says we cannot touch the code").
Anyway, when I read their FizzBuzz "specification", I immediately thought of how I would solve it :) Using SQL of course!
ops$tkyte%ORA10GR2> with data
2 as
3 (select level l
4 from dual
5 connect by level <= 100)
6 select l,
7 case when mod(l,3)=0
8 then case when mod(l,5)=0
9 then 'FizzBuzz'
10 else 'Fizz'
11 end
12 when mod(l,5)=0
13 then 'Buzz'
14 else to_char(l)
15 end fb
16 from data
17 /
L FB
---------- ----------------------------------------
1 1
2 2
3 Fizz
4 4
5 Buzz
6 Fizz
7 7
8 8
9 Fizz
10 Buzz
11 11
12 Fizz
13 13
14 14
15 FizzBuzz
...
90 FizzBuzz
91 91
92 92
93 Fizz
94 94
95 Buzz
96 Fizz
97 97
98 98
99 Fizz
100 Buzz
100 rows selected.
24 Comments:
or if you do not want to repeat Fizz and Buzz and 5 then
SQL> exec for i in 1..100 loop dbms_output.put_line(i||' '||nvl(case mod(i,3) when 0 then 'Fizz' end||case mod(i,5) when 0 then 'Buzz' end,i));end loop
1 1
2 2
3 Fizz
4 4
5 Buzz
6 Fizz
7 7
8 8
9 Fizz
10 Buzz
11 11
12 Fizz
13 13
14 14
15 FizzBuzz
...
98 98
99 Fizz
100 Buzz
Scratching head... the specification didn't specify whether to print the number also when it is a multiple of 5 or a multiple of both 3 and 5 (it only stated that when the number is a multiple of 3, output should be "Fizz" instead of the number, no similar mention for the other cases).
Of course, this could once again be my limited english kicking in, but to be sure and secure, I'd request more specific specifications :)
I did it in PL/SQL ( I know, when it can be done in SQL....). I read it as wanting:
1
2
Fizz
4
5
Fizz
7
8
Fizz
10
11
Fizz
13
14
Buzz
16
.
.
I did it in python too. Just learning python, that is why I did it in PL/SQL first. Get a test/reference.
Funny, that was a drinking game back in my freshman year of college. Never did make it to 100 :)
Love the SQL example.
' VBScript FizBuzz
'Write a program that prints the numbers from 1 to 100.
'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.
Main
Private Sub Main
For x = 1 to 100
WScript.Echo EfferVesce(x)
Next
End Sub
Private Function EfferVesce(ByVal TheNumber)
If 0 = (TheNumber mod 3) + (TheNumber Mod 5) Then
EfferVesce = "FizzBuzz"
ElseIf 0 = TheNumber Mod 3 Then
EfferVesce = "Fizz"
ElseIf 0 = TheNumber Mod 5 Then
EfferVesce = "Buzz"
Else
EfferVesce = TheNumber
End If
Next
End Function
Just curious Tom-what's the advantage (if any) of using a WITH clause rather than an inline view? I've never jumped on the WITH bandwagon-maybe its time to?
On my first try, I used the same solution as Tom, but then I liked the idea of not repeating Fizz, Buzz and 5, so I switched to:
select n, nvl(
case when mod(n,3) = 0 then 'Fizz' end ||
case when mod(n,5) = 0 then 'Buzz' end,
to_char(n)) as answer
from (select level as n from dual connect by level <= 100)
in coding, isn't it better to make the code understandable? Thus, coding in the fewest terms isn't necessarily optimal. If it takes more than 5 seconds to understand something that should take 2, doesn't that cost?
I skipped MOD, but I'm surprised that people chose to code a MOD 3 and a MOD 5 for FizzBuzz rather than work out the 'lowest common multiple' themselves and code that it.
select case when (fb) = trunc(fb) then 'Fizzbuzz'
when (f) = trunc(f) then 'Fizz'
when (b) = trunc(b) then 'Buzz'
else to_char(rn) end fb
from (select rownum rn, rownum/15 fb, rownum/5 b, rownum/3 f from user_objects where rownum <=100)
Neil:
apart from being supposedly the correct "spelling" of ANSI-SQL, WITH can make reading the statement a little easier in the case of complex inline views. but I'm not aware of any inherent advantage in terms of efficiency. Tom, do you agree?
Gary:
Cool! ;-)
with is often more efficient if the subquery is used more than once !
SQL> with t as (select 1 from dual group by cube(1,1,1,1,1,1)) select count(*) from t,t,t,t;
COUNT(*)
----------
16777216
Elapsed: 00:00:03.10
SQL> select count(*) from
2 (select 1 from dual group by cube(1,1,1,1,1,1)),
3 (select 1 from dual group by cube(1,1,1,1,1,1)),
4 (select 1 from dual group by cube(1,1,1,1,1,1)),
5 (select 1 from dual group by cube(1,1,1,1,1,1));
COUNT(*)
----------
16777216
Elapsed: 00:00:03.67
print '\n'.join(map(lambda x : str((x%5==0 and x%3==0) and 'FizzBuzz' or (x%5==0 and 'Buzz' or ( x%3 == 0 and 'Fizz' or x))),range(1,101)))
Python... kinda functional
As Laurent noted above, with subquery factoring can have an edge when the same subquery is repeated over and over as the optimizer will tend to materialize it and reuse the results from temp.
So, sometimes "yes", it is a performance thing.
good info!
thanks, folks
So... do we win points by using MODEL, or get thrown out of the interview on mental health grounds?
Nobody in their right mind actually uses this stuff, right?
:)
select id
, n
from all_objects
where object_id = 1
model
dimension by (object_id id)
measures (object_name n)
rules (
n[for id from 1 to 100 increment 1] = to_char(cv(id)),
n[mod(id, 3) = 0] = 'fizz',
n[mod(id, 5) = 0] = 'buzz',
n[mod(id, 15) = 0] = 'fizzbuzz'
)
order by id
SQL(189)> /
ID N
---------- ---------
1 1
2 2
3 fizz
4 4
5 buzz
6 fizz
7 7
8 8
9 fizz
10 buzz
11 11
12 fizz
13 13
14 14
15 fizzbuzz
...
98 98
99 fizz
100 buzz
100 rows selected.
SELECT
DECODE(DECODE(MOD(LEVEL,3),0,'FIZZ')||DECODE(MOD(LEVEL,5),0,'BUZZ'),NULL,TO_CHAR(LEVEL),DECODE(MOD(LEVEL,3),0,'FIZZ')||DECODE(MOD(LEVEL,5),0,'BUZZ'))
"My Buzz"
FROM dual
CONNECT BY LEVEL<=100
the strength of case
funny enough - nobody seemed to notice that one case is sufficient, due to the strength of (Oracle)-case
select l, case 0 when power("3", 2) + power("5", 2) then 'FizzBuzz'
when "3" then 'Fizz'
when "5" then 'Buzz'
else '' || l
end
from
(
select level l, mod(level,3) "3", mod(level, 5) "5"
from dual
connect by level<=100
)
of course
simply "3" + "5"
instead of
power("3", 2) + power("5", 2)
would also do it
but anyway - the "avoiding the to_char" - trick is nice too, isn't it ?
SELECT DECODE(MOD(LEVEL,15),0,'FizzBuzz',
5,'Buzz',10,'Buzz',
DECODE(MOD(LEVEL,3),0,'Fizz',LEVEL)) as FIZZBUZZ
FROM dual
CONNECT BY LEVEL <= 100
predicates
fizzbuzz(integer)
solution(integer)
clauses
fizzbuzz(I) :- I mod 15 = 0, write("fizzbuzz", "\n"), !.
fizzbuzz(I) :- I mod 3 = 0, write("fizz", "\n"), !.
fizzbuzz(I) :- I mod 5 = 0, write("buzz","\n"), !.
fizzbuzz(I) :- write(I, "\n"), !.
solution(X) :-
X <= 100, fizzbuzz(X), Y = X + 1, solution(Y).
goal
solution(1).
I have in the past been asked to participate in developer interviews.
After some discussion I would show the applicants a simple schema (2 tables) with requirements for simple SQL queries to write.
After getting past the first 3 of 5 questions, I would add a table and a request for data that would require an outer join.
I have been pleasantly surprised to find that most developers we interviewed had little trouble with this test, though all applicants were used SQL Server syntax. (sigh)
hai tom,
you have done a wrong
see specifications
http://ostermiller.org/calc/fizzbuzz.html
FizzBuzz is played by counting but saying "Buzz" if a number is divisible by three or contains the digit three and saying "Fizz" if a number is divisiable by seven or contains the digit seven.
The sequence starts: 1, 2, Buzz, 4, 5, Buzz, Fizz, 8, Buzz, 10, 11, Buzz, Buzz, Fizz, Buzz, 16, Fizz, Buzz, 19, 20, FizzBuzz, 22, ...
you have taken 3 and 5 see 13 not a fizz
you have done a wrong
see specifications
No, you have done wrong, the specifications are not at the URL you pointed to but rather - they were at the URL I pointed to initially.
You see, you just proved out a point - why programmers cannot program. You moved the goalpost here.
Here's the C#, took me < 2min...
for (int i = 1; i <= 100; i++)
{
string output = "";
if (i % 3 == 0) output += "Fizz";
if (i % 5 == 0) output += "Buzz";
if (output == "") output = i.ToString();
Console.WriteLine(output);
}
POST A COMMENT
<< Home