Prime Number Generator Code
Do know that this question should be quite basic but i have spent hours trying to figure out why my code is stuck in the loop as below. Have added a Console.WriteLine($"{counttemp} , {count1} "); in the if loop to check the 2 numbers and seems like it is not breaking out of the if condition when the condition is true
this is the console output for the writeline in the if loop
5 , 5
6 , 2
7 , 7
8 , 2
9 , 3
10 , 2
11 , 11
12 , 2
13 , 13
14 , 2
15 , 3
16 , 2
17 , 17
18 , 2
19 , 19
Problematic Loop??
for (count1 = 2; count1 <= counttemp ; ++count1)
{
if(counttemp % count1 == 0)
{
Console.WriteLine($"{counttemp} , {count1} ");
Console.ReadKey();
primetest1 = 0;
break;
}
}
full code sequence
static void Main(string[] args)
{
int prime1 = 10000, count1, primetest1, counttemp;
for (counttemp = 5; counttemp <= prime1; counttemp++)
{
primetest1 = 1;
for (count1 = 2; count1 <= counttemp ; ++count1)
{
if(counttemp % count1 == 0)
{
Console.WriteLine($"{counttemp} , {count1} ");
Console.ReadKey();
primetest1 = 0;
break;
}
}
if (primetest1 == 1)
{
Console.Write($"{counttemp}");
}
}
}
You're almost there. The problem is that you're checking if your candidate number is a prime by getting the remainder when divided by each number up to and including the number itself.
I think you'll find that N is a factor of N for all values of N. To fix this, you should only be checking up to but excluding the number.
And, as an aside, you don't really need to check all the way up to N - 1. You only need to go to the square root of N, adjusted up to the nearest integer. That's because, if it has a factor above the square root, you would already have found a factor below it.
Consider 24 as an example. It has 6, 8, and 12 as factors above the square root, but the matching values below the square root are 4, 3, and 2 respectively.
And there's a another trick you can use by realising that if a number is a multiple of a non-prime, it's also a multiple of every prime factor of that non-prime. In other words, every multiple of 12 is also a multiple of 2 and 3.
So you only need to check prime numbers up to the square root, to see if there's a factor. And prime numbers, other than two or three, are guaranteed to be of the form 6x-1 or 6x+1, so it's quite easy to filter out a large chunk of candidates very quickly, by checking only for those values.
In other words, check two and three as special cases. Then start at 5 and alternately add 2 and 4: 5, 7, 11, 13, 17, 19, .... Not every number in that set is prime (e.g, 25) every prime is guaranteed to be in that set.
You can check out an earlier answer of mine for more detail on why this is so, and how to do this sequence efficiently.
Related
I’m having an issue with an algorithm I’m trying to implement in C# (the language doesn't matter much I guess).
Let’s say I have a list that could be of any length..for example:
var maxNumbers = new List<int>{5,3,2}();
The numbers in the list represent the maximum value of each entry. For example, the first entry means that it can be any number between 1 and 5 (5 is included).
Now, I want to print all combinations of every possible value for each entry in the list.
To explain:
The first number in the list is 5, so the possible values are 1,2,3,4,5
The second number in the list is 3, so the possible values
are 1,2,3
The last number in the list is 2, so the possible values
are 1,2
My algorithm should print something like:
1-1-1
1-1-2
1-2-1
1-2-2
1-3-1
1-3-2
1-2-1
etc.
I tried to implement this using recursion but wasn't able to get it. Here is my code:
void Iterate(List<int> numbers)
{
if (numbers.Count == 0)
{
Console.WriteLine("");
return;
}
int number = numbers[0];
for (int i = 1; i <= number; i++)
{
Console.WriteLine($"{i} ");
Iterate(numbers.Where((v, index) => index != 0).ToList());
}
}
Can anyone provide insights?
A non recursive approach;
We use Select(Enumerable.Range) to turn your list of maxes into a list of list of ints representing all the numbers..
Then we repeatedly use SelectMany to add another level to the list. SelectMany expects to be fed an enumerable. In the first instance there is only one item in combos, which gets crossed with 5 items from the first entry in ints, so SelectMany produces 5 items.
Second time round SelectMany effectively thinks it's expanding a "5 lists of 3 items" into a "list of 15 items". Third time round SelectMany thinks it's expanding a "15 lists of 2 items" into a "list of 30 items"...
public static string[] Combine(IEnumerable<int> maxes)
{
var ints = maxes.Select(max => Enumerable.Range(1, max));
IEnumerable<string> combos = new[] { "" };
foreach (var i in ints)
{
combos = combos.SelectMany(r => i.Select(x => r + (r == "" ? "" : "-") + x));
}
return combos.ToArray();
}
This answer fixes your code, the crucial problem with which, for me, was that the solution didn't carry any memory of where it had got to so far with making the output, so there isn't any way for iterate to repeat the earlier loop outputs
Here's the fixed code:
static void Iterate(List<int> numbers, string sofar)
{
if (numbers.Count == 0)
{
Console.WriteLine(sofar);
return;
}
for (int i = 1; i <= numbers[0]; i++)
{
Iterate(numbers.Skip(1).ToList(), sofar + i + " ");
}
}
Your code in the question hs a bit of a typo in that it does a WriteLine in the for loop which really messed up the output. Removing that to just Write you get:
1 1 1
2
2 1
2
3 1
2
2 1 1
2
2 1
2
3 1
2
3 1 1
2
2 1
2
3 1
2
4 1 1
2
2 1
2
3 1
2
5 1 1
2
2 1
2
3 1
2
If I add some spaces to change the alignment:
1 1 1
2 --> it's 1 1 2
2 1 --> it's 1 2 1
2 --> it's 1 2 2 etc
3 1
2
2 1 1
2
2 1
2
3 1
2
3 1 1
2
2 1
2
3 1
2
...
You can see it's nearly there, in that it's printing the number that changes each time, it's just lost any memory of what to print in terms of the numbers that haven't changed. The altered code passes the "string we generated so far" and devolves responsibility for printing it to just the if. Each time the loop calls Iterate it passes the string built so far so it keeps that memory of where it got up to
In this particular code how does it not output 6 1, because 6 gives no remainder dividing 18 by it.
int n = 18;
int[] fact = new int[100];
int[] pow = new int[100];
int d = 0;
for (int i = 2; i <= n; i++)
{
int s = 0;
while(n % i == 0)
{
s++;
n /= i;
}
if (s > 0)
{
fact[d] = i;
pow[d] = s;
d++;
}
}
Every numbers is either a prime, or a multiple of a prime. Look at: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
If it is not divisible by a prime, it can not be divisible by any multiple of that prime either. As 18 can be divided by 2 - 4, 6, 8, 10 and everything else never needs to be tested. As 19 can not be divided by 2, 4, 6, 8 and 10 never need to be tested. That 20 is divisible by 10, never needs to be tested. It already divides by 2 so we excluded half the possible numbers back then.
We do that exclusion of divisors instinctively, but usually only for 2 - testing only odd numbers - but you can drive that way further. As the result of a division must also be a prime or multiple of a prime, we even can stop once we passed the Squareroot.
All you really need is a unbroken list of primes, going to up to whatever Prime is > Squarroot(PrimeCandidate). Short of reading it from memory, that is the quickest way I know off.
I actually wrote something on the topic a while back, about the 5-ish ways of checking for a prime: https://social.msdn.microsoft.com/Forums/en-US/85fc2406-d2e9-495a-bea7-e516661f8b40/primal-issues-multithreading-lists-in-memory-and-checking-for-prime-number?forum=csharpgeneral
UPDATE: Okay I've revamped this question due to some negative people that merely want to complain rather than attempt to provide some sort of constructive help.
I know variations of this question have been asked, but I'm fairly certain mine is different.
I'm trying to do something similar to the tic tac toe Magic Box, but with a variation.
Traditionally, the Magic TicTacToe box refers to the numbers 1-9 and you're asked to arrange them in the tictactoe box in such a way that every iteration of the sets of 3 equal the same. In that sense, each run of 3 numbers would have to equal 15. With every possible direction, there's 8 sequences to test. The important part of the calculation is that the total sum of 1-9 is 45 and that divided by 3 is what tells you each run of 3 should equal 15.
Now, as I understand it, there's a form of recursion that would have to take place to run through the combinations of numbers, but I'm not quite sure how to do that. I'd like to be able to put a number (divisible by 3 and 9) in for an input and have it not only determine the unique (non-recurring) numbers it takes to get to that total, but how those numbers should be used.
Example:
I know I can simply divide a number by 9 to determine the median, which in this case already gives me one letter, which would be E in this case. I know I can simply run a couple for loops to get the remaining numbers. What I'm not sure how to do is figure out the recursion process to determine the correct assignment of each number.
Here's the example of the letter assignment:
G | F | A
H | E | B
I | D | C
You'd need the following combinations:
A+B+C
F+E+D
G+H+I
A+E+I
G+E+C
G+F+A
H+E+B
I+D+C
Now, what I'm not sure of, and the effect it could have, is the frequency in which each number is used. I know each of the above sequences would need to equal the number input divided by 3 would in this case would be 30, but I'm not sure what important facts can be used to create the proper nested for loops and/or if statements that sort through the list or array of numbers created and properly assign them based on their relevance.
Considering E is used 4 times (which is why it's the center), A,C,I, and G are used 3 times, and H,B,D, and F are used 2 times.
So, for clarification, I would like all of this to output what A,B,C, etc. should be equal to given the restrictions.
Thanks for any help.
As an additional request, although not required, but extremely appreciated - if you do provide an answer, explaining some of the important portions of the recursions, functions used and how it achieves my desired outcome would be great.
I think I've made my question clear at this point. In regards to someone's comment, yes I'm asking for the code, because I one am not proficient enough to figure out the complex use of recursion it would take to constantly check the needed constraints required, and two, no other questions really get into the kind of detail I feel I'm trying to go to. Most just what a normal statistical use of Combinations and Permutations, but it doesn't seem there's as many restrictions on the results, and/or their end goal is different.
For the sake of making some things clear, here's another edit:
Below is what I have to first generate the list of all the numbers that will be used.
int A, B, C, D, E, F, G, H, I;
Console.WriteLine("Choose a number that's all 9 spots added together.");
Console.WriteLine("Make sure the number is divisble by 3 and 9.");
int myNumber = int.Parse(Console.ReadLine());
int sums = myNumber / 3;
E = myNumber / 9;
if (E%1 != 0)
{
Console.WriteLine("You did not enter a value divisible by 3 and 9");
Console.WriteLine("Try again.");
Console.ReadLine();
}
else
{
List<int> list = new List<int>();
int lowest = E - 4;
for (int x = lowest;x < E; x++)
{
list.Add(x);
}
int highest = E + 4;
for (int y=E;y<highest;y++)
{
list.Add(y+1);
}
//Testing output
foreach (int i in list)
{
Console.WriteLine(i);
}
I made this to first see if I could establish the numbers that would be used, then go into finding all the variations of the numbers that would make all the lines equal the same. For example: if they entered 45, all directions would have to equal 15; if they entered 90, all directions would have to equal 30, etc.
Here you go. Knock yourself out.
Func<IEnumerable<int>, IEnumerable<int[]>> permutate = null;
permutate = ns =>
{
if (!ns.Skip(1).Any())
{
return new [] { ns.ToArray() };
}
else
{
return
from n in ns
from ns2 in permutate(ns.Except(new [] { n }))
select new [] { n }.Concat(ns2).ToArray();
}
};
var results =
permutate(Enumerable.Range(1, 9))
.Where(ns => Enumerable.Range(0, 3).All(n => ns[n * 3] + ns[n * 3 + 1] + ns[n * 3 + 2] == 15))
.Where(ns => Enumerable.Range(0, 3).All(n => ns[n] + ns[3 + n] + ns[6 + n] == 15))
.Where(ns => Enumerable.Range(0, 3).All(n => ns[0] + ns[4] + ns[8] == 15))
.Where(ns => Enumerable.Range(0, 3).All(n => ns[2] + ns[4] + ns[6] == 15));
This gives:
2, 7, 6
9, 5, 1
4, 3, 8
2, 9, 4
7, 5, 3
6, 1, 8
4, 3, 8
9, 5, 1
2, 7, 6
4, 9, 2
3, 5, 7
8, 1, 6
6, 1, 8
7, 5, 3
2, 9, 4
6, 7, 2
1, 5, 9
8, 3, 4
8, 1, 6
3, 5, 7
4, 9, 2
8, 3, 4
1, 5, 9
6, 7, 2
I understand what #tekGiant is asking but I do not know how to answer it yet...
G | F | A
H | E | B
I | D | C
You'd need the following combinations:
A+B+C=X
F+E+D=X
G+H+I=X
A+E+I=X
G+E+C=X
G+F+A=X
H+E+B=X
I+D+C=X
Where X is the initial number that you designate to be the one that each of the different combinations add up to.
I need to find one missing number, from a sequence of numbers
such as
4 8 12 16 __ 24.
I need to find the missing number. How would I do that programmatically?
the numbers and the missing placement are not static, so they should be able to change.
Hope it is possible.
You could use some silly linq like this silly example :)
var numbers = new List<int>{4, 8, 12, 16, 24, 28, 36};
int first = numbers.First();
int last = numbers.Last();
var missing = Enumerable.Range(first, last).Where(n => n % first == 0).Except(numbers);
Returns:
20
32
-Bracing self for downvotes-
If you know that it is always an Arithmetic Progression, you can use the formula:
an = a1 + (n - 1) * d
being a1 the first element, d the difference between 2 elements and n the position to calculate, in your case:
an = 4 + (5 - 1) * 4 = 20
Check this: https://en.wikipedia.org/wiki/Arithmetic_progression
I'm trying to refactor this algorithm to make it faster. What would be the first refactoring here for speed?
public int GetHowManyFactors(int numberToCheck)
{
// we know 1 is a factor and the numberToCheck
int factorCount = 2;
// start from 2 as we know 1 is a factor, and less than as numberToCheck is a factor
for (int i = 2; i < numberToCheck; i++)
{
if (numberToCheck % i == 0)
factorCount++;
}
return factorCount;
}
The first optimization you could make is that you only need to check up to the square root of the number. This is because factors come in pairs where one is less than the square root and the other is greater.
One exception to this is if n is an exact square then its square root is a factor of n but not part of a pair.
For example if your number is 30 the factors are in these pairs:
1 x 30
2 x 15
3 x 10
5 x 6
So you don't need to check any numbers higher than 5 because all the other factors can already be deduced to exist once you find the corresponding small factor in the pair.
Here is one way to do it in C#:
public int GetFactorCount(int numberToCheck)
{
int factorCount = 0;
int sqrt = (int)Math.Ceiling(Math.Sqrt(numberToCheck));
// Start from 1 as we want our method to also work when numberToCheck is 0 or 1.
for (int i = 1; i < sqrt; i++)
{
if (numberToCheck % i == 0)
{
factorCount += 2; // We found a pair of factors.
}
}
// Check if our number is an exact square.
if (sqrt * sqrt == numberToCheck)
{
factorCount++;
}
return factorCount;
}
There are other approaches you could use that are faster but you might find that this is already fast enough for your needs, especially if you only need it to work with 32-bit integers.
Reducing the bound of how high you have to go as you could knowingly stop at the square root of the number, though this does carry the caution of picking out squares that would have the odd number of factors, but it does help reduce how often the loop has to be executed.
Looks like there is a lengthy discussion about this exact topic here: Algorithm to calculate the number of divisors of a given number
Hope this helps
The first thing to notice is that it suffices to find all of the prime factors. Once you have these it's easy to find the number of total divisors: for each prime, add 1 to the number of times it appears and multiply these together. So for 12 = 2 * 2 * 3 you have (2 + 1) * (1 + 1) = 3 * 2 = 6 factors.
The next thing follows from the first: when you find a factor, divide it out so that the resulting number is smaller. When you combine this with the fact that you need only check to the square root of the current number this is a huge improvement. For example, consider N = 10714293844487412. Naively it would take N steps. Checking up to its square root takes sqrt(N) or about 100 million steps. But since the factors 2, 2, 3, and 953 are discovered early on you actually only need to check to one million -- a 100x improvement!
Another improvement: you don't need to check every number to see if it divides your number, just the primes. If it's more convenient you can use 2 and the odd numbers, or 2, 3, and the numbers 6n-1 and 6n+1 (a basic wheel sieve).
Here's another nice improvement. If you can quickly determine whether a number is prime, you can reduce the need for division even further. Suppose, after removing small factors, you have 120528291333090808192969. Even checking up to its square root will take a long time -- 300 billion steps. But a Miller-Rabin test (very fast -- maybe 10 to 20 nanoseconds) will show that this number is composite. How does this help? It means that if you check up to its cube root and find no factors, then there are exactly two primes left. If the number is a square, its factors are prime; if the number is not a square, the numbers are distinct primes. This means you can multiply your 'running total' by 3 or 4, respectively, to get the final answer -- even without knowing the factors! This can make more of a difference than you'd guess: the number of steps needed drops from 300 billion to just 50 million, a 6000-fold improvement!
The only trouble with the above is that Miller-Rabin can only prove that numbers are composite; if it's given a prime it can't prove that the number is prime. In that case you may wish to write a primality-proving function to spare yourself the effort of factoring to the square root of the number. (Alternately, you could just do a few more Miller-Rabin tests, if you would be satisfied with high confidence that your answer is correct rather than a proof that it is. If a number passes 15 tests then it's composite with probability less than 1 in a billion.)
You can limit the upper limit of your FOR loop to numberToCheck / 2
Start your loop counter at 2 (if your number is even) or 3 (for odd values). This should allow you to check every other number dropping your loop count by another 50%.
public int GetHowManyFactors(int numberToCheck)
{
// we know 1 is a factor and the numberToCheck
int factorCount = 2;
int i = 2 + ( numberToCheck % 2 ); //start at 2 (or 3 if numberToCheck is odd)
for( ; i < numberToCheck / 2; i+=2)
{
if (numberToCheck % i == 0)
factorCount++;
}
return factorCount;
}
Well if you are going to use this function a lot you can use modified algorithm of Eratosthenes http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes and store answars for a interval 1 to Max in array. It will run IntializeArray() once and after it will return answers in 0(1).
const int Max =1000000;
int arr [] = new int [Max+1];
public void InitializeArray()
{
for(int i=1;i<=Max;++i)
arr[i]=1;//1 is factor for everyone
for(int i=2;i<=Max;++i)
for(int j=i;i<=Max;i+=j)
++arr[j];
}
public int GetHowManyFactors(int numberToCheck)
{
return arr[numberToCheck];
}
But if you are not going to use this function a lot I think best solution is to check unitll square root.
Note: I have corrected my code!
An easy to implement algorithm that will bring you much farther than trial division is Pollard Rho
Here is a Java implementation, that should be easy to adapt to C#: http://www.cs.princeton.edu/introcs/78crypto/PollardRho.java.html
https://codility.com/demo/results/demoAAW2WH-MGF/
public int solution(int n) {
var counter = 0;
if (n == 1) return 1;
counter = 2; //1 and itself
int sqrtPoint = (Int32)(Math.Truncate(Math.Sqrt(n)));
for (int i = 2; i <= sqrtPoint; i++)
{
if (n % i == 0)
{
counter += 2; // We found a pair of factors.
}
}
// Check if our number is an exact square.
if (sqrtPoint * sqrtPoint == n)
{
counter -=1;
}
return counter;
}
Codility Python 100 %
Here is solution in python with little explanation-
def solution(N):
"""
Problem Statement can be found here-
https://app.codility.com/demo/results/trainingJNNRF6-VG4/
Codility 100%
Idea is count decedent factor in single travers. ie. if 24 is divisible by 4 then it is also divisible by 8
Traverse only up to square root of number ie. in case of 24, 4*4 < 24 but 5*5!<24 so loop through only i*i<N
"""
print(N)
count = 0
i = 1
while i * i <= N:
if N % i == 0:
print()
print("Divisible by " + str(i))
if i * i == N:
count += 1
print("Count increase by one " + str(count))
else:
count += 2
print("Also divisible by " + str(int(N / i)))
print("Count increase by two count " + str(count))
i += 1
return count
Example by run-
if __name__ == '__main__':
# result = solution(24)
# result = solution(35)
result = solution(1)
print("")
print("Solution " + str(result))
"""
Example1-
24
Divisible by 1
Also divisible by 24
Count increase by two count 2
Divisible by 2
Also divisible by 12
Count increase by two count 4
Divisible by 3
Also divisible by 8
Count increase by two count 6
Divisible by 4
Also divisible by 6
Count increase by two count 8
Solution 8
Example2-
35
Divisible by 1
Also divisible by 35
Count increase by two count 2
Divisible by 5
Also divisible by 7
Count increase by two count 4
Solution 4
Example3-
1
Divisible by 1
Count increase by one 1
Solution 1
"""
Github link
I got pretty good results with complexity of O(sqrt(N)).
if (N == 1) return 1;
int divisors = 0;
int max = N;
for (int div = 1; div < max; div++) {
if (N % div == 0) {
divisors++;
if (div != N/div) {
divisors++;
}
}
if (N/div < max) {
max = N/div;
}
}
return divisors;
Python Implementation
Score 100% https://app.codility.com/demo/results/trainingJ78AK2-DZ5/
import math;
def solution(N):
# write your code in Python 3.6
NumberFactor=2; #one and the number itself
if(N==1):
return 1;
if(N==2):
return 2;
squareN=int(math.sqrt(N)) +1;
#print(squareN)
for elem in range (2,squareN):
if(N%elem==0):
NumberFactor+=2;
if( (squareN-1) * (squareN-1) ==N):
NumberFactor-=1;
return NumberFactor