Only assignment, call, decrement can be used - c#

I'm trying to find integers in a certain range that are prime. I seem to be getting an error when I put a for loop in my else statement.
private static bool prime(int n,out int factor)
{
factor = 1;
if (n < 2)
return false;
else if (n == 2 || n == 3)
return true;
else if( n % 2 == 0)
return false;
for(int r = 3; r < (Math.Sqrt(n) + 1); r + 2)
{
if ((Convert.ToInt32(n)) % r == 0)
return false;
}
}

for(int r=3;r<(Math.Sqrt(n)+1);r+2)
r+2 creates a result, but it isn't assigned to anything. You want either r = r + 2 or r += 2

There are couple of problems with your code.
Firstly you can fix the assigment problem like
r=r+2
secondly, your function needs to return something from all code paths. Which it isn't doing at the moment. I have returned true at the end, though you can choose your logic here.
private static bool prime(int n, out int factor)
{
factor = 1;
if (n < 2)
return false;
else if (n == 2 || n == 3)
return true;
else if (n % 2 == 0)
{
return false;
}
for (int r = 3; r < (Math.Sqrt(n) + 1); r = r + 2)
{
if ((Convert.ToInt32(n)) % r == 0)
return false;
}
return true;
}

Related

Correctly determining if an IList<int> already exists in IList<IList<int>>

I'm using 3 iterators to iterate through an int[] object to find lists containing three int's that all sum to 0, without adding duplicate lists to the final return object. Once the iterators find a valid sequence, each array value that the iterator points to is added to a temporary IList object via syntax such as "tempList.Add(nums[a]);" e.t.c. This tempList is then added to the final IList<IList> return object.
To check for duplicates, I'm using the following sytax:
if ((nums[c] + nums[a] + nums[b] == 0) && !answerList.Contains(tempList))
{
answerList.Add(tempList);
}
This works when the IList<IList> is initially empty, however the second clause evaluated "false" for the following scenario, which is preventing the valid tempList from being added to the IList<IList> answerList :
IList<IList<int>> == [[-1,0,1]]
tempList == [-1,-1,2]
Do I need to extend a Comparable interface to correct this? I've double checked the array values for a, b and c and they collectively sum to 0, so I'm certain that it's the .Contains comparison that is causing issue.
Here is the code:
public IList<IList<int>> ThreeSum(int[] nums) // maybe use three index pointers to fill triplet, one starting at index 0, one
// starting at index nums.Lenght - 1 and one starting near or at middle
// 5 billion possible combinations of triplets among array of 3001 triplets
{
IList<int> tempList = new List<int>();
IList<IList<int>> answerList = new List<IList<int>>();
int countPositive = 0;
int countNegative = 0;
bool addAnswerList = false;
int indexPositive = 0;
int a = 0;
int b = 0;
int c = 0;
bool aExtreme = false;
bool bExtreme = false;
bool cExtreme = false;
if (nums == null)
return answerList;
if (nums.Length == 0 /* || /* nums.Length < 3 */)
return answerList;
if (nums.Length == 1 && nums[0] == 0)
return answerList;
for (int i = 0; i < nums.Length; i++) // corner case where all array values are either postive or negative
// 0 sum triplet not possible
{
if (nums[i] > 0)
countPositive++;
else if (nums[i] < 0)
countNegative++;
}
if ((countPositive == nums.Length || countNegative == nums.Length) || (countNegative == 0 && countPositive == 0))
return answerList;
if (nums.Length < 51)
{
int temp = 0;
for (int i = 1; i < nums.Length; i++) // use recursive sort to go through 3001 elements, use linear if less than 51
{
temp = nums[i];
int j = i;
while (j > 0 && nums[j-1] > temp)
{
nums[j] = nums[j-1];
j--;
}
nums[j] = temp;
}
Console.WriteLine(String.Join(" ", nums));
}
else if (nums.Length > 50) // recursive sort for larger input array
{
mergeSort(nums);
}
// Now nums is storted, 0 sum triplet will most likely be found where entries change from negative to positive
for (int i = 0; i < nums.Length; i++)
{
if (nums[i] > 0)
{
// toPositive = true;
indexPositive = i;
break;
}
}
Console.WriteLine(indexPositive);
if (indexPositive == 0) // case to make sure accessors do not get invalid number
{
a = 0; // initialize other two index accessors in addition to indexPositive
b = 0;
}
else
{
a = indexPositive - 1; // initialize other two index accessors in addition to indexPositive
b = indexPositive - 1;
}
c = indexPositive; // store initial indexPositive value into variable c as indexPositive will change
// throughtout the interation
// if indexPositive is less than (nums.Length / 2), iterate two other accessors towards end of nums
// else, interate two other accessors towards nums[0]
if (c < (nums.Length / 2)) // use iterator c in place of indexPositive
{
while (c < nums.Length && b < nums.Length && a >= 0)
{
if (a == 0 || a == nums.Length - 3)
{
aExtreme = true;
}
else
{
aExtreme = false;
}
if (b == 1 || b == nums.Length - 2)
{
bExtreme = true;
}
else
{
bExtreme = false;
}
if (c == 2 || c == nums.Length - 1)
{
cExtreme = true;
}
else
{
cExtreme = false;
}
if ((c != a && c != b && a != b) && (nums[c] + nums[a] + nums[b] == 0)) // if nums add to 0, add them to tempList
{
tempList.Add(nums[a]);
tempList.Add(nums[b]);
tempList.Add(nums[c]);
}
// need to check if exact triplet is duplicate or if tempList triplet contains same 3 values in different order
// 3 values in different order not an issues since input list is already sorted!!!!
// but need to be aware order accessors are added to temp list. Accessors cannot "crossover" one another!!!
if ((nums[c] + nums[a] + nums[b] == 0) && !answerList.Any(x => x.SequenceEqual(tempList)) /*!answerList.Contains(tempList)*/)
// Having issues, answerList.Contains does not currently do what is desired
{
answerList.Add(tempList); // add tempList to answerList
addAnswerList = true;
}
else
{
addAnswerList = false;
}
tempList.Clear(); // clear tempList to prepare for next entry
// Make changes here to make sure only 1 accessor iterates at a time, to check all possible and logical combinations
// Since array is now sorted, iteration towards sums[0] only has to continue if sum of 3 accessors is greater than 0
// Once active accessor returns a value that results in 0 sum, further iteration is guaranteed to return
// an identical triplet or one that sums to less than 0. At this point, the two accessors that are going in the same
// direction should be iterated by 1 position and the cycle repeated
if (nums[a] + nums[b] + nums[c] < 0) // still have chance to get to 0 value triplet with rightmost accessor
{
c++;
}
else if ((addAnswerList == true) || nums[a] + nums[b] + nums[c] > 0) // no point in further iteration,
// reset 'c' accessor to original starting
// position and decrement other accessors by 1
// towards first array element
{ // to begin cycle again
c = indexPositive - 1;
b--;
a--;
}
}
}
else // a and b accessors are interated towards 0
{
while (c < nums.Length && a >= 0 && b >= 0)
{
if (a == 0 || a == nums.Length - 3)
{
aExtreme = true;
}
else
{
aExtreme = false;
}
if (b == 1 || b == nums.Length - 2)
{
bExtreme = true;
}
else
{
bExtreme = false;
}
if (c == 2 || c == nums.Length - 1)
{
cExtreme = true;
}
else
{
cExtreme = false;
}
if ((c != a && c != b && a != b) && (nums[c] + nums[a] + nums[b] == 0)) // if nums add to 0, add them to tempList
// need to check if exact triplet is duplicate
{
tempList.Add(nums[a]);
tempList.Add(nums[b]);
tempList.Add(nums[c]);
}
Console.WriteLine(String.Join(" ", tempList));
// need to check if exact triplet is duplicate or if tempList triplet contains same 3 values in different order
// 3 values in different order not an issues since input list is already sorted!!!!
// but need to be aware order accessors are added to temp list. Accessors cannot "crossover" one another!!!
if ((nums[c] + nums[a] + nums[b] == 0) && !answerList.Any(x => x.SequenceEqual(tempList)))
// Having issues, answerList.Contains does not currently do what is desired
{
answerList.Add(tempList); // add tempList to answerList
addAnswerList=true;
}
else
{
addAnswerList = false;
}
tempList.Clear(); // clear tempList to prepare for next entry
// Make changes here to make sure only 1 accessor iterates at a time, to check all possible and logical combinations
// Since array is now sorted, iteration towards sums[0] only has to continue if sum of 3 accessors is greater than 0
// Once active accessor returns a value that results in 0 sum, further iteration is guaranteed to return
// an identical triplet or one that sums to less than 0. At this point, the two accessors that are going in the same
// direction should be iterated by 1 position and the cycle repeated
if (nums[a] + nums[b] + nums[c] > 0) // still have chance to get to 0 value triplet with
// leftmost accessor
{
a--;
}
else if ((addAnswerList == true) || nums[a] + nums[b] + nums[c] < 0) // no point in further iteration,
// reset 'a' accessor to original starting
// position and increment other accessors by 1
// towards last array element
{ // to begin cycle again
a = b; // a = indexPositive - 1;
if ((bExtreme == false && b < nums.Length - 2) && (cExtreme == false && c < nums.Length - 1))
// if there is still room to run towards end of array, increment, else decrement
{
b++;
c++;
}
else
{
bExtreme = true;
cExtreme = true;
a -= 2;
b--;
}
}
}
}
Console.WriteLine(String.Join(" ", answerList));
return answerList;
}
public void merge(int[] array1, int[] array2, int[] outArray)
{
int i = 0;
int j = 0;
while (i + j < outArray.Length)
{
if (j == array2.Length || (i < array1.Length && (array1[i] < array2[j])))
{
outArray[i + j] = array1[i++];
}
else
{
outArray[i + j] = array2[j++];
}
}
}
public void mergeSort(int[] inputArray)
{
if (inputArray.Length < 2)
return;
int[] firstHalf = new int[inputArray.Length / 2];
int[] secondHalf = new int[inputArray.Length / 2];
for (int i = 0; i < (inputArray.Length / 2); i++)
{
firstHalf[i] = inputArray[i];
}
for (int i = inputArray.Length / 2; i < inputArray.Length; i++)
{
secondHalf[i] = inputArray[i];
}
mergeSort(firstHalf);
mergeSort(secondHalf);
merge(firstHalf, secondHalf, inputArray);
}
You can replace
answerList.Contains(tempList))
which checks only for reference equality, with
answerList.Any(x => x.SequenceEqual(tempList))
which will run SequenceEqual on the answerList until it finds the first answer that has the same integer elements and returns false if none can be found.
Keep in mind that these functions require System.Linq.
Credit: thanks Hans Kesting for suggesting Any(...) over FirstOrDefault(...) != null

Problem with prime numbers not printed correctly [duplicate]

This question already has answers here:
Check if number is prime number
(31 answers)
Closed 2 years ago.
I have a problem with my code and i don't know how to solve it. Basically this program prints prime numbers based on the user input and at the end it prints their sum. This works perfectly until a certain amount, example: if i input 10, it shows ten correct prime numbers, but if i input 100, it also prints a number that is not prime, in this case 533. I don't know where i'm wrong.
Thanks for the support.
EDIT: I solved it on my own. Basically there was an error in the first "If" inside the for loop, i've simply added "c = n - 1;" after n++. Now it works perfectly.
Console.Write("How many prime numbers?: ");
int l = Convert.ToInt32(Console.ReadLine());
int n = 2;
int sum = 0;
sum += n;
Console.WriteLine(n);
n++;
int i = 1;
l++;
while (i < l)
{
for (int c = n - 1; c > 1; c--)
{
if (n % c == 0)
{
n++;
}
else if (n % c != 0 && c == 2)
{
sum += n;
Console.WriteLine(n);
n++;
i++;
}
}
}
Console.WriteLine("Sum: " + sum);
Let's start from extracting method:
public static bool IsPrime(int value) {
if (value <= 1)
return false;
if (value % 2 == 0)
retutn value == 2;
int n = (int) (Math.Sqrt(value) + 0.5);
for (int d = 3; d <= n; d += 2)
if (value % d == 0)
return false;
return true;
}
Having this method implemented you can easily compute the sum of the first N primes:
int N = 100;
long s = 0;
for (int p = 1; N > 0; ++p) {
if (IsPrime(p)) {
s += p;
N -= 1;
}
}
Console.Write(s);
Another (a bit more complex) possibility is prime numbers enumeration:
public static IEnumerable<long> Primes() {
yield return 2;
List<int> knownPrimes = new List<int>();
for (int p = 3; ; p += 2) {
int n = (int) (Math.Sqrt(p) = 0.5);
bool isPrime = true;
foreach (int d in knownPrimes) {
if (d > n)
break;
if (p % n == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
knownPrimes.Add(p);
yield return p;
}
}
}
Then you can query enumeration with a help of Linq:
using System.Linq;
...
long s = Primes()
.Take(N)
.Sum();

Can somebody tell me why this code is not working? I am trying to find the 10001st prime number

The code gives me the answer 43739 which is wrong. I don't know which part of the code I messed up, help would be much appreciated.
{
int primenumbers = 4;
int thenumber = 2;
int finalnumber = 0;
while (primenumbers <= 10001)
{
for (int x = 2; x < 10; x++)
{
if (thenumber % x == 0)
{
x = 10;
}
if (x == 9)
{
finalnumber = thenumber;
primenumbers += 1;
break;
}
}
thenumber += 1;
}
Console.WriteLine(finalnumber);
}
Let's split the initial problem into smaller ones: first, check for being prime:
private static bool IsPrime(int value) {
if (value <= 1)
return false;
else if (value % 2 == 0)
return value == 2;
int n = (int) (Math.Sqrt(value) + 0.5);
for (int d = 3; d <= n; d += 2)
if (value % d == 0)
return false;
return true;
}
Then enumerate prime numbers (2, 3, 5, 7, 11...):
// Naive; sieve algorithm will be better off
private static IEnumerable<int> Primes() {
for (int i = 1; ; ++i)
if (IsPrime(i))
yield return i;
}
Finally, query with a help of Linq:
using System.Linq;
...
int result = Primes().Skip(10000).First();
Console.Write(result);
And you'll get
104743

Write method that checks if a given number (positive integer) contains digit 3. If it is true answer is true.if it is false answer is false.in C#

Do not convert number to other type. Do not use built-in functions like Contains(), StartsWith(), etc.
while (number > 0)
{
if (number % 10 == 3)
{
return true;
}
number /= 10;
}
return false;`
Method that checks if given number (positive integer) contains digit 3
You were nearly there
private static bool HasDigit(int num,int digit)
{
while (num > 0)
{
if(num % 10 == digit)
return true;
num /= 10;
}
return false;
}
Usage
Console.WriteLine(HasDigit(1222, 3));
Console.WriteLine(HasDigit(23345, 3));
Output
False
True
Other approaches might be
private static bool HasDigit2(int num, int digit)
{
var str = num.ToString();
for (int i = 0; i < str.Length; i++)
if (str[i] == ((char) digit) + '0')
return true;
return false;
}
Or
private static bool HasDigit3(int num, int digit)
=> num.ToString().Any(t => t == ((char) digit) + '0');
Here's a recursive solution:
public static bool Contains3(int n) {
if (n < 10) {
if (n == 3) {
return true;
} else {
return false;
}
}
return n % 10 == 3 || Contains3(n / 10);
}

Why does this code give two different outputs for (what appears to be) the same inputs?

I'm trying to program some AI for a game of checkers. My program is saying there are 0 moves for the white player, even though I know there are. The GetValidMoves() function is tested, and works in other areas of the code.
To try and isolate the program I saved out the problematic board-state then loaded it back up to see if I would get the same problem:
using(Stream s = File.Open("board.dat", FileMode.Create))
{
var bf = new BinaryFormatter();
bf.Serialize(s, board);
}
Debug.WriteLine(board.GetValidMoves(Color.White).Count());
using (Stream s = File.Open("board.dat", FileMode.Open))
{
var bf = new BinaryFormatter();
board = (Board)bf.Deserialize(s);
}
Debug.WriteLine(board.GetValidMoves(Color.White).Count());
This prints:
0
7
When I would expect the output to be the same (7 is correct).
What could cause this to start working after deserialization? Both instances of the board appear to be exactly the same... I printed out all the properties and they all same correct. I'm not sure where to go from here?
The first instance of the board (before deserialization) is the result of a clone. Could I be cloning it wrong? Are there "dangling references"?
GetValidMoves:
public IEnumerable<Move> GetValidMoves(Color c)
{
var jumps = GetJumps(c);
if (jumps.Any())
foreach (var j in jumps)
yield return j;
else
foreach (var s in GetSlides(c))
yield return s;
}
public IEnumerable<Move> GetSlides(Color c)
{
foreach (int i in Enumerate(c))
foreach (var s in GetSlides(c, i))
yield return s;
}
public IEnumerable<Move> GetJumps(Color c)
{
foreach (int i in Enumerate(c))
foreach (var j in GetJumps(c, i))
yield return j;
}
public IEnumerable<Move> GetJumps(Color c, int i)
{
Checker checker = this[c, i] as Checker;
bool indentedRow = i % Width < rowWidth;
int column = i % rowWidth;
int offset = indentedRow ? 0 : -1;
bool againstLeft = column == 0;
bool againstRight = column == rowWidth - 1;
int moveSW = i + rowWidth + offset;
int moveSE = moveSW + 1;
int jumpSW = i + rowWidth * 2 - 1;
int jumpSE = jumpSW + 2;
if (!againstLeft && jumpSW < Count && IsEnemy(c, moveSW) && IsEmpty(c, jumpSW))
yield return new Move(c, i, jumpSW, jump: true, crown: IsCrowned(checker, jumpSW));
if (!againstRight && jumpSE < Count && IsEnemy(c, moveSE) && IsEmpty(c, jumpSE))
yield return new Move(c, i, jumpSE, jump: true, crown: IsCrowned(checker, jumpSE));
if (checker.Class == Class.King)
{
int moveNW = i - rowWidth + offset;
int moveNE = moveNW + 1;
int jumpNW = i - rowWidth * 2 - 1;
int jumpNE = jumpNW + 2;
if (!againstLeft && jumpNW >= 0 && IsEnemy(c, moveNW) && IsEmpty(c, jumpNW))
yield return new Move(c, i, jumpNW, jump: true);
if (!againstRight && jumpNE >= 0 && IsEnemy(c, moveNE) && IsEmpty(c, jumpNE))
yield return new Move(c, i, jumpNE, jump: true);
}
}
public IEnumerable<Move> GetSlides(Color c, int i)
{
Checker checker = this[c, i] as Checker;
bool indentedRow = i % Width < rowWidth;
int column = i % rowWidth;
int offset = indentedRow ? 0 : -1;
bool againstLeft = !indentedRow && column == 0;
bool againstRight = indentedRow && column == rowWidth - 1;
int moveSW = i + rowWidth + offset;
int moveSE = moveSW + 1;
if (!againstLeft && moveSW < Count && IsEmpty(c, moveSW))
yield return new Move(c, i, moveSW, crown: IsCrowned(checker, moveSW));
if (!againstRight && moveSE < Count && IsEmpty(c, moveSE))
yield return new Move(c, i, moveSE, crown: IsCrowned(checker, moveSE));
if (checker.Class == Class.King)
{
int moveNW = i - rowWidth + offset;
int moveNE = moveNW + 1;
if (!againstLeft && moveNW >= 0 && IsEmpty(c, moveNW))
yield return new Move(c, i, moveNW, crown: IsCrowned(checker, moveNW));
if (!againstRight && moveNE >= 0 && IsEmpty(c, moveNE))
yield return new Move(c, i, moveNE, crown: IsCrowned(checker, moveNE));
}
}
It shouldn't have side effects.
To answer your queries about whether valid moves is inadvertently changing the board state:
var board = new Board(8, 8);
board.SetUp();
foreach(var m in board.GetValidMoves(Color.White))
Console.WriteLine(m);
Console.WriteLine("---");
foreach(var m in board.GetValidMoves(Color.White))
Console.WriteLine(m);
Prints:
8-12
8-13
9-13
9-14
10-14
10-15
11-15
---
8-12
8-13
9-13
9-14
10-14
10-15
11-15
(The same output twice) As you'd expect.
Just a wild guess, but did you make sure there are absolutely no side effects from calling GetValidMoves?
Since you are serializing and deserializing the board after calling GetValidMoves, it appears that GetValidMoves changes the board in some way (which seems a bit odd to me given the function's name). So perhaps there are also other side-effects you did not take into consideration.
Pretty sure the bug was in the Board.Clone method actually. I think serializing/deserializing created brand new objects whereas my clone method wasn't cloning everything correctly, but rather returning references.
See How to clone an inherited object? for details.

Categories