I'm using 3 iterators to iterate through an int[] object to find lists containing three int's that all sum to 0, without adding duplicate lists to the final return object. Once the iterators find a valid sequence, each array value that the iterator points to is added to a temporary IList object via syntax such as "tempList.Add(nums[a]);" e.t.c. This tempList is then added to the final IList<IList> return object.
To check for duplicates, I'm using the following sytax:
if ((nums[c] + nums[a] + nums[b] == 0) && !answerList.Contains(tempList))
{
answerList.Add(tempList);
}
This works when the IList<IList> is initially empty, however the second clause evaluated "false" for the following scenario, which is preventing the valid tempList from being added to the IList<IList> answerList :
IList<IList<int>> == [[-1,0,1]]
tempList == [-1,-1,2]
Do I need to extend a Comparable interface to correct this? I've double checked the array values for a, b and c and they collectively sum to 0, so I'm certain that it's the .Contains comparison that is causing issue.
Here is the code:
public IList<IList<int>> ThreeSum(int[] nums) // maybe use three index pointers to fill triplet, one starting at index 0, one
// starting at index nums.Lenght - 1 and one starting near or at middle
// 5 billion possible combinations of triplets among array of 3001 triplets
{
IList<int> tempList = new List<int>();
IList<IList<int>> answerList = new List<IList<int>>();
int countPositive = 0;
int countNegative = 0;
bool addAnswerList = false;
int indexPositive = 0;
int a = 0;
int b = 0;
int c = 0;
bool aExtreme = false;
bool bExtreme = false;
bool cExtreme = false;
if (nums == null)
return answerList;
if (nums.Length == 0 /* || /* nums.Length < 3 */)
return answerList;
if (nums.Length == 1 && nums[0] == 0)
return answerList;
for (int i = 0; i < nums.Length; i++) // corner case where all array values are either postive or negative
// 0 sum triplet not possible
{
if (nums[i] > 0)
countPositive++;
else if (nums[i] < 0)
countNegative++;
}
if ((countPositive == nums.Length || countNegative == nums.Length) || (countNegative == 0 && countPositive == 0))
return answerList;
if (nums.Length < 51)
{
int temp = 0;
for (int i = 1; i < nums.Length; i++) // use recursive sort to go through 3001 elements, use linear if less than 51
{
temp = nums[i];
int j = i;
while (j > 0 && nums[j-1] > temp)
{
nums[j] = nums[j-1];
j--;
}
nums[j] = temp;
}
Console.WriteLine(String.Join(" ", nums));
}
else if (nums.Length > 50) // recursive sort for larger input array
{
mergeSort(nums);
}
// Now nums is storted, 0 sum triplet will most likely be found where entries change from negative to positive
for (int i = 0; i < nums.Length; i++)
{
if (nums[i] > 0)
{
// toPositive = true;
indexPositive = i;
break;
}
}
Console.WriteLine(indexPositive);
if (indexPositive == 0) // case to make sure accessors do not get invalid number
{
a = 0; // initialize other two index accessors in addition to indexPositive
b = 0;
}
else
{
a = indexPositive - 1; // initialize other two index accessors in addition to indexPositive
b = indexPositive - 1;
}
c = indexPositive; // store initial indexPositive value into variable c as indexPositive will change
// throughtout the interation
// if indexPositive is less than (nums.Length / 2), iterate two other accessors towards end of nums
// else, interate two other accessors towards nums[0]
if (c < (nums.Length / 2)) // use iterator c in place of indexPositive
{
while (c < nums.Length && b < nums.Length && a >= 0)
{
if (a == 0 || a == nums.Length - 3)
{
aExtreme = true;
}
else
{
aExtreme = false;
}
if (b == 1 || b == nums.Length - 2)
{
bExtreme = true;
}
else
{
bExtreme = false;
}
if (c == 2 || c == nums.Length - 1)
{
cExtreme = true;
}
else
{
cExtreme = false;
}
if ((c != a && c != b && a != b) && (nums[c] + nums[a] + nums[b] == 0)) // if nums add to 0, add them to tempList
{
tempList.Add(nums[a]);
tempList.Add(nums[b]);
tempList.Add(nums[c]);
}
// need to check if exact triplet is duplicate or if tempList triplet contains same 3 values in different order
// 3 values in different order not an issues since input list is already sorted!!!!
// but need to be aware order accessors are added to temp list. Accessors cannot "crossover" one another!!!
if ((nums[c] + nums[a] + nums[b] == 0) && !answerList.Any(x => x.SequenceEqual(tempList)) /*!answerList.Contains(tempList)*/)
// Having issues, answerList.Contains does not currently do what is desired
{
answerList.Add(tempList); // add tempList to answerList
addAnswerList = true;
}
else
{
addAnswerList = false;
}
tempList.Clear(); // clear tempList to prepare for next entry
// Make changes here to make sure only 1 accessor iterates at a time, to check all possible and logical combinations
// Since array is now sorted, iteration towards sums[0] only has to continue if sum of 3 accessors is greater than 0
// Once active accessor returns a value that results in 0 sum, further iteration is guaranteed to return
// an identical triplet or one that sums to less than 0. At this point, the two accessors that are going in the same
// direction should be iterated by 1 position and the cycle repeated
if (nums[a] + nums[b] + nums[c] < 0) // still have chance to get to 0 value triplet with rightmost accessor
{
c++;
}
else if ((addAnswerList == true) || nums[a] + nums[b] + nums[c] > 0) // no point in further iteration,
// reset 'c' accessor to original starting
// position and decrement other accessors by 1
// towards first array element
{ // to begin cycle again
c = indexPositive - 1;
b--;
a--;
}
}
}
else // a and b accessors are interated towards 0
{
while (c < nums.Length && a >= 0 && b >= 0)
{
if (a == 0 || a == nums.Length - 3)
{
aExtreme = true;
}
else
{
aExtreme = false;
}
if (b == 1 || b == nums.Length - 2)
{
bExtreme = true;
}
else
{
bExtreme = false;
}
if (c == 2 || c == nums.Length - 1)
{
cExtreme = true;
}
else
{
cExtreme = false;
}
if ((c != a && c != b && a != b) && (nums[c] + nums[a] + nums[b] == 0)) // if nums add to 0, add them to tempList
// need to check if exact triplet is duplicate
{
tempList.Add(nums[a]);
tempList.Add(nums[b]);
tempList.Add(nums[c]);
}
Console.WriteLine(String.Join(" ", tempList));
// need to check if exact triplet is duplicate or if tempList triplet contains same 3 values in different order
// 3 values in different order not an issues since input list is already sorted!!!!
// but need to be aware order accessors are added to temp list. Accessors cannot "crossover" one another!!!
if ((nums[c] + nums[a] + nums[b] == 0) && !answerList.Any(x => x.SequenceEqual(tempList)))
// Having issues, answerList.Contains does not currently do what is desired
{
answerList.Add(tempList); // add tempList to answerList
addAnswerList=true;
}
else
{
addAnswerList = false;
}
tempList.Clear(); // clear tempList to prepare for next entry
// Make changes here to make sure only 1 accessor iterates at a time, to check all possible and logical combinations
// Since array is now sorted, iteration towards sums[0] only has to continue if sum of 3 accessors is greater than 0
// Once active accessor returns a value that results in 0 sum, further iteration is guaranteed to return
// an identical triplet or one that sums to less than 0. At this point, the two accessors that are going in the same
// direction should be iterated by 1 position and the cycle repeated
if (nums[a] + nums[b] + nums[c] > 0) // still have chance to get to 0 value triplet with
// leftmost accessor
{
a--;
}
else if ((addAnswerList == true) || nums[a] + nums[b] + nums[c] < 0) // no point in further iteration,
// reset 'a' accessor to original starting
// position and increment other accessors by 1
// towards last array element
{ // to begin cycle again
a = b; // a = indexPositive - 1;
if ((bExtreme == false && b < nums.Length - 2) && (cExtreme == false && c < nums.Length - 1))
// if there is still room to run towards end of array, increment, else decrement
{
b++;
c++;
}
else
{
bExtreme = true;
cExtreme = true;
a -= 2;
b--;
}
}
}
}
Console.WriteLine(String.Join(" ", answerList));
return answerList;
}
public void merge(int[] array1, int[] array2, int[] outArray)
{
int i = 0;
int j = 0;
while (i + j < outArray.Length)
{
if (j == array2.Length || (i < array1.Length && (array1[i] < array2[j])))
{
outArray[i + j] = array1[i++];
}
else
{
outArray[i + j] = array2[j++];
}
}
}
public void mergeSort(int[] inputArray)
{
if (inputArray.Length < 2)
return;
int[] firstHalf = new int[inputArray.Length / 2];
int[] secondHalf = new int[inputArray.Length / 2];
for (int i = 0; i < (inputArray.Length / 2); i++)
{
firstHalf[i] = inputArray[i];
}
for (int i = inputArray.Length / 2; i < inputArray.Length; i++)
{
secondHalf[i] = inputArray[i];
}
mergeSort(firstHalf);
mergeSort(secondHalf);
merge(firstHalf, secondHalf, inputArray);
}
You can replace
answerList.Contains(tempList))
which checks only for reference equality, with
answerList.Any(x => x.SequenceEqual(tempList))
which will run SequenceEqual on the answerList until it finds the first answer that has the same integer elements and returns false if none can be found.
Keep in mind that these functions require System.Linq.
Credit: thanks Hans Kesting for suggesting Any(...) over FirstOrDefault(...) != null
This is not the actual code but it's what I want to do.
for loop is must but the nested if else loop inside should be executed according to the value of count_final which can be random between 1 to 3.
Like if the value of count_final is 3, all if...else loop should be considered. but if the value of count_final is 2, then only if...(1st)else if and else part only be executed. And if count_final=1 then only if and else part is executed (not any else-if).
Thought of putting another if...else within every if...else and checking count_final, but what if I'm not getting values of count2 and count3 when count_final=1.
Same, when count_final=2, I'm not getting the value of count3.
Ask in comment if you don't understand my question.
int count_final=Session["abc"];
//count_final=1;
//count_final=2;
//count_final=3;
for(int i=1;i<=10;i++)
{
if ((count1 <= count5) && (count1 <= count6))
{
Label1.Text="Hello1";
}
else if (count2 <= count4 && count2 <= count6)
{
Label2.Text="Hello2";
}
else if (count3 <= count4 && count3 <= count5)
{
Label3.Text="Hello3";
}
else
{
Label1.Text="Hello1";
}
}
Seems you have collection of "conditions" where amount of executed conditions depend on value of finalCount.
var rules = new Func<string>[]
{
() => (count1 <= count5 && count1 <= count6) ? "Hello1" : null,
() => (count2 <= count4 && count2 <= count6) ? "Hello2" : null,
() => (count3 <= count4 && count3 <= count5) ? "Hello3" : null
};
Label1.Text = rules.Take(finalCount)
.Select(rule => rule())
.Where(result => result != null)
.DefaultIfEmpty("Hello1")
.First();
Of course this solution is assuming that finalCount is always 1, 2 or 3.
DefaultIfEmpty is playing role of last else - will be used all conditions fails.
if i understand right.. which is a little unlikely
just add more criteria to your ifs!
if ((count1 <= count5) && (count1 <= count6))
{
if (count_final == 3 || count_final == 2) Label1.Text="Hello1";
}
else if (count2 <= count4 && count2 <= count6)
{
if (count_final == 3) Label2.Text="Hello2";
}
else if (count3 <= count4 && count3 <= count5)
{
if (count_final == 3) Label3.Text="Hello3";
}
else
{
if (count_final == 3 || count_final == 1) Label1.Text="Hello1";
}
Remembering that from what I understood there will be loops in that can achieve nothing, eg, if count_final == 2 and its not less or equal to count5 or count6, nothing will happen, same as for count_final == 1, if it matches any of the first bits the last else wont happen.
I suggest extending the conditions of your else if statements:
int count_final=Session["abc"];
//count_final=1;
//count_final=2;
//count_final=3;
for(int i=1; i<=10; i++)
{
if ((count1 <= count5) && (count1 <= count6))
{
Label1.Text="Hello1";
}
else if (count_final >= 2 && count2 <= count4 && count2 <= count6)
{
Label2.Text="Hello2";
}
else if (count_final >= 3 && count3 <= count4 && count3 <= count5)
{
Label3.Text="Hello3";
}
else
{
Label1.Text="Hello1";
}
}
When count_final == 1 this will not try to evaluate count2, count3 or count4 (which I understand is a requirement) because && will not evaluate its right hand side when there is false on the left.
Is this what you are looking for? To use less if/else statements:
int count_final = Session["abc"]; // random between 1 and 3
for(int i=1; i <= 10; i++)
{
switch(count_final)
{
case 3:
Label1.Text="Hello1";
// no break; so all gets executed
case 2:
Label2.Text="Hello2";
case 1:
Label3.Text="Hello3";
default: Label1.Text="Hello1";
}
}
Reading the coding horror, I just came across the FizzBuzz another time.
The original post is here: Coding Horror: Why Can't Programmers.. Program?
For those who do not know:
FizzBuzz is a quite popular children's game. Counting from 1 to 100,
and every time a number is divisible by 3 the string "Fizz" is called, every time
a number is divisible by 5 the string "Buzz" is called and every time a number
is divisible by 3 and 5 both strings together "FizzBuzz" are called instead of the number.
This time, I wrote the code and it took me a minute,
but there are several things that I do not like.
Here is my 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);
}
}
So my questions are:
How do I get rid of the bool found?
Is there a better way of testing
than the foreach?
I think your implementation is unnecessarily complex. This one does the job and is easier to understand:
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);
}
}
Unrolled for maximum efficiency. This program can outfizzbuzz all others.
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;
}
}
Take advantage of conditional format specifiers to get a nicely golfed version:
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);
}
I think what you're trying to accomplish is a generic solution to FizzBuzz, that will work for any number of number-word combinations.
You have a good start - I think I can answer your questions with this example:
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);
}
}
In practice, you would pass combinations in to the method, but I included it inside just to be concise.
3rd edit:
Here is one way to "get rid of the bool" from your version (that is replace the for loop in your original question with this):
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);
}
Prior answers:
For a pure C# solution check out 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);
}
}
}
}
I worked a bit on FixBuzz using linq. These are the solutions I came up with -- I believe they represent the best way to express the solution to this problem using 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);
}
}
and the crazy one line version:
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);
}
}
This gets rid of the bool found, but forces you to do duplicate evaluation. It is slightly different from some of the other answers using i % 15 == 0 for the FizzBuzz qualification. Whether or not this is better is up for debate. However, it is a different way.
Did anyone do this one already?
Enumerable.Range(1, 100).Select(x =>
(x % 15 == 0) ? "FIZZBUZZ"
: (x % 5 == 0) ? "BUZZ"
: (x % 3 == 0) ? "FIZZ"
: x.ToString()
)
.ToList()
.ForEach(console.WriteLine);
I think you started with a complicated way. Improving that code would be more complicated. You can use a temp variable to track and display that variable at the end of the FizzBuzz check. Below is code and you can also watch this detail c# FizzBuzz youtube video ( http://www.youtube.com/watch?v=OX5TM3q-JQg ) which explains how the below code is implemented.
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
}
Will add my 5 cents to solution by Linq. Everybody is using Select, which is basically Map function. IMHO foldl function suits better to solve this 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()));
In my opinion, the FizzBuzz problem is always presented as a challenge to the interviwee to make the word FizzBuzz appear without explicitly printing it. Here is my solution in 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();
}
Not the most efficient, but here's one using C#-6 string interpolation:
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}"));
This answer has it all:
LINQ
Conditional formatting
String interpolation
All on a single line
Victory!
The FizzBuzz question is a great interview question. We have started using it in our interview process. It is astounding how many people cannot solve such a simple problem.
Keep in mind, the original blog post was eventually locked due to a flood of people posting more solutions. Hahaha.
Regardless, here is mine in 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;
}
Ok, what the heck, here's the solution I've come to like :)
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;
}
}
Obviously, this is not the fastest solution, but I like it because it emphasizes readability and makes the "FizzBuzz" case no longer a special case, but something that will happen naturally through the code path.
In the end, what I love most about this question whenever it comes up is that we get to see just how many different solutions ppl can come up with.
I am a beginner, here is my attempt:
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();
}
Is there anything wrong with my approach?
Mine seems a lot simpler than everyone's else approach so it must be wrong.
You want probably make it configurable, but the question is what should be made configurable - we don't know that. Maybe we should make configurable all the cycle (FizzBuzz has the cycle). Here is very small and fun version with configurable cycle:
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);
So if the strings or whole cycle should be changed it is easy to change. But you just don't know what to make configurable. Maybe condition will change: "for prime numbers print Pizz" and for this modification the solution by #ThomasLevesque is better, because it is easier to change.
I tried to solve this problem without looking at the answers.
It took me 3 hours to succeed. (I'm just a hobby programmer by the way so don't bash me hard please :))
This is my c# version solution:
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");
}
}
}
}
The null-coalescing operator is really useful:
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();
I recommend using the ++i instead of the i++ in a for loop because i++ requires a copy to be made ;)
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);
}
}
With the input of Rob H and Jacob Krall here is what I have at the moment.
Perhaps I will play around with that in future... just wanted to provide it.
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);
}
}
I would suggest this compact code as an addition to the previous simple and nice versions.
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);
}
A functional approach...
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())))));
Obviously this is a bit outside the spirit of the FizzBuzz challenge. But in my benchmark this was the fastest I could make it while single threaded and still terminating at 100. It is semi-unrolled and uses a StringBuilder. It is approximately three times faster than the standard approach.
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());
Relatively simple solution using a for loop.
No Linq or anything - just basic shorthand if statements
for(int x=1;x<101;x++)
Console.WriteLine(x%3==0?"Fizz"+(x%5==0?"Buzz":""):x%5==0?"Buzz":x+"");
The Linq solution which is a lot like csells (sans string interpolation) and fits on one line would be:
Enumerable.Range(1,100).ToList().ForEach(x=>Console.WriteLine(x%3==0?"Fizz"+(x%5==0?"Buzz":""):x%5==0?"Buzz":x+""));
I'll add mine even though there's 20 other solutions already written:
It goes like this....
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++
}
First solution I came up with. Simple, to the point and gets the job done. No need for bool.
This my effort mixing Func with IEnumerable
class Program
{
static void Main(string[] args)
{
foreach (var i in FizzBuzz(100))
{
Console.WriteLine(i);
}
}
private static IEnumerable<string> FizzBuzz(int maxvalue)
{
int count = 0;
//yield return count.ToString();
Func<int, string> FizzBuzz = (x) => ((x % 5 == 0 && x % 3 == 0) ? "FizzBuzz" : null);
Func<int, string> Buzz = (x) => ((x % 5 == 0) ? "Buzz" : null);
Func<int, string> Fizz = (x) => ((x % 3 == 0) ? "Fizz" : null);
Func<int, string> Number = (x) => x.ToString();
while (count < maxvalue)
{
count++;
yield return FizzBuzz(count) ?? Buzz(count) ?? Fizz(count) ?? Number(count);
}
}
}
The original questions were:
1.How to get rid of the bool found?
2.Is there a better way of testing than the foreach?
This gets rid of the bool and the foreach, and I think it's still readable.
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);
}
}
Who'd a thunk we'd be getting so excited about a simple kids game? :)
You can use either use this and only take the amount you want
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);
}
}
Or simply use this :
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);
With no if conditions, just one ternary operator.
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);
}