I have a basic grasp of For Loops in C#, but I'm having difficulty following this particular function. I have attempted to run the function in Visual Studio, but it results in an overflow exception.
"Describe what will happen when you call doSomething(5) given the following function:"
private void doSomething(int x = 10)
{
for(var y = 1; y <= x; y++)
{
Console.WriteLine(y);
if(y == 3)
doSomething(x);
}
}
Here's what I can see from analyzing the code. Starting from 1 the loop will check if y is <= 10. If y <= 10, it will write the value of y to the console. It will then check to see if y is equal to 3. If true, it will then call doSomething again, checking y against 10 again.
It is a recursive function, if you call doSomethig (5), when it enters the cycle will send to doSomethig the same value (in this case 5) forever.
If you create simulation how this code will assign values to variables, you will notice that y will always be assigned with 3, that means doSomething(x) will be called infinity times and calling something infinity times results to overflow exception.
Related
I've been working on a slotmachine in C# for practise purposes, and the machine itself works as intentional. The points system, however, does not. The game starts at 100 points, and if, for example, the player lose three 5-point bets and wins 40 points on the fourth bet, the expected points would be 100-20+40=120 points. For some reason however, the code treats ALL the previous bets as being 40 point wins as well, bringing the total to 100-20+160=240 points. If the player then lose the fifth 5-point bet, the score jumps to 75.
I start by setting the 'points' value to 100, which should then update everytime the 'game()' function is called upon.
public static void Main()
{
int points = 100;
int num = 0;
Console.WriteLine("Welcome to 'Slotmachine'!\nThe aim of this game is to get a score of 1000 or higher.\nYou lose if you reach 0 or lower.\nPress enter to play");
Console.ReadLine();
Console.Clear();
points = points + game(100);
while(points<1000 && points>0)
{
num = num + 1;
Console.WriteLine("You've played for "+num+" number of round(s)");
points = points + game(points);
}
}
The 'game()' funtion returns the players winnings, which is used to update the 'points' value (Suspect nr 1?).
Inside the game function I have a 'usrbet' which takes an input from the user (1-10), which is then fed into the 'slots()' function to determine the winnings (the 'points' that are fed from 'Main()' are checked to see what the user can bet)
Console.WriteLine("Here are your current points: "+points+"\nHow much would you like to bet?\nmin bet: 1\nmax bet: 10");
try
{
usrbet = Convert.ToInt32(Console.ReadLine());
}
catch
{
usrbet = 1;
}
winnings = slots(usrbet);
int RetWin = winnings - usrbet;
return RetWin;
Here's what the 'slots()' function does, with some examples of the winnings calculations
public static int slots(int usrbet)
{
int Win;
int x;
int y;
int z;
Random slot = new Random();
x = slot.Next(2,10);
y = slot.Next(2,10);
z = slot.Next(2,10);
Console.WriteLine(x+""+y+""+z);
Example 1
if(x == y && y == z && x== 7)
{
Win = usrbet*250;
Console.WriteLine("WOW! That's incredible, you just won "+Win+"!");
}
Example 2
else if(x == z)
{
Win = usrbet*5;
Console.WriteLine("Congratulations, you win "+Win+".");
}
Example 3
else
{
Win = 0;
Console.WriteLine("Ah, bummer. You didn't win anything this time.");
}
After that, the 'Win' value is sent back to 'game()', updating 'winnings'.
I apologize for poor formatting of the question. I'll include a link to the code, in case my problem lies elsewhere in the code: https://dotnetfiddle.net/D5TwL0
I've tried making arrays of the 'bet' and 'usrbet' variables, in an attempt to have a "new" value to update the 'points' with at every run of 'game()', but that changed absolutely nothing other than limiting how many times 'game()' can run before getting an overflow error.
It turns out that the problem wasn't with the code, but with the compiler. Dotnetfiddle is where I made the code and had the issue, but trying it in another compiler, it managed to count just fine.
If I run this simple code in a console app:
For i As Integer = 1 To 10
Dim s As String = i.ToString()
Dim x As Decimal
If i = 1 Then
x = Decimal.Parse(s)
End If
Console.WriteLine(x.ToString())
Next
Console.ReadLine()
Unexpectedly, x retains its value of 1 and so 1 gets printed 10 times. I thought each iteration of the loop was its own code block, and that the state didn't carry over? Why does this happen? I would expect x to have the default value of System.Decimal.
Same thing happens in C#, except that the complier won't let you call ToString() on an uninitialized variable, but if you set a breakpoint in Visual Studio, you can see that x retains its value of 1.
for (int i = 1; i <= 10; i++)
{
string s = i.ToString();
Decimal x;
if(i == 1)
{
x = Decimal.Parse(s);
}
// Value of x remains 1
}
Console.ReadLine();
Regarding VB.NET take a look about scope here. In the "Block Scope" section there is a note which states the following:
Even if the scope of a variable is limited to a block, its lifetime is
still that of the entire procedure. If you enter the block more than
once during the procedure, each block variable retains its previous
value. To avoid unexpected results in such a case, it is wise to
initialize block variables at the beginning of the block.
So this behavior is by design and you should initialize the variable to whatever value your code needs.
I modified your code to show that the first time x is initialized to 0 but after that it retains the value of 1.
For i As Integer = 1 To 10
Dim s As String = i.ToString()
Dim x As Decimal
Console.WriteLine(x.ToString())
If i = 1 Then
x = Decimal.Parse(s)
End If
Console.WriteLine(x.ToString())
Next
Console.ReadLine()
thought each iteration of the loop was its own code block, and that the state didn't carry over
It does "carry over."
int i is scoped to the entire range of the loop, with values from 1 to 10.
The if statement only executes on the first iteration, and x is scoped as a local variable to the outer method (assuming the loop is entered), not only the loop body. That being said, after & outside the loop, x == 1 as well.
In fact, Decimal x; in the loop is redundant, and you have the same execution logic as
string s;
Decimal x;
for (int i = 1; i <= 10; i++)
{
s = i.ToString();
if(i == 1)
{
x = Decimal.Parse(s);
}
Console.WriteLine(x);
}
// x still defined here
To make some sense of what you want, it should be just like this:
For i As Integer = 1 To 10
If i = 1 Then
Console.WriteLine(Decimal.Parse(i.ToString()))
End If
Next
This will give you the same result you want but it is readable.
I'm coding a nested for loop to fill a multidimensional array and have run into, not necessarily a problem, but a conundrum. First i'll explain that the code does what i want it to do which is fill a multi dimensional array completely with something; for now that something is the number 1. My conundrum comes when inside the for loop i have a "print()" function. To clear things up im coding c# inside unity.
static int[,] array;
array = new int[5,5];
for(int x = 0; x < 5; x++){
print("outer: " + x);
for (int y = 0; y < 5; y++){
print("-inner: " + y);
array [x, y] = 1;
}
}
The output is:
outer: 0
-inner: 0
-inner: 1
-inner: 2
-inner: 3
-inner: 4
outer: 1
outer: 2
outer: 3
outer: 4
It won't print inner between ever outer yet when outside the for loop i directly try to print something like:
print("data: " + array[2,3]);
It outputs:
data: 1
So its clearly filling the array using the nested for loops but it isn't printing out my string every time it iterates within the nested for loop. Is there a reason for this?
It isn't about for loop or another coding thing! Just disable the "Collapse" option from your Unity editor's "Console" and it is OK.
If you enable it, it will only print each unique message once with a counter on the right side indicating the number of times it printed.
I'm trying to solve a problem on code wars and the unit tests provided make absolutely no sense...
The problem is as follows and sounds absolutely simple enough to have something working in 5 minutes
Consider a sequence u where u is defined as follows:
The number u(0) = 1 is the first one in u.
For each x in u, then y = 2 * x + 1 and z = 3 * x + 1 must be in u too.
There are no other numbers in u.
Ex: u = [1, 3, 4, 7, 9, 10, 13, 15, 19, 21, 22, 27, ...]
1 gives 3 and 4, then 3 gives 7 and 10, 4 gives 9 and 13, then 7 gives 15 and 22 and so on...
Task:
Given parameter n the function dbl_linear (or dblLinear...) returns the element u(n) of the ordered (with <) sequence u.
Example:
dbl_linear(10) should return 22
At first I used a sortedset with a linq query as I didnt really care about efficiency, I quickly learned that this operation will have to calculate to ranges where n could equal ~100000 in under 12 seconds.
So this abomination was born, then butchered time and time again since a for loop would generate issues for some reason. It was then "upgraded" to a while loop which gave slightly more passed unit tests ( 4 -> 8 ).
public class DoubleLinear {
public static int DblLinear(int n) {
ListSet<int> table = new ListSet<int> {1};
for (int i = 0; i < n; i++) {
table.Put(Y(table[i]));
table.Put(Z(table[i]));
}
table.Sort();
return table[n];
}
private static int Y(int y) {
return 2 * y + 1;
}
private static int Z(int z) {
return 3 * z + 1;
}
}
public class ListSet<T> : List<T> {
public void Put(T item) {
if (!this.Contains(item))
this.Add(item);
}
}
With this code it still fails the calculation in excess of n = 75000, but passes up to 8 tests.
I've checked if other people have passed this, and they have. However, i cannot check what they wrote to learn from it.
Can anyone provide insight to what could be wrong here? I'm sure the answer is blatantly obvious and I'm being dumb.
Also is using a custom list in this way a bad idea? is there a better way?
ListSet is slow for sorting, and you constantly get memory reallocation as you build the set. I would start by allocating the table in its full size first, though honestly I would also tell you using a barebones array of the size you need is best for performance.
If you know you need n = 75,000+, allocate a ListSet (or an ARRAY!) of that size. If the unit tests start taking you into the stratosphere, there is a binary segmentation technique we can discuss, but that's a bit involved and logically tougher to build.
I don't see anything logically wrong with the code. The numbers it generates are correct from where I'm standing.
EDIT: Since you know 3n+1 > 2n+1, you only ever have to maintain 6 values:
Target index in u
Current index in u
Current x for y
Current x for z
Current val for y
Current val for z
public static int DblLinear(int target) {
uint index = 1;
uint ind_y = 1;
uint ind_z = 1;
uint val_y = 3;
uint val_z = 4;
if(target < 1)
return 1;
while(index < target) {
if(val_y < val_z) {
ind_y++;
val_y = 2*ind_y + 1;
} else {
ind_z++;
val_z = 3*ind_z + 1;
}
index++;
}
return (val_y < val_z) ? val_y : val_z;
}
You could modify the val_y if to be a while loop (more efficient critical path) if you either widen the branch to 2 conditions or implement a backstep loop for when you blow past your target index.
No memory allocation will definitely speed your calculations up, even f people want to (incorrectly) belly ache about branch prediction in such an easily predictable case.
Also, did you turn optimization on in your Visual Studio project? If you're submitting a binary and not a code file, then that can also shave quite a bit of time.
I understand every cog in this code with the exception of one part: the "e--;" within the While loop. Can anybody explain its importance to me?
public class Power
{
public static void Main()
{
int e;
int result;
for(int i=0; i < 10; i++)
{
result = 1;
e = i;
while(e > 0)
{
result *= 2;
e--;
}
Console.WriteLine(string.Format("2 to the {0} power is {1}", i, result));
}
}
}
You're looking at a postfix decrement operator.
It evaluates the value of e and then subtracts one from the value; since it's a standalone statement, it simply subtracts one from e's value.
The idea here is to simply multiply result by 2 i times. It does this by setting e to i, subtracting one each iteration of the loop, and looping while it's positive. This means that the while loop will always loop i times. You could just as easily (and arguably more clearly) write:
for(int e = 0; e < i; e++)
result *= 2;
while(e > 0)
This means that your loop will run as long as e is greater than zero. e-- is decrementing e's value on each iteration. If you didn't decrement it inside of your loop then you will get an infinite loop because your condition will become always true and your loop won't end.
The e-- just decrements the value of e. It is equivalent to e = e - 1;.
The reason you decrement the value is to eventually exit of the while loop; once you set e to the value of i, the loop will run indefinitely unless the value of e becomes less or equal to zero, which makes the while loop condition of e > 0 false.
In the larger picture, you are using e to stored the current value of i and then use it to execute i times the statement result *= 2;. In other words, you are using e to count how many times the variable result needs to be multiplied by 2 during the current iteration of the outer for loop.
This is similar to doing something like,
for (int i=0; i < 10; i++)
{
result = 1;
e = 0;
for (e = i; e > 0; e--)
{
result *= 2;
}
}
Since the while loop is really acting as a for loop.
e is your counter variable. It will repeat the while loop until the result has been multiplied the specified number of times (which is whatever i is when the loop started). As others have stated, e-- just decrements the value of e by one. You can read more here. This means that, in the code you provided, it will multiply result by 2 e times which mathematically will compute 2^i (i.e. 2^0 = 1, 2^1 = 2, 2^2 = 4, etc.).
e-- means it will decrease 1 in each loop, e++ will increase 1
check this article http://msdn.microsoft.com/en-us/library/36x43w8w.aspx