Compression using prime numbers - compression
I think I've found a way you can do lossless compression using prime numbers or make other methods available over and over again.
There are 54 prime numbers in the range 0-255. When we have the prime number in a byte array, we can store it using the prime number indexes of that number, using 6 bits instead of 8 bits, right?
We need to create a map using a bit for each byte, which we can store for which numbers we are compressing, and add it to the data array.
This seems to work at first, but increases the file size slightly, but reduces the file to a re-compressible structure for algorithms like LZ4 or Huffman.
The indexes 0-53 correspond to the prime numbers 2-251, but there are unused numbers for 6 bits. (54-63). These 10 numbers can also be an opportunity to store 10 different non-prime numbers with the highest frequency in 6 bits. So we're going to squeeze more numbers. If this ratio exceeds 50%, we will be able to perform successful compression.
In addition, this method can create an opportunity to recompress compressed numbers. Do you think that if we create a method for uint and ulong data types in 4 or 8 byte data blocks instead of one byte, we can reduce the map of compressed data to a smaller size, right?
There are 203280221 prime numbers less than 2 ^ 32. This means that we can store 28 bits instead of 32 bits for each prime number.
By looking at the ratio of prime numbers in the data array, we can determine whether we can perform efficient compression.
I think that this method is not an effective compression method, but rather a data exchange that may allow re-compression of compressed files.
I would like to ask you know of other methods that we can do using prime numbers? Because obtaining prime numbers was very easy, especially for numbers below 2 ^ 32. We need to add prime number methods to our methods.
One efficient and practical compression method for 32-bit primes is storing the halved difference between consecutive primes using simple 8-bit bytes (and pulling the prime 2 out of thin air when needed). With a bit of indexing magic this gives superfast 'decompression' - i.e. it is an ideal form of representation when iteration over prime ranges is required since it uses less memory than plain primes.
The 203,280,220 odd primes below 2^32 need a corresponding number of bytes, i.e. a bit less than 194 MB. The usability of byte-sized halved differences extends to 304,599,508,537 (roughly 2^38) but from that point on it is necessary to invent a scheme for coding occasional gaps greater than 510. However, when storing gap indices instead of halved gap widths then the scheme can pretty much go on forever (see Prime gap article # Wikipedia).
These blocks of consecutive differences can be further compressed using the usual zlib-stile compression or similar, in which case you get better compression than when compressing a packed odds-only bitmap or a mod 30 wheel. This could be used as a compact on-disk representation.
Note, however, that a mod 30 wheel takes only 136 MB and it is directly indexable - like for satisfying primality queries. Extracting (decoding) ranges of primes is quite a bit slower than for delta-coded primes but still faster than sieving the primes afresh. Hence storing primes using the mod 30 wheel is one of the most efficient ways for 'compressing' primes in a way that keeps them directly available/usable.
Mixed forms can also be quite successful. For example, when decoding primes from a mod 30 wheel you can store them directly in delta-coded form without materialising them as vectors of numbers. This could be viewed as a form of re-compression. The mod 30 wheel would be the on-disk and main memory format, the delta coding would be the interchange format for the results of certain queries.
Delta coding and wheeled storage share one important advantage: their storage requirements are basically independent of the size of the represented primes. By contrast, if you store the primes as numbers than you get logarithmically increasing storage requirements. I.e. a 64-bit prime takes four times as much space as a 16-bit prime.
An explanation of prime wheels can be found in the Wikipedia article Wheel factorization.
The following table shows the space reduction that you get when adding more and more primes to the wheel, both relative to an unwheeled representation ('ratio') and relative to the preceding step ('delta'). The column 'spokes' gives the number of of potentially prime-bearing spokes (residues) per wheel rotation, which gives you an idea of the complexity of an optimised, fully unrolled implementation à la Kim Walisch's primesieve. As you can see the gains are diminishing rapidly while complexity is exploding.
The wheel mod 2 - a.k.a. odds-only sieve - is important because it gives you most of the bang at virtually no cost in code complexity. Most of speed benefits of the mod 3 wheel can be reaped with almost no effort by sleight-of-hand (indexing tricks) when operating an odds-only sieve. The wheel mod 30 is important because it offers a good balance between code complexity and speedup, which makes it an ideal target for optimised implementations. The wheels up to mod 30030 have been used in practical implementations but the gain compared to the mod 30 wheel is actually negligible while the increased complexity and lost performance are not. Even higher-order wheels have been seen on university campuses, in the context of special projects.
One of the reasons why Kim Walisch's sieve program is the fastest that you can find anywhere on the Net is that he implemented unrolled versions of each of the 8 possible striding sequences of the mod 30 wheel, with specific loop entry points for each of the 8 possible phases of each sequence. All that in the only language (C/C++) for which you can get optimising compilers that are actually worthy of the name.
Doing the same for the 48 residues of the wheel mod 210 would mean 36 times as much code (!) while the reduction in bitmap size is negligible. However, mod 210 and mod 2310 might be promising targets for a code generator (C/C++ code or .NET IL), if you have a couple months of spare time to burn.
You guys got me wrong. I'm talking about compressing random data. If you divide a file into 4-byte data blocks, 1 out of 10 of each 4-byte number will be prime. You should also use a bitmap to determine whether each number is prime. Using a bitmap will clearly increase the size of the file, but I think it can be compressed more than 32/80. Because it has too many 0 bits.
You might say, "This is a very funny compression algorithm." Because it is more compressed size is using other compression algorithms. But isn't it important to have the ability to repeat the compression process? Please ignore this funny situation.
Step by step. First of all, let me share the Prime Helper codes we need.
How can the findPrimes () and saveToFile () methods be more efficient in these codes? For now, the prime numbers up to 2 ^ 32 are found on my Core i7 in about 23 minutes and are saved in 512MB. You can then load the prime numbers from the file for direct use without recalculating.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace PrimeNumbers {
public static class PrimeHelper {
public static IEnumerable<long> FindPrimes (long limit) {
return (new Primes (limit));
}
public static IEnumerable<long> FindPrimes (long start, long end) {
return FindPrimes (end).Where (pn => pn >= start);
}
public static bool IsPrime (this long number) {
if (number < 2)
return false;
else if (number < 4)
return true;
var limit = (Int32) System.Math.Sqrt (number) + 1;
var foundPrimes = new Primes (limit);
return foundPrimes.IsPrime (number);
}
public static bool IsPrime (this int number) {
return IsPrime (Convert.ToInt64 (number));
}
public static bool IsPrime (this short number) {
return IsPrime (Convert.ToInt64 (number));
}
public static bool IsPrime (this byte number) {
return IsPrime (Convert.ToInt64 (number));
}
public static bool IsPrime (this uint number) {
return IsPrime (Convert.ToInt64 (number));
}
public static bool IsPrime (this ushort number) {
return IsPrime (Convert.ToInt64 (number));
}
public static bool IsPrime (this sbyte number) {
return IsPrime (Convert.ToInt64 (number));
}
}
public class Primes : IEnumerable<long>, IDisposable {
private long limit;
private MyBitArray numbers;
public Primes (long limit) {
startTime = DateTime.Now;
calculateTime = startTime - startTime;
this.limit = limit + 1;
try { findPrimes (); } catch (Exception e) { Console.WriteLine (e.Message); /*Overflows or Out of Memory*/ }
calculateTime = DateTime.Now - startTime;
}
public Primes (MyBitArray bitArray) {
this.numbers = bitArray;
this.limit = bitArray.Limit;
}
private void findPrimes () {
/*
The Sieve Algorithm
http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
*/
numbers = new MyBitArray (limit, true);
for (long i = 2; i < limit; i++)
if (numbers[i])
for (long j = i * 2; j < limit; j += i)
numbers[j] = false;
}
public IEnumerator<long> GetEnumerator () {
for (long i = 2; i < limit; i++)
if (numbers[i])
yield return i;
}
IEnumerator IEnumerable.GetEnumerator () {
return GetEnumerator ();
}
// Extended big long number for quickly calculation
public bool IsDivisible (long number) {
var sqrt = System.Math.Sqrt (number);
foreach (var prime in this) {
if (number % prime == 0) {
DivisibleBy = prime;
return true;
}
if (prime > sqrt)
return false;
}
return false;
}
// For big long number
public bool IsPrime (long number) {
return number < limit ?
this.SingleOrDefault (n => n == number) != 0 :
!IsDivisible (number);
}
public void Dispose () {
numbers.Dispose ();
}
public void SaveToFile (string fileName, SaveOptions saveOptions) {
int elementSize = 8;
if ((this.limit - 1L) <= Convert.ToInt64 (byte.MaxValue))
elementSize = 1;
else if ((this.limit - 1L) <= Convert.ToInt64 (ushort.MaxValue))
elementSize = 2;
else if ((this.limit - 1L) <= Convert.ToInt64 (uint.MaxValue))
elementSize = 4;
switch (saveOptions) {
case SaveOptions.TextFile:
saveToTextFile (fileName);
break;
case SaveOptions.BinaryAllNumbersBitArray:
saveToFile (fileName, this.Numbers.Bytes);
break;
case SaveOptions.BinaryPrimeList:
saveToFile (fileName, this, elementSize);
break;
case SaveOptions.BinaryAllNumbersAndPrimeIndex:
saveToFileOnlyIndex (fileName, this, elementSize);
break;
case SaveOptions.All:
saveToFile (Path.Combine (Path.GetDirectoryName (fileName), Path.GetFileNameWithoutExtension (fileName) + "_BinaryAllNumbersBitArray.bin"), this.Numbers.Bytes);
saveToFile (Path.Combine (Path.GetDirectoryName (fileName), Path.GetFileNameWithoutExtension (fileName) + "_BinaryPrimeList.bin"), this, elementSize);
saveToFileOnlyIndex (Path.Combine (Path.GetDirectoryName (fileName), Path.GetFileNameWithoutExtension (fileName) + "_BinaryAllNumbersPrimeIndex.bin"), this, elementSize);
saveToTextFile (Path.Combine (Path.GetDirectoryName (fileName), Path.GetFileNameWithoutExtension (fileName) + "_TextFile.txt"));
break;
}
}
protected void saveToFile (string fileName, byte[] data) {
Console.WriteLine ("Saving numbers bits if is prime bit 1 else bit 0...");
using (MemoryStream mstream = new MemoryStream (data)) {
ProgressCallback callback = (long position, long total) => { };
copy (mstream, fileName, callback);
}
}
protected void saveToFile (string fileName, Primes primes, int elementSize = 4) {
Console.WriteLine ("Saving primes. Element size: {0}...", elementSize);
using (FileStream file = File.OpenWrite (fileName)) {
long writed = 0;
foreach (var prime in primes) {
byte[] data = new byte[elementSize];
if (elementSize == 8) {
data = BitConverter.GetBytes (Convert.ToUInt64 (prime));
} else if (elementSize == 4) {
data = BitConverter.GetBytes (Convert.ToUInt32 (prime));
} else if (elementSize == 2) {
data = BitConverter.GetBytes (Convert.ToUInt16 (prime));
} else if (elementSize == 1) {
data = BitConverter.GetBytes (Convert.ToByte (prime));
}
file.Write (data, 0, elementSize);
writed++;
if (writed == 536870912L) {
file.Flush (true);
writed = 0;
}
}
file.Close ();
}
}
protected void saveToFileOnlyIndex (string fileName, Primes primes, int elementSize = 4) {
Console.WriteLine ("Saving all numbers prime indexes if not prime index is -1. Element size: {0}...", elementSize);
using (FileStream file = File.OpenWrite (fileName)) {
int index = 0;
long writed = 0;
long length = Convert.ToInt64 (uint.MaxValue) + 1L;
for (long i = 0; i < length; i++) {
byte[] data = new byte[elementSize];
if (elementSize == 8) {
if (primes.Numbers[i]) {
index++;
data = BitConverter.GetBytes (Convert.ToInt64 (index));
} else {
data = BitConverter.GetBytes (Convert.ToInt32 (-1));
}
} else if (elementSize == 4) {
if (primes.Numbers[i]) {
index++;
data = BitConverter.GetBytes (Convert.ToInt32 (index));
} else {
data = BitConverter.GetBytes (Convert.ToInt32 (-1));
}
} else if (elementSize == 2) {
if (primes.Numbers[i]) {
index++;
data = BitConverter.GetBytes (Convert.ToInt16 (index));
} else {
data = BitConverter.GetBytes (Convert.ToInt16 (-1));
}
} else if (elementSize == 1) {
if (primes.Numbers[i]) {
index++;
data = BitConverter.GetBytes (Convert.ToSByte (index));
} else {
data = BitConverter.GetBytes (Convert.ToSByte (-1));
}
}
file.Write (data, 0, elementSize);
writed++;
if (writed == 536870912L) {
file.Flush (true);
writed = 0;
}
}
file.Close ();
}
}
public delegate void ProgressCallback (long position, long total);
protected void copy (Stream inputStream, string outputFile, ProgressCallback progressCallback) {
using (var outputStream = File.OpenWrite (outputFile)) {
int writed = 0;
const int bufferSize = 65536;
while (inputStream.Position < inputStream.Length) {
byte[] data = new byte[bufferSize];
int amountRead = inputStream.Read (data, 0, bufferSize);
outputStream.Write (data, 0, amountRead);
writed++;
if (progressCallback != null)
progressCallback (inputStream.Position, inputStream.Length);
if (writed == 32768) {
outputStream.Flush (true);
writed = 0;
}
}
outputStream.Flush (true);
}
}
protected void saveToTextFile (string fileName) {
Console.WriteLine ("Saving primes to text file...");
using (System.IO.StreamWriter file =
new System.IO.StreamWriter (fileName)) {
long writed = 0;
foreach (var prime in this) {
file.WriteLine (prime.ToString ());
if (writed == 536870912L) {
file.Flush ();
writed = 0;
}
}
file.Close ();
}
}
private static DateTime startTime;
private static TimeSpan calculateTime;
public TimeSpan CalculateTime { get { return calculateTime; } }
public long DivisibleBy { get; set; }
public long Length { get { return limit; } }
public MyBitArray Numbers { get { return numbers; } }
}
public class MyBitArray : IDisposable {
byte[] bytes;
public MyBitArray (long limit, bool defaultValue = false) {
long byteCount = Convert.ToInt64 ((limit >> 3) + 1);
this.bytes = new byte[byteCount];
for (long i = 0; i < byteCount; i++) {
bytes[i] = (defaultValue == true ? (byte) 0xFF : (byte) 0x00);
}
this.limit = limit;
}
public MyBitArray (long limit, byte[] bytes) {
this.limit = limit;
this.bytes = bytes;
}
public bool this [long index] {
get {
return getValue (index);
}
set {
setValue (index, value);
}
}
bool getValue (long index) {
if (index < 8) {
return getBit (bytes[0], (byte) index);
}
long byteIndex = (index & 7) == 0 ? ((index >> 3) - 1) : index >> 3;
byte bitIndex = (byte) (index & 7);
return getBit (bytes[byteIndex], bitIndex);
}
void setValue (long index, bool value) {
if (index < 8) {
bytes[0] = setBit (bytes[0], (byte) index, value);
return;
}
long byteIndex = (index & 7) == 0 ? (index >> 3) - 1 : index >> 3;
byte bitIndex = (byte) (index & 7);
bool old = getBit (bytes[byteIndex], bitIndex);
bytes[byteIndex] = setBit (bytes[byteIndex], bitIndex, value);
}
bool getBit (byte byt, byte index) {
return ((byt & (1 << index)) >> index) == 1;
}
byte setBit (byte byt, byte index, bool value) {
return (byte) ((byt & ~(1 << index)) + (value ? 1 << index : 0));
}
public void Dispose () {
GC.Collect (2, GCCollectionMode.Optimized);
}
private long limit;
public long Limit { get { return limit; } }
public byte[] Bytes { get { return this.bytes; } }
}
public enum SaveOptions {
All,
TextFile,
BinaryAllNumbersBitArray,
BinaryPrimeList,
BinaryAllNumbersAndPrimeIndex
}
}
Related
Find an element in a matrix M*M of numbers which have exactly 3 divisors in given time?
This was a task given on a coding competition a few months ago, and its still bugging me now. I did solve it, but my code did not give the result in required time for 3 test samples, likely due to the very large numbers they used. The thing is, looking at my code i see no obvious improvements that would reduce the time further. The input has 3 numbers: the side length of the matrix, row and column of the required number. For a matrix size 3, it would look like: 4 9 16 121 49 25 169 289 361 A number that has 3 divisors can only be a squared prime number, so my solution was to generate primes until the needed position. #include<iostream> bool prime(long long a) { //if(a%2==0) // return false; //no numbers passed will be even for(long long i=3;i*i<=a;i+=2) if(a%i==0) return false; return true; } int main() { int side, row, col, elem, count=1; long long num=1; std::cin >> side >> row >> col; if(row==1 && col==1) { std::cout << '4'; return 0; } elem=(row-1)*side+col+(row%2==0)*(side-2*col+1);//gets required position in matrix while(count<elem) { num+=2; if(prime(num)) count++; } std::cout << num*num; }
Rather than this: while(count<elem) { num+=2; if(prime(num)) count++; } This: vector<long long> primes; primes.push_back(2); while (count < elem) { num += 2; if (prime(num, primes)) { primes.push_back(num); count++; } } Where your prime function is modified to only test divisibility against previously found prime numbers: bool prime(long long num, const vector<long long>& primes) { for (auto p : primes) { if (num % p == 0) { return false; } } return true; } The above should speed things up significantly. There's also the sieve of eros thing. But the above should be sufficient for most leet coding challenge sites.
A bare-bones implementation of Sieve of Eratosthenes, you could try with this: bool is_prime(size_t p, std::vector<bool>& primes) { if (!primes[p]) return false; for (auto i = p * p; i < primes.size(); i += p) { primes[i] = false; } return true; } void init_primes(std::vector<bool>& primes, size_t N) { primes = std::vector(N, true); primes[0] = false; primes[1] = false; primes[2] = true; } int main() { std::vector<bool> p; init_primes(p, 1000); // <- insert some large enough number here ... }
Convert inefficient recursive coin change function to iteration
I have an inefficient recursive coin change function that works out the number of coin combinations for a given amount. I would like to convert it to a more efficient iterative function if possible. One problem is that I am using backtracking to try out different coins in an array called denominations. I am also using memoization but it doesn't speed things up when the amount is large. Here's my code: unsigned long long CalculateCombinations(std::vector<double> &denominations, std::vector<double> change, double amount, unsigned int index) { double current = 0.0; unsigned long long combinations = 0; if (amount == 0.0) { if (change.size() % 2 == 0) { combinations = Calculate(change); } return combinations; } // If amount is less than 0 then no solution exists if (amount < 0.0) return 0; // If there are no coins and index is greater than 0, then no solution exist if (index >= denominations.size()) return 0; std::string str = std::to_string(amount) + "-" + std::to_string(index) + "-" + std::to_string(change.size()); auto it = Memo.find(str); if (it != Memo.end()) { return it->second; } while (current <= amount) { double remainder = amount - current; combinations += CalculateCombinations(denominations, change, remainder, index + 1); current += denominations[index]; change.push_back(denominations[index]); } Memo[str] = combinations; return combinations; } Any ideas how this can be done? I know there are DP solutions for coin change problems, but mine doesn't lend itself easily to one. I can have half pennies. *Update: I changed the function to be iterative and I scaled up by a factor of 2 to use integers, bit it made no considerable difference. Here's my new code: unsigned long long CalculateCombinations(std::vector<int> &denominations, std::vector<int> change, int amount, unsigned int index) { unsigned long long combinations = 0; if (amount <= 0) return combinations; std::stack<Param> mystack; mystack.push({ change, amount, index }); while (!mystack.empty()) { int current = 0; std::vector<int> current_coins = mystack.top().Coins; int current_amount = mystack.top().Amount; unsigned int current_index = mystack.top().Index; mystack.pop(); if (current_amount == 0) { if (current_coins.size() % 2 == 0) { combinations += Calculate(std::move(current_coins)); } } else { std::string str = std::to_string(current_amount) + "-" + std::to_string(current_index); if (Memo.find(str) == Memo.end()) { // If amount is less than 0 then no solution exists if (current_amount >= 0 && current_index < denominations.size()) { while (current <= current_amount) { int remainder = current_amount - current; mystack.push({ current_coins, remainder, current_index + 1 }); current += denominations[current_index]; current_coins.push_back(denominations[current_index]); } } else { Memo.insert(str); } } } } return combinations; } Memo is defined as std::unordered_set. Can this be solved by DP? The problem is that I'm not interested in all combinations - only combinations that are even in size.
I don't see any strategy in your code that discards denominations. My recursive answer would be at each recursive stage to create 2 children: 1 child uses the full list of denominations, and spends 1 of the end denomination The second child discards the same end denomination They each recurse, but in the second case the children have one less denomination to work with. I believe the results returned are all distinct, but of course you do get the pain case where you recurse 10000 levels deep to get $100 in pennies. This can easily be optimised for when you get down to 1 denomination, and probably indicates that it is best to process and discard higher denominations in each round rather than lower denominations. You can also detect the case where all remaining denominations are simple multiples of each other and quickly generate the permutations without doing the full recursion: Generate the minimum coin set (max of each high denomination) then work backward replacing each coin with numbers of smaller coins.
Find Largest Prime Factor - Complexity of Code
I tried a code on a coding website to find the largest prime factor of a number and it's exceeding the time limit for the last test case where probably they are using a large prime number. Can you please help me to reduce the complexity of the following code? int main() { long n; long int lar, fact; long int sqroot; int flag; cin >> n; lar=2, fact=2; sqroot = sqrt(n); flag = 0; while(n>1) { if((fact > sqroot) && (flag == 0)) //Checking only upto Square Root { cout << n << endl; break; } if(n%fact == 0) { flag = 1; lar = fact; while(n%fact == 0) n = n/fact; } fact++; } if(flag == 1) //Don't display if loop fact reached squareroot value cout << lar << endl; } Here I've also taken care of the loop checking till Square Root value. Still, how can I reduce its complexity further?
You can speed things up (if not reduce the complexity) by supplying a hard-coded list of the first N primes to use for the initial values of fact, since using composite values of fact are a waste of time. After that, avoid the obviously composite values of fact (like even numbers).
You can reduce the number of tests by skipping even numbers larger than 2, and stopping sooner if you have found smaller factors. Here is a simpler and faster version: int main() { unsigned long long n, lar, fact, sqroot; cin >> n; lar = 0; while (n && n % 2 == 0) { lar = 2; n /= 2; } fact = 3; sqroot = sqrt(n); while (fact <= sqroot) { if (n % fact == 0) { lar = fact; do { n /= fact; } while (n % fact == 0); sqroot = sqrt(n); } fact += 2; } if (lar < n) lar = n; cout << lar << endl; return 0; } I am not sure how large the input numbers may become, using the larger type unsigned long long for these computations will get you farther than long. Using a precomputed array of primes would help further, but not by a large factor.
The better result I've obtained is using the function below (lpf5()). It's based on the primality() function (below) that uses the formulas 6k+1, 6k-1 to individuate prime numbers. All prime numbers >= 5 may be expressed in one of the forms p=k*6+1 or p=k*6-1 with k>0 (but not all the numbers having such a forms are primes). Developing these formulas we can see a sequence like the following: k=1 5,7 k=2 11,13 k=3 17,19 k=4 23,25* k=5 29,31 . . . k=10 59,61 k=11 65*,67 k=12 71,73 ... 5,7,11,13,17,19,23,25,29,31,...,59,61,65,67,71,73,... We observe that the difference between the terms is alternatively 2 and 4. Such a results may be obtained also using simple math. Is obvious that the difference between k*6+1 and k*6-1 is 2. It's simple to note that the difference between k*6+1 and (k+1)*6-1 is 4. The function primality(x) returns x when x is prime (or 0 - take care) and the first divisor occurs when x is not prime. I think you may obtain a better result inlining the primality() function inside the lpf5() function. I've also tried to insert a table with some primes (from 1 to 383 - the primes in the first 128 results of the indicated formulas) inside the primality function, but the speed difference is unappreciable. Here the code: #include <stdio.h> #include <math.h> typedef long long unsigned int uint64; uint64 lpf5(uint64 x); uint64 primality(uint64 x); uint64 lpf5(uint64 x) { uint64 x_=x; while ( (x_=primality(x))!=x) x=x/x_; return x; } uint64 primality(uint64 x) { uint64 div=7,f=2,q; if (x<4 || x==5) return x; if (!(x&1)) return 2; if (!(x%3)) return 3; if (!(x%5)) return 5; q=sqrt(x); while(div<=q) { if (!(x%div)) { return div; } f=6-f; div+=f; } return x; } int main(void) { uint64 x,k; do { printf("Input long int: "); if (scanf("%llu",&x)<1) break; printf("Largest Prime Factor: %llu\n",lpf5(x)); } while(x!=0); return 0; }
Atomic int incorrectly incrementing? Intel TBB Implementation
I'm implementing a multi-threaded program to validate the Collatz Conjecture for a range of numbers using Intel TBB, and I am having trouble figuring out why the atomic variable <int> count (which keeps count of how many numbers were validated) is not incremented correctly. For the relevant code listed below, I used a small interval (validating just numbers 1-10, but the problem scales as the interval gets larger) and I consistently get a return value of 18 for count. Any ideas? task_scheduler_init init(4); atomic<int> count; void main { tick_count parallel_collatz_start = tick_count::now(); parallel_collatz(); tick_count parallel_collatz_end = tick_count::now(); double parallel_time = 1000 *(parallel_collatz_end - parallel_collatz_start).seconds(); } void parallel_collatz() { parallel_for ( blocked_range<int>(1,10), [=](const blocked_range<int>&r) { for (int k = r.begin(); k <= r.end(); k++) { collatz(k); } } ); } long long collatz (long long n) { while (n != 1) { if (n%2 == 0) n = (n/2); else n = (3*n + 1); } if (n == 1) { count++; return n; } return -1; }
The reason is probably that the constructor uses the half-open range, [1, 10) which means 1 inclusive 10 exclusive, so you're not validating numbers 1-10 but rather 1-9. Additionally you probably want to use != instead of <= in your loop condition.
Determining if a number is prime
I have perused a lot of code on this topic, but most of them produce the numbers that are prime all the way up to the input number. However, I need code which only checks whether the given input number is prime. Here is what I was able to write, but it does not work: void primenumber(int number) { if(number%2!=0) cout<<"Number is prime:"<<endl; else cout<<"number is NOt prime"<<endl; } I would appreciate if someone could give me advice on how to make this work properly. Update I modified it to check on all the numbers in a for loop. void primenumber(int number) { for(int i=1; i<number; i++) { if(number%i!=0) cout<<"Number is prime:"<<endl; else cout<<"number is NOt prime"<<endl; } }
bool isPrime(int number){ if(number < 2) return false; if(number == 2) return true; if(number % 2 == 0) return false; for(int i=3; (i*i)<=number; i+=2){ if(number % i == 0 ) return false; } return true; }
My own IsPrime() function, written and based on the deterministic variant of the famous Rabin-Miller algorithm, combined with optimized step brute forcing, giving you one of the fastest prime testing functions out there. __int64 power(int a, int n, int mod) { __int64 power=a,result=1; while(n) { if(n&1) result=(result*power)%mod; power=(power*power)%mod; n>>=1; } return result; } bool witness(int a, int n) { int t,u,i; __int64 prev,curr; u=n/2; t=1; while(!(u&1)) { u/=2; ++t; } prev=power(a,u,n); for(i=1;i<=t;++i) { curr=(prev*prev)%n; if((curr==1)&&(prev!=1)&&(prev!=n-1)) return true; prev=curr; } if(curr!=1) return true; return false; } inline bool IsPrime( int number ) { if ( ( (!(number & 1)) && number != 2 ) || (number < 2) || (number % 3 == 0 && number != 3) ) return (false); if(number<1373653) { for( int k = 1; 36*k*k-12*k < number;++k) if ( (number % (6*k+1) == 0) || (number % (6*k-1) == 0) ) return (false); return true; } if(number < 9080191) { if(witness(31,number)) return false; if(witness(73,number)) return false; return true; } if(witness(2,number)) return false; if(witness(7,number)) return false; if(witness(61,number)) return false; return true; /*WARNING: Algorithm deterministic only for numbers < 4,759,123,141 (unsigned int's max is 4294967296) if n < 1,373,653, it is enough to test a = 2 and 3. if n < 9,080,191, it is enough to test a = 31 and 73. if n < 4,759,123,141, it is enough to test a = 2, 7, and 61. if n < 2,152,302,898,747, it is enough to test a = 2, 3, 5, 7, and 11. if n < 3,474,749,660,383, it is enough to test a = 2, 3, 5, 7, 11, and 13. if n < 341,550,071,728,321, it is enough to test a = 2, 3, 5, 7, 11, 13, and 17.*/ } To use, copy and paste the code into the top of your program. Call it, and it returns a BOOL value, either true or false. if(IsPrime(number)) { cout << "It's prime"; } else { cout<<"It's composite"; } If you get a problem compiling with "__int64", replace that with "long". It compiles fine under VS2008 and VS2010. How it works: There are three parts to the function. Part checks to see if it is one of the rare exceptions (negative numbers, 1), and intercepts the running of the program. Part two starts if the number is smaller than 1373653, which is the theoretically number where the Rabin Miller algorithm will beat my optimized brute force function. Then comes two levels of Rabin Miller, designed to minimize the number of witnesses needed. As most numbers that you'll be testing are under 4 billion, the probabilistic Rabin-Miller algorithm can be made deterministic by checking witnesses 2, 7, and 61. If you need to go over the 4 billion cap, you will need a large number library, and apply a modulus or bit shift modification to the power() function. If you insist on a brute force method, here is just my optimized brute force IsPrime() function: inline bool IsPrime( int number ) { if ( ( (!(number & 1)) && number != 2 ) || (number < 2) || (number % 3 == 0 && number != 3) ) return (false); for( int k = 1; 36*k*k-12*k < number;++k) if ( (number % (6*k+1) == 0) || (number % (6*k-1) == 0) ) return (false); return true; } } How this brute force piece works: All prime numbers (except 2 and 3) can be expressed in the form 6k+1 or 6k-1, where k is a positive whole number. This code uses this fact, and tests all numbers in the form of 6k+1 or 6k-1 less than the square root of the number in question. This piece is integrated into my larger IsPrime() function (the function shown first). If you need to find all the prime numbers below a number, find all the prime numbers below 1000, look into the Sieve of Eratosthenes. Another favorite of mine. As an additional note, I would love to see anyone implement the Eliptical Curve Method algorithm, been wanting to see that implemented in C++ for a while now, I lost my implementation of it. Theoretically, it's even faster than the deterministic Rabin Miller algorithm I implemented, although I'm not sure if that's true for numbers under 4 billion.
You need to do some more checking. Right now, you are only checking if the number is divisible by 2. Do the same for 2, 3, 4, 5, 6, ... up to number. Hint: use a loop. After you resolve this, try looking for optimizations. Hint: You only have to check all numbers up to the square root of the number
I would guess taking sqrt and running foreach frpm 2 to sqrt+1 if(input% number!=0) return false; once you reach sqrt+1 you can be sure its prime.
C++ bool isPrime(int number){ if (number != 2){ if (number < 2 || number % 2 == 0) { return false; } for(int i=3; (i*i)<=number; i+=2){ if(number % i == 0 ){ return false; } } } return true; } Javascript function isPrime(number) { if (number !== 2) { if (number < 2 || number % 2 === 0) { return false; } for (var i=3; (i*i)<=number; i+=2) { if (number % 2 === 0){ return false; } } } return true; } Python def isPrime(number): if (number != 2): if (number < 2 or number % 2 == 0): return False i = 3 while (i*i) <= number: if(number % i == 0 ): return False; i += 2 return True;
If you know the range of the inputs (which you do since your function takes an int), you can precompute a table of primes less than or equal to the square root of the max input (2^31-1 in this case), and then test for divisibility by each prime in the table less than or equal to the square root of the number given.
This code only checks if the number is divisible by two. For a number to be prime, it must not be evenly divisible by all integers less than itself. This can be naively implemented by checking if it is divisible by all integers less than floor(sqrt(n)) in a loop. If you are interested, there are a number of much faster algorithms in existence.
If you are lazy, and have a lot of RAM, create a sieve of Eratosthenes which is practically a giant array from which you kicked all numbers that are not prime. From then on every prime "probability" test will be super quick. The upper limit for this solution for fast results is the amount of you RAM. The upper limit for this solution for superslow results is your hard disk's capacity.
I follow same algorithm but different implementation that loop to sqrt(n) with step 2 only odd numbers because I check that if it is divisible by 2 or 2*k it is false. Here is my code public class PrimeTest { public static boolean isPrime(int i) { if (i < 2) { return false; } else if (i % 2 == 0 && i != 2) { return false; } else { for (int j = 3; j <= Math.sqrt(i); j = j + 2) { if (i % j == 0) { return false; } } return true; } } /** * #param args */ public static void main(String[] args) { for (int i = 1; i < 100; i++) { if (isPrime(i)) { System.out.println(i); } } } }
Use mathematics first find square root of number then start loop till the number ends which you get after square rooting. check for each value whether the given number is divisible by the iterating value .if any value divides the given number then it is not a prime number otherwise prime. Here is the code bool is_Prime(int n) { int square_root = sqrt(n); // use math.h int toggle = 1; for(int i = 2; i <= square_root; i++) { if(n%i==0) { toggle = 0; break; } } if(toggle) return true; else return false; }
bool check_prime(int num) { for (int i = num - 1; i > 1; i--) { if ((num % i) == 0) return false; } return true; } checks for any number if its a prime number
Someone had the following. bool check_prime(int num) { for (int i = num - 1; i > 1; i--) { if ((num % i) == 0) return false; } return true; } This mostly worked. I just tested it in Visual Studio 2017. It would say that anything less than 2 was also prime (so 1, 0, -1, etc.) Here is a slight modification to correct this. bool check_prime(int number) { if (number > 1) { for (int i = number - 1; i > 1; i--) { if ((number % i) == 0) return false; } return true; } return false; }
Count by 6 for better speed: bool isPrime(int n) { if(n==1) return false; if(n==2 || n==3) return true; if(n%2==0 || n%3==0) return false; for(int i=5; i*i<=n; i=i+6) if(n%i==0 || n%(i+2)==0) return false; return true; }
There are several different approches to this problem. The "Naive" Method: Try all (odd) numbers up to (the root of) the number. Improved "Naive" Method: Only try every 6n ± 1. Probabilistic tests: Miller-Rabin, Solovay-Strasse, etc. Which approach suits you depends and what you are doing with the prime. You should atleast read up on Primality Testing.
If n is 2, it's prime. If n is 1, it's not prime. If n is even, it's not prime. If n is odd, bigger than 2, we must check all odd numbers 3..sqrt(n)+1, if any of this numbers can divide n, n is not prime, else, n is prime. For better performance i recommend sieve of eratosthenes. Here is the code sample: bool is_prime(int n) { if (n == 2) return true; if (n == 1 || n % 2 == 0) return false; for (int i = 3; i*i < n+1; i += 2) { if (n % i == 0) return false; } return true; }
I came up with this: int counter = 0; bool checkPrime(int x) { for (int y = x; y > 0; y--){ if (x%y == 0) { counter++; } } if (counter == 2) { counter = 0; //resets counter for next input return true; //if its only divisible by two numbers (itself and one) its a prime } else counter = 0; return false; }
This is a quick efficient one: bool isPrimeNumber(int n) { int divider = 2; while (n % divider != 0) { divider++; } if (n == divider) { return true; } else { return false; } } It will start finding a divisible number of n, starting by 2. As soon as it finds one, if that number is equal to n then it's prime, otherwise it's not.
//simple function to determine if a number is a prime number //to state if it is a prime number #include <iostream> using namespace std; int isPrime(int x); //functioned defined after int main() int main() { int y; cout << "enter value" << endl; cin >> y; isPrime(y); return 0; } //end of main function //-------------function int isPrime(int x) { int counter = 0; cout << "factors of " << x << " are " << "\n\n"; //print factors of the number for (int i = 0; i <= x; i++) { for (int j = 0; j <= x; j++) { if (i * j == x) //check if the number has multiples; { cout << i << " , "; //output provided for the reader to see the // muliples ++counter; //counts the number of factors } } } cout << "\n\n"; if (counter > 2) { cout << "value is not a prime number" << "\n\n"; } if (counter <= 2) { cout << "value is a prime number" << endl; } }
Here is a simple program to check whether a number is prime or not: #include <iostream> using namespace std; int main() { int n, i, m=0, flag=0; cout << "Enter the Number to check Prime: "; cin >> n; m=n/2; for(i = 2; i <= m; i++) { if(n % i == 0) { cout<<"Number is not Prime."<<endl; flag=1; break; } } if (flag==0) cout << "Number is Prime."<<endl; return 0; }
Here is a C++ code to determine that a given number is prime: bool isPrime(int num) { if(num < 2) return false; for(int i = 2; i <= sqrt(num); i++) if(num % i == 0) return false; return true; } PS Don't forget to include math.h library to use sqrt function
well crafted, share it with you: bool isPrime(int num) { if (num == 2) return true; if (num < 2) return false; if (num % 2 == 0) return false; for (int i = num - 1; i > 1; i--) { if (num % i == 0) return false; } return true; }
There are many potential optimization in prime number testing. Yet many answers here, not only are worse the O(sqrt(n)), they suffer from undefined behavior (UB) and incorrect functionality. A simple prime test: // Return true when number is a prime. bool is_prime(int number) { // Take care of even values, it is only a bit test. if (number % 2 == 0) { return number == 2; } // Loop from 3 to square root (n) for (int test_factor = 3; test_factor <= number / test_factor; test_factor += 2) { if (number % test_factor == 0) { return false; } } return n > 1; } Do not use test_factor * test_factor <= number. It risks signed integer overflow (UB) for large primes. Good compilers see nearby number/test_factor and number % test_factor and emit code that computes both for the about the time cost of one. If still concerned, consider div(). Avoid sqrt(n). Weak floating point libraries do not perform this as exactly as we need for this integer problem, possible returning a value just ever so less than an expected whole number. If still interested in a sqrt(), use lround(sqrt(n)) once before the loop. Avoid sqrt(n) with wide integer types of n. Conversion of n to a double may lose precision. long double may fair no better. Test to insure the prime test code does not behave poorly or incorrectly with 1, 0 or any negative value. Consider bool is_prime(unsigned number) or bool is_prime(uintmax_t number) for extended range. Avoid testing with candidate factors above the square root n and less than n. Such test factors are never factors of n. Not adhering to this makes for slow code. A factor is more likely a small value that an large one. Testing small values first is generally far more efficient for non-primes. Pedantic: Avoid if (number & 1 == 0) {. It is an incorrect test when number < 0 and encoded with rare ones' complement. Use if (number % 2 == 0) { and trust your compiler to emit good code. More advanced techniques use a list of known/discovered primes and the Sieve of Eratosthenes.
#define TRUE 1 #define FALSE -1 int main() { /* Local variables declaration */ int num = 0; int result = 0; /* Getting number from user for which max prime quadruplet value is to be found */ printf("\nEnter the number :"); scanf("%d", &num); result = Is_Prime( num ); /* Printing the result to standard output */ if (TRUE == result) printf("\n%d is a prime number\n", num); else printf("\n%d is not a prime number\n", num); return 0; } int Is_Prime( int num ) { int i = 0; /* Checking whether number is negative. If num is negative, making it positive */ if( 0 > num ) num = -num; /* Checking whether number is less than 2 */ if( 2 > num ) return FALSE; /* Checking if number is 2 */ if( 2 == num ) return TRUE; /* Checking whether number is even. Even numbers are not prime numbers */ if( 0 == ( num % 2 )) return FALSE; /* Checking whether the number is divisible by a smaller number 1 += 2, is done to skip checking divisibility by even numbers. Iteration reduced to half */ for( i = 3; i < num; i += 2 ) if( 0 == ( num % i )) /* Number is divisible by some smaller number, hence not a prime number */ return FALSE; return TRUE; }
I Have Use This Idea For Finding If The No. Is Prime or Not: #include <conio.h> #include <iostream> using namespace std; int main() { int x, a; cout << "Enter The No. :"; cin >> x; int prime(unsigned int); a = prime(x); if (a == 1) cout << "It Is A Prime No." << endl; else if (a == 0) cout << "It Is Composite No." << endl; getch(); } int prime(unsigned int x) { if (x == 1) { cout << "It Is Neither Prime Nor Composite"; return 2; } if (x == 2 || x == 3 || x == 5 || x == 7) return 1; if (x % 2 != 0 && x % 3 != 0 && x % 5 != 0 && x % 7 != 0) return 1; else return 0; }
if(number%2!=0) cout<<"Number is prime:"<<endl; The code is incredibly false. 33 divided by 2 is 16 with reminder of 1 but it's not a prime number...