En lisant l'horreur du codage, je suis tombé sur le FizzBuzz une autre fois.
Le message original est ici: Coding Horror: Pourquoi les programmeurs ne peuvent-ils pas ... programmer?
Pour ceux qui ne connaissent pas: FizzBuzz est un jeu pour enfants très populaire. Compter de 1 à 100, .__ et chaque fois qu'un nombre est divisible par 3 en appelant "Fizz", chaque fois Un nombre est divisible par 5 en appelant "Buzz" et chaque fois un nombre est divisible par 3 et 5, en appelant "FizzBuzz au lieu du numéro
Mais cette fois, je viens de commencer à le coder. C'était un travail d'une minute, Mais il y a plusieurs choses que je n'aime pas.
Voici mon code
public void DoFizzBuzz()
{
var combinations = new Tuple<int, string>[]
{
new Tuple<int, string> (3, "Fizz"),
new Tuple<int, string> (5, "Buzz"),
};
for (int i = 1; i <= 100; ++i)
{
bool found = false;
foreach (var comb in combinations)
{
if (i % comb.Item1 == 0)
{
found = true;
Console.Write(comb.Item2);
}
}
if (!found)
{
Console.Write(i);
}
Console.Write(Environment.NewLine);
}
}
Donc mes questions sont:
Je pense que ce que vous essayez de réaliser est une solution générique à FizzBuzz, qui fonctionnera pour n’importe quel nombre de combinaisons nombre-mot.
Vous avez un bon départ - je pense pouvoir répondre à vos questions avec cet exemple:
public void DoFizzBuzz()
{
var combinations = new List<Tuple<int, string>>
{
new Tuple<int, string> (3, "Fizz"),
new Tuple<int, string> (5, "Buzz"),
};
Func<int, int, bool> isMatch = (i, comb) => i % comb == 0;
for (int i = 1; i <= 100; i++)
{
Console.Write(i);
var matchingCombs = combinations.Where(c => isMatch(i, c.Item1)).ToList();
if (matchingCombs.Any())
{
Console.Write(string.Join("", matchingCombs.Select(c => c.Item2)));
}
else
{
Console.Write(i);
}
Console.Write(Environment.NewLine);
}
}
En pratique, vous transmettriez combinations
à la méthode, mais je l’ai incluse à l’intérieur pour être juste.
Je pense que votre mise en œuvre est inutilement complexe. Celui-ci fait le travail et est plus facile à comprendre:
public void DoFizzBuzz()
{
for (int i = 1; i <= 100; i++)
{
bool fizz = i % 3 == 0;
bool buzz = i % 5 == 0;
if (fizz && buzz)
Console.WriteLine ("FizzBuzz");
else if (fizz)
Console.WriteLine ("Fizz");
else if (buzz)
Console.WriteLine ("Buzz");
else
Console.WriteLine (i);
}
}
Tirez parti des spécificateurs de format conditionnels pour obtenir une version bien jouée:
public void DoFizzBuzz()
{
for(int i=1;i<101;i++)Console.WriteLine("{0:#;}{1:;;Fizz}{2:;;Buzz}",i%3*i%5==0?0:i,i%3,i%5);
}
Déroulé pour une efficacité maximale. Ce programme peut outfizzbuzz tous les autres.
public void FizzBuzz()
{
const string FIZZ = "Fizz";
const string BUZZ = "Buzz";
const string FIZZBUZZ = "FizzBuzz";
int i = 0;
while (i < 150)
{
Console.WriteLine(++i);
Console.WriteLine(++i);
Console.WriteLine(FIZZ); ++i;
Console.WriteLine(++i);
Console.WriteLine(BUZZ); ++i;
Console.WriteLine(FIZZ); ++i;
Console.WriteLine(++i);
Console.WriteLine(++i);
Console.WriteLine(FIZZ); ++i;
Console.WriteLine(BUZZ); ++i;
Console.WriteLine(++i);
Console.WriteLine(FIZZ); ++i;
Console.WriteLine(++i);
Console.WriteLine(++i);
Console.WriteLine(FIZZBUZZ); ++i;
}
}
3ème édition:
Voici un moyen de "supprimer le booléen" de votre version (c'est-à-dire remplacer la boucle for dans votre question initiale par ceci):
for (int i = 1; i <= 100; i++)
{
var x = combinations.Where(n => i % n.Item1 == 0);
if (x.Count() == 0)
Console.Write(i);
else
Console.Write(string.Join("",x.Select(e => e.Item2)));
Console.Write(Environment.NewLine);
}
Réponses antérieures:
Pour une solution C # pure, consultez Keith Thompson's solution.
using System;
class FizzBuzz {
static void Main() {
for (int n = 1; n <= 100; n ++) {
if (n % 15 == 0) {
Console.WriteLine("FizzBuzz");
}
else if (n % 3 == 0) {
Console.WriteLine("Fizz");
}
else if (n % 5 == 0) {
Console.WriteLine("Buzz");
}
else {
Console.WriteLine(n);
}
}
}
}
J'ai travaillé un peu sur FixBuzz en utilisant linq. Ce sont les solutions que j'ai proposées - je pense qu'elles représentent le meilleur moyen d'exprimer la solution à ce problème en utilisant Linq. ( GitHub )
using System;
using System.Linq;
class FizzBuzz {
static void Main() {
var list = Enumerable.Range(1,100)
.Select(n => {
if (n % 15 == 0) {
return "FizzBuzz";
}
if (n % 3 == 0) {
return "Fizz";
}
if (n % 5 == 0) {
return "Buzz";
}
return n.ToString();
});
foreach(string item in list)
Console.WriteLine(item);
}
}
et la folle version à une ligne:
using System;
using System.Linq;
class FizzBuzz {
static void Main() {
Console.WriteLine(
String.Join(
Environment.NewLine,
Enumerable.Range(1, 100)
.Select(n => n % 15 == 0 ? "FizzBuzz"
: n % 3 == 0 ? "Fizz"
: n % 5 == 0 ? "Buzz"
: n.ToString())
));
}
}
public void DoFizzBuzz()
{
for (int i = 1; i <= 100; i++)
{
if (i % 3 == 0)
Console.Write("Fizz");
if (i % 5 == 0)
Console.Write("Buzz");
if (!(i % 3 == 0 || i % 5 == 0))
Console.Write(i);
Console.Write(Environment.NewLine);
}
}
Cela supprime le bool found
, mais vous oblige à effectuer une évaluation en double. Il est légèrement différent des autres réponses utilisant i % 15 == 0
pour la qualification FizzBuzz. Que ce soit ou non meilleur est à débattre. Cependant, c'est une différente manière.
Est-ce que quelqu'un a déjà fait celui-ci?
Enumerable.Range(1, 100).Select(x =>
(x % 15 == 0) ? "FIZZBUZZ"
: (x % 5 == 0) ? "BUZZ"
: (x % 3 == 0) ? "FIZZ"
: x.ToString()
)
.ToList()
.ForEach(console.WriteLine);
Ajoutera mes 5 cents à la solution de Linq. Tout le monde utilise Select, qui est essentiellement une fonction de la carte. Fonction IMHO foldl convient mieux pour résoudre ce quiz:
Console.WriteLine(
Enumerable
.Range(1, 100)
.Aggregate(new StringBuilder(), (builder, i)
=> i % 15 == 0 ? builder.AppendLine("FizzBuzz")
: i % 3 == 0 ? builder.AppendLine("Fizz")
: i % 5 == 0 ? builder.AppendLine("Buzz")
: builder.AppendLine(i.ToString()))
.ToString());
Linq:
Enumerable.Range(1, 100).ToList().ForEach(i => Console.WriteLine( i % 3 * i % 5 == 0 ? (i % 3 == 0 ? "Fizz" : "") + (i % 5 == 0 ? "Buzz" : "") : i.ToString()));
Je pense que vous avez commencé avec une manière compliquée. Améliorer ce code serait plus compliqué. Vous pouvez utiliser une variable temp pour suivre et afficher cette variable à la fin de la vérification FizzBuzz. Ci-dessous le code et vous pouvez également regarder ce détail c # vidéo youtube FizzBuzz ( http://www.youtube.com/watch?v=OX5TM3q-JQg ) qui explique comment le code ci-dessous est implémenté.
for (int j = 1; j <= 100; j++)
{
string Output = "";
if (j % 3 == 0) Output = "Fizz";// Divisible by 3 --> Fizz
if (j % 5 == 0) Output += "Buzz"; // Divisible by 5 --> Buzz
if (Output == "") Output = j.ToString(); // If none then --> number
Console.WriteLine(Output); // Finally print the complete output
}
Pas le plus efficace, mais en voici un qui utilise l’interpolation C # -6 string :
void Main()
{
for (int i = 1; i <= 100; i++)
{
Console.WriteLine($"{(i % 15 == 0 ? "FizzBuzz" :
i % 3 == 0 ? "Fizz" :
i % 5 == 0 ? "Buzz" : i.ToString())}");
}
}
Enumerable.Range(1, 100).ToList().ForEach(i=>Console.WriteLine($"{(i%3*i%5==0?0:i):#;}{i%3:;;Fizz}{i%5:;;Buzz}"));
Cette réponse a tout:
La victoire!
Ok, bon sang, voici la solution que je viens d'aimer :)
public void DoFizzBuzz()
{
for (int i = 1; i <= 100; ++i)
{
bool isDivisibleByThree = i % 3 == 0;
bool isDivisibleByFive = i % 5 == 0;
if (isDivisibleByThree || isDivisibleByFive)
{
if (isDivisibleByThree)
cout << "Fizz";
if (isDivisibleByFive)
cout << "Buzz";
}
else
{
cout << i;
}
cout << endl;
}
}
Évidemment, ce n’est pas la solution la plus rapide, mais j’aime bien parce qu’elle met l’accent sur la lisibilité et fait du cas "FizzBuzz" un cas à part, mais quelque chose qui se produira naturellement à travers le chemin du code.
En fin de compte, ce que j'aime le plus à propos de cette question, quand elle se pose, c'est de voir combien de solutions différentes peuvent être trouvées.
Vous voulez probablement le rendre configurable, mais la question est de savoir ce qui devrait être rendu configurable - nous ne le savons pas. Peut-être devrions-nous rendre configurable tout le cycle (FizzBuzz a le cycle). Voici une version très petite et amusante avec cycle configurable:
string[] fizzBuzzCycle =
"FizzBuzz,{0},{0},Fizz,{0},Buzz,Fizz,{0},{0},Fizz,Buzz,{0},Fizz,{0},{0}"
.Split(',');
for (int i = 1; i <= 100; i++)
Console.WriteLine(fizzBuzzCycle[i%fizzBuzzCycle.Length], i);
Donc, si les chaînes ou tout le cycle doivent être changés, il est facile de changer. Mais vous ne savez tout simplement pas quoi rendre configurable. Peut-être que la condition va changer: "pour les nombres premiers, imprimer Pizz" et pour cette modification, la solution de @ThomasLevesque est préférable, car elle est plus facile à modifier.
J'ai essayé de résoudre ce problème sans regarder les réponses ..__ Il m'a fallu 3 heures pour réussir. (Je suis juste un programmeur amateur, alors ne me punissez pas trop fort s'il vous plait))
static void Main(string[] args)
{
for (int i = 1; i <= 100; i++)
{
if( ((i % 3) != 0) && ((i % 5) != 0))
{
WriteLine($"{i}");
}
else
{
if ((i % 15) == 0)
{
WriteLine("FizzBuzz");
}
else if ((i % 3) == 0)
{
WriteLine("Fizz");
}
else if ((i % 5) == 0)
{
WriteLine("Buzz");
}
}
}
}
Je suis débutant, voici ma tentative:
public void DoFizzBuzz()
{
for (int i = 1; i < 101; i++)
{
if ((i % 3 == 0) && (i % 5 == 0))
{
Console.WriteLine("{0} FizzBuzz", i);
}
else if (i % 3 == 0)
{
Console.WriteLine("{0} Fizz", i);
}
else if (i % 5 == 0)
{
Console.WriteLine("{0} Buzz", i);
}
else
{
Console.WriteLine(i);
}
}
Console.ReadLine();
}
Y a-t-il un problème avec mon approche? Le mien semble beaucoup plus simple que l'approche de tout le monde, alors ça doit être faux.
Une approche fonctionnelle ...
Console.WriteLine(Enumerable
.Range(1,100)
.Aggregate("",
(a,i) => a + "\n" + (i%15==0 ? "fizzbuzz" :
(i%5==0 ? "buzz" :
(i%3==0 ? "fizz" : i.ToString())))));
Solution relativement simple utilisant une boucle for.
Pas de Linq ou quoi que ce soit - juste un raccourci de base si les déclarations
for(int x=1;x<101;x++)
Console.WriteLine(x%3==0?"Fizz"+(x%5==0?"Buzz":""):x%5==0?"Buzz":x+"");
La solution Linq qui ressemble beaucoup à csells (sans interpolation de chaîne) et s'adapte sur une seule ligne serait:
Enumerable.Range(1,100).ToList().ForEach(x=>Console.WriteLine(x%3==0?"Fizz"+(x%5==0?"Buzz":""):x%5==0?"Buzz":x+""));
À mon avis, le problème de FizzBuzz est toujours présenté comme un défi pour l'interviewé de faire apparaître le mot FizzBuzz sans l'avoir explicitement imprimé. Voici ma solution en C #.
internal void PrintFizzBuzzAlternative(int num)
{
if (num % 5 == 0)
Console.Write("Fizz");
if (num % 3 == 0)
Console.Write("Buzz");
if (num % 5 != 0 && num % 3 != 0)
Console.Write(num);
Console.WriteLine();
}
J'ajouterai le mien même s'il y a déjà 20 autres solutions écrites:.
var x = 1;
while (x <= 100)
{
if (x % 3 == 0 && x % 5 == 0)
{Console.Writeline("FizzBuzz");}
else if (x % 3 == 0)
{Console.Writeline("fizz");}
else if (x % 5 == 0)
{Console.Writeline("Buzz");}
else
{Console.Writeline(x);}
x++
}
Première solution que je suis venu avec. Simple, au point et fait le travail. Pas besoin de bool.
L'opérateur null-coalescing est vraiment utile:
string output = null;
for (int i = 1; i <= 100; i++)
{
if (i % 3 == 0) output += "fizz";
if (i % 5 == 0) output += "buzz";
Console.WriteLine(output ?? i.ToString());
output = null;
}
Console.ReadKey();
Avec les contributions de Rob H et de Jacob Krall, voici ce que j’ai pour le moment… .. Peut-être que je vais jouer avec cela à l’avenir… je voulais juste le fournir.
public void DoFizzBuzz()
{
// expect this to come in as parameter
var combinations = new Tuple<int, string>[]
{
new Tuple<int, string> (3, "Fizz"),
new Tuple<int, string> (5, "Buzz"),
};
Func<int, int, bool> isMatch = (i, comb) => i % comb == 0;
// expect the borders 1, 100 to come in as parameters
for (int i = 1; i <= 100; ++i)
{
var matchingCombs = combinations.Where(c => isMatch(i, c.Item1)).DefaultIfEmpty(new Tuple<int, string>(i, i.ToString())).Aggregate((v, w) => new Tuple<int, string>(v.Item1, v.Item2 + w.Item2)).Item2;
Console.WriteLine(matchingCombs);
}
}
Je suggérerais ce code compact comme un ajout aux versions précédentes simple et Nice.
for (int i = 1; i <= 100; i++) // i++ but not ++i as in your example, be careful here
{
bool fizz = i % 3 == 0;
bool buzz = i % 5 == 0;
string output = fizz && buzz ? "FizzBuzz" :
fizz ? "Fizz" :
buzz ? "Buzz" :
i.ToString();
Console.WriteLn(output);
}
La question FizzBuzz est une excellente question d’entrevue. Nous avons commencé à l'utiliser dans notre processus d'entrevue. C'est stupéfiant combien de personnes ne peuvent pas résoudre un problème aussi simple.
N'oubliez pas que le billet de blog original a finalement été verrouillé en raison de l'afflux de personnes postant davantage de solutions. Hahaha.
Quoi qu'il en soit, voici le mien en C++! ^ _ ^
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
for (int i = 1; i <= 100; ++i)
{
bool isMultipleOfThree = (i % 3) == 0;
bool isMultipleOfFive = (i % 5) == 0;
if (isMultipleOfThree) cout << "Fizz";
if (isMultipleOfFive) cout << "Buzz";
if (!isMultipleOfThree && !isMultipleOfFive) cout << i;
cout << '\n';
}
return 0;
}
Évidemment, cela est un peu en dehors de l'esprit du défi FizzBuzz. Mais dans mon cas-test, c’était le plus rapide que j’ai pu réaliser avec un seul thread et se terminant toujours à 100. Il est semi-déroulé et utilise une StringBuilder
. Il est environ trois fois plus rapide que l'approche standard.
const string FIZZ = " Fizz\n";
const string BUZZ = " Buzz\n";
const string FIZZBUZZ = " FizzBuzz\n";
...
var sb = new StringBuilder();
int i = 0;
while(true)
{
sb.Append(i+3);
sb.Append(FIZZ);
sb.Append(i+5);
sb.Append(BUZZ);
sb.Append(i+6);
sb.Append(FIZZ);
sb.Append(i+9);
sb.Append(FIZZ);
sb.Append(i+10);
sb.Append(BUZZ);
if(i+12 > 100)
break;
sb.Append(i+12);
sb.Append(FIZZ);
i+=15;
sb.Append(i);
sb.Append(FIZZBUZZ);
}
Console.Write(sb.ToString());
Vous pouvez utiliser soit utiliser ceci et ne prendre que le montant que vous voulez
static void Main(string[] args)
{
GetFizzBuzz().Take(100).ToList().ForEach(Console.WriteLine);
}
private static IEnumerable<string> GetFizzBuzz()
{
for (var i = 0; i < int.MaxValue; i++)
{
if (i % 3 == 0 && i % 5 == 0) yield return "FizzBuzz";
if (i % 3 == 0) yield return "Fizz";
yield return i % 5 == 0 ? "Buzz" : i.ToString(CultureInfo.InvariantCulture);
}
}
Ou simplement utiliser ceci:
Enumerable.Range(1, 100).Select(s => {
if (s % 3 == 0 && s % 5 == 0) return "FizzBuzz";
if (s % 3 == 0) return "Fizz";
return s%5 == 0 ? "Buzz" : s.ToString(CultureInfo.InvariantCulture);
}).ToList().ForEach(Console.WriteLine);
Sans conditions si, seulement un opérateur ternaire.
string[] s = new string[6]{"Fizz", "Buzz", "", "", "", ""};
for (int i = 1; i <= 100; i++)
{
string output = s[(i%3)*2] + s[(i%5)+1];
Console.WriteLine(string.IsNullOrEmpty(output)? "" + i : output);
}
Les questions initiales étaient: 1.Comment se débarrasser du booléen trouvé? 2. Existe-t-il un meilleur moyen de tester que le foreach?
Cela supprime le bool et le foreach, et je pense que c'est toujours lisible.
public static void DoFizzBuzz()
{
var combinations = new Tuple<int, string>[]
{
new Tuple<int, string> (3, "Fizz"),
new Tuple<int, string> (5, "Buzz"),
};
for (int i = 1; i <= 100; i++)
{
var fb = combinations.Where(t => {
if (i % t.Item1 == 0)
{
Console.Write(t.Item2);
return true;
}
return false;
}).ToList();
if (!fb.Any())
{
Console.Write(i);
}
Console.Write(Environment.NewLine);
}
}
Qui aurait pu nous exciter à l'idée d'un jeu simple? :)
Je recommande d'utiliser ++ i au lieu de i ++ dans une boucle for car i ++ nécessite une copie;)
public void DoFizzBuzz()
{
for (int i = 1; i < 101; ++i)
{
if (i % 15 == 0)
Console.WriteLine ("FizzBuzz");
else if (i % 3 == 0)
Console.WriteLine ("Fizz");
else if (i % 5 == 0)
Console.WriteLine ("Buzz");
else
Console.WriteLine (i);
}
}
Trouvé Stringbuilder pour être le plus rapide.
Je trouve cette implémentation la plus facile à lire.
public static void FizzBuzz() {
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 100; i++) {
if (i % 3 == 0 && i % 5 == 0) {
sb.AppendLine($"{i} - FizzBuzz");
} else if (i % 3 == 0) {
sb.AppendLine($"{i} - Fizz");
} else if (i % 5 == 0) {
sb.AppendLine($"{i} - Buzz");
} else {
sb.AppendLine($"{i}");
}
}
Console.WriteLine(sb);
}
In C#...
using System;
using System.IO;
class Solution {
static void Main(String[] args) {
for(int i=1;i<=100;i++)
{
string result=(i%3==0 && i%5==0) ? "FizzBuzz" :
(i%5==0) ? "Buzz" :
(i%3==0) ? "Fizz" : i.ToString();
Console.WriteLine(res);
}
}
}
In VB.NET...
Imports System
Imports System.IO
Class Solution
Private Shared Sub Main(ByVal args As String())
For i As Integer = 1 To 100
Dim res As String = If((i Mod 3 = 0 AndAlso i Mod 5 = 0), "FizzBuzz", If((i Mod 5 = 0), "Buzz", If((i Mod 3 = 0), "Fizz", i.ToString())))
Console.WriteLine(res)
Next
End Sub
End Class
Été répondu à mort mais juste pour montrer une autre solution qui répond à la question
public static void DoFizzBuzz()
{
var combinations = new (int multiple, string output)[]
{
(3, "Fizz"),
(5, "Buzz")
};
for (int i = 1; i <= 100; ++i)
{
// Seed the accumulation function with an empty string and add any 'matches' from each combination
var fb = combinations.Aggregate("", (c, comb) => c + (i % comb.multiple == 0 ? comb.output : ""));
Console.WriteLine(!string.IsNullOrEmpty(fb) ? fb : $"{i}");
}
}
C'est une réponse écrite en JavaScript
//returns true if modulus is zero and is reusable
var isModulusZero = (challenge, modulator) => {
let answer = challenge % modulator;
if (answer == 0) {
return true
} else {
return false
}
}
var printOneToHundred = () => {
var i = 1;
for (i; i <= 100; i++) {
if (isModulusZero(i, 3) && isModulusZero(i, 5)) {
console.log('FizzBuzz')
} else if (isModulusZero(i, 3)) {
console.log('Fizz')
} else if (isModulusZero(i, 5)) {
console.log('Buzz')
} else {
console.log(i)
}
}
}
Implémentation C++
vector<string> FizzBuzz::execute(int n) {
if(n == 0)
return vector<string>();
auto Push = n % 15 == 0 ? "fizzbuzz" :
n % 3 == 0 ? "fizz" :
n % 5 == 0 ? "buzz" :
to_string(n);
auto execution = execute(n-1);
execution.Push_back(Push);
return execution;
}
Sans utiliser de If, code C #.
//False = 0, True = 1.
private void DivisibilityByFiveThreeTest(int num)
{
string[,] values = new string [2,2]{
{"None","Fizz"},
{"Buzz","FizzBuzz"}
};
for(int i=1;i< num;i++)
Console.WriteLine(values[Convert.ToInt32(i % 5 == 0), Convert.ToInt32(i%3==0)]);
}
solution simple en JavaScript
var i = 1;
while (i <= 100){
console.log((i % 3 === 0 && i % 5 === 0) ? "FizzBuzz" : (i % 3 === 0) ? "Fizz" : (i % 5 === 0 ? "Buzz" : i));
i++;
}