El problema «Fizz Buzz», o cómo cribar programadores en una entrevista de trabajo

«Fizz Buzz»
Las entrevistas de trabajo pertenecen a un universo aparte muy alejado del mundo real. Te hacen preguntas incómodas a las que tienes que contestar de manera sicológica, te estimulan o te procuran motivar de una manera peculiarmente curiosa, te examinan atentamente con la mirada y, de vez en cuando, te prueban técnicamente para verificar tus conocimientos reales. El orbe informático no se escapa de estos ensayos y, con cierta frecuencia, recurre a los exámenes expertos para determinar la valía de un candidato o su más absoluta incompetencia.
El problema conocido como «Fizz Buzz» es un buen ejemplo de lo anteriormente comentado. No es más que un método para descartar, de una forma ágil, a un aspirante a programador, ahorrando mucho tiempo al contratador y, por supuesto, al posible contratado. El dilema en sí parece sencillo (y, en el fondo, lo es), pero tiene truco.
El enunciado del problema que se plantea a los candidatos es el siguiente:
Escribe, en el lenguaje de programación que desees, un programa que muestre en pantalla los números del 1 al 100, sustituyendo los múltiplos de 3 por el palabro “Fizz” y, a su vez, los múltiplos de 5 por “Buzz”. Para los guarismos que, al tiempo, son múltiplos de 3 y 5, utiliza el combinado “FizzBuzz”.
Una tontería, ¿no? Pues no. Este programa se puede resolver de cincuenta millones de maneras diferentes, lo que importa (lo que realmente buscan) es que lo hagas de la forma más elegante posible, esto es, utilizando el menor número de líneas de código o, en su defecto, de un modo tal que eyaculen de placer con el procedimiento aplicado. Todo vale, o un sinfín de sentencias condicionales anidadas de Basic o una de línea de 56 caracteres en Ruby.
Los resultados de «Fizz Buzz» son concluyentes y, para mí, bastante preocupantes. Dicen los expertos de las mejores empresas de desarrollo que la mayoría de los graduados, ingenieros o diplomados en informática no pueden hacerlo o, por el contrario, lo saben resolver pero invierten demasiado tiempo en ello. Los entendidos comentan que cualquier candidato deseable no debería tardar más de dos o tres minutos en terminarlo y, pasados 10 minutos, podría ser descartado sin ningún tipo de miramiento.
Parece ser que sólo uno de cada doscientos programadores en una entrevista de trabajo es capaz de pasar la prueba, y eso es muy alarmante.
Lo curioso es que el juego proviene de un divertimento adolescente, últimamente también ligado al hecho de beber alcohol en grupo. Un conjunto de chavales en corro recitan la serie lo más rápido posible, a razón de un número cada uno e introduciendo los «Fizz», los «Buzz» y los «FizzBuzz» correspondientes: 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, 16
… Y así hasta el 100
(que, por cierto, es «Buzz»). El que se equivoque bebe; y se vuelve a empezar.
A mí mismo me ha tocado lidiar con esta prueba no hace mucho, y pienso que se puede resolver, elegantemente en muy poco tiempo, siempre y cuando tengas la cabeza estructurada y pienses como un programador de verdad. Existen miles de soluciones en cientos de lenguajes de programación diferentes, y en la web Technical Support existe un hilo en el que se pueden encontrar un montonazo de ellas, algunas muy curiosas y otras muy divertidas. Hay una versión para la consola de MS-DOS, otra para Excel, versiones para Python, ensamblador, GW-BASIC, PHP y hasta una en código MSIL y otra en el lenguaje de programación esotérico Ook!
Yo, así a bote pronto, voy a improvisar dos, una en Visual Basic .NET y otra en C# (ambas como aplicación de consola). Y reto a los lectores a que, en cualquiera de estos dos lenguajes (que son de los más típicos) intenten escribir versiones con menos líneas de código y más elegantes. Se puede hacer seguro, y ahora mismo se me está ocurriendo una manera, pero voy a plasmar mis primeras ideas para dar más juego.
If i Mod 3 = 0 Or i Mod 5 = 0 Then
If i Mod 3 <> 0 Then
Console.WriteLine("Buzz")
ElseIf i Mod 5 <> 0 Then
Console.WriteLine("Fizz")
Else
Console.WriteLine("FizzBuzz")
End If
Else
Console.WriteLine(i)
End If
Next
{
if (i % 3 == 0 || i % 5 == 0)
{
if (i % 3 != 0)
{
Console.WriteLine("Buzz");
}
else if (i % 5 != 0)
{
Console.WriteLine("Fizz");
}
else
{
Console.WriteLine("FizzBuzz");
}
}
else
{
Console.WriteLine(i);
}
}
Pues, lo dicho, a pensar un poco y a fizzbuzzear un rato.
No tengo mucha mano con ninguno de los dos lenguajes que decís, pero lo escribí en python y me parece que queda mas simple 🙂
for i in range(1,101):
s = «»
if not i % 3: s += «Fizz»
if not i % 5: s += «Buzz»
if not s: s = i
print s
@ABorgna
Efectivamente ese método es muy bueno. Y ya q se pide en el Visual.net lo voy a intentar mejorar basándome en el comentario anterior,q queda más elegante y con menos lineas d código. Esta es mi propuesta:
For i As Byte = 1 To 100
Dim s As String = «»
If i Mod 3 = 0 Then s &= «Fizz»
If i Mod 5 = 0 Then s &= «Buzz»
If i Mod 3 <> 0 And i Mod 5 <> 0 Then s = i.ToString
Console.WriteLine(s)
Next
He dicho.
[…] "CRITEO-300×250", 300, 250); 1 meneos El problema “Fizz Buzz”, o cómo cribar programadores en una entrevista de trabajo https://www.teknoplof.com/2012/02/11/el-problema-fizz-buzz-o-como… por kirhom hace […]
void fizzBuzz(int n) {
for (int i = 1; i <= n; ++i) {
if (i != 1) cout << ", ";
bool mul3 = i%3 == 0, mul5 = i%5 == 0;
if (mul3) cout << "Fizz";
if (mul5) cout << "Buzz";
if (not mul3 and not mul5) cout << i;
}
}
En C
int n;
char *fizz[]={«»,»Fizz»},*buzz[]={«»,»Buzz»};
for (n=1;n <=100;++n)
printf("%d\r%s%s\n",n,fizz[(n%3==0)],buzz[(n%5==0)]);
<?php
for($i=1;$i
en java:
for(int i=1;i<=100;i++)
System.out.println(
(i%3==0||i%5==0)?((i%3!=0)"Buzz":(i%5!=0?"Fizz":BuzzFizz)):""+i
);
OK. Todos los códigos son correctos (menos el de PHP que se ha cortado) y bastante elegantes. Pero estoy convencido de que lo podéis hacer mejor.
Según los comentarios en el blog y los de Menéame, lo que mejor me sale en VB .Net es:
For i As Byte = 1 To 100
Dim s As String = «»
If i Mod 3 = 0 Then s &= «Fizz»
If i Mod 5 = 0 Then s &= «Buzz»
If s = «» Then s = i.ToString
Console.WriteLine(s)
Next
Y, lo que mejor me parece en C# es:
for (byte i=1;i<=100;i++) { string s=""; if (i%3==0){s+="Fizz";} if (i%5==0){s+="Buzz";} if (s==""){s=i.ToString();} Console.WriteLine(s); } Pero, ¿se puede mejorar?
En octave .m
p=3*(1:floor(100/3));
q=5*(1:floor(100/5));
n3=n5=zeros(1,100);
n3(p)=-1;
n5(q)=-2;
total=n3+n5;
for i=1:100
switch (total(i))
case -1
disp(‘Fizz’)
case -2
disp(‘Buzz’)
case -3
disp(‘FizzBuzz’)
otherwise
disp(i)
end
endfor
Aca aporto mi granito de arena, en Haskell:
–Main 😉
–[fizzOrBuzz x | x «FizzBuzz»
(True, _) -> «Fizz»
(_, True) -> «Buzz»
otherwise -> show x
–Aux
isMulX x n = n `mod` x == 0
Al parecer salió la mitad… va sin tabulaciones a ver si sale…
–Main 😉
–[fizzOrBuzz x | x «FizzBuzz»
(True, _) -> «Fizz»
(_, True) -> «Buzz»
otherwise -> show x
–Aux
isMulX x n = n `mod` x == 0
Mmmmm, lastima no quiere salir todo el codigo 🙁
Información Bitacoras.com…
Valora en Bitacoras.com: «Fizz Buzz» Las entrevistas de trabajo pertenecen a un universo aparte muy alejado del mundo real. Te hacen preguntas incómodas a las que tienes que contestar de manera sicológica, te estimulan o te procuran motivar de una……
en PHP esperemos salga completo
for($i=1;$i<=100;$i++)
echo ($i%5==0)?(($i%3==0)?'FizzBuzz':'Fizz'):(($i%3==0)?'Buzz':$i);
El anterior comentario coloque al reves el orden de Fizz y Buzz lo siento es asi
for($i=1;$i<=100;$i++)
echo ($i%5==0)?(($i%3==0)?'FizzBuzz':'Buzz'):(($i%3==0)?'Fizz':$i);
No lo creo. Cualquier persona que termine el primer curso de programación en la universidad podría resolver ese problema con 4 if en muy poco tiempo.
Descartar un profesional por este rompecabezas lo único que demuestra es que una nueva peste que se abate sobre el mundo laboral: recursos humanos.
Aunque ya lo has solucionado en C#
lo voy a intentar mejorar dejándolo en dos lineas utilizando el operador condicional
for (int i=1;i<=100;i++)
Console.WriteLine( (i % 3 == 0 && i % 5 == 0) ? "FizzBuzz" : (i % 3 == 0) ? "Fizz" : (i % 5 == 0) ? "Buzz" : i.ToString() );
Mi version en 10 lineas python
#!/usr/bin/env python
for i in range(1,101):
if i % 3 == 0 and i % 5 == 0:
print «fizzbuzz»
elif i % 5 == 0:
print «buzz»
elif i % 3 == 0:
print «fizz»
else:
print i
#include
using namespace std;
int main(int argc, char** argv) {
int i = 0; // 3 y 5 son primos, entonces 15 es válido
while(i < 100) (++i % 15 == 0) ? cout << "FizzBuzz\r\n" : (i % 3 == 0) ? cout << "Fizz\r\n" : (i % 5 == 0) ? cout << "Buzz\r\n" : cout << i << "\r\n";
return 0;
}
[…] El problema “Fizz Buzz”, o cómo cribar programadores en una entrevista de trabajo […]
[…] El problema “Fizz Buzz”, o cómo cribar programadores en una entrevista de trabajo […]
[…] El problema “Fizz Buzz”, o cómo cribar programadores en una entrevista de trabajo […]
JS FTW!
for (let i = 1; i < 101; i++) {
const isFizz = i % 3 === 0;
const isBuzz = i % 5 === 0;
let output =
isFizz && isBuzz ? 'FizzBuzz'
: isFizz ? 'Fizz'
: isBuzz ? 'Buzz'
: i;
console.log(output);
}
para subir mi res puesta en raptor
en java utilizando net beans
ublic class FizzBuzz {
public static void main(String[] args) {
for (int i=1; i <= 100; i++){
if((i%5 == 0) && (i%3 == 0)){
System.out.print(i + " FizzBuzz");
}
else if(i%3 == 0){
System.out.print(i + " Fizz");
}
else if(i%5 == 0){
System.out.print(i + " Buzz");
}
else
System.out.print(i);
System.out.println();
}
}
}
piensen que es lo que quieren que se lo que necesitan adelante
programen por pasos reconlciendo codigo
En Elm:
getString num =
case (rem num 3 == 0, rem num 5 == 0) of
(False, False) ->
toString num
(False, True) ->
«Buzz»
(True, False) ->
«Fizz»
(True, True) ->
«FizzBuzz»
main =
List.map getString (List.range 1 100)
// JS. Yeas, I can do it in one statement too…
const range = (init, end) => {
const nums = [];
for(let i = init; i x % num === 0;
const printNumber = num => {
if(multipleOf(3, num) && multipleOf(5, num))
return console.log(«FizzBuzz»);
if(multipleOf(5, num))
return console.log(«Buzz»);
if(multipleOf(3, num))
return console.log(«Fizz»);
console.log(num);
}
const nums = range(1, 100);
nums.forEach(n => printNumber(n));
well, the code in the comment looks terrible, this is better:
https://gist.github.com/ajchambeaud/6427a270cb4ef6f5d505e717c48a3a23
En java:
public class FizzBuzz{
private static int MAX = 100;
public static void main(String [] args){
int fizz = 3, buzz=5;
for(int i = 1; i <= MAX; i++){
if(((i % fizz) == 0) && ((i % buzz) == 0)){
System.out.println("FizzBuzz");
}else if((i % fizz) == 0){
System.out.println("Fizz");
}else if((i % buzz) == 0){
System.out.println("Buzz");
}else{
System.out.println(i);
}
}
}
}
La diferencia con el otro código que publicaron de java es que no tiene constantes en código, y eso es algo para tener en cuenta más cuando esas constantes se repiten.
en swift 4.0 -> playground
var numeros = [Int]()
for num in 1…100 {
numeros.append(num)
}
for num in numeros {
if num % 15 == 0 {
print(«\(num) fizzbuzz»)
} else if num % 3== 0 {
print(«\(num) fizz»)
} else if num % 5 == 0 {
print(«\(num) buzz»)
} else {
print (num)
}
}
primero creo un array vacío,.. después en el primer ciclo le defino el limite agregando y sumando + 1 hasta dar 100 después hago otro ciclo for en donde determino con los las condicionales if y enseguida los clásicos operaciones de modulo para el 3, 5 y 15, primero comienzo con el 15 dado que colocándolo en una posición diferente no imprime el fizzbuzz, y respectivamente 3 y 5
Para OpenOffice Calc (no tengo Excel):
=SI(RESIDUO(A2;3)=0;SI(RESIDUO(A2;5)=0;»FIZZBUZZ»;»FIZZ»);SI(RESIDUO(A2;5)=0;»BUZZ»;A2))
Asumiendo que se copia en la columna B las 100 veces requeridas, y que la columna A contiene los valores del 1 al 100.
No me critiquen por favor, me acabo de cambiar y aun no tengo acceso a nada más que un Open Office.
Saludos!
En Ruby
def fizzbuzz(int)
if int % 3 == 0 && int % 5 == 0
«FizzBuzz»
elsif int % 5 == 0
«Buzz»
elsif int % 3 == 0
«Fizz»
else
nil
end
end
*****En las comillas me faltó poner el puts antes de las mismas.
En R:
for (i in 1:100){
ifelse(i%%3==0 & i%%5==0,print(«FizzBuzz»),ifelse(i%%3==0,print(«Fizz»),ifelse(i%%5==0,print(«Buzz»),print(i))))
}