2017-09-04 9 views
1

j'avais une question d'entrevue qui m'a demandé d'écrire un programme avec les exigences suivantes en langue Lua:Lua ForLoop avec plusieurs conditions

  • numéros d'impression entre 1 à 100
  • si le nombre est multiple de 3 , imprimez 'Fizz' au lieu du numéro
  • si le nombre est multiple de 5, imprimez 'Buzz' au lieu du numéro
  • si le nombre est multiple de 5 et 3, imprimez 'FizzBuzz' au lieu du numéro

j'écrit ce qui suit:

for i=1,100 do 
    if i%5==0 then 
    if i%3==0 then 
     print("FizzBuzz") 
    else 
     print("Buzz") 
    end 
    elseif i%3==0 then 
    print("Fizz") 
    else 
    print(i) 
    end 
end 

réponse n'a pas été bonne, en disant la qualité du code n'a pas été à leur niveau. Comment puis-je améliorer le code ci-dessus aux normes les plus élevées pour référence future? Après avoir relu le code, je me rends compte qu'il n'est pas facilement lisible, donc je suis sûr que c'était la raison principale. Peut-être moins de traitement pourrait être impliqué aussi? Vous cherchez des conseils.

+0

La question semble être libellé malformé du problème fizbuzz. https://www.google.ru/search?hl=&q=fizz+buz Votre code ne fait pas ce qui est décrit ci-dessus ("multiple de 3, imprimer 'fizz \ multiple de 5, imprimer' fuzz '"). Pour le problème classique cela fonctionne, je suppose (si "Bizz" est "Fizz" en fait). Et le processus d'entrevue n'est pas un processus objectif dont la décision peut être expliquée par un gars aléatoire d'Internet. – Dimitry

+0

@Dimitry ahh, merci pour les informations de fond sur le problème de fizbuzz, je ne savais pas en fait qu'il s'agit d'un processus de sélection d'entrevue populaire. Bizz était une faute de frappe, et vous avez raison, c'est en fait pour être Fizz. En ce qui concerne la question, c'est en référence au code lui-même, pas à l'interview. Je l'ai posté dans la section de révision de code pour voir si le code peut être amélioré, autre que la faute de frappe. –

+0

Peut-être mieux adapté à https://codereview.stackexchange.com. – lhf

Répondre

1

Il est difficile de dire ce que la personne a demandé, mais il y a plusieurs façons de rendre le code un peu plus court ou moins répétitif. Par exemple, vous pouvez le modifier pour vérifier uniquement pour i%3 une fois (avec le coût supplémentaire des contrôles de TRUTHINESS) et réduire le nombre de print appels:

for i=1,100 do 
    local s = i%3==0 and "Fizz" 
    if i%5==0 then s = (s or "") .. "Buzz" end 
    print(s or i) 
end 

Vous pouvez également inclure le second si dans print:

for i=1,100 do 
    local s = i%3==0 and "Fizz" 
    print(i%5==0 and (s or "") .. "Buzz" or s or i) 
end 

Il est certainement plus court, mais on peut dire qu'il n'est pas plus lisible.

Vous pouvez également éviter concaténation en utilisant FizzBuzz:

for i=1,100 do 
    local s = i%3==0 and "Fizz" 
    print(i%5==0 and (s and "FizzBuzz" or "Buzz") or s or i) 
end 

En termes de l'entrevue, vous auriez pu demander quels aspects ils veulent améliorer. Je pense que l'utilisation de print moins de fois serait une étape logique, mais à part ça, je m'attendrais à ce qu'ils spécifient s'ils se soucient plus de la clarté, de la concision, de la vitesse, ou de quelque chose d'autre. J'ai également couru tous les 4 extraits de code (votre original + 3 montré) avec print remplacé par simplement en stockant une valeur dans une variable et voici les résultats (exécutant la boucle 100,000,000 fois et chronométrant avec os.clock en utilisant Lua 5.3):

9.515 
10.797 
10.672 
10.047 

Il est également possible qu'ils vous simplement tenus de vérifier 15, 5 et 3:

for i=1,100 do 
    print(i%15==0 and "FizzBuzz" or i%3==0 and "Fizz" or i%5==0 and "Buzz" or i) 
end 
+0

merci pour la réponse approfondie, cela m'aidera beaucoup dans le futur, et ma façon de penser. Le résultat du temps est-il un ordre, avec ma réponse en premier, et les trois réponses possibles que vous avez présentées dans l'ordre que vous avez présenté? –

+1

Oui, l'ordre des résultats est le même que l'ordre des exemples, le code d'origine étant le premier (avec les appels 'print' remplacés par des affectations à la même variable locale). –

1

OMI, le code le plus clair serait la suivante:

for n = 1, 100 do 
    local s = (n%3 == 0 and 'Fizz' or '')..(n%5 == 0 and 'Buzz' or '') 
    print(s == '' and n or s) 
end 
+1

Je changerais la dernière ligne en 'print (s> '' et s ou n)', non pas parce qu'il est plus court, mais parce qu'il ne nécessite pas de passer de 's' à' n' et de revenir 's '. –

+1

Voulez-vous dire "interrupteur mental"? Il n'y a pas de "switch technique" ici (c'est-à-dire que les bytecodes sont presque identiques) –

+1

oui, "switch mental";) –

1

Pour moi, le code le plus clair est

for i=1,100 do 
    if i%15==0 then 
    print("FizzBuzz") 
    elseif i%3==0 then 
    print("Fizz") 
    elseif i%5==0 then 
    print("Buzz") 
    else 
    print(i) 
    end 
end 

Je suppose qu'ils n'aimaient pas votre répéter le test i%3==0.

Le code ci-dessus repose sur la possibilité d'exprimer succinctement A(i) and B(i). Je suppose que dans le cas général, vous auriez à faire quelque chose comme ça, ce qui est clair et évite recalculant les prédicats:

for i=1,100 do 
    local a=A(i) 
    local b=B(i) 
    if a and b then 
    print("FizzBuzz") 
    elseif a then 
    print("Fizz") 
    elseif b then 
    print("Buzz") 
    else 
    print(i) 
    end 
end 
+0

Nice opérateur: 'i% == 3' :-) –

+0

@EgorSkriptunoff, oups, merci! – lhf

+0

J'ai l'habitude de convertir les exigences directement en code, c'est pourquoi je n'en ai pas utilisé 15. Bien que le résultat soit le même, l'exigence ne mentionne pas 15 donc je l'ai complètement négligé. Dans mon cas, si c'était la raison, j'ai besoin de changer d'habitude. Merci pour le conseil, cela m'aidera dans le futur. –