What will be the output of this and how? - c#

The output of this code is
0 1 2 3
But I am not getting the factorial part. I mean 1!=1 (i.e. i factorial equals to 1), so it does not satisfy the condition, so type for input 2 and 3, but they get printed as output?
static void Main(string[] args)
{
int i = 0;
int b = 8, a = 32;
for (i = 0; i <= 10; i++)
{
if ((a / b * 2)== 2)
{
Console.WriteLine( i + " ");
continue;
}
else if (i!=4)
Console.Write(i + " ");
else
break;
}
Console.ReadLine();
}

OK, let's see:
int b = 8, a = 32;
...
a / b * 2 == 32 / 8 * 2 == 4 * 2 == 8
That's why if ((a / b * 2) == 2) will never succeed, and so we can drop this if and simplify the loop into
for (i = 0; i <= 10; i++)
if (i != 4) // i != means "i doesn't equal", not "i factorial equals"
Console.Write(i + " "); // print 0, 1, 2, 3
else
break; // break on 4
Here we can clearly see that the routine will be printing out i up to 4 So you have
0 1 2 3
Side note: in order to avoid such errors, format out your code and let the compiler help you:
i!=4 // Bad, it can be read in different ways (not equal or factorial)
i != 4 // i is not equal to 4
i! = 4 // assign 4 to i factorial: compile time error
i! == 4 // i factorial equals to 4: compile time error - C# doesn't have factorials

Related

Difficulty understanding logic of the implemented algorithm - C#

I am finding it hard to understand the logic of the following algorithm that outputs 8,8. I would appreciate if you could provide some insight.
using System;
namespace Console_Example
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(g(4) + g(5) + "," + g(6));
Console.ReadKey();
}
static int g(int k)
{
if ((k == 1) || (k == 2))
return 1;
else
return g(k - 1) + g(k - 2);
}
}
}
Just a recursive function. You have to follow all steps.
if k = 1:
return 1;
if k = 2:
return 1;
if k = 3:
return (g(2) + g(1)) result is: 1 + 1 = 2
if k = 4:
return (g(3) + g(2)) result is: (1 + 1) + 1 = 3
if k = 5:
return (g(4) + g(3)) result is: 5 + 3 = 5
if k = 6:
return (g(5) + g(4)) result is: 5 + 3 = 8
This looks very similar to the Fibonacci sequence (wikipedia), where each number is the sum of the two previous numbers.
Because it is a recursive function, look at the return g(k - 1) + g(k - 2); where it calls itself, you must follow all the recursion until it ends.
g(1): 1 -- Because the return 1;
g(2): 1 -- Because the return 1;
g(3): g(2) + g(1) = 1 + 1 = 2 -- Here starts the recursion
g(4): g(3) + g(2) = 2 + 1 = 3
g(5): g(4) + g(3) = 3 + 2 = 5
g(6): g(5) + g(4) = 5 + 3 = 8
So g(4) + g(5) +"," +g(6) would be:
3 + 5 , 8 = 8, 8
Pretty much the sum of the F4 F5 resulting in the F6 value.
A better implementation of the Fibonacci sequence would be
static int Fibonacci(int k)
{
if(k < 0)
throw new ArgumentException("Fibonnaci works with numbers >= 0");
if (k == 0 || k == 1)
return k;
else
return Fibonacci(k - 1) + Fibonacci(k - 2);
}

Get divisible numbers in a range without certain operators (+, -, /, *, %, += %=, etc)

find numbers in an input range that are evenly divisible by 3. Only =, ++, -- operators can be used.
I've tried to get the remainder using shift operators and other loops but I always require a -= or something similar.
Console.Clear();
int n,
d,
count = 1;
// get the ending number
n = getNumber();
// get the divisor
d = 3;// getDivisor();
Console.WriteLine();
Console.WriteLine(String.Format("Below are all the numbers that are evenly divisible by {0} from 1 up to {1}", d, n));
Console.WriteLine();
// loop through
while (count <= n)
{
// if no remainder then write number
if(count % d == 0)
Console.Write(string.Format("{0} ", count));
count++;
}
Console.WriteLine();
Console.WriteLine();
Console.Write("Press any key to try again. Press escape to cancel");
Expected results:
Enter the ending number: 15
Below are all the numbers that are evenly divisible by 3 from 1 up to 15
3, 6, 9, 12, 15
If the == operator is permitted for the assignment, you can have something like
int remainder = 0; // assumes we always count up from 1 to n, we will increment before test
Inside the loop replace the existing if with
remainder++;
if (remainder == 3) {
Console.Write(string.Format("{0} ", count));
remainder = 0;
}
[EDIT: Typo in code corrected]
Think about the underlying maths:
2 x 3 = 3 + 3
3 x 3 = 3 + 3 + 3
4 * 3 = 3 + 3 + 3 + 3
...and so on.
Also, to be evenly divisible by 3 means that the number multiplying 3 must be even.. So...
public bool EvenlyDivisibleBy3(int aNumber)
{
int even = 2;
int currentMultiple = 0;
while (currentMultiple < aNumber)
{
int xTimes = 0;
for (int x = 1; x <= even; x++)
{
((xTimes++)++)++; // add three to xTimes
}
currentMultiple = xTimes;
(even++)++: // next even number
}
return currentMultiple == aNumber;
}

Rotating numbers using modulus

I have a function (some kind of rotation) for argument i in [1001..999999] range:
int a = ((i - 1) % (1000000 - 1000) + 1001)
As you can see
i = 1001 a = 2001
...
i = 5000 a = 6000
...
i = 999999 a = 1999
I want to inverse this function, i.e. to have i = f(a), such that if, say, a = 6000 is given I want to have 5000 as a return etc. Unfortunately, I've experienced a problem with inversing % (modulo operation). Are there any suggestions in rotating numbers or reversing the above formula?
As you can see, since (1000000 - 1000) is quite greate a value, you get for (i - 1) % (1000000 - 1000) just two cases
i - 1 if i < 999001
i - 1 - 999001 if i >= 999001
And in order to inverse the formula, you have to analyze just these two cases only and you'll get as easy as
if (a > 2000)
return a - 1000;
else
return a + 998000;
Test
for (int i = 1001; i <= 999999; ++i) {
// forward, the formula from the question
int a = ((i - 1) % (1000000 - 1000) + 1001);
// ...and inverse one
int r = (a > 2000) ? a - 1000 : a + 998000;
// do we have reversed value != initial one?
if (r != i) {
// this will never happen
Console.Write("Counter example {0}", i);
break;
}
}

Proper way to exit from recursive loop

I am trying to write a program to identify the occurrences of 3 consecutive integers in a given array of N numbers and replace them with the middle value by deleting the other two.
For example Input->55 99 99 100 101 101 34 35 36 5 28 7 50 50 51 52 52 24 13 14 15 5 6 7 37 31 37 38 39 36 40
Output->55 100 35 5 28 7 51 24 14 6 37 31 38 36 40
To achieve this i wrote this method which accepts array as an input and it returns the modified array.
//input
int[] original = new int[] { 1, 3, 4, 5, 5, 6, 8} ;
List<int> lstoriginal = new List<int>(original);
List<int> modified = Test(lstoriginal);
//method
public static List<int> Test(List<int> arrayInput)
{
for (i = 0; i < arrayInput.Count; i++)
{
if (i + 2 < arrayInput.Count)
{
if (arrayInput[i + 2] == arrayInput[i + 1] + 1
&& arrayInput[i + 2] == arrayInput[i] + 2)
{
arrayInput.RemoveAt(i + 2);
arrayInput.RemoveAt(i);
List<int> temp = arrayInput;
Test(temp);
}
}
}
return arrayInput;
}
Follwoing are the execution steps/result which i analyzed-
1-Initially if the test input is 1, 3, 4, 5, 5, 6, 8
2-When i=1 and it finds that 3,4,5 is in sequence it removes 3 and 5 and list becomes 1,4,5,6,8
3-Next time when i=1 then it finds 4,5,6 and it removes 4 and 6 and the new list is 1,5,8
4-i am expecting to exit from loop when i + 2 < arrayInput.Count returns false and trying to retrun the modified array immediately here the return statement gets executed but instead of return the result it again calls the Test(temp); statement few more times and then get exit. Please suggest
You actually don't need recursion at all. You can perform the task significantly faster by just moving i after you're removed your sequence. Here's a function that is much simpler and does the exact same thing. I tested it on tens of thousands of randomly generated unordered sequences.
public static List<int> Test2(List<int> arrayInput)
{
for (int i = 0; i < arrayInput.Count - 2; i++)
{
if (arrayInput[i + 2] == arrayInput[i + 1] + 1
&& arrayInput[i + 2] == arrayInput[i] + 2)
{
arrayInput.RemoveAt(i + 2);
arrayInput.RemoveAt(i);
i = Math.Max(-1, i - 3); // -1 'cause i++ in loop will increment it
}
}
return arrayInput;
}
That said, to answer your specific question, the best way to exit a recursive loop like your original is to change the signature of your recursive function to return a bool indicating whether or not it actually made any changes. When the first one returns with no changes, they all can exist, so your call to Test can be wrapped in if (!Test(...)) { return; }.
Here's the complete test and test data comparing your original to my modified version:
public static void Main()
{
const int COUNT = 10000;
var r = new Random();
int matchCount = 0;
var stopwatch1 = new Stopwatch();
var stopwatch2 = new Stopwatch();
for (int j = 0; j < COUNT; j++)
{
var list = new List<int>(100) {1};
for(int k=1; k<100; k++)
{
switch(r.Next(5))
{
case 0:
case 1:
case 2:
list.Add(list[k - 1] + 1);
break;
case 3:
list.Add(list[k - 1] + r.Next(2));
break;
case 4:
list.Add(list[k - 1] - r.Next(5));
break;
}
}
stopwatch1.Start();
List<int> copy1 = Test1(new List<int>(list));
stopwatch1.Stop();
stopwatch2.Start();
List<int> copy2 = Test2(new List<int>(list));
stopwatch2.Stop();
string list1 = String.Join(",", copy1);
string list2 = String.Join(",", copy2);
if (list1 == list2)
{
if (copy1.Count == list.Count)
{
Console.WriteLine("No change:" + list1);
}
else
{
matchCount++;
}
}
else
{
Console.WriteLine("MISMATCH:");
Console.WriteLine(" Orig : " + String.Join(",", list));
Console.WriteLine(" Test1 : " + list1);
Console.WriteLine(" Test2 : " + list2);
}
}
Console.WriteLine("Matches: " + matchCount);
Console.WriteLine("Elapsed 1: {0:#,##0} ms", stopwatch1.ElapsedMilliseconds);
Console.WriteLine("Elapsed 2: {0:#,##0} ms", stopwatch2.ElapsedMilliseconds);
}
public static List<int> Test1(List<int> arrayInput)
{
for (int i = 0; i < arrayInput.Count; i++)
{
if (i + 2 < arrayInput.Count)
{
if (arrayInput[i + 2] == arrayInput[i + 1] + 1
&& arrayInput[i + 2] == arrayInput[i] + 2)
{
arrayInput.RemoveAt(i + 2);
arrayInput.RemoveAt(i);
List<int> temp = arrayInput;
Test1(temp);
}
}
else
{ // modified part: return the array
return arrayInput;
}
}
return arrayInput;
}
//method
public static List<int> Test2(List<int> arrayInput)
{
for (int i = 0; i < arrayInput.Count - 2; i++)
{
if (arrayInput[i + 2] == arrayInput[i + 1] + 1
&& arrayInput[i + 2] == arrayInput[i] + 2)
{
arrayInput.RemoveAt(i + 2);
arrayInput.RemoveAt(i);
i = Math.Max(-1, i - 3); // -1 'cause i++ in loop will increment it
}
}
return arrayInput;
}
Please define "cannot exit". Do you mean the for keeps looping indefinitely? I don't see that happening from this code.
What it looks like to me:
This function will:
Step through the input, int by int. Checks to see if this int and the next 2 are sequential. Then it removes this one and the one after next, then feeds the result back into this same function. It then ignores any value this may have given us and continues on its merry way.
You have an input of 8,9,10
It starts to step through: i = 0 and all that.
so it finds that 8,9,10 are sequential, it then removes 8 and 9 and feeds that result into this same function.
So we start over again:
You have an input of 9
It starts to step through: i = 0 again.
it steps through and finds that there are not at least 3 values in the list, and returns the original.
We then completely ignore that result and continue the original loop above. Now i = 1, but there's only 1 thing in the arrayInput anymore, so it should end.
From what you're doing, I see no reason to make a recursive call. You're not doing anything with the result and even if you were, it would only help you if you had a collection like 8,9,10,10,11. Then the first call would trim it down to 9,10,11 and the recursive call would trim it down to 10

Solving brain teaser using linq

At the very outset let me express my sincere thanks to Marc Gravel,Dahlbyk and the rest for helping me to apply linq practically.
The following are few questions which I have faced in an interview to solve applying Linq. As I am not familiar with Linq I solved it without using Linq.
I appreciate the answers which helps me to solve them using Linq
Thanks in advance.
Question 1:
The Problem is to find different digits such that,in whatever order they are used to make a three-digit number,that number will not be divisible by:
3,5,7,11,13 or 17.
To ensure that there is no ambuigity,suppose the three digits
are a,b,and c.Then,none of the combination of the numbers:
say abc,acb,bac,bca,cab and cba will divide by 3,5,7,11,13 or 17.
Example :
When I take 248 none of its combination(284,428,482,842,824) will exactly divisible by 3,5,7,11,13 or 17.
public void FindingRareNumbers()
{
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= 9; j++)
{
for (int k = 1; k <= 9; k++)
{
//to form the three digit
string digit = i.ToString() + j.ToString() + k.ToString();
//converting to integer
int StrToDigit = Convert.ToInt32(digit);
char[] digitcombination = digit.ToCharArray();
string PossibleCombination = "";
bool testpassed = false;
int dcount = 0;
#region different possible combinations
for (int p = 0; p <= 2; p++)
{
for (int q = 0; q <= 2; q++)
{
for (int r = 0; r <= 2; r++)
{
// The following condition avoid the repeatance
// of digit like 111,111,111
if (p != q && p != r && r != q)
{
PossibleCombination =
digitcombination[p].ToString() +
digitcombination[q].ToString() +
digitcombination[r].ToString();
int num = Convert.ToInt32(PossibleCombination);
if (num % 3 != 0 && num % 5 != 0 && num % 7 != 0
&& num % 11 != 0 && num % 11 != 0
&& num % 13 != 0 && num % 17 != 0)
{
//count is increment for 6 times
// it satisfies the condition
dcount++;
testpassed = true;
}
}
}
}
}
#endregion combination
if (testpassed && dcount==6)
{
Console.WriteLine(StrToDigit);
}
}
}
}
}
(coding is working)
Question 2:
The task is to arrange the element in matrix so that all rows,columns,and diagonals add up to the same total.(Bit problem in coding ,I am trying to solve it).
------------------
1 2 3
-----------------
4 5 6
-----------------
7 8 9
-----------------
example :
The one of solutions is as follows:
-----------
2 9 4
-----------
7 5 3
----------
6 1 8
----------
I agree that Marc's solution to your first problem is a reasonable approach. But I think there's a larger question here, which is "how do I solve problems like this in a LINQ-ish manner?"
Notice how your solution is completely "procedural" and "imperative". Your code specifies a series of steps that you would execute, one after the other, with deep loops. Each step along the way is meaningless unless you understand its place in the larger whole.
There are two ideas I like to use when solving problems with LINQ:
Describe what the program is doing logically, rather than listing a series of commands
Characterize the problem as a query against a data set rather than as a procedure to follow.
So, what's our data set? We wish to filter out some elements from the set of all combinations of three digits.
How do we filter them? Permute the digits and then perform a divisibility check on each permutation.
OK, so now we have a structure for our program:
var query = from c in ThreeDigitCombinations()
where DivisibilityCheckPasses(c)
select c;
foreach(Combination result in query) Console.WriteLine(result);
And now you can continue breaking down each of those further, solving each sub-problem using LINQ in turn.
Same goes for your "magic square" problem; you're looking for a permutation that has a certain property, so write a generator of permutations, write a filter, and execute it.
For the first:
static IEnumerable<int> Permute(int x, int y, int z)
{
yield return x * 100 + y * 10 + z;
yield return x * 100 + z * 10 + y;
yield return y * 100 + x * 10 + z;
yield return y * 100 + z * 10 + x;
yield return z * 100 + x * 10 + y;
yield return z * 100 + y * 10 + x;
}
static void Main()
{
var divs = new[] {3,5,7,11,13,17};
// combinations of 1-9
var combinations =
from x in Enumerable.Range(1, 7)
from y in Enumerable.Range(x + 1, 8 - x)
from z in Enumerable.Range(y + 1, 9 - y)
select new { x, y, z };
// permute
var qry = from comb in combinations
where !Permute(comb.x, comb.y, comb.z).Any(
i => divs.Any(d => i % d == 0))
select comb;
foreach (var answer in qry)
{
Console.WriteLine("{0}, {1}, {2}", answer.x, answer.y, answer.z);
}
}
For the second - not elegant, but it works (returns the 8 permutations of the sample):
static void Main() {
var data = Enumerable.Range(1, 9);
var magicSquares =
// generate 1st row and deduce the target
from a in data let arrA = new[] { a }
from b in data.Except(arrA) let arrB = new[] { a,b }
from c in data.Except(arrB) let arrC = new[] { a,b,c }
let target = a + b + c
// generate 2nd row and filter to target matches
from d in data.Except(arrC) let arrD = new[] { a,b,c,d }
from e in data.Except(arrD) let arrE = new[] { a,b,c,d,e }
from f in data.Except(arrE) let arrF = new[] { a,b,c,d,e,f }
where d + e + f == target
// generate 3rd row and filter to target matches
from g in data.Except(arrF) let arrG = new[] { a,b,c,d,e,f,g }
from h in data.Except(arrG) let arrH = new[] { a,b,c,d,e,f,g,h }
from i in data.Except(arrH)
where g + h + i == target
// filter columns
&& a + d + g == target
&& b + e + h == target
&& c + f + i == target
// filter diagonals
&& a + e + i == target
&& c + e + g == target
select new {a,b,c,d,e,f,g,h,i};
foreach (var row in magicSquares)
{
Console.WriteLine("{0} {1} {2}", row.a, row.b, row.c);
Console.WriteLine("{0} {1} {2}", row.d, row.e, row.f);
Console.WriteLine("{0} {1} {2}", row.g, row.h, row.i);
Console.WriteLine();
}
}

Categories