I was writing a program which takes input from the keyboard and prints a square matrix in the following spiral manner
1 2 3
8 9 4
7 6 5
I managed to write the program but I encountered a weird error.
in line 26 it gives me an index out of bound exception
while (matrix[row, col] == 0 && col < matrix.GetLength(0) )
However if I switch the order of the two statements inside the loop the exception is gone ? Does this mean that the order of the two statements in the while loop is important ? And if yes , why ? Shouldn't it be if both statements are true to execute the loop, and if one of them is false, no matter which one, to stop executing it.
Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpiralMatrixN
{
class Program
{
static void Main(string[] args)
{
//prompt the user to enter n
Console.WriteLine("Enter the value of n");
int n = int.Parse(Console.ReadLine());
int[,] matrix = new int[n,n];
Console.Clear();
System.Console.SetWindowSize(100, 30);
int value = 1;
int col = 0;
int row = 0;
if (n>0 && n<21)
{
while(value <= n*n)
{
while (matrix[row, col] == 0 && col < matrix.GetLength(0) )
{
matrix[row, col++] = value;
value++;
}
col--;
row++;
while (row < matrix.GetLength(1) && matrix[row, col] == 0)
{
matrix[row++, col] = value;
value++;
}
row--;
col--;
while (col >= 0 && matrix[row, col] == 0 )
{
matrix[row, col--] = value;
value++;
}
col++;
row--;
while (matrix[row, col] == 0 && row >= 0)
{
matrix[row--, col] = value;
value++;
}
col++;
row++;
}
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
Console.SetCursorPosition(j * 5, i * 2);
Console.Write(matrix[i, j] + " ");
}
Console.WriteLine();
}
}
}
}
}
Yes, order is important. Conditions in the && clause are executed in the order of precedence, and if one fails another is not executed. Currently what you have fails because matrix[row, col] == 0 is executed first, and col comes out of bounds. So your check for col (which is absolutely correct btw) should come first:
while (col < matrix.GetLength(0) && matrix[row, col] == 0)
If it fails, second statement won't be executed and you won't have an error. This is called "short-circuit evaluation".
Yes, it is called short circuit evaluation. Since you are using "&&", the second condition gets evaluated only after the first one evaluates to true.
The order in && is important && uses short-circuiting vs & which does not. In an && expression from left to right if a condition is false the other conditions are not evaluated.
Conditional logical operators
The && and || operators are called the conditional logical operators.
They are also called the "short-circuiting" logical operators.
conditional-and-expression:
inclusive-or-expression
conditional-and-expression && inclusive-or-expression
conditional-or-expression:
conditional-and-expression
conditional-or-expression || conditional-and-expression*
The && and || operators are conditional versions of the & and |
operators:
The operation x && y corresponds to the operation x & y,
except that y is evaluated only if x is true.
The operation x || y corresponds to the operation x | y, except that y
is evaluated only if x is false.
An operation of the form x && y or x || y is processed by applying
overload resolution (Section 7.2.4) as if the operation was written x
& y or x | y. Then,
If overload resolution fails to find a single best
operator, or if overload resolution selects one of the predefined
integer logical operators, a compile-time error occurs.
Otherwise, if the selected operator is one of the predefined Boolean
logical operators (Section 7.10.2), the operation is processed as
described in Section 7.11.1.
Otherwise, the selected operator is a user-defined operator, and the
operation is processed as described in Section 7.11.2.
It is not possible to directly overload the conditional logical operators.
However, because the conditional logical operators are evaluated in
terms of the regular logical operators, overloads of the regular
logical operators are, with certain restrictions, also considered
overloads of the conditional logical operators. This is described
further in Section 7.11.2.
From MSDN C# Conditional Operators
The && and || operators are known as "shortcut short-circuit operators"; the second half is only evaluated if necessary. This is useful for two reasons:
It's more efficient during execution since less code is run (not usually much more, but if you're doing IO or something it could be), and
It's convenient for programming since you can use the first half as a precondition to the second half even being evaluated. Such as,
if (myObj != null && myObj.Name == "something")
If both halves were evaluated above, you'd get an error from myObj.Name whenever myObj was null.
If you do need both halves of the expression evaluated no matter what, you can use the & or the | operators. I find I rarely do.
MSDN: && Operator (C# Reference)
Related
Newbie and i´ve browsed for answers for a while but can´t seem to get it to work. I have a loop with two int variables that increase with different amount each loop depending on their set value before the loop starts. I want the loop to break and print the value of both ints when both of them have exceeded a set value. The problem i keep getting is that it seems like as soon as the first condition in both the "if" conditions and "while" conditions are met the So grateful if anyone could point out where I´m going wrong. Maybe this isn´t the best way to create this function?
Console.WriteLine("Please enter value1");
string strValue1 = Console.ReadLine();
int value1 = Convert.ToInt32(strValue1);
int value2 = 20;
do
{
if (value1 < 50 || value2 < 50)
{
Console.WriteLine("increase value 2 a little");
value2 = value2 + 10;
}
else
{
Console.WriteLine("increase value 2 a lot");
value2 = value2 + 30;
}
value1++;
}
while ((value2 < 200) && (value1 < 60));
Console.WriteLine("value1 is " + value1);
Console.WriteLine("value2 is " + value2);
Console.ReadKey();
Your loop condition tests both variables to be less than a certain threshold. As soon as one variable exceeds the threshold, the condition is no longer true. This is different from testing if both variables are above a certain threshold.
If you want the loop to exit only when both variables exceed the threshold, change the condition to use || (i.e. or): while (value2 < 200 || value1 < 60). Your condition tests the opposite ("both variables must be less"); but could be adapted to match your verbal description more closly: while (!(value2 >= 200 && value >= 60))
As a general rule of thumb: !(a && b) is equivalent to !a || !b. Same for !(a || b) is equivalent to !a && !b.
I implemented the code using if...else.. This is working properly.
public static byte GetLengthWithCascadedIfElse(int number)
{
if (number < 10 && number > -10)
{
return 1;
}
if (number > 10 && number < 100)
{
return 2;
}
if (number > 1000000 && number < int.MaxValue)
{
return 3;
}
if (number < -100000000 && number > -1000000000)
{
return 4;
}
return 10;
}
My problem is that I need to implement the code above, using switch expression. I tried! Its dont work.
public static byte GetLengthWithSwitchExpression(int number)
{
return number switch
{
_ when number == 0 && number == -1 => 1,
_ => throw new InvalidOperationException()
};
}
CS0266 Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)
Perhaps you're thinking of C# 9's relational patterns?
number switch
{
> -10 and < 10 => 1,
> 10 and < 100 => 2,
> 1000000 and < int.MaxValue => 3,
> -1000000000 and < -100000000 => 4,
_ => 10
};
Or C# 8's when?
number switch
{
int a when a > -10 && a < 10 => 1,
int a when a > 10 && a < 100 => 2,
int a when a > 1000000 && a < int.MaxValue => 3,
int a when a > -1000000000 && a < -100000000 => 4,
_ => 10
};
Your stab at the conversion seems to use totally different parameters to what you say want/works.. so I didn't try to convert "the case of 0 and 1"
I did wonder if your "less than int.maxvalue" is redundant? Or will you really have a maxvalue passed in, and want it to be 10?
Convert if statement to switch statement or switch expression from visualstudio
This refactoring applies to:
C#
What: Convert an if statement to a switch statement or to the C# 8.0 switch expression.
When: You want to convert an if statement to a switch statement or a switch expression and vice versa.
Why: If you are using an if statement, this refactoring enables an easy transition to switch statements or switch expressions.
How-to
1-Place your cursor in the if keyword.
2-Press Ctrl+. to trigger the Quick Actions and Refactorings menu.
3-Select from the following two options:
Select Convert to 'switch' statement.
enter image description here
Select Convert to 'switch' expression.
enter image description here
I am trying to make two loops into one. This Loop should go through the array from the beginning to the end and otherwise. However my increment is not correct. Can anyone help? Thank you in advance.
for (int i = ((asc == true) ? 0 : calendar.Length - 1);
((asc == true) ? i < calendar.Length : i > 0);
(asc==true) ? i++ : i--)
Personally, I find that very hard to read, as well as invalid (it won't compile) - because you're trying to use the conditional operator as a statement expression, when it's not. Personally, I'd write something like:
for (int i = 0; i < calendar.Length; i++)
{
int index = asc ? i : calendar.Length - 1 - i;
// Now use index...
}
Making three different aspects all conditional feels like a nasty way to go.
Look at the C# reference of "for": http://msdn.microsoft.com/en-us/library/ch45axte.aspx
Specifically:
The iterator section defines what happens after each iteration of the body of the loop. The iterator section contains zero or more of the following statement expressions, separated by commas:
assignment statement
invocation of a method
prefix or postfix increment expression, such as ++i or i++
prefix or postfix decrement expression, such as --i or i--
creation of an object by using new
await expression
The expression: "(asc==true) ? i++ : i--" is none of these things.
Therefore, you'd want the assignment: i += (asc ? 1 : -1)
for (int i = ((asc) ? 0 : calendar.Length - 1);
((asc) ? i < calendar.Length : i >= 0);
i += (asc) ? 1 : -1)
Incidentally, as pointed out in comment, you'll probably want to look at index 0 in the condition, so your condition statement in the "descending" case should be i >= 0 (reflected in the code).
Jon offered a good option, but if principle:
for (int i = (asc ? 0 : calendar.Length - 1);
asc ? i < calendar.Length : i >= 0;
i += asc?1:-1)
{
//body
}
That for loop is... odd. It is also very hard to read. In the spirit of "better ways to do this", I would suggest just using Reverse:
IEnumerable<Day> collection = asc ? calendar : calendar.Reverse();
for (int i = 0; i < calendar.Length; i++)
{
collection.ElemantAt(i);// This is the current element
}
//Or better, you are getting everything anyways:
foreach (Day day in collection)
{
}
I'm trying to get away with a slick one liner as I feel it is probably possible.
I'll put my code below and then try to explain a little more what I'm trying to achieve.
for (int p = 0; p < 2; p++)
{
foreach (string player in players[p])
{
if (PlayerSkills[player].streak_count *>* 0) //This line
PlayerSkills[player].streak_count++;
else
PlayerSkills[player].streak_count = 0;
}
}
*(p==0 ? >:<) the comparison operator is chosen depending on p.
Of course what I've written is rubbish. But basically I want to use >0 when p==0, and <0 when p>>0. Is there a nice way to achieve this?
Well, you should use what is most readable, even if it is not as consice. That said...
// Invert the count for all but the first player and check for a positive number
if (PlayerSkills[player].streak_count * (p==0 ? 1 : -1) > 0)
I don't know about slick, but the following and/or combination is one line:
if ((p == 0 && PlayerSkills[player].streak_count > 0)
|| PlayerSkills[player].streak_count < 0)
...
This will only ever do the array index once (due to the p==0 condition occurring first) and so is equivalent to the "ternary" you wrote (albeit a bit more verbose).
p > 0 ? whenGreaterThanZero : whenZeroOrLess ;
E.g.
int p = 1; bool test = p > 0 ? true : false ;
Lets test = True
I have an if statement as follows
if (1 <= value <= 20)
{
}
value is a double.
however I get an error which says that "Operator '<=' cannot be applied to operands of type 'bool' and 'double'"
Is there a way around this error?
C# doesn't allow you to do this.
Do like this:
if (1 <= value && value <= 20)
The problem is not the double, problem is your syntax is incorrect.
You:
if (1 <= value <= 20)
{
}
That is interpreted as
(1 <= value) <= 20
so first 1 will be compared with value and it will be determined if the former is "less than or equal" the latter. That gives a boolean. Then that boolean, True or False, is compared with <= to 20. But you cannot ask if True/False is less than or equal 20, in C#.
Problem : you can not check two expressions without Combining them.
Solution : i think you want to check whether value is in beteween 1 and 20
You can Use Logical AND && operator for checking this
Try This:
if (value >= 1 && value <= 20)
{
}
1 <= value evaluates out to be bool (false if value is less than 1 and true otherwise).
So it evaluates out to be (true <= 20) or (false <=20) and error states clearly that you cannot use operator <= to compare bool and double.
You need and (&&) operator to do comparison:
if (1 <= value && value <= 20)
{
}