This question already has answers here:
Unassigned local variable mystery
(3 answers)
Closed 2 years ago.
Good Day guys! I'm trying to make solve a programming challenge named NextPrime. Its just basically will return the next number that is prime. for example the input is 8, the return value is 11 since 11 is a prime number. I made my code below and got this Use of unassigned local variable result. The code below is my source code:
public static int NextPrime(int num)
{
int half = num / 2;
int outer = num * 2;
int x, y, result;
for (x = num; x <= outer; x++)
{
for (y = 2; y <= half; y++)
{
if (x % y == 0)
{
break;
}
else if (y == half)
{
result = x;
x = outer + 1;
break;
}
}
}
return result;
}
Well, result can well appear uninitialized; the easiest example is
var demo = NextPrime(-1);
Note, that outer loop for (x = num; x <= outer; x++) is not entered and that's why result is not assigned.
What can you do? Direct approach is to implement IsPrime method:
public static bool IsPrime(int x) {
if (x <= 1)
return false;
else if (x % 2 == 0) // we have only one even prime, that is 2
return x == 2;
int n = (int)(Math.Sqrt(x) + 0.5);
for (int divisor = 3; divisor <= n; divisor += 2)
if (x % divisor == 0)
return false;
return true;
}
And then use it in NextPrime:
public static int NextPrime(int num) {
if (num <= 1)
return 2;
for (int x = num + 1 + num % 2; ; start += 2)
if (IsPrime(x))
return x;
}
Compiler Error CS0165
Use of unassigned local variable 'name'
The C# compiler doesn't allow the use of uninitialized variables. If
the compiler detects the use of a variable that might not have been
initialized, it generates compiler error CS0165. For more information,
see Fields. This error is generated when the compiler encounters a
construct that might result in the use of an unassigned variable, even
if your particular code does not. This avoids the necessity of overly
complex rules for definite assignment.
You need to be explicit about what is returned if the loops don't run. The compiler only goes so far with static analysis and doesn't probe whether loops are meaningfully setting values within
public static int NextPrime(int num)
{
int half = num / 2;
int outer = num * 2;
int result = 0; // Explicit
for (var x = num; x <= outer; x++)
for (var y = 2; y <= half; y++)
if (x % y == 0)
break;
else if (y == half)
{
result = x;
x = outer + 1;
break;
}
return result;
}
Related
I recently started with the euler Project for practice, I completed 1 and 2, but 3 is just not working. I used the same line of code for every solution to check if the number is decimal or not. This worked fine except this time, but I dont know why. This code
for (float i = 0; i < 1000; i++)
{
float temp = i / 3;
float temp2 = i/ 5;
if ((temp % 1) == 0 || (temp2 % 1) == 0)
{
num += i;
}
}
worked perfectly fine, but this one (which is basically the same)
float input = 600851475143;
for (float i = 0; i < 1000; i++)
{
float temp = input/i;
if ((temp % 1) == 0)
{
Console.Write(temp + ", ");
}
just returns every number. Then I tried this
float temp = 10/9;
Console.WriteLine(temp);
But it just returns 1. So i thought of an overflow or something like that, but my next approach didnt work either:
float temp = 10/9;
bool temp2 = (temp%1) == 0;
Console.WriteLine(temp2);
Return: True
I dont now what to do anymore, does someone know why this happens? Thanks in advance.
float in C# has precision of 6-9 digits according to docs, 600851475143 divided by maximum i in the loop (i.e. 999) will have more than 9 digits in mantissa so float will not be able to cover fractional part, so try switching to double or even decimal:
double input = 600851475143;
for (double i = 0; i < 1000; i++)
{
double temp = input / i;
if ((temp % 1) == 0)
{
Console.Write(temp + ", ");
}
}
Also I would say that you can use long's in this case:
long input = 600851475143;
for (long i = 1; i < 1000; i++)
{
var x = (input % i);
if (x == 0)
{
Console.WriteLine(input / i);
}
}
As for the last snippet - 10 and 9 in 10/9 are int's, so the result of 10/9 is an int and equals to 1, which give you the result you get.
I've been having troubles trying to get my fractional calculator to work. I'm trying to get the simplifying to work, it works correctly simplifiyng positive fractions, but if I were to put a negative fraction it won't simplify it, I'm not sure what I'm doing wrong and I've read over it numerous times (the Gcd and Reduce functions).
Im new to all of this, any help appreciated.
My Reduce and GCD functions:
public int gcd()
{
// assigned x and y to the answer Numerator/Denominator, as well as an
// empty integer, this is to make code more simple and easier to read
int x = answerNumerator;
int y = answerDenominator;
int m;
// check if numerator is greater than the denominator,
// make m equal to denominator if so
if (x > y)
m = y;
else
// if not, make m equal to the numerator
m = x;
// assign i to equal to m, make sure if i is greater
// than or equal to 1, then take away from it
for (int i = m; i >= 1; i--)
{
if (x % i == 0 && y % i == 0)
{
//return the value of i
return i;
}
}
return 1;
}
public void Reduce()
{
try
{
//assign an integer to the gcd value
int gcdNum = gcd();
if (gcdNum != 0)
{
answerNumerator = answerNumerator / gcdNum;
answerDenominator = answerDenominator / gcdNum;
}
if (answerDenominator < 0)
{
answerDenominator = answerDenominator * -1;
answerNumerator = answerNumerator * -1;
}
}
catch (Exception exp)
{
// display the following error message
// if the fraction cannot be reduced
throw new InvalidOperationException(
"Cannot reduce Fraction: " + exp.Message);
}
}
I think the problem is that, when you determine the GCD, you are checking that the value is >= 1 in your for loop, even though it may be negative. In order to avoid this, you should capture the absolute values of the numerator and denominator when determining the GCD.
For example, this should fix it:
public int gcd()
{
// assigned x and y to the absolute values of the answer Numerator/Denominator,
// as well as an empty integer, this is to make code more simple and easier to read
int x = Math.Abs(answerNumerator);
int y = Math.Abs(answerDenominator);
int m;
// check if numerator is greater than the denominator,
// make m equal to denominator if so
if (x > y)
m = y;
else
// if not, make m equal to the numerator
m = x;
// assign i to equal to m, make sure if i is greater
// than or equal to 1, then take away from it
for (int i = m; i >= 1; i--)
{
if (x % i == 0 && y % i == 0)
{
//return the value of i
return i;
}
}
return 1;
}
Short Answer
You need:
int x = Math.Abs(answerNumerator);
int y = Math.Abs(answerDenominator);
Running Code
Here is a running Fiddle for you: https://dotnetfiddle.net/nBzr0i
Output:
Initial: 2/4
Reduced: 1/2
---
Initial: 2/-4
Reduced: -1/2
---
Running Code:
using System;
public class Program
{
public static void Main()
{
Calc.Reduce(2,4);
Calc.Reduce(2,-4);
}
}
public static class Calc
{
public static int gcd(int answerNumerator, int answerDenominator)
{
// assigned x and y to the answer Numerator/Denominator, as well as an
// empty integer, this is to make code more simple and easier to read
int x = Math.Abs(answerNumerator);
int y = Math.Abs(answerDenominator);
int m;
// check if numerator is greater than the denominator,
// make m equal to denominator if so
if (x > y)
m = y;
else
// if not, make m equal to the numerator
m = x;
// assign i to equal to m, make sure if i is greater
// than or equal to 1, then take away from it
for (int i = m; i >= 1; i--)
{
if (x % i == 0 && y % i == 0)
{
//return the value of i
return i;
}
}
return 1;
}
public static void Reduce(int answerNumerator, int answerDenominator)
{
Console.Write("Initial: ");
WriteFraction(answerNumerator, answerDenominator);
try
{
//assign an integer to the gcd value
int gcdNum = gcd(answerNumerator, answerDenominator);
if (gcdNum != 0)
{
answerNumerator = answerNumerator / gcdNum;
answerDenominator = answerDenominator / gcdNum;
}
if (answerDenominator < 0)
{
answerDenominator = answerDenominator * -1;
answerNumerator = answerNumerator * -1;
}
}
catch (Exception exp)
{
// display the following error message
// if the fraction cannot be reduced
throw new InvalidOperationException("Cannot reduce Fraction: " + exp.Message);
}
Console.Write("Reduced: ");
WriteFraction(answerNumerator, answerDenominator);
Console.WriteLine("---");
}
public static void WriteFraction(int answerNumerator, int answerDenominator)
{
Console.WriteLine(string.Format("{0}/{1}", answerNumerator, answerDenominator));
}
}
I keep getting this error:
"Cannot implicitly convert type 'double' to 'int'. An explicit
conversion exists (are you missing a cast?)"
Code:
Console.WriteLine("ISBN-Prüfziffer berechnen");
Console.WriteLine("=========================");
Console.WriteLine();
Console.Write("ISBN-Nummer ohne Prüfziffer: ");
string ISBNstring = Console.ReadLine();
int ISBN = Convert.ToInt32(ISBNstring);
int PZ;
int i;
double x = Math.Pow(3, (i + 1) % 2);
int y = (int)x;
for (i = 1; i <= 12; i++)
{
PZ = ((10-(PZ + ISBN * x) % 10) % 10);
}
Console.WriteLine(PZ);
Console.ReadLine();
Here is the new code:
Console.WriteLine("ISBN-Prüfziffer berechnen");
Console.WriteLine("=========================");
Console.WriteLine();
Console.Write("ISBN-Nummer ohne Prüfziffer: ");
string ISBNstring = Console.ReadLine();
long ISBN = Convert.ToInt32(ISBNstring);
long ISBN1 = (Int64)ISBN;
int PZ = 0;
int i;
for (i = 1; i <= 12; i++)
{
double x = Math.Pow(3, (i + 1) % 2);
long y = (double)x;
PZ = ((10 - (PZ + ISBN * y) % 10) % 10);
}
Console.WriteLine(PZ);
Console.ReadLine();
But I'm still getting a conversion error for double to long and long to int...
I think you meant to use your y variable here instead of x :
PZ = ((10-(PZ + ISBN * y) % 10) % 10);
As a side note, you'll get compilation errors on both PZ and i, you need to initialize their values before using them, e.g. int PZ = 0; and int i = 0;
And please, use meaningful names; PZ, i, x and y don't mean anything to someone reading your code, or even to you in a few weeks.
Okay, I've modified it a little...
Console.WriteLine("ISBN-Prüfziffer berechnen");
Console.WriteLine("=========================");
Console.WriteLine();
Console.Write("ISBN-Nummer ohne Prüfziffer: ");
string ISBNstring = Console.ReadLine();
int sum = 0;
for (int i = 0; i < 12; i++)
{
int digit = ISBNstring[i] - '0';
if (i % 2 == 1)
{
digit *= 3;
}
sum += digit;
}
int result = 10 - (sum%10);
Console.WriteLine(result);
Console.ReadLine();
Here's the changes :
- You can declare i directly in your for loop, it'll save you a line.
- Instead of putting the ISBN into a long, keep in in a string. Just iterate over each character one by one.
- Each digit can be obtained by taking the ASCII value, and removing the value of 0.
- The % 2 == 1 thing is basically "If the number is at an odd position", where you can apply the *3. This replaces your Math.Pow that wasn't very clear.
I have a code here written in C# that finds the smallest multiple by all numbers from 1 to 20. However, I find it very inefficient since the execution took awhile before producing the correct answer. I would like to know what are the different ways that I can do to improve the code. Thank You.
public static void SmallestMultiple()
{
const ushort ARRAY_SIZE = 21;
ushort[] array = new ushort[ARRAY_SIZE];
ushort check = 0;
for (uint value = 1; value < uint.MaxValue; value++)
{
for (ushort j = 1; j < ARRAY_SIZE; j++)
{
array[j] = j;
if (value % array[j] == 0)
{
check++;
}
}
if (check == 20)
{
Console.WriteLine("The value is {0}", value);
}
else
{
check = 0;
}
}
}
static void Main(string[] args)
{
int[] nums = Enumerable.Range(1, 20).ToArray();
int lcm = 1;
for (int i = 0; i < nums.Length; i++)
{
lcm = LCM(lcm, nums[i]);
}
Console.WriteLine("LCM = {0}", lcm);
}
public static int LCM(int value1, int value2)
{
int a = Math.Abs(value1);
int b = Math.Abs(value2);
// perform division first to avoid potential overflow
a = checked((a / GCD(a, b)));
return checked((a * b));
}
public static int GCD(int value1, int value2)
{
int gcd = 1; // Greates Common Divisor
// throw exception if any value=0
if (value1 == 0 || value2 == 0)
{
throw new ArgumentOutOfRangeException();
}
// assign absolute values to local vars
int a = Math.Abs(value1); // local var1
int b = Math.Abs(value2); // local var2
// if numbers are equal return the first
if (a == b) { return a; }
// if var "b" is GCD return "b"
if (a > b && a % b == 0) { return b; }
// if var "a" is GCD return "a"
if (b > a && b % a == 0) { return a; }
// Euclid algorithm to find GCD (a,b):
// estimated maximum iterations:
// 5* (number of dec digits in smallest number)
while (b != 0)
{
gcd = b;
b = a % b;
a = gcd;
}
return gcd;
}
}
Source : Fast Integer Algorithms: Greatest Common Divisor and Least Common Multiple, .NET solution
Since the result must also be divisible by 19 (which is the greatest prime number) up to 20, you might only cycle through multiples of 19.
This should get to to the result about 19 times faster.
Here's the code that does this:
public static void SmallestMultiple()
{
const ushort ARRAY_SIZE = 21;
ushort[] array = new ushort[ARRAY_SIZE];
ushort check = 0;
for (uint value = 19; value < uint.MaxValue; value += 19)
{
for (ushort j = 1; j < ARRAY_SIZE; j++)
{
array[j] = j;
if (value % array[j] == 0)
{
check++;
}
}
if (check == 20)
{
Console.WriteLine("The value is {0}", value);
return;
}
else
{
check = 0;
}
}
}
On my machine, this finds the result 232792560 in a little over 2 seconds.
Update
Also, please note that the initial program did not stop when reaching a solution; I have added a return statement to make it stop.
You're just looking for the LCM of the numbers from 1 to 20:
Where the GCD can be efficiently calculated with the Euclidean algorithm.
I don't know C#, but this Python solution shouldn't be hard to translate:
def gcd(a, b):
while b != 0:
a, b = b, a % b
return a
def lcm(a, b):
return (a * b) / gcd(a, b)
numbers = range(1, 20 + 1)
print reduce(numbers, lcm)
It's pretty fast too:
>>> %timeit reduce(lcm, range(1, 20000))
1 loops, best of 3: 258 ms per loop
EDIT: v2.0 - Major speed improvement
Building on w0lf's solution. A faster solution:
public static void SmallestMultiple()
{
// this is a bit quick and dirty
// (not too difficult to change to generate primeProduct dynamically for any range)
int primeProduct = 2*3*5*7*11*13*17*19;
for (int value = primeProduct; ; value += primeProduct)
{
bool success = true;
for (int j = 11; j < 21; j++)
{
if (value % j != 0)
{
success = false;
break;
}
}
if (success)
{
Console.WriteLine("The value is {0}", value);
break;
}
}
}
You needn't check 1-10 since if something is divisible by x (e.g. 12), it is divisible by x/n (e.g. 12/2 = 6). The smallest multiple will always be a multiple of a product of all the primes involved.
Didn't benchmark C# solution, but equivalent Java solution runs in about 0.0000006 seconds.
Well I'm not sure what exactly you are trying to accomplish here but your out side for loop will run approximately 4,294,967,295 time (uint.MaxValue). So that will take some time...
If you have a way to keep from going to uint.MaxValue - like breaking your loop when you have accomplished what you need to - that will speed it up.
Also, since you are setting array[j] equal to j and then apparently never using the array again why not just do:
value % j
instead of
value % array[j]
Using also code written by W0lf (sorry but i cannot comment on your post) I would improve it (only a little) deleting the array that I think is useless..
public static void SmallestMultiple()
{
const ushort ARRAY_SIZE = 21;
ushort check = 0;
for (uint value = 1; value < uint.MaxValue; value++)
{
for (ushort j = 1; j < ARRAY_SIZE; j++)
{
if (value % j == 0)
{
check++;
}
}
if (check == 20)
{
Console.WriteLine("The value is {0}", value);
}
else
{
check = 0;
}
}
}
I am practising a C# console application, and I am trying to get the function to verify if the number appears in a fibonacci series or not but I'm getting errors.
What I did was:
class Program
{
static void Main(string[] args)
{
System.Console.WriteLine(isFibonacci(20));
}
static int isFibonacci(int n)
{
int[] fib = new int[100];
fib[0] = 1;
fib[1] = 1;
for (int i = 2; i <= 100; i++)
{
fib[i] = fib[i - 1] + fib[i - 2];
if (n == fib[i])
{
return 1;
}
}
return 0;
}
}
Can anybody tell me what am I doing wrong here?
Here's a fun solution using an infinite iterator block:
IEnumerable<int> Fibonacci()
{
int n1 = 0;
int n2 = 1;
yield return 1;
while (true)
{
int n = n1 + n2;
n1 = n2;
n2 = n;
yield return n;
}
}
bool isFibonacci(int n)
{
foreach (int f in Fibonacci())
{
if (f > n) return false;
if (f == n) return true;
}
}
I actually really like this kind of Fibonacci implementation vs the tradition recursive solution, because it keeps the work used to complete a term available to complete the next. The traditional recursive solution duplicates some work, because it needs two recursive calls each term.
The problem lies in <= the following statement:
for (int i = 2; i <= 100; i++)
more to the point the =. There is no fib[100] (C# zero counts) so when you check on i=100 you get an exception.
the proper statement should be
for (int i = 2; i < 100; i++)
or even better
for (int i = 2; i < fib.Length; i++)
And here is a solution that beats all of yours!
Because, why iteration when you have smart mathematicians doing closed-form solutions for you? :)
static bool IsFibonacci(int number)
{
//Uses a closed form solution for the fibonacci number calculation.
//http://en.wikipedia.org/wiki/Fibonacci_number#Closed-form_expression
double fi = (1 + Math.Sqrt(5)) / 2.0; //Golden ratio
int n = (int) Math.Floor(Math.Log(number * Math.Sqrt(5) + 0.5, fi)); //Find's the index (n) of the given number in the fibonacci sequence
int actualFibonacciNumber = (int)Math.Floor(Math.Pow(fi, n) / Math.Sqrt(5) + 0.5); //Finds the actual number corresponding to given index (n)
return actualFibonacciNumber == number;
}
Well, for starters your array is only 10 long and you're filling it with ~100 items (out-of-range-exception) - but there are better ways to do this...
for example, using this post:
long val = ...
bool isFib = Fibonacci().TakeWhile(x => x <= val).Last() == val;
int[] fib = new int[10];
for (int i = 2; i <= *100*; i++)
You're going out of the bounds of your array because your loop conditional is too large. A more traditional approach would be to bound the loop by the size of the array:
for (int i = 2; i < fib.Length; i++)
And make your array bigger, but as Marc said, there are better ways to do this, and I would advise you spend some time reading the wikipedia article on Fibonacci numbers.
One thing you can do is check for an early exit. Since you're trying to determine if a given number is in the Fibonacci sequence, you can do bounds checking to exit early.
Example:
static bool isFibonacci(int n)
{
int[] fib = new int[100];
fib[0] = 1;
fib[1] = 1;
for (int i = 2; i <= fib.Length; i++)
{
fib[i] = fib[i - 1] + fib[i - 2];
if (n == fib[i])
{
return true;
}
else if (n < fib[i])
{
return false; //your number has been surpassed in the fib seq
}
}
return false;
}
public static int FibNo(int n) {
int result = 0; int No = 0; int N1 = 1;
if (n< 0)
{ throw new ArguementException("number must be a positive value"); }
if (n <= 1)
{ result = n; return result; }
for(int x=1; x < n; x++)
{ result = No + N1; No = N1; N1=result; }
return result;
}