Writing FizzBuzz - c#

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);
}

Related

Is a given number a prime or not, if not output all its divisors

The main part of my code is working, the only thing that doesn't work is the output of all its divisors. My result if it's not a prime should be like this:
Input -> 4
Output -> false 1 2 4
Console.WriteLine("Type your number: ");
int n = Convert.ToInt32(Console.ReadLine());
int a = 0, i;
for (i = 1; i <= n; i++)
{
if (n % i == 0)
{
a++;
}
}
if (a == 2)
{
Console.WriteLine("true");
}
else
{
Console.WriteLine("false" + i);
}
Console.ReadLine();
To print all the divisors, you'll need to gather them up in a collection of some sort – a list of integers, here.
In addition, all integers are divisible by 1, so you don't want to start there; neither do you want to end at n, since n % n == 0.
var divisors = new List<int>();
for (var i = 2; i < 2; i++)
{
if (n % i == 0)
{
divisors.Add(i);
}
}
if (divisors.Count == 0)
{
Console.WriteLine("true");
}
else
{
Console.WriteLine("false " + String.Join(" ", divisors));
}
Here is a working solution. You basically have to store your divisors somewhere or print them directly:
public static void Method(int n)
{
if (IsPrime(n))
{
Console.WriteLine($"{n} is a prime");
return;
}
var divisors = new List<int>();
for(var i = 1; i <= n; i++)
{
if (n % i == 0)
divisors.Add(i);
}
Console.WriteLine($"{n} isn't a prime");
Console.WriteLine($"The divisors are: {string.Join(", ", divisors)}");
}
public static bool IsPrime(int n)
{
for(var i = 2; i < n; i++)
{
if (n % i == 0)
return false;
}
return true;
}
From a brief inspection, there are two ways to generate the output. So far, you count the number of divisors, but neither store them nor write them to the output. You could replace
if (n % i == 0)
{
a++;
}
by
if (n % i == 0)
{
Console.WriteLine(i);
a++;
}
or store the divisors in a
List<int>
to generate the output afterwards.

How can i find if a number is prime with C#? [duplicate]

This question already has answers here:
Program to find prime numbers
(28 answers)
Closed 3 years ago.
I am having trouble with a problem that will tell me if a number is prime or not. I am passing every test but the random test. I am an entry level dev so it may not be pretty but I would like help on how to get this to pass a test even if the number is "1008985750798" for example...
public static bool IsPrime(int n)
{
bool returnMe = true;
if (n% 2 == 0 || n % 3 == 0 || n <= 1)
{
returnMe = false;
}
if (n % 2 == 0 && n % 3 == 0)
{
returnMe = false;
}
if ( n == 2 || n == 3 || n == 7)
{
returnMe = true;
While Program to find prime numbers shows a nice, efficient implementation I think you are after something that is easier to understand.
Here's a naive approach:
public static void Main()
{
for(uint i = 0; i < 1000; i++) {
if (IsPrime(i)) Console.Write($"{i},");
}
}
private static bool IsPrime(uint n)
{
if (n < 3) return false;
for (uint i = 2; i < n; i++)
if (n % i == 0) return false;
return true;
}
If you want to go a bit faster, let's ask Wikipedia for help.
/// <summary>
/// Tests the number for primality. It is a c# version of the pseudocode from
/// https://en.wikipedia.org/wiki/Primality_test
/// </summary>
private static bool IsPrime2(uint n)
{
// The following is a simple primality test in pseudocode using
// the simple 6k ± 1 optimization mentioned earlier.
// More sophisticated methods described below are much faster for large n.
if (n <= 3)
return n > 1;
if (n % 2 == 0 || n % 3 == 0)
return false;
uint i = 5;
while (i * i <= n)
{
if (n % i == 0 || n % (i + 2) == 0)
return false;
i = i + 6;
}
return true;
}

Input an Integer and get its prime factors and duplicates [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Prime Factors In C#
I am trying to get this coding to give me all the prime factors of the integer that is inputted, including its duplicates. I have this current code and it seems to be working sort of but it isn't showing all of it's prime factors and duplicates. Any help would be appreciated.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace _1_Numeric_Problem
{
class Program
{
static void Main(string[] args)
{
string myInput;
int myInt;
int p;
Console.WriteLine(("Please input an integer"));
myInput = Console.ReadLine();
myInt = Int32.Parse(myInput);
{
for (int i = 2; i > 1; i++)
{
if (i == 100000)
break;
if (myInt % i == 0)
{
if (i <= 3)
{
Console.Write("{0} ", i);
Console.ReadLine();
continue;
}
else
{
for (p = 2; p < i; p++)
if (i % p != 0)
{
Console.Write("{0} ", i);
Console.ReadLine();
return;
Console.ReadLine();
}
else
{
p++;
continue;
}
}
}
}
}
}
}
}
Try replacing the following code:
for (p = 2; p < i; p++) {
if (i % p != 0) {
Console.Write("{0} ", i);
Console.ReadLine();
return;
Console.ReadLine();
} else {
p++;
continue;
}
}
With this instead:
bool isPrime = true;
for (p = 2; p <= Math.Sqrt(i); p++) {
if (i % p == 0) {
isPrime = false;
break;
}
if (isPrime) {
Console.Write("{0} ", i);
Console.ReadLine();
}
}
Can't you just make a for loop like this?
for (int i = 2; i < myInt; i++)
{
if(myInt % i == 0)
//Do something with it.
}
The basic algorithm for integer factorization using trial division tries each potential factor starting from 2, and if it divides n, outputs the factor, reduces n, and searches for the next factor; note that f is not incremented if it divides n, since it might again divide the reduced n. The loop stops when f is greater than the square root of n, since at that point n must be prime. Here's the pseudocode:
function factors(n)
f := 2
while f * f <= n
if n % f == 0
output f
n := n / f
else
f := f + 1
output n
There are better ways to factor integers, but that should get you started. When you're ready for more, I modestly recommend this essay on my blog.

C# return and display syntax issue

I am having trouble passing the return value from TheMethod() to Main and displaying the word if the if statement is passed as true.
I have thought of two ways of doing this, neither has worked but I think I am missing synatx.
Using a return ?; non void method and then displaying the returned value.
Using a void method and actually writing out(example below)
So yes I am new at this, however I have made so many iterations everything is blending together and I have forgot what I have tried. Any help on the syntax be great for either of these ways.
Basically I need it to iterate numbers
1,2,3,4 and depending on if the current iteration matches an expression in the if statements it will display a word.
Example:
if (3 = i)
{
Console.WriteLine("Word");
}
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Proj5
{
class Program
{
int i = 0;
static void Main(int i)
{
for (i = 0; i < 101; i++)
{
Console.WriteLine("test");
}
}
string TheMethod(int i)
{
string f = "Word1";
string b = "Word2";
if (i == 3)
{
return f;
}
if (i == 5)
{
return b;
}
if (0 == (i % 3))
{
return f;
}
if (0 == i % 5)
{
return b;
}
else
{
return b;
}
}
}
}
Note: You don't need if i == 5 and a separate one for i % 5 == 0. % is "mod" which means the remainder after the division, so 5 / 5 = 1, there is no remainder so 5 mod 5 = 0...
Here is a rough guide/fix for you attempt at FizzBuzz:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Proj5
{
class Program
{
private static void Main()
{
for (int i = 0; i < 101; i++)
{
Console.WriteLine(TheMethod(i));
}
}
string TheMethod(int i)
{
string f = "Fizz";
string b = "Buzz";
if ((i % 3 == 0) && (i % 5 == 0))
{
return f+b;
}
if (i % 3 == 0)
{
return f;
}
if (i % 5 == 0)
{
return b;
}
return i.ToString();
}
}
}
However there are cleaner solutions:
string result = "";
for (int i = 1; i < = 101; ++i)
{
if ((i % 3 == 0) && (i % 5 == 0)) result += "FizzBuzz";
else if (i % 3 == 0) result += "Fizz";
else if (i % 5 == 0) result += "Buzz";
else result += i.ToString();
result += ", ";
}
Or, if you prefer LINQ-y Lambas:
public static void FizzBuzz()
{
Dictionary<Func<int, bool>, Func<int, string>> rules = new Dictionary<Func<int, bool>, Func<int, string>>();
rules.Add(x => x % 5 == 0 && x % 3 == 0, x => “fizzbuzz”);
rules.Add(x => x % 3 == 0, x => "fizz");
rules.Add(x => x % 5 == 0, x => "buzz");
rules.Add(x => x % 5 != 0 && x % 3 != 0, x => x.ToString());
rules.Add(x => true, x => "\n");
var output = from n in Enumerable.Range(1, 100)
from f in rules
where f.Key(n)
select f.Value(n);
output.ToList().ForEach(x => Console.Write(x));
}
You can't refer to non-static variables (i) and methods (TheMethod) from inside your static Main class. Try this:
class Program
{
static void Main()
{
for (int i = 0; i < 101; i++)
{
Console.WriteLine(TheMethod(i));
}
}
static string TheMethod(int i)
{
string f = "Word1";
string b = "Word2";
if (i%3 == 0) return f;
if (i%5 == 0) return b;
return b;
}
}

Largest Prime Factor algorithm optimization

I'm trying to improve this interesting algorithm as much as I can.
For now, I have this:
using System;
class Program
{
static void Main()
{
ulong num, largest_pFact;
uint i = 2;
string strNum;
Console.Write("Enter number: ");
strNum = Console.ReadLine();
num = ulong.Parse(strNum);
largest_pFact = num;
while (i < Math.Sqrt((double) largest_pFact))
{
if (i % 2 != 0 | i == 2) {
if (largest_pFact % i == 0)
largest_pFact /= i;
}
i++;
}
Console.WriteLine("Largest prime factor of {0} is: {1}", num, largest_pFact);
Console.ReadLine();
}
}
So any ideas?
Thanks!
EDIT: I implemented Ben's algorithm, thanks eveyone for your help!
I've got a faster algorithm here.
It eliminates the square root and handles repeated factors correctly.
Optimizing further:
static private ulong maxfactor (ulong n)
{
unchecked
{
while (n > 3 && 0 == (n & 1)) n >>= 1;
uint k = 3;
ulong k2 = 9;
ulong delta = 16;
while (k2 <= n)
{
if (n % k == 0)
{
n /= k;
}
else
{
k += 2;
if (k2 + delta < delta) return n;
k2 += delta;
delta += 8;
}
}
}
return n;
}
Here's a working demo: http://ideone.com/SIcIL
-Store Math.Sqrt((double) largest_pFact) in some variable, preferably a ulong. That avoids recalculating the function every pass through the loop, and integer comparison may be faster than floating-point comparisons. You will need to change the comparison to a <= though.
-Avoid looping on even numbers at all. Just include a special case for i=2, and then start with i at 3, incrementing by 2 on each loop. You can go even further by letting i=2,3 be special cases, and then only testing i = 6n+1 or 6n-1.
Well, first I would move the special case 2 out of the loop, there is no point in checking for that throughout the loop when it can be handled once. If possible use the data type int rather than uint, as it's generally faster:
if (largest_pFact % 2 == 0) {
largest_pFact /= 2;
}
int i = 3;
while (i < Math.Sqrt((double) largest_pFact)) {
if (i % 2 != 0) {
if (largest_pFact % i == 0) {
largest_pFact /= i;
}
}
i++;
}
The square root calculation is relatively expensive, so that should also be done beforehand:
if (largest_pFact % 2 == 0) {
largest_pFact /= 2;
}
int i = 3;
int sq = Math.Sqrt((double) largest_pFact);
while (i < sq) {
if (i % 2 != 0) {
if (largest_pFact % i == 0) {
largest_pFact /= i;
}
}
i++;
}
Then I would increment i in steps of two, to elliminate one modulo check:
if (largest_pFact % 2 == 0) {
largest_pFact /= 2;
}
int i = 3;
int sq = Math.Sqrt((double) largest_pFact);
while (i < sq) {
if (largest_pFact % i == 0) {
largest_pFact /= i;
}
i += 2;
}
To work, I believe that you need a while instead of an if inside the loop, otherwise it will skip factors that are repeated:
if (largest_pFact % 2 == 0) {
largest_pFact /= 2;
}
int i = 3;
int sq = Math.Sqrt((double) largest_pFact);
while (i < sq) {
while (largest_pFact % i == 0) {
largest_pFact /= i;
}
i += 2;
}
For one thing, you don't need to run Math.Sqrt on every iteration.
int root = Math.Sqrt((double) largest_pFact);
while (i < root)
{
if ((i % 2 != 0 | i == 2) && largest_pFact % i == 0) {
largest_pFact /= i;
root = Math.Sqrt((double) largest_pFact);
}
i++;
}
I think:
generate primes up to num/2
then check from largest to lowest if your num is divisible by the prime
would be faster.
edit num/2 NOT sqrt
It's always faster to look between sqrt(num) and 2 than it is to start at num/2. Every factor pair (besides the square-root one) has one number that is less than sqrt(num).
Ex: For 15, int(sqrt(15))==3
15/3=5, so you found the "5" factor by starting your testing at 3 instead of 7.

Categories