How can i reudce the number if if statments to 2 [duplicate] - c#

This question already has answers here:
Writing FizzBuzz
(47 answers)
Closed 5 years ago.
how do I reduce the number of if statements in this code
for (int i = 1; i < number;i++)
{
if ( i % 3 == 0 && i % 5 != 0)
{
Console.WriteLine(i + " Fizz");
}
else if (i % 5 == 0 && i % 3 != 0)
{
Console.WriteLine(i + " Buzz");
}
else if(i % 3 == 0 && i % 5 == 0)
{
Console.WriteLine(i + " FizzBuzz");
}
else
{
Console.WriteLine(i);
}
}

You could do the following:
for (int i = 1; i < number;i++)
{
Console.WriteLine(string.Format("{0} {1}{2}", i, i % 3 == 0 ? "Fizz":"", i % 5 == 0 ? "Buzz":"");
}
And use no if ;-)

for (int i = 1; i < number;i++)
{
string result = i + " ";
if ( i % 3 == 0)
{
result += "Fizz";
}
if (i % 5 == 0)
{
result += "Buzz";
}
Console.WriteLine(result);
}
This would display for example 1_, 3 Fizz, 5 Buzz, 15 FizzBuzz.
See the javascript equivalent code snippet below :
var number = 20;
for (var i = 1; i < number;i++)
{
var result = i + " ";
if (i % 3 == 0)
{
result += "Fizz";
}
if (i % 5 == 0)
{
result += "Buzz";
}
document.write(result+"<br>");
}

Variables and the conditional operator can help to make code more readable:
for (int i = 1; i < number;i++)
{
bool isMod3 = i % 3 == 0;
bool isMod5 = i % 5 == 0;
string fizz = isMod3 ? "Fizz" : "";
string buzz = isMod5 ? "Buzz" : "";
string result = $"{i} {fizz}{buzz}";
Console.WriteLine(result);
}
Here's another approach that works with even more values(theoretically umlimited):
var modDict = new Dictionary<int, string> { { 3, "Fizz" }, { 5, "Buzz" } };
for (int i = 1; i < number; i++)
{
string text = string.Join("", modDict.Select(kv => i % kv.Key == 0 ? kv.Value : ""));
Console.WriteLine(i + " " + text);
}

you can try conditional operators.
(i % 3 == 0)
? (i % 5 == 0)
? Console.WriteLine(i + " FizzBuzz")
: Console.WriteLine(i + " Fizz");
: (i % 5 == 0)
? Console.WriteLine(i + " Buzz");
: Console.WriteLine(i);

Try:
string str;
for (int i = 1; i < number; i++)
{
str = i + " ";
if (i % 3 == 0)
str += "Fizz";
if (i % 5 == 0)
str += "Buzz";
Console.WriteLine(str.Trim());
}

We can do like below, but it is not good for readability
for (int i = 1; i < number; i++)
{
var x = i % 3 == 0;
var y = i % 5 == 0;
string istr = i.ToString();
string a = x ? (y ? istr + " FizzBuzz"
: istr + " Fizz")
: (y ? istr + " Buzz"
: istr);
Console.WriteLine(a);
}

string output = i % 3 == 0
? ( i % 5 != 0 ? $"{i} Fizz" : $"{i} FizzBuzz" )
: i % 5 == 0 && i % 3 != 0
? $"{i} Buzz"
: i.ToString();
Console.WriteLine( output );

Related

find common substrings in 2 string in c#

I have strings like:
1) Cookie:ystat_tw_ss376223=9_16940400_234398;
2) Cookie:zynga_toolbar_fb_uid=1018132522
3) GET /2009/visuels/Metaboli_120x600_UK.gif HTTP/1.1
4) GET /2010/07/15/ipad-3hk-smv-price-hk/ HTTP/1.1
1 ad 2 have common substtring{cookie:}
3 and 4 have common substtring{GET /20, HTTP/1.1}
I want to find all common substrings that have the length more than three characters(contain space character) between 2 strings.(like 1 and 2)
i want to code in c#. i have a program but it has some problems.
Could anyone help me?
public static string[] MyMCS2(string a, string b)
{
string[] st = new string[100];
// List<string> st = new List<string>();
List<char> f = new List<char>();
int ctr = 0;
char[] str1 = a.ToCharArray();
char[] str2 = b.ToCharArray();
int m = 0;
int n = 0;
while (m < str1.Length)
{
for (n = 0; n < str2.Length; n++)
{
if (m < str1.Length)
{
if (str1[m] == str2[n])
{
if ((m > 1) && (n > 1) &&(str1[m - 1] == str2[n - 1]) && (str1[m - 2] == str2[n - 2]))
{
//f[m]= str1[m];
f.Add(str1[m]);
char[] ff = f.ToArray();
string aaa = new string(ff);
if (aaa.Length >= 3)
{
st[ctr] = aaa + "()";
//st.Add(aaa);
ctr++;
}
kk = m;
m++;
}
else if ((n == 0) ||(n == 1))
{
f.Add(str1[m]);
kk = m;
m++;
}
else
f.Clear();
}
//else if ((str1[m] == str2[n]) && (m == str1.Length - 1) && (n == str2.Length - 1))
//{
// f.Add(str1[m]);
// char[] ff = f.ToArray();
// string aaa = new string(ff);
// if (aaa.Length >= 3)
// {
// st[ctr] = aaa;
// ctr++;
// }
// // m++;
//}
else if ((str1[m] != str2[n]) && (n == (str2.Length - 1)))
{
m++;
}
else if ((m > 1) && (n > 1) && (str1[m] != str2[n]) && (str1[m - 1] == str2[n - 1]) && (str1[m - 2] == str2[n - 2]) && (str1[m - 3] == str2[n - 3]))
{
//
char[] ff = f.ToArray();
string aaa = new string(ff);
if (aaa.Length >= 3)
{
st[ctr] = aaa + "()" ;
//st.Add(aaa);
ctr++;
f.Clear();
}
//f.Clear();
//for (int h = 0; h < ff.Length; h++)
//{
// f[h] = '\0';
//}
}
else if (str1[m] != str2[n])
continue;
}
}
}
//int gb = st.Length;
return st;
}
This is an exact matching problem not a substring. You can solve it with aho-corasick algorithm. Use the first string and compute a finite state machine. Then process the search string. You can extend the aho-corasick algorithm to use a wildcard and search also for substrings. You can try this animated example: http://blog.ivank.net/aho-corasick-algorithm-in-as3.html

Fizz buzz program wierd output?

Why does this result in 1 2 Fizz 3 ? Shouldn't it result in 1 2 Fizz?! I'am a little confused with the output of this loop..? Adding else if removes this problem,my question is why?
for (int i = 1; i <= value; i++)
{
if (i % 3 == 0)
{
ViewBag.Output += "Fizz ";
}
if (i % 5 == 0)
{
ViewBag.Output += "Buzz ";
}
else
{
ViewBag.Output += i.ToString() + " ";
}
}
You are not skipping iteration if first if matches. Thus you have else part of i % 5 if block evaluated when current i is not divided by 5:
for (int i = 1; i <= value; i++)
{
if (i % 3 == 0)
ViewBag.Output += "Fizz ";
if (i % 5 == 0)
ViewBag.Output += "Buzz ";
if ((i % 3 != 0) && (i % 5 != 0))
ViewBag.Output += i.ToString() + " ";
}
Alternative solution which uses common else block as you have it now:
for (int i = 1; i <= value; i++)
{
if (i % 3 == 0)
{
ViewBag.Output += "Fizz ";
if (i % 5 == 0)
ViewBag.Output += "Buzz ";
}
else if (i % 5 == 0)
{
ViewBag.Output += "Buzz "
}
else // neither divided by 3 nor by 5
{
ViewBag.Output += i.ToString() + " ";
}
}
And one more solution with dictionary, to avoid all this additional if...else checks:
var valuesToCheck = new Dictionary<int, string> {
{ 3, "Fizz" },
{ 5, "Buzz" }
};
for (int i = 1; i <= value; i++)
{
bool divisorFound = false;
foreach(var kvp in valuesToCheck)
{
if (i % kvp.Key == 0)
{
divisorFound = true;
ViewBag.Output += kvp.Value + " ";
}
}
if (!divisorFound)
ViewBag.Output += i + " ";
}
It is because your second if is evaluated, no matter the result of the first if.
So when i == 3, the first if evaluates to true and the second to false, and therefore the second if's else block is executed.
The second if is executed, regardless of the preceeding if so, the output you experience should be expected.
Here's a simple solution to the FizzBuzz problem lifted from a #KonradRudolph answer to a previous question
for (int i = 1; i <= value; i++)
ViewBag.Output +=
i % 15 == 0 ? "FizzBuzz " :
i % 3 == 0 ? "Fizz " :
i % 5 == 0 ? "Buzz " :
i.ToString() + " ";
or, alternatively.
string FizzBuzz(int value, int a = 3, int b = 5)
{
if value % (a * b) == 0 return "FizzBuzz";
if value % a == 0 return "Fizz";
if value % b == 0 return "Buzz";
return value.ToString();
}
used with,
viewBag.Output = string.Join(" ", Enumerable.Range(1, value).Select(FizzBuzz));
or, going beyond reason
IEnumerable<string> Checker<T>(
this IEnumerable<T> source,
params KeyValuePair<Predicate<T>, string>>[] checks)
(
var found = false;
foreach(var t int source)
{
var result =
string.Concat(checks.Where(c => c.Key(t)).Select(c => c.Value));
if (result.IsNullOrEmpty())
{
yield return t.ToString();
continue;
}
yield return result;
}
)
which could be used like this,
ViewBag.Output = string.Join(" ", Enumerable.Range(1, value).Checker(
new KeyValuePair<Predicate<T>, string>>(i => i % 3 == 0, "Fizz"),
new KeyValuePair<Predicate<T>, string>>(i => i % 5 == 0, "Buzz"));

Checking for prime number - C# logic

Here is a snippet from my code. Basically once the button is clicked this logic should fire out and determine if the number is prime or not. The problem is that some numbers are returning as "not prime", when in reality they are. Can anyone point out where the flaw is?
Thank you
private void bntTestPrime_Click(object sender, EventArgs e)
{
int num;
double num_sqrt;
int num_fl;
num = Convert.ToInt32(txtInput.Text);
num_sqrt = Math.Sqrt(num);
num_fl = Convert.ToInt32(Math.Floor(num_sqrt));
for (int i = 1; i <= num_fl; i++)
{
if (num % i == 0 && i != num)
lblResult_prime.Text = "Number " + num + " is not Prime.";
else
lblResult_prime.Text = "Number " + num + " is Prime.";
}
}
To add to Blender's answer, I'd like to point out that you're simply setting the output text on every iteration loop. That means your result will only depend upon the last number checked. What you need to do is assume the number is prime and loop through until a divisor is found. If a divisor is found. The number is prime if and only if no divisors are found. In the end the code should look something like this:
private bool IsPrime(int num)
{
double num_sqrt = Math.Sqrt(num);
int num_fl = Convert.ToInt32(Math.Floor(num_sqrt));
for (int i = 2; i <= num_fl; i++)
{
if (num % i == 0)
{
return false;
}
}
return true;
}
private void bntTestPrime_Click(object sender, EventArgs e)
{
int num = Convert.ToInt32(txtInput.Text);
bool isPrime = IsPrime(num);
if (isPrime)
lblResult_prime.Text = "Number " + num + " is Prime.";
else
lblResult_prime.Text = "Number " + num + " is not Prime.";
}
1 is a factor of every number, so you shouldn't check it. Start at 2. Also, you're already looping from 2 to sqrt(num), so there's no way for i to be equal to num.
You can decrease the performance hit on checking large numbers by using a conditional to check the first 4 primes, then start the loop at 11 and increment by 2. Something like this:
private bool IsPrime(int num)
{
double num_sqrt = Math.Sqrt(num);
int num_fl = Convert.ToInt32(Math.Floor(num_sqrt));
if (num !=1 && num !=2 && num != 3 && num != 5 && num != 7 && num % 2 > 0 _
&& num % 3 > 0 && num % 5 > 0 && num % 7 > 0)
{
for (int i = 11; i <= num_fl; i+=2)
{
if (num % i == 0)
{
return false;
}
}
}
else
return false;
return true;
}
You can shorten your code and increase the performance tremendously by using a List of primes that go big enough to cover the upper limit you want to check. Then use the Contains method to test for prime.
Try the code below.
bool IsPrime(int number) {
if(number%2==0 && number!=2) return false; //no need to check for even numbers
for (int i = 2; i < number; i++) {
if (number % i == 0 && i != number) return false;
}
return true;
}
Try this code below:
bool isPrimeNubmer(int n)
{
if (n >=0 && n < 4) //1, 2, 3 are prime numbers
return true;
else if (n % 2 == 0) //even numbers are not prime numbers
return false;
else
{
int j = 3;
int k = (n + 1) / 2 ;
while (j <= k)
{
if (n % j == 0)
return false;
j = j + 2;
}
return true;
}
}
public class PrimeChecker
{
public static bool Prime(int m)
{
for (int i =2; i< m; i++)
{
if (m % i ==0)
{
return false ;
}
}
return true;
}
public static void Main()
{
Console.WriteLine(Prime(13));
}
}

Print numbers from 1 to 100 and replace some with strings (fizzbuzz)

I am trying the fizzbuzz program from here: Why Can't Programmers.. Program?
"Write a program that prints the numbers from 1 to 100. But for multiples of three print "Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz"."
protected void btn1_Click(object sender, EventArgs e)
{
for (int i = 1; i < 101; i++)
{
if (i % 3 == 0 & i % 5 == 0)
{
Response.Write("fizzbuzz" + ",");
}
else if (i % 3 == 0)
{
Response.Write("fizz" + ",");
}
else if (i % 5 == 0)
{
Response.Write("buzz" + ",");
}
else
{
i = i + 0;
}
Response.Write(i +",");
}
}
I am able to produce some kind of result like:
1,2,fizz,3,4,buzz,5,fizz,6,7,8,fizz,9,buzz,10,11,fizz,12,13,14,fizzbuzz,15,16,17,fizz,18,19,buzz,20,fizz,21,22,23,fizz,24,buzz,25,26,fizz,27,28,29,fizzbuzz,30,31,32,fizz,33,34,buzz,35,fizz,36,37,38,fizz,39, and so on..
The word fizz was printed but it did not replace 3 and fizzbuzz was printed but it did not replace 15 and so ...
Whether you hit the if condition or not you are still printing i at the end of your code.
Look specifically at your for loop:
for (int i = 1; i < 101; i++)
{
if (i % 3 == 0 & i % 5 == 0)
{
Response.Write("fizzbuzz" + ",");
}
else if (i % 3 == 0)
{
Response.Write("fizz" + ",");
}
else if (i % 5 == 0)
{
Response.Write("buzz" + ",");
}
else
{
i = i + 0;
}
Response.Write(i +","); //look here you print i
}
So you need to move that last Response.Write(i + ","); in the last else condition. The easiest way to find bugs like these is to use the debugger and debug your program. You will then easily see what the output is. So definately use the debugger and set breakpoints / watches and watch what happens. Your code should change to this:
for (int i = 1; i < 101; i++)
{
if (i % 3 == 0 & i % 5 == 0)
{
Response.Write("fizzbuzz" + ",");
}
else if (i % 3 == 0)
{
Response.Write("fizz" + ",");
}
else if (i % 5 == 0)
{
Response.Write("buzz" + ",");
}
else
{
Response.Write(i +","); //look here you print i
}
}
Notice the removal of i=i+1 your for loop is handling this already by incrementing i.
Edit Not sure if this is easier but here is another way to do this using lambda's:
List<int> t;
t = Enumerable.Range(1, 100).ToList();
var fizzBuzz = t.Where(num => num % 3 == 0 && num % 5 == 0);
var fizz = t.Where(num => num % 3 == 0);
var buzz = t.Where(num => num % 5 == 0);
var notFizzBuzz = t.Where(num => num % 3 != 0 && num % 5 !=0);
//print fizzBuzz elements
Console.WriteLine("Printing fizzBuzz elements...");
foreach (int i in fizzBuzz)
Console.WriteLine(i);
//print fizz elements
Console.WriteLine("Printing fizz elements...");
foreach (int i in fizz)
Console.WriteLine(i);
//print buzz elements
Console.WriteLine("Printing buzz elements...");
foreach (int i in buzz)
Console.WriteLine(i);
//print other elements
Console.WriteLine("Printing all others...");
foreach (int i in notFizzBuzz)
Console.WriteLine(i);
Try these changes
protected void btn1_Click(object sender, EventArgs e)
{
for (int i = 1; i < 101; i++)
{
if (i % 3 == 0 & i % 5 == 0)
{
Response.Write("fizzbuzz" + ",");
}
else if (i % 3 == 0)
{
Response.Write("fizz" + ",");
}
else if (i % 5 == 0)
{
Response.Write("buzz" + ",");
}
else
{
Response.Write(i +",");
}
}
}
Your i = i + 0 obviously does nothing, since you are adding 0 to the value of i.
And you are printing the number to the response regardless of the result of the if/else block (it's put after it), so it should be moved into else (meaning only print if the if, or else if did not match.
move Response.Write(i +","); into your final else
protected void btn1_Click(object sender, EventArgs e)
{
for (int i = 1; i < 101; i++)
{
if (i % 3 == 0 & i % 5 == 0)
{
Response.Write("fizzbuzz" + ",");
}
else if (i % 3 == 0)
{
Response.Write("fizz" + ",");
}
else if (i % 5 == 0)
{
Response.Write("buzz" + ",");
}
else
{
i = i + 0; //this is totally useless
Response.Write(i + ",");
}
//Response.Write(i +","); //This will always write the number, even if you wrote fizz or buzz
}
}
Another simple implementation of it:
for (int i = 1; i <= 100; i++)
{
Console.WriteLine((i % 3 == 0) ? ((i % 5 == 0) ? "FizzBuzz" : "Fizz") : ((i % 5 == 0) ? "Buzz" : i.ToString()));
}
Console.ReadKey();
public static void PrintMod3And5FromInterval(int start, int end)
{
if (end < start)
{
Console.WriteLine("End number should be higher than start.");
}
else
{
string result = "";
for (int x = start; x <= end; x++)
{
if (x % 3 == 0)
result += "fizz";
if (x % 5 == 0)
result += "buzz";
if (result == "")
Console.WriteLine(x);
else
Console.WriteLine(result);
result = "";
}
}
}
static void Main(string[] args)
{
PrintMod3And5FromInterval(1, 100);
Console.Read();
}
Here was my original solution...
for (let number = 1; number <= 100; number ++) {
if (number % 3 === 0 && number % 5 === 0) {
console.log(number + "fizzbuzz");
} else if (number % 5 === 0) {
console.log(number + "buzz");
} else if (number % 3 === 0)
console.log(number + "fizz");
else {
console.log(number);
}
}
But this one is much shorter...
for (let n = 1; n <= 100; n++) {
let output = "";
if (n % 3 == 0) output += "Fizz";
if (n % 5 == 0) output += "Buzz";
console.log(output || n);
}

Code Smell in Dynamic Expression

This code solves an interesting puzzle outlined in http://www.programgood.net/2011/01/13/DynamicOperatorsGuernseyChallenge.aspx
Problem: There seems to be lots of repeating here.. DRY (Don't Repeat Yourself) principle springs to mind here. Anyone see a refactor?
string opZ = "";
string opA = "";
string opB = "";
string opC = "";
string opD = "";
for (int h = 1; h <= 2; h++) // making the first number positive or negative
{
if (h == 1) opZ = "";
if (h == 2) opZ = "-";
for (int i = 1; i <= 4; i++)
{
if (i == 1) opA = "*";
if (i == 2) opA = "/";
if (i == 3) opA = "+";
if (i == 4) opA = "-";
for (int j = 1; j <= 4; j++)
{
if (j == 1) opB = "*";
if (j == 2) opB = "/";
if (j == 3) opB = "+";
if (j == 4) opB = "-";
for (int k = 1; k <= 4; k++)
{
if (k == 1) opC = "*";
if (k == 2) opC = "/";
if (k == 3) opC = "+";
if (k == 4) opC = "-";
for (int l = 1; l <= 4; l++)
{
if (l == 1) opD = "*";
if (l == 2) opD = "/";
if (l == 3) opD = "+";
if (l == 4) opD = "-";
string expression = opZ + 1 + opA + 3 + opB + 5 + opC + 7 + opD + 9;
DataTable dummy = new DataTable();
double result = Convert.ToDouble(dummy.Compute(expression, string.Empty));
if (result == 3)
Debug.WriteLine(expression + " = 3");
if (result == 47)
Debug.WriteLine(expression + " = 47");
if (result == 18)
Debug.WriteLine(expression + " = 18");
}
}
}
}
}
Well, the first obvious refactoring would be to have an array of operators:
String[] operators = { null, "*", "/", "+", "-" };
Then use:
opC = operators[j]; // etc
(Personally I'd use loops going from 0 to 3 instead of 1 to 4 - that's more idiomatic IMO, but that's a different matter.)
Then there's the way of building the permutations. I'd actually use LINQ for this:
string[] prefixes = { "", "-" };
string[] operators = { "*", "/", "+", "-" };
var expressions = from prefix in prefixes
from opA in operators
from opB in operators
from opC in operators
from opD in operators
select prefix + 1 + opA + 3 + opB + 5 + opC + 7 + opD + 9;
foreach (string expression in expressions)
{
...
}
char[] ops = new [] {'*','/','+','-'};
foreach(string opA in ops)
foreach(string opB in ops)
foreach(string opC in ops)
foreach(string opD in ops)
foreach(string opZ in new []{'-',' '}) {
string expression = opZ + 1 + opA + 3 + opB + 5 + opC + 7 + opD + 9;
DataTable dummy = new DataTable();
double result = Convert.ToDouble(dummy.Compute(expression, string.Empty));
if (result == 3)
Debug.WriteLine(expression + " = 3");
if (result == 47)
Debug.WriteLine(expression + " = 47");
if (result == 18)
Debug.WriteLine(expression + " = 18");
}
I suppose there's no real point doing this while using DataTable.Compute, but
var calculator = new DataTable () ;
var operators = "*/+-" ;
for (int i = 0 ; i < 0x200 ; ++i)
{
var value = calculator.Compute (String.Format ("{0}1{1}3{2}5{3}7{4}9",
(i & 0x100) != 0 ? "-" : "",
operators[(i >> 0) & 3],
operators[(i >> 2) & 3],
operators[(i >> 4) & 3],
operators[(i >> 6) & 3]), String.Empty) ;
...
}
Otherwise, this will definitely be faster if somewhat more abstruse:
var opstrings = "+-*/" ;
var operators = new Func<int, int, int>[] {
(a, b) => a + b,
(a, b) => a - b,
(a, b) => a * b,
(a, b) => a / b, } ;
for (int i = 0 ; i < 0x200 ; ++i)
{
var stack = 0 ; // seed value
var last = 0 ; // imitate + for lowest precedence
var value =(i & 0x100) != 0 ? -1 : 1 ;
for (int j = 0 ; j < 5 ; ++j) // extra item to force last reduction
{
var oper = (i >> j * 2) & 3 ; // "input" operator
var input = 3 + j * 2 ; // "input" number
if (oper / 2 <= last / 2) // reduce below top?
{
stack = operators[last] (stack, value) ;
last = oper ; // shift operator
value = input ; // shift number
}
else // reduce top
value = operators[oper] (value, input) ;
}
var result = stack ;
if (result == 3 || result == 47 || result == 18)
Debug.WriteLine ("{0}1{1}3{2}5{3}7{4}9 = {5}",
(i & 0x100) != 0 ? "-" : "",
opstrings[(i >> 0) & 3],
opstrings[(i >> 2) & 3],
opstrings[(i >> 4) & 3],
opstrings[(i >> 6) & 3],
result) ;
}

Categories

Resources