How do I check if a number is a palindrome? - algorithm

How do I check if a number is a palindrome?
Any language. Any algorithm. (except the algorithm of making the number a string and then reversing the string).

For any given number:
n = num;
rev = 0;
while (num > 0)
{
dig = num % 10;
rev = rev * 10 + dig;
num = num / 10;
}
If n == rev then num is a palindrome:
cout << "Number " << (n == rev ? "IS" : "IS NOT") << " a palindrome" << endl;

This is one of the Project Euler problems. When I solved it in Haskell I did exactly what you suggest, convert the number to a String. It's then trivial to check that the string is a pallindrome. If it performs well enough, then why bother making it more complex? Being a pallindrome is a lexical property rather than a mathematical one.

def ReverseNumber(n, partial=0):
if n == 0:
return partial
return ReverseNumber(n // 10, partial * 10 + n % 10)
trial = 123454321
if ReverseNumber(trial) == trial:
print("It's a Palindrome!")
Works for integers only. It's unclear from the problem statement if floating point numbers or leading zeros need to be considered.

Above most of the answers having a trivial problem is that the int variable possibly might overflow.
Refer to http://articles.leetcode.com/palindrome-number/
boolean isPalindrome(int x) {
if (x < 0)
return false;
int div = 1;
while (x / div >= 10) {
div *= 10;
}
while (x != 0) {
int l = x / div;
int r = x % 10;
if (l != r)
return false;
x = (x % div) / 10;
div /= 100;
}
return true;
}

int is_palindrome(unsigned long orig)
{
unsigned long reversed = 0, n = orig;
while (n > 0)
{
reversed = reversed * 10 + n % 10;
n /= 10;
}
return orig == reversed;
}

Push each individual digit onto a stack, then pop them off. If it's the same forwards and back, it's a palindrome.

I didn't notice any answers that solved this problem using no extra space, i.e., all solutions I saw either used a string, or another integer to reverse the number, or some other data structures.
Although languages like Java wrap around on integer overflow, this behavior is undefined in languages like C. (Try reversing 2147483647 (Integer.MAX_VALUE) in Java)
Workaround could to be to use a long or something but, stylistically, I don't quite like that approach.
Now, the concept of a palindromic number is that the number should read the same forwards and backwards. Great. Using this information, we can compare the first digit and the last digit. Trick is, for the first digit, we need the order of the number. Say, 12321. Dividing this by 10000 would get us the leading 1. The trailing 1 can be retrieved by taking the mod with 10. Now, to reduce this to 232. (12321 % 10000)/10 = (2321)/10 = 232. And now, the 10000 would need to be reduced by a factor of 2. So, now on to the Java code...
private static boolean isPalindrome(int n) {
if (n < 0)
return false;
int div = 1;
// find the divisor
while (n / div >= 10)
div *= 10;
// any number less than 10 is a palindrome
while (n != 0) {
int leading = n / div;
int trailing = n % 10;
if (leading != trailing)
return false;
// % with div gets rid of leading digit
// dividing result by 10 gets rid of trailing digit
n = (n % div) / 10;
// got rid of 2 numbers, update div accordingly
div /= 100;
}
return true;
}
Edited as per Hardik's suggestion to cover the cases where there are zeroes in the number.

Fastest way I know:
bool is_pal(int n) {
if (n % 10 == 0) return 0;
int r = 0;
while (r < n) {
r = 10 * r + n % 10;
n /= 10;
}
return n == r || n == r / 10;
}

In Python, there is a fast, iterative way.
def reverse(n):
newnum=0
while n>0:
newnum = newnum*10 + n % 10
n//=10
return newnum
def palindrome(n):
return n == reverse(n)
This also prevents memory issues with recursion (like StackOverflow error in Java)

Just for fun, this one also works.
a = num;
b = 0;
if (a % 10 == 0)
return a == 0;
do {
b = 10 * b + a % 10;
if (a == b)
return true;
a = a / 10;
} while (a > b);
return a == b;

except making the number a string and then reversing the string.
Why dismiss that solution? It's easy to implement and readable. If you were asked with no computer at hand whether 2**10-23 is a decimal palindrome, you'd surely test it by writing it out in decimal.
In Python at least, the slogan 'string operations are slower than arithmetic' is actually false. I compared Smink's arithmetical algorithm to simple string reversal int(str(i)[::-1]). There was no significant difference in speed - it happened string reversal was marginally faster.
In compiled languages (C/C++) the slogan might hold, but one risks overflow errors with large numbers.
def reverse(n):
rev = 0
while n > 0:
rev = rev * 10 + n % 10
n = n // 10
return rev
upper = 10**6
def strung():
for i in range(upper):
int(str(i)[::-1])
def arithmetic():
for i in range(upper):
reverse(i)
import timeit
print "strung", timeit.timeit("strung()", setup="from __main__ import strung", number=1)
print "arithmetic", timeit.timeit("arithmetic()", setup="from __main__ import arithmetic", number=1)
Results in seconds (lower is better):
strung 1.50960231881
arithmetic 1.69729960569

I answered the Euler problem using a very brute-forcy way. Naturally, there was a much smarter algorithm at display when I got to the new unlocked associated forum thread. Namely, a member who went by the handle Begoner had such a novel approach, that I decided to reimplement my solution using his algorithm. His version was in Python (using nested loops) and I reimplemented it in Clojure (using a single loop/recur).
Here for your amusement:
(defn palindrome? [n]
(let [len (count n)]
(and
(= (first n) (last n))
(or (>= 1 (count n))
(palindrome? (. n (substring 1 (dec len))))))))
(defn begoners-palindrome []
(loop [mx 0
mxI 0
mxJ 0
i 999
j 990]
(if (> i 100)
(let [product (* i j)]
(if (and (> product mx) (palindrome? (str product)))
(recur product i j
(if (> j 100) i (dec i))
(if (> j 100) (- j 11) 990))
(recur mx mxI mxJ
(if (> j 100) i (dec i))
(if (> j 100) (- j 11) 990))))
mx)))
(time (prn (begoners-palindrome)))
There were Common Lisp answers as well, but they were ungrokable to me.

Here is an Scheme version that constructs a function that will work against any base. It has a redundancy check: return false quickly if the number is a multiple of the base (ends in 0).
And it doesn't rebuild the entire reversed number, only half.
That's all we need.
(define make-palindrome-tester
(lambda (base)
(lambda (n)
(cond
((= 0 (modulo n base)) #f)
(else
(letrec
((Q (lambda (h t)
(cond
((< h t) #f)
((= h t) #t)
(else
(let*
((h2 (quotient h base))
(m (- h (* h2 base))))
(cond
((= h2 t) #t)
(else
(Q h2 (+ (* base t) m))))))))))
(Q n 0)))))))

Recursive solution in ruby, without converting the number to string.
def palindrome?(x, a=x, b=0)
return x==b if a<1
palindrome?(x, a/10, b*10 + a%10)
end
palindrome?(55655)

Golang version:
package main
import "fmt"
func main() {
n := 123454321
r := reverse(n)
fmt.Println(r == n)
}
func reverse(n int) int {
r := 0
for {
if n > 0 {
r = r*10 + n%10
n = n / 10
} else {
break
}
}
return r
}

Pop off the first and last digits and compare them until you run out. There may be a digit left, or not, but either way, if all the popped off digits match, it is a palindrome.

Here is one more solution in c++ using templates . This solution will work for case insensitive palindrome string comparison .
template <typename bidirection_iter>
bool palindrome(bidirection_iter first, bidirection_iter last)
{
while(first != last && first != --last)
{
if(::toupper(*first) != ::toupper(*last))
return false;
else
first++;
}
return true;
}

a method with a little better constant factor than #sminks method:
num=n
lastDigit=0;
rev=0;
while (num>rev) {
lastDigit=num%10;
rev=rev*10+lastDigit;
num /=2;
}
if (num==rev) print PALINDROME; exit(0);
num=num*10+lastDigit; // This line is required as a number with odd number of bits will necessary end up being smaller even if it is a palindrome
if (num==rev) print PALINDROME

here's a f# version:
let reverseNumber n =
let rec loop acc = function
|0 -> acc
|x -> loop (acc * 10 + x % 10) (x/10)
loop 0 n
let isPalindrome = function
| x when x = reverseNumber x -> true
| _ -> false

A number is palindromic if its string representation is palindromic:
def is_palindrome(s):
return all(s[i] == s[-(i + 1)] for i in range(len(s)//2))
def number_palindrome(n):
return is_palindrome(str(n))

def palindrome(n):
d = []
while (n > 0):
d.append(n % 10)
n //= 10
for i in range(len(d)/2):
if (d[i] != d[-(i+1)]):
return "Fail."
return "Pass."

To check the given number is Palindrome or not (Java Code)
class CheckPalindrome{
public static void main(String str[]){
int a=242, n=a, b=a, rev=0;
while(n>0){
a=n%10; n=n/10;rev=rev*10+a;
System.out.println(a+" "+n+" "+rev); // to see the logic
}
if(rev==b) System.out.println("Palindrome");
else System.out.println("Not Palindrome");
}
}

A lot of the solutions posted here reverses the integer and stores it in a variable which uses extra space which is O(n), but here is a solution with O(1) space.
def isPalindrome(num):
if num < 0:
return False
if num == 0:
return True
from math import log10
length = int(log10(num))
while length > 0:
right = num % 10
left = num / 10**length
if right != left:
return False
num %= 10**length
num /= 10
length -= 2
return True

I always use this python solution due to its compactness.
def isPalindrome(number):
return int(str(number)[::-1])==number

int reverse(int num)
{
assert(num >= 0); // for non-negative integers only.
int rev = 0;
while (num != 0)
{
rev = rev * 10 + num % 10;
num /= 10;
}
return rev;
}
This seemed to work too, but did you consider the possibility that the reversed number might overflow? If it overflows, the behavior is language specific (For Java the number wraps around on overflow, but in C/C++ its behavior is undefined). Yuck.
It turns out that comparing from the two ends is easier. First, compare the first and last digit. If they are not the same, it must not be a palindrome. If they are the same, chop off one digit from both ends and continue until you have no digits left, which you conclude that it must be a palindrome.
Now, getting and chopping the last digit is easy. However, getting and chopping the first digit in a generic way requires some thought. The solution below takes care of it.
int isIntPalindrome(int x)
{
if (x < 0)
return 0;
int div = 1;
while (x / div >= 10)
{
div *= 10;
}
while (x != 0)
{
int l = x / div;
int r = x % 10;
if (l != r)
return 0;
x = (x % div) / 10;
div /= 100;
}
return 1;
}

Try this:
reverse = 0;
remainder = 0;
count = 0;
while (number > reverse)
{
remainder = number % 10;
reverse = reverse * 10 + remainder;
number = number / 10;
count++;
}
Console.WriteLine(count);
if (reverse == number)
{
Console.WriteLine("Your number is a palindrome");
}
else
{
number = number * 10 + remainder;
if (reverse == number)
Console.WriteLine("your number is a palindrome");
else
Console.WriteLine("your number is not a palindrome");
}
Console.ReadLine();
}
}

Here is a solution usings lists as stacks in python :
def isPalindromicNum(n):
"""
is 'n' a palindromic number?
"""
ns = list(str(n))
for n in ns:
if n != ns.pop():
return False
return True
popping the stack only considers the rightmost side of the number for comparison and it fails fast to reduce checks

public class Numbers
{
public static void main(int givenNum)
{
int n= givenNum
int rev=0;
while(n>0)
{
//To extract the last digit
int digit=n%10;
//To store it in reverse
rev=(rev*10)+digit;
//To throw the last digit
n=n/10;
}
//To check if a number is palindrome or not
if(rev==givenNum)
{
System.out.println(givenNum+"is a palindrome ");
}
else
{
System.out.pritnln(givenNum+"is not a palindrome");
}
}
}

let isPalindrome (n:int) =
let l1 = n.ToString() |> List.ofSeq |> List.rev
let rec isPalindromeInt l1 l2 =
match (l1,l2) with
| (h1::rest1,h2::rest2) -> if (h1 = h2) then isPalindromeInt rest1 rest2 else false
| _ -> true
isPalindromeInt l1 (n.ToString() |> List.ofSeq)

checkPalindrome(int number)
{
int lsd, msd,len;
len = log10(number);
while(number)
{
msd = (number/pow(10,len)); // "most significant digit"
lsd = number%10; // "least significant digit"
if(lsd==msd)
{
number/=10; // change of LSD
number-=msd*pow(10,--len); // change of MSD, due to change of MSD
len-=1; // due to change in LSD
} else {return 1;}
}
return 0;
}

Related

Produce solutions of k & x = k in range (0,n)

How to efficiently generate all numbers within 0,1,2...n.
(large n).
Such that for a fixed x and varying k (0 <= k < n), k & x = k.
It is easily found out that all the bits with value 1 in k is also 1 in x.
But I have trouble computing all of them.
I used DP to find all the subset sums of set bit in x,to arrive at all the possible solutions.
But this method proves inefficient over multiple such cases requesting for a different x.
Do I have to consider each and every bit which needs to be changed to get all the possibilities?Any other efficient way? Also I certainly dont want to check with all of n.
There is a neat way to do that
for(int i = x ;; i = x & (i - 1)){
print i;
if(i == 0)
break;
}
Notice the condition i = x & (i - 1) make sure i always decreasing and only contains bits in x
See running Java code in here
In case x > n, so i should start with i = min(x, n - 1) & x
First note that the 0-bits in x denote the bits that must be 0 in k, while the 1-bits in x can be either 0 or 1 in k. The algorithm should thus iterate over all possible bit combinations in k for where x has a 1 bit and the resulting number (k) is not greater than n.
These combinations can best be produced by using something like a Grey code sequence, since one can then step from one bit pattern to the next in constant time.
Example:
x = 0b011010 (26)
n = 0b010000 (16)
The values to generate for k are (in order of Grey code sequence):
0b000000 ( = 0)
0b000010 ( = 2)
0b001010 ( = 10)
0b001000 ( = 8)
0b011000 ( = 24) too large: exclude
0b011010 ( = 26) too large: exclude
0b010010 ( = 18) too large: exclude
0b010000 ( = 16)
Because of using a Grey code scheme, only one bit changes from one combination to the next. This means that numbers are not generated in order and some can be too large (> n). This downside is worth it still, as generating them in order would involve more bit changes per step.
Here is a snippet that implements this idea in JavaScript:
function get_nums(n, x) {
// Solution array. Add zero as it is always a solution (assuming non-negative n)
let result = [0],
k = 0,
arr = []; // Helper to follow Grey code sequence
for (let i = 1; i <= n && i <= x; i <<= 1) { // Shift bit to the left
if (x & i) { // This bit is set to 1 in x
arr.push(i);
k += i; // Set this bit in k
if (k <= n) result.push(k); // Add k to solution array
// Produce other matches following Grey code sequence
for (let j = arr.length-2; j >= 0; j--) {
arr.push(-arr[j]);
k -= arr[j]; // Toggle a bit in k
if (k <= n) result.push(k);
}
}
}
return result;
}
console.log(get_nums(16, 26));
Note that the output is not ordered (because of the Grey code sequence used). If you need them ordered, apply some radix sort (or hashing).
In JavaScript it is quite easy to implement such a radix sort, given the values are unique. But in other languages you could implement a more explicit, simplified radix sort. Here is the JavaScript function for it:
function radix_sort_uniques(arr) {
let result = {};
// Add a property to the object for each value in the array
for (let i of arr) result[i] = true;
// Get those properties and convert them back to numeric data type (via map)
// JavaScript will produce them in ascending order:
return Object.keys(result).map(Number);
}
console.log(radix_sort_uniques([0, 2, 10, 8, 16]));
Complexity:
The outer loop iterates once per bit position in n, i.e. log(n) times, while the inner loop approximately doubles each time its number of iterations. So in the worst case (when x is 0 and the inner loop always executes) we get a total number of innermost operations in the order of 2log(n) times, giving a O(n) time complexity.
As x is fixed, the complexity should be expressed in x too. Let's say x has b 1-bits, then the time complexity is O(b+2b).
Imagine, that we have x in binary representation, like this:
x = 00001010110
In this case all k such that k & x = k should be in form
x = 00001010110
k = 0000?0?0??0
where ? is either 0 or 1. So we have to obtain all indexes 1 in x ([1, 2, 4, 6] in the example above) and generate all combinations (16 in the example) of 0 and 1s at the corresponding indexes:
C# implementation:
private static IEnumerable<int> MySolution(int x) {
int[] indexes = Enumerable
.Range(0, 32)
.Where(i => (x >> i) % 2 != 0)
.ToArray();
for (int value = 0; value < 1 << indexes.Length; ++value)
yield return indexes
.Select((v, i) => ((value >> i) % 2) * (1 << v))
.Sum();
}
Test:
Console.WriteLine(String.Join(", ", MySolution(5)));
Outcome (please, notice that the solutions are sorted out):
0, 1, 4, 5
If you want to restrict solutions generated, you can modify the loop:
private static IEnumerable<int> MySolution(int x, int n = -1) {
int[] indexes = Enumerable
.Range(0, 32)
.Where(i => (x >> i) % 2 != 0)
.ToArray();
for (int value = 0; value < 1 << indexes.Length; ++value) {
int result = indexes
.Select((v, i) => ((value >> i) % 2) * (1 << v))
.Sum();
if (n < 0 || result <= n)
yield return;
else
break;
}
}

Binary searching via bitmasking?

I have used this algorithm many times to binary search over Ints or Longs. Basically, I start from Long.MinValue and Long.MaxValue and decide to set the bit at ith position depending on the value of the function I am maximizing (or minimizing). In practice, this turns out to be faster (exactly 63*2 bitwise operations) and easier to code and avoids the many gotchas of traditional binary search implementations.
Here is my algorithm in Scala:
/**
* #return Some(x) such that x is the largest number for which f(x) is true
* If no such x is found, return None
*/
def bitBinSearch(f: Long => Boolean): Option[Long] = {
var n = 1L << 63
var p = 0L
for (i <- 62 to 0 by -1) {
val t = 1L << i
if (f(n + t)) n += t
if (f(p + t)) p += t
}
if (f(p)) Some(p) else if (f(n)) Some(n) else None
}
I have 3 questions:
What is this algorithm called in literature? Surely, I can't be the inventor of this - but, I did not find anything when I tried googling for various combinations of binary-search + bit-masking/toggling. I have been personally calling it "bitBinSearch". I have not seen this mentioned at all in articles going over binary search over an Int or Long domain where this would be trivial to write.
Can the code be improved/shortened in anyway? Right now I keep track of the negative and positive solutions in n and p. Any clever way I can merge them into single variable? Here are some sample test cases: http://scalafiddle.net/console/70a3e3e59bc61c8eb7acfbba1073980c before you attempt an answer
Is there a version that can be made to work with Doubles and Floats?
As long as you're bit-twiddling (a popular pastime in some circles) why not go all the way? I don't know if there's any efficiency to be gained, but I think it actually makes the algorithm a little clearer.
def bitBinSearch(f: Long => Boolean): Option[Long] = {
var n = Long.MinValue
var p = 0L
var t = n >>> 1
while (t > 0) {
if ( f(n|t) ) n |= t
if ( f(p|t) ) p |= t
t >>= 1
}
List(p,n).find(f)
}
Of course, if you go recursive you can eliminate those nasty vars.
import scala.annotation.tailrec
#tailrec
def bitBinSearch( f: Long => Boolean
, n: Long = Long.MinValue
, p: Long = 0L
, t: Long = Long.MinValue >>> 1 ): Option[Long] = {
if (t > 0) bitBinSearch(f
, if (f(n|t)) n|t else n
, if (f(p|t)) p|t else p
, t >> 1
)
else List(p,n).find(f)
}
Again, probably not more efficient, but perhaps a bit more Scala-like.
UPDATE
Your comment about Int/Long got me wondering if one function could do it all.
After traveling down a few dead-ends I finally came up with this (which is, oddly, actually pretty close to your original code).
import Integral.Implicits._
import Ordering.Implicits._
def bitBinSearch[I](f: I => Boolean)(implicit ev:Integral[I]): Option[I] = {
def topBit(x: I = ev.one):I = if (x+x < ev.zero) x else topBit(x+x)
var t:I = topBit()
var p:I = ev.zero
var n:I = t+t
while (t > ev.zero) {
if ( f(p+t) ) p += t
if ( f(n+t) ) n += t
t /= (ev.one+ev.one)
}
List(p,n).find(f)
}
This passes the following tests.
assert(bitBinSearch[Byte] (_ <= 0) == Some(0))
assert(bitBinSearch[Byte] (_ <= 1) == Some(1))
assert(bitBinSearch[Byte] (_ <= -1) == Some(-1))
assert(bitBinSearch[Byte] (_ <= 100) == Some(100))
assert(bitBinSearch[Byte] (_ <= -100) == Some(-100))
assert(bitBinSearch[Short](_ <= 10000) == Some(10000))
assert(bitBinSearch[Short](_ <= -10000) == Some(-10000))
assert(bitBinSearch[Int] (_ <= Int.MinValue) == Some(Int.MinValue))
assert(bitBinSearch[Int] (_ <= Int.MaxValue) == Some(Int.MaxValue))
assert(bitBinSearch[Long] (_ <= Long.MinValue) == Some(Long.MinValue))
assert(bitBinSearch[Long] (_ <= Long.MaxValue) == Some(Long.MaxValue))
assert(bitBinSearch[Long] (_ < Long.MinValue) == None)
I don't know Scala, but this is my version of Binary searching via bitmasking in java
My algorithm is like this
We start with the index with highest power of 2 and end at 20. Every time we see A[itemIndex] ≤ A[index] we update itemIndex += index
After the iteration itemIndex gives the index of the item if present in the array else gives the floor value in A
int find(int[] A, int item) { // A uses 1 based indexing
int index = 0;
int N = A.length;
for (int i = Integer.highestOneBit(N); i > 0; i >>= 1) {
int j = index | i;
if (j < N && A[j] <= item) {
index = j;
if (A[j] == item) break;
}
}
return item == A[index] ? index : -1;
}

How many numbers with length N with K digits D consecutively

Given positive numbers N, K, D (1<= N <= 10^5, 1<=K<=N, 1<=D<=9). How many numbers with N digits are there, that have K consecutive digits D? Write the answer mod (10^9 + 7).
For example: N = 4, K = 3, D = 6, there are 18 numbers:
1666, 2666, 3666, 4666, 5666, 6660,
6661, 6662, 6663, 6664, 6665, 6666, 6667, 6668, 6669, 7666, 8666 and 9666.
Can we calculate the answer in O(N*K) (maybe dynamic programming)?
I've tried using combination.
If
N = 4, K = 3, D = 6. The number I have to find is abcd.
+) if (a = b = c = D), I choose digit for d. There are 10 ways (6660, 6661, 6662, 6663, 6664, 6665, 6666, 6667, 6668, 6669)
+) if (b = c = d = D), I choose digit for a (a > 0). There are 9 ways (1666, 2666, 3666, 4666, 5666, 6666, 7666, 8666, 9666)
But in two cases, the number 6666 is counted twice. N and K is very large, how can I count all of them?
If one is looking for a mathematical solution (vs. necessarily an algorithmic one) it's good to look at it in terms of the base cases and some formulas. They might turn out to be something you can do some kind of refactoring and get a tidy formula for. So just for the heck of it...here's a take on it that doesn't deal with the special treatment of zeros. Because that throws some wrenches in.
Let's look at a couple of base cases, and call our answer F(N,K) (not considering D, as it isn't relevant to account for; but taking it as a parameter anyway.):
when N = 0
You'll never find any length sequences of digits when there's no digit.
F(0, K) = 0 for any K.
when N = 1
Fairly obvious. If you're looking for K sequential digits in a single digit, the options are limited. Looking for more than one? No dice.
F(1, K) = 0 for any K > 1
Looking for exactly one? Okay, there's one.
F(1, 1) = 1
Sequences of zero sequential digits allowed? Then all ten digits are fine.
F(1, 0) = 10
for N > 1
when K = 0
Basically, all N-digit numbers will qualify. So the number of possibilities meeting the bar is 10^N. (e.g. when N is 3 then 000, 001, 002, ... 999 for any D)
F(N, 0) = 10^N for any N > 1
when K = 1
Possibilities meeting the condition is any number with at least one D in it. How many N-digit numbers are there which contain at least one digit D? Well, it's going to be 10^N minus all the numbers that have no instances of the digit D. 10^N - 9^N
F(N, 1) = 10^N - 9^N for any N > 1
when N < K
No way to get K sequential digits if N is less than K
F(N, K) = 0 when N < K
when N = K
Only one possible way to get K sequential digits in N digits.
F(N, K) = 1 when N = K
when N > K
Okay, we already know that N > 1 and K > 1. So this is going to be the workhorse where we hope to use subexpressions for things we've already solved.
Let's start by considering popping off the digit at the head, leaving N-1 digits on the tail. If that N-1 series could achieve a series of K digits all by itself, then adding another digit will not change anything about that. That gives us a term 10 * F(N-1, K)
But if our head digit is a D, that is special. Our cases will be:
It might be the missing key for a series that started with K-1 instances of D, creating a full range of K.
It might complete a range of K-1 instances of D, but on a case that already had a K series of adjacent D (that we thus accounted for in the above term)
It might not help at all.
So let's consider two separate categories of tail series: those that start with K-1 instances of D and those that do not. Let's say we have N=7 shown as D:DDDXYZ and with K=4. We subtract one from N and from K to get 6 and 3, and if we subtract them we get how many trailing any-digits (XYZ here) are allowed to vary. Our term for the union of (1) and (2) to add in is 10^((N-1)-(K-1)).
Now it's time for some subtraction for our double-counts. We haven't double counted any cases that didn't start with K-1 instances of D, so we keep our attention on that (DDDXYZ). If the value in the X slot is a D then it was definitely double counted. We can subtract out the term for that as 10^(((N - 1) - 1) - (K - 1)); in this case giving us all the pairings of YZ digits you can get with X as D. (100).
The last thing to get rid of are the cases where X is not a D, but in whatever that leftover after the X position there was still a K length series of D. Again we reuse our function, and subtract a term 9 * F(N - K, K, D).
Paste it all together and simplify a couple of terms you get:
F(N, K) = 10 * F(N-1,K,D) + 10^(N-K) - 10^(10,N-K-1) - 9 * F(N-K-1,K,D)
Now we have a nice functional definition suitable for Haskelling or whatever. But I'm still awkward with that, and it's easy enough to test in C++. So here it is (assuming availability of a long integer power function):
long F(int N, int K, int D) {
if (N == 0) return 0;
if (K > N) return 0;
if (K == N) return 1;
if (N == 1) {
if (K == 0) return 10;
if (K == 1) return 1;
return 0;
}
if (K == 0)
return power(10, N);
if (K == 1)
return power(10, N) - power(9, N);
return (
10 * F(N - 1, K, D)
+ power(10, N - K)
- power(10, N - K - 1)
- 9 * F(N - K - 1, K, D)
);
}
To double-check this against an exhaustive generator, here's a little C++ test program that builds the list of vectors that it scans using std::search_n. It checks the slow way against the fast way for N and K. I ran it from 0 to 9 for each:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
// http://stackoverflow.com/a/1505791/211160
long power(int x, int p) {
if (p == 0) return 1;
if (p == 1) return x;
long tmp = power(x, p/2);
if (p%2 == 0) return tmp * tmp;
else return x * tmp * tmp;
}
long F(int N, int K, int D) {
if (N == 0) return 0;
if (K > N) return 0;
if (K == N) return 1;
if (N == 1) {
if (K == 0) return 10;
if (K == 1) return 1;
return 0;
}
if (K == 0)
return power(10, N);
if (K == 1)
return power(10, N) - power(9, N);
return (
10 * F(N - 1, K, D)
+ power(10, N - K)
- power(10, N - K - 1)
- 9 * F(N - K - 1, K, D)
);
}
long FSlowCore(int N, int K, int D, vector<int> & digits) {
if (N == 0) {
if (search_n(digits.begin(), digits.end(), K, D) != end(digits)) {
return 1;
} else
return 0;
}
long total = 0;
digits.push_back(0);
for (int curDigit = 0; curDigit <= 9; curDigit++) {
total += FSlowCore(N - 1, K, D, digits);
digits.back()++;
}
digits.pop_back();
return total;
}
long FSlow(int N, int K, int D) {
vector<int> digits;
return FSlowCore(N, K, D, digits);
}
bool TestF(int N, int K, int D) {
long slow = FSlow(N, K, D);
long fast = F(N, K, D);
cout << "when N = " << N
<< " and K = " << K
<< " and D = " << D << ":\n";
cout << "Fast way gives " << fast << "\n";
cout << "Slow way gives " << slow << "\n";
cout << "\n";
return slow == fast;
}
int main() {
for (int N = 0; N < 10; N++) {
for (int K = 0; K < 10; K++) {
if (!TestF(N, K, 6)) {
exit(1);
}
}
}
}
Of course, since it counts leading zeros it will be different from the answers you got. See the test output here in this gist.
Modifying to account for the special-case zero handling is left as an exercise for the reader (as is modular arithmetic). Eliminating the zeros make it messier. Either way, this may be an avenue of attack for reducing the number of math operations even further with some transformations...perhaps.
Miquel is almost correct, but he missed a lot of cases. So, with N = 8, K = 5, and D = 6, we will need to look for those numbers that has the form:
66666xxx
y66666xx
xy66666x
xxy66666
with additional condition that y cannot be D.
So we can have our formula for this example:
66666xxx = 10^3
y66666xx = 8*10^2 // As 0 can also not be the first number
xy66666x = 9*9*10
xxy66666 = 9*10*9
So, the result is 3420.
For case N = 4, K = 3 and D = 6, we have
666x = 10
y666 = 8//Again, 0 is not counted!
So, we have 18 cases!
Note: We need to be careful that the first number cannot be 0! And we need to handle the case when D is zero too!
Update Java working code, Time complexity O(N-K)
static long cal(int n, int k, int d) {
long Mod = 1000000007;
long result = 0;
for (int i = 0; i <= n - k; i++) {//For all starting positions
if (i != 0 || d != 0) {
int left = n - k;
int upper_half = i;//Amount of digit that preceding DDD
int lower_half = n - k - i;//Amount of digit following DDD
long tmp = 1;
if (upper_half == 1) {
if (d == 0) {
tmp = 9;
} else {
tmp = 8;
}
}else if(upper_half >= 2){
//The pattern is x..yDDD...
tmp = (long) (9 * 9 * Math.pow(10, upper_half - 2));
}
tmp *= Math.pow(10, lower_half);
//System.out.println(tmp + " " + upper_half + " " + lower_half);
result += tmp;
result %= Mod;
}
}
return result;
}
Sample Tests:
N = 8, K = 5, D = 6
Output
3420
N = 4, K = 3, D = 6
Output
18
N = 4, K = 3, D = 0
Output
9

Check if one integer is an integer power of another

This is an interview question: "Given 2 integers x and y, check if x is an integer power of y" (e.g. for x = 8 and y = 2 the answer is "true", and for x = 10 and y = 2 "false").
The obvious solution is:int n = y; while(n < x) n *= y; return n == x
Now I am thinking about how to improve it.
Of course, I can check some special cases: e.g. both x and y should be either odd or even numbers, i.e. we can check the least significant bit of x and y. However I wonder if I can improve the core algorithm itself.
You'd do better to repeatedly divide y into x. The first time you get a non-zero remainder you know x is not an integer power of y.
while (x%y == 0) x = x / y
return x == 1
This deals with your odd/even point on the first iteration.
It means logy(x) should be an integer. Don't need any loop. in O(1) time
public class PowerTest {
public static boolean isPower(int x, int y) {
double d = Math.log(Math.abs(x)) / Math.log(Math.abs(y));
if ((x > 0 && y > 0) || (x < 0 && y < 0)) {
if (d == (int) d) {
return true;
} else {
return false;
}
} else if (x > 0 && y < 0) {
if ((int) d % 2 == 0) {
return true;
} else {
return false;
}
} else {
return false;
}
}
/**
* #param args
*/
public static void main(String[] args) {
System.out.println(isPower(-32, -2));
System.out.println(isPower(2, 8));
System.out.println(isPower(8, 12));
System.out.println(isPower(9, 9));
System.out.println(isPower(-16, 2));
System.out.println(isPower(-8, -2));
System.out.println(isPower(16, -2));
System.out.println(isPower(8, -2));
}
}
This looks for the exponent in O(log N) steps:
#define MAX_POWERS 100
int is_power(unsigned long x, unsigned long y) {
int i;
unsigned long powers[MAX_POWERS];
unsigned long last;
last = powers[0] = y;
for (i = 1; last < x; i++) {
last *= last; // note that last * last can overflow here!
powers[i] = last;
}
while (x >= y) {
unsigned long top = powers[--i];
if (x >= top) {
unsigned long x1 = x / top;
if (x1 * top != x) return 0;
x = x1;
}
}
return (x == 1);
}
Negative numbers are not handled by this code, but it can be done easyly with some conditional code when i = 1
This looks to be pretty fast for positive numbers as it finds the lower and upper limits for desired power and then applies binary search.
#include <iostream>
#include <cmath>
using namespace std;
//x is the dividend, y the divisor.
bool isIntegerPower(int x, int y)
{
int low = 0, high;
int exp = 1;
int val = y;
//Loop by changing exponent in the powers of 2 and
//Find out low and high exponents between which the required exponent lies.
while(1)
{
val = pow((double)y, exp);
if(val == x)
return true;
else if(val > x)
break;
low = exp;
exp = exp * 2;
high = exp;
}
//Use binary search to find out the actual integer exponent if exists
//Otherwise, return false as no integer power.
int mid = (low + high)/2;
while(low < high)
{
val = pow((double)y, mid);
if(val > x)
{
high = mid-1;
}
else if(val == x)
{
return true;
}
else if(val < x)
{
low = mid+1;
}
mid = (low + high)/2;
}
return false;
}
int main()
{
cout<<isIntegerPower(1024,2);
}
double a=8;
double b=64;
double n = Math.log(b)/Math.log(a);
double e = Math.ceil(n);
if((n/e) == 1){
System.out.println("true");
} else{
System.out.println("false");
}
I would implement the function like so:
bool IsWholeNumberPower(int x, int y)
{
double power = log(x)/log(y);
return floor(power) == power;
}
This shouldn't need check within a delta as is common with floating point comparisons, since we're checking whole numbers.
On second thoughts, don't do this. It does not work for negative x and/or y. Note that all other log-based answers presented right now are also broken in exactly the same manner.
The following is a fast general solution (in Java):
static boolean isPow(int x, int y) {
int logyx = (int)(Math.log(x) / Math.log(y));
return pow(y, logyx) == x || pow(y, logyx + 1) == x;
}
Where pow() is an integer exponentiation function such as the following in Java:
static int pow(int a, int b) {
return (int)Math.pow(a, b);
}
(This works due to the following guarantee provided by Math.pow: "If both arguments are integers, then the result is exactly equal to the mathematical result of raising the first argument to the power of the second argument...")
The reason to go with logarithms instead of repeated division is performance: while log is slower than division, it is slower by a small fixed multiple. At the same time it does remove the need for a loop and therefore gives you a constant-time algorithm.
In cases where y is 2, there is a quick approach that avoids the need for a loop. This approach can be extended to cases where y is some larger power of 2.
If x is a power of 2, the binary representation of x has a single set bit. There is a fairly simple bit-fiddling algorithm for counting the bits in an integer in O(log n) time where n is the bit-width of an integer. Many processors also have specialised instructions that can handle this as a single operation, about as fast as (for example) an integer negation.
To extend the approach, though, first take a slightly different approach to checking for a single bit. First determine the position of the least significant bit. Again, there is a simple bit-fiddling algorithm, and many processors have fast specialised instructions.
If this bit is the only bit, then (1 << pos) == x. The advantage here is that if you're testing for a power of 4, you can test for pos % 2 == 0 (the single bit is at an even position). Testing for a power of any power of two, you can test for pos % (y >> 1) == 0.
In principle, you could do something similar for testing for powers of 3 and powers of powers of 3. The problem is that you'd need a machine that works in base 3, which is a tad unlikely. You can certainly test any value x to see if its representation in base y has a single non-zero digit, but you'd be doing more work that you're already doing. The above exploits the fact that computers work in binary.
Probably not worth doing in the real world, though.
Here is a Python version which puts together the ideas of #salva and #Axn and is modified to not generate any numbers greater than those given and uses only simple storage (read, "no lists") by repeatedly paring away at the number of interest:
def perfect_base(b, n):
"""Returns True if integer n can be expressed as b**e where
n is a positive integer, else False."""
assert b > 1 and n >= b and int(n) == n and int(b) == b
# parity check
if not b % 2:
if n % 2:
return False # b,n is even,odd
if b == 2:
return n & (n - 1) == 0
if not b & (b - 1) and n & (n - 1):
return False # b == 2**m but n != 2**M
elif not n % 2:
return False # b,n is odd,even
while n >= b:
d = b
while d <= n:
n, r = divmod(n, d)
if r:
return False
d *= d
return n == 1
Previous answers are correct, I liked Paul's answer the best. It's Simple and clean.
Here is the Java implementation of what he suggested:
public static boolean isPowerOfaNumber(int baseOrg, int powerOrg) {
double base = baseOrg;
double power = powerOrg;
while (base % power == 0)
base = base / power;
// return true if base is equal 1
return base == 1;
}
in the case the number is too large ... use log function to reduce time complexity:
import math
base = int(input("Enter the base number: "))
for i in range(base,int(input("Enter the end of range: "))+1):
if(math.log(i) / math.log(base) % 1 == 0 ):
print(i)
If you have access to the largest power of y, that can be fitted inside the required datatype, this is a really slick way of solving this problem.
Lets say, for our case, y == 3. So, we would need to check if x is a power of 3.
Given that we need to check if an integer x is a power of 3, let us start thinking about this problem in terms of what information is already at hand.
1162261467 is the largest power of 3 that can fit into an Java int.
1162261467 = 3^19 + 0
The given x can be expressed as [(a power of 3) + (some n)]. I think it is fairly elementary to be able to prove that if n is 0(which happens iff x is a power of 3), 1162261467 % x = 0.
So, to check if a given integer x is a power of three, check if x > 0 && 1162261467 % x == 0.
Generalizing. To check if a given integer x is a power of a given integer y, check if x > 0 && Y % x == 0: Y is the largest power of y that can fit into an integer datatype.
The general idea is that if A is some power of Y, A can be expressed as B/Ya, where a is some integer and A < B. It follows the exact same principle for A > B. The A = B case is elementary.
I found this Solution
//Check for If A can be expressed as power of two integers
int isPower(int A)
{
int i,a;
double p;
if(A==1)
return 1;
for(int a=1; a<=sqrt(A);++a )
{
p=log(A)/log(a);
if(p-int(p)<0.000000001)
return 1;
}
return 0;
}
binarycoder.org

Algorithm to find Largest prime factor of a number

What is the best approach to calculating the largest prime factor of a number?
I'm thinking the most efficient would be the following:
Find lowest prime number that divides cleanly
Check if result of division is prime
If not, find next lowest
Go to 2.
I'm basing this assumption on it being easier to calculate the small prime factors. Is this about right? What other approaches should I look into?
Edit: I've now realised that my approach is futile if there are more than 2 prime factors in play, since step 2 fails when the result is a product of two other primes, therefore a recursive algorithm is needed.
Edit again: And now I've realised that this does still work, because the last found prime number has to be the highest one, therefore any further testing of the non-prime result from step 2 would result in a smaller prime.
Here's the best algorithm I know of (in Python)
def prime_factors(n):
"""Returns all the prime factors of a positive integer"""
factors = []
d = 2
while n > 1:
while n % d == 0:
factors.append(d)
n /= d
d = d + 1
return factors
pfs = prime_factors(1000)
largest_prime_factor = max(pfs) # The largest element in the prime factor list
The above method runs in O(n) in the worst case (when the input is a prime number).
EDIT:
Below is the O(sqrt(n)) version, as suggested in the comment. Here is the code, once more.
def prime_factors(n):
"""Returns all the prime factors of a positive integer"""
factors = []
d = 2
while n > 1:
while n % d == 0:
factors.append(d)
n /= d
d = d + 1
if d*d > n:
if n > 1: factors.append(n)
break
return factors
pfs = prime_factors(1000)
largest_prime_factor = max(pfs) # The largest element in the prime factor list
Actually there are several more efficient ways to find factors of big numbers (for smaller ones trial division works reasonably well).
One method which is very fast if the input number has two factors very close to its square root is known as Fermat factorisation. It makes use of the identity N = (a + b)(a - b) = a^2 - b^2 and is easy to understand and implement. Unfortunately it's not very fast in general.
The best known method for factoring numbers up to 100 digits long is the Quadratic sieve. As a bonus, part of the algorithm is easily done with parallel processing.
Yet another algorithm I've heard of is Pollard's Rho algorithm. It's not as efficient as the Quadratic Sieve in general but seems to be easier to implement.
Once you've decided on how to split a number into two factors, here is the fastest algorithm I can think of to find the largest prime factor of a number:
Create a priority queue which initially stores the number itself. Each iteration, you remove the highest number from the queue, and attempt to split it into two factors (not allowing 1 to be one of those factors, of course). If this step fails, the number is prime and you have your answer! Otherwise you add the two factors into the queue and repeat.
My answer is based on Triptych's, but improves a lot on it. It is based on the fact that beyond 2 and 3, all the prime numbers are of the form 6n-1 or 6n+1.
var largestPrimeFactor;
if(n mod 2 == 0)
{
largestPrimeFactor = 2;
n = n / 2 while(n mod 2 == 0);
}
if(n mod 3 == 0)
{
largestPrimeFactor = 3;
n = n / 3 while(n mod 3 == 0);
}
multOfSix = 6;
while(multOfSix - 1 <= n)
{
if(n mod (multOfSix - 1) == 0)
{
largestPrimeFactor = multOfSix - 1;
n = n / largestPrimeFactor while(n mod largestPrimeFactor == 0);
}
if(n mod (multOfSix + 1) == 0)
{
largestPrimeFactor = multOfSix + 1;
n = n / largestPrimeFactor while(n mod largestPrimeFactor == 0);
}
multOfSix += 6;
}
I recently wrote a blog article explaining how this algorithm works.
I would venture that a method in which there is no need for a test for primality (and no sieve construction) would run faster than one which does use those. If that is the case, this is probably the fastest algorithm here.
JavaScript code:
'option strict';
function largestPrimeFactor(val, divisor = 2) {
let square = (val) => Math.pow(val, 2);
while ((val % divisor) != 0 && square(divisor) <= val) {
divisor++;
}
return square(divisor) <= val
? largestPrimeFactor(val / divisor, divisor)
: val;
}
Usage Example:
let result = largestPrimeFactor(600851475143);
Here is an example of the code:
Similar to #Triptych answer but also different. In this example list or dictionary is not used. Code is written in Ruby
def largest_prime_factor(number)
i = 2
while number > 1
if number % i == 0
number /= i;
else
i += 1
end
end
return i
end
largest_prime_factor(600851475143)
# => 6857
All numbers can be expressed as the product of primes, eg:
102 = 2 x 3 x 17
712 = 2 x 2 x 2 x 89
You can find these by simply starting at 2 and simply continuing to divide until the result isn't a multiple of your number:
712 / 2 = 356 .. 356 / 2 = 178 .. 178 / 2 = 89 .. 89 / 89 = 1
using this method you don't have to actually calculate any primes: they'll all be primes, based on the fact that you've already factorised the number as much as possible with all preceding numbers.
number = 712;
currNum = number; // the value we'll actually be working with
for (currFactor in 2 .. number) {
while (currNum % currFactor == 0) {
// keep on dividing by this number until we can divide no more!
currNum = currNum / currFactor // reduce the currNum
}
if (currNum == 1) return currFactor; // once it hits 1, we're done.
}
//this method skips unnecessary trial divisions and makes
//trial division more feasible for finding large primes
public static void main(String[] args)
{
long n= 1000000000039L; //this is a large prime number
long i = 2L;
int test = 0;
while (n > 1)
{
while (n % i == 0)
{
n /= i;
}
i++;
if(i*i > n && n > 1)
{
System.out.println(n); //prints n if it's prime
test = 1;
break;
}
}
if (test == 0)
System.out.println(i-1); //prints n if it's the largest prime factor
}
The simplest solution is a pair of mutually recursive functions.
The first function generates all the prime numbers:
Start with a list of all natural numbers greater than 1.
Remove all numbers that are not prime. That is, numbers that have no prime factors (other than themselves). See below.
The second function returns the prime factors of a given number n in increasing order.
Take a list of all the primes (see above).
Remove all the numbers that are not factors of n.
The largest prime factor of n is the last number given by the second function.
This algorithm requires a lazy list or a language (or data structure) with call-by-need semantics.
For clarification, here is one (inefficient) implementation of the above in Haskell:
import Control.Monad
-- All the primes
primes = 2 : filter (ap (<=) (head . primeFactors)) [3,5..]
-- Gives the prime factors of its argument
primeFactors = factor primes
where factor [] n = []
factor xs#(p:ps) n =
if p*p > n then [n]
else let (d,r) = divMod n p in
if r == 0 then p : factor xs d
else factor ps n
-- Gives the largest prime factor of its argument
largestFactor = last . primeFactors
Making this faster is just a matter of being more clever about detecting which numbers are prime and/or factors of n, but the algorithm stays the same.
n = abs(number);
result = 1;
if (n mod 2 == 0) {
result = 2;
while (n mod 2 = 0) n /= 2;
}
for(i=3; i<sqrt(n); i+=2) {
if (n mod i == 0) {
result = i;
while (n mod i = 0) n /= i;
}
}
return max(n,result)
There are some modulo tests that are superflous, as n can never be divided by 6 if all factors 2 and 3 have been removed. You could only allow primes for i, which is shown in several other answers here.
You could actually intertwine the sieve of Eratosthenes here:
First create the list of integers up
to sqrt(n).
In the for loop mark all multiples
of i up to the new sqrt(n) as not
prime, and use a while loop instead.
set i to the next prime number in
the list.
Also see this question.
I'm aware this is not a fast solution. Posting as hopefully easier to understand slow solution.
public static long largestPrimeFactor(long n) {
// largest composite factor must be smaller than sqrt
long sqrt = (long)Math.ceil(Math.sqrt((double)n));
long largest = -1;
for(long i = 2; i <= sqrt; i++) {
if(n % i == 0) {
long test = largestPrimeFactor(n/i);
if(test > largest) {
largest = test;
}
}
}
if(largest != -1) {
return largest;
}
// number is prime
return n;
}
Python Iterative approach by removing all prime factors from the number
def primef(n):
if n <= 3:
return n
if n % 2 == 0:
return primef(n/2)
elif n % 3 ==0:
return primef(n/3)
else:
for i in range(5, int((n)**0.5) + 1, 6):
#print i
if n % i == 0:
return primef(n/i)
if n % (i + 2) == 0:
return primef(n/(i+2))
return n
I am using algorithm which continues dividing the number by it's current Prime Factor.
My Solution in python 3 :
def PrimeFactor(n):
m = n
while n%2==0:
n = n//2
if n == 1: # check if only 2 is largest Prime Factor
return 2
i = 3
sqrt = int(m**(0.5)) # loop till square root of number
last = 0 # to store last prime Factor i.e. Largest Prime Factor
while i <= sqrt :
while n%i == 0:
n = n//i # reduce the number by dividing it by it's Prime Factor
last = i
i+=2
if n> last: # the remaining number(n) is also Factor of number
return n
else:
return last
print(PrimeFactor(int(input())))
Input : 10
Output : 5
Input : 600851475143
Output : 6857
Inspired by your question I decided to implement my own version of factorization (and finding largest prime factor) in Python.
Probably the simplest to implement, yet quite efficient, factoring algorithm that I know is Pollard's Rho algorithm. It has a running time of O(N^(1/4)) at most which is much more faster than time of O(N^(1/2)) for trial division algorithm. Both algos have these running times only in case of composite (non-prime) number, that's why primality test should be used to filter out prime (non-factorable) numbers.
I used following algorithms in my code: Fermat Primality Test ..., Pollard's Rho Algorithm ..., Trial Division Algorithm. Fermat primality test is used before running Pollard's Rho in order to filter out prime numbers. Trial Division is used as a fallback because Pollard's Rho in very rare cases may fail to find a factor, especially for some small numbers.
Obviously after fully factorizing a number into sorted list of prime factors the largest prime factor will be the last element in this list. In general case (for any random number) I don't know of any other ways to find out largest prime factor besides fully factorizing a number.
As an example in my code I'm factoring first 190 fractional digits of Pi, code factorizes this number within 1 second, and shows largest prime factor which is 165 digits (545 bits) in size!
Try it online!
def is_fermat_probable_prime(n, *, trials = 32):
# https://en.wikipedia.org/wiki/Fermat_primality_test
import random
if n <= 16:
return n in (2, 3, 5, 7, 11, 13)
for i in range(trials):
if pow(random.randint(2, n - 2), n - 1, n) != 1:
return False
return True
def pollard_rho_factor(N, *, trials = 16):
# https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm
import random, math
for j in range(trials):
i, stage, y, x = 0, 2, 1, random.randint(1, N - 2)
while True:
r = math.gcd(N, x - y)
if r != 1:
break
if i == stage:
y = x
stage <<= 1
x = (x * x + 1) % N
i += 1
if r != N:
return [r, N // r]
return [N] # Pollard-Rho failed
def trial_division_factor(n, *, limit = None):
# https://en.wikipedia.org/wiki/Trial_division
fs = []
while n & 1 == 0:
fs.append(2)
n >>= 1
d = 3
while d * d <= n and limit is None or d <= limit:
q, r = divmod(n, d)
if r == 0:
fs.append(d)
n = q
else:
d += 2
if n > 1:
fs.append(n)
return fs
def factor(n):
if n <= 1:
return []
if is_fermat_probable_prime(n):
return [n]
fs = trial_division_factor(n, limit = 1 << 12)
if len(fs) >= 2:
return sorted(fs[:-1] + factor(fs[-1]))
fs = pollard_rho_factor(n)
if len(fs) >= 2:
return sorted([e1 for e0 in fs for e1 in factor(e0)])
return trial_division_factor(n)
def demo():
import time, math
# http://www.math.com/tables/constants/pi.htm
# pi = 3.
# 1415926535 8979323846 2643383279 5028841971 6939937510 5820974944 5923078164 0628620899 8628034825 3421170679
# 8214808651 3282306647 0938446095 5058223172 5359408128 4811174502 8410270193 8521105559 6446229489 5493038196
# n = first 190 fractional digits of Pi
n = 1415926535_8979323846_2643383279_5028841971_6939937510_5820974944_5923078164_0628620899_8628034825_3421170679_8214808651_3282306647_0938446095_5058223172_5359408128_4811174502_8410270193_8521105559_6446229489
print('Number:', n)
tb = time.time()
fs = factor(n)
print('All Prime Factors:', fs)
print('Largest Prime Factor:', f'({math.log2(fs[-1]):.02f} bits, {len(str(fs[-1]))} digits)', fs[-1])
print('Time Elapsed:', round(time.time() - tb, 3), 'sec')
if __name__ == '__main__':
demo()
Output:
Number: 1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489
All Prime Factors: [3, 71, 1063541, 153422959, 332958319, 122356390229851897378935483485536580757336676443481705501726535578690975860555141829117483263572548187951860901335596150415443615382488933330968669408906073630300473]
Largest Prime Factor: (545.09 bits, 165 digits) 122356390229851897378935483485536580757336676443481705501726535578690975860555141829117483263572548187951860901335596150415443615382488933330968669408906073630300473
Time Elapsed: 0.593 sec
Here is my attempt in c#. The last print out is the largest prime factor of the number. I checked and it works.
namespace Problem_Prime
{
class Program
{
static void Main(string[] args)
{
/*
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
*/
long x = 600851475143;
long y = 2;
while (y < x)
{
if (x % y == 0)
{
// y is a factor of x, but is it prime
if (IsPrime(y))
{
Console.WriteLine(y);
}
x /= y;
}
y++;
}
Console.WriteLine(y);
Console.ReadLine();
}
static bool IsPrime(long number)
{
//check for evenness
if (number % 2 == 0)
{
if (number == 2)
{
return true;
}
return false;
}
//don't need to check past the square root
long max = (long)Math.Sqrt(number);
for (int i = 3; i <= max; i += 2)
{
if ((number % i) == 0)
{
return false;
}
}
return true;
}
}
}
#python implementation
import math
n = 600851475143
i = 2
factors=set([])
while i<math.sqrt(n):
while n%i==0:
n=n/i
factors.add(i)
i+=1
factors.add(n)
largest=max(factors)
print factors
print largest
Calculates the largest prime factor of a number using recursion in C++. The working of the code is explained below:
int getLargestPrime(int number) {
int factor = number; // assumes that the largest prime factor is the number itself
for (int i = 2; (i*i) <= number; i++) { // iterates to the square root of the number till it finds the first(smallest) factor
if (number % i == 0) { // checks if the current number(i) is a factor
factor = max(i, number / i); // stores the larger number among the factors
break; // breaks the loop on when a factor is found
}
}
if (factor == number) // base case of recursion
return number;
return getLargestPrime(factor); // recursively calls itself
}
Here is my approach to quickly calculate the largest prime factor.
It is based on fact that modified x does not contain non-prime factors. To achieve that, we divide x as soon as a factor is found. Then, the only thing left is to return the largest factor. It would be already prime.
The code (Haskell):
f max' x i | i > x = max'
| x `rem` i == 0 = f i (x `div` i) i -- Divide x by its factor
| otherwise = f max' x (i + 1) -- Check for the next possible factor
g x = f 2 x 2
The following C++ algorithm is not the best one, but it works for numbers under a billion and its pretty fast
#include <iostream>
using namespace std;
// ------ is_prime ------
// Determines if the integer accepted is prime or not
bool is_prime(int n){
int i,count=0;
if(n==1 || n==2)
return true;
if(n%2==0)
return false;
for(i=1;i<=n;i++){
if(n%i==0)
count++;
}
if(count==2)
return true;
else
return false;
}
// ------ nextPrime -------
// Finds and returns the next prime number
int nextPrime(int prime){
bool a = false;
while (a == false){
prime++;
if (is_prime(prime))
a = true;
}
return prime;
}
// ----- M A I N ------
int main(){
int value = 13195;
int prime = 2;
bool done = false;
while (done == false){
if (value%prime == 0){
value = value/prime;
if (is_prime(value)){
done = true;
}
} else {
prime = nextPrime(prime);
}
}
cout << "Largest prime factor: " << value << endl;
}
Found this solution on the web by "James Wang"
public static int getLargestPrime( int number) {
if (number <= 1) return -1;
for (int i = number - 1; i > 1; i--) {
if (number % i == 0) {
number = i;
}
}
return number;
}
Prime factor using sieve :
#include <bits/stdc++.h>
using namespace std;
#define N 10001
typedef long long ll;
bool visit[N];
vector<int> prime;
void sieve()
{
memset( visit , 0 , sizeof(visit));
for( int i=2;i<N;i++ )
{
if( visit[i] == 0)
{
prime.push_back(i);
for( int j=i*2; j<N; j=j+i )
{
visit[j] = 1;
}
}
}
}
void sol(long long n, vector<int>&prime)
{
ll ans = n;
for(int i=0; i<prime.size() || prime[i]>n; i++)
{
while(n%prime[i]==0)
{
n=n/prime[i];
ans = prime[i];
}
}
ans = max(ans, n);
cout<<ans<<endl;
}
int main()
{
ll tc, n;
sieve();
cin>>n;
sol(n, prime);
return 0;
}
Guess, there is no immediate way but performing a factorization, as examples above have done, i.e.
in a iteration you identify a "small" factor f of a number N, then continue with the reduced problem "find largest prime factor of N':=N/f with factor candidates >=f ".
From certain size of f the expected search time is less, if you do a primality test on reduced N', which in case confirms, that your N' is already the largest prime factor of initial N.
Here is my attempt in Clojure. Only walking the odds for prime? and the primes for prime factors ie. sieve. Using lazy sequences help producing the values just before they are needed.
(defn prime?
([n]
(let [oddNums (iterate #(+ % 2) 3)]
(prime? n (cons 2 oddNums))))
([n [i & is]]
(let [q (quot n i)
r (mod n i)]
(cond (< n 2) false
(zero? r) false
(> (* i i) n) true
:else (recur n is)))))
(def primes
(let [oddNums (iterate #(+ % 2) 3)]
(lazy-seq (cons 2 (filter prime? oddNums)))))
;; Sieve of Eratosthenes
(defn sieve
([n]
(sieve primes n))
([[i & is :as ps] n]
(let [q (quot n i)
r (mod n i)]
(cond (< n 2) nil
(zero? r) (lazy-seq (cons i (sieve ps q)))
(> (* i i) n) (when (> n 1) (lazy-seq [n]))
:else (recur is n)))))
(defn max-prime-factor [n]
(last (sieve n)))
Recursion in C
Algorithm could be
Check if n is a factor or t
Check if n is prime. If so, remember n
Increment n
Repeat until n > sqrt(t)
Here's an example of a (tail)recursive solution to the problem in C:
#include <stdio.h>
#include <stdbool.h>
bool is_factor(long int t, long int n){
return ( t%n == 0);
}
bool is_prime(long int n0, long int n1, bool acc){
if ( n1 * n1 > n0 || acc < 1 )
return acc;
else
return is_prime(n0, n1+2, acc && (n0%n1 != 0));
}
int gpf(long int t, long int n, long int acc){
if (n * n > t)
return acc;
if (is_factor(t, n)){
if (is_prime(n, 3, true))
return gpf(t, n+2, n);
else
return gpf(t, n+2, acc);
}
else
return gpf(t, n+2, acc);
}
int main(int argc, char ** argv){
printf("%d\n", gpf(600851475143, 3, 0));
return 0;
}
The solution is composed of three functions. One to test if the candidate is a factor, another to test if that factor is prime, and finally one to compose those two together.
Some key ideas here are:
1- Stopping the recursion at sqrt(600851475143)
2- Only test odd numbers for factorness
3- Only testing candidate factors for primeness with odd numbers
It seems to me that step #2 of the algorithm given isn't going to be all that efficient an approach. You have no reasonable expectation that it is prime.
Also, the previous answer suggesting the Sieve of Eratosthenes is utterly wrong. I just wrote two programs to factor 123456789. One was based on the Sieve, one was based on the following:
1) Test = 2
2) Current = Number to test
3) If Current Mod Test = 0 then
3a) Current = Current Div Test
3b) Largest = Test
3c) Goto 3.
4) Inc(Test)
5) If Current < Test goto 4
6) Return Largest
This version was 90x faster than the Sieve.
The thing is, on modern processors the type of operation matters far less than the number of operations, not to mention that the algorithm above can run in cache, the Sieve can't. The Sieve uses a lot of operations striking out all the composite numbers.
Note, also, that my dividing out factors as they are identified reduces the space that must be tested.
Compute a list storing prime numbers first, e.g. 2 3 5 7 11 13 ...
Every time you prime factorize a number, use implementation by Triptych but iterating this list of prime numbers rather than natural integers.
With Java:
For int values:
public static int[] primeFactors(int value) {
int[] a = new int[31];
int i = 0, j;
int num = value;
while (num % 2 == 0) {
a[i++] = 2;
num /= 2;
}
j = 3;
while (j <= Math.sqrt(num) + 1) {
if (num % j == 0) {
a[i++] = j;
num /= j;
} else {
j += 2;
}
}
if (num > 1) {
a[i++] = num;
}
int[] b = Arrays.copyOf(a, i);
return b;
}
For long values:
static long[] getFactors(long value) {
long[] a = new long[63];
int i = 0;
long num = value;
while (num % 2 == 0) {
a[i++] = 2;
num /= 2;
}
long j = 3;
while (j <= Math.sqrt(num) + 1) {
if (num % j == 0) {
a[i++] = j;
num /= j;
} else {
j += 2;
}
}
if (num > 1) {
a[i++] = num;
}
long[] b = Arrays.copyOf(a, i);
return b;
}
This is probably not always faster but more optimistic about that you find a big prime divisor:
N is your number
If it is prime then return(N)
Calculate primes up until Sqrt(N)
Go through the primes in descending order (largest first)
If N is divisible by Prime then Return(Prime)
Edit: In step 3 you can use the Sieve of Eratosthenes or Sieve of Atkins or whatever you like, but by itself the sieve won't find you the biggest prime factor. (Thats why I wouldn't choose SQLMenace's post as an official answer...)
Here is the same function#Triptych provided as a generator, which has also been simplified slightly.
def primes(n):
d = 2
while (n > 1):
while (n%d==0):
yield d
n /= d
d += 1
the max prime can then be found using:
n= 373764623
max(primes(n))
and a list of factors found using:
list(primes(n))
I think it would be good to store somewhere all possible primes smaller then n and just iterate through them to find the biggest divisior. You can get primes from prime-numbers.org.
Of course I assume that your number isn't too big :)
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include <time.h>
factor(long int n)
{
long int i,j;
while(n>=4)
{
if(n%2==0) { n=n/2; i=2; }
else
{ i=3;
j=0;
while(j==0)
{
if(n%i==0)
{j=1;
n=n/i;
}
i=i+2;
}
i-=2;
}
}
return i;
}
void main()
{
clock_t start = clock();
long int n,sp;
clrscr();
printf("enter value of n");
scanf("%ld",&n);
sp=factor(n);
printf("largest prime factor is %ld",sp);
printf("Time elapsed: %f\n", ((double)clock() - start) / CLOCKS_PER_SEC);
getch();
}

Resources