Sum of factorials for large numbers - algorithm

I want to calculate the sum of digits of N!.
I want to do this for really large values of N, say N(1500). I am not using .NET 4.0. I cannot use the BigInteger class to solve this.
Can this be solved by some other algorithm or procedure? Please help.
I want to do some thing like this Calculate the factorial of an arbitrarily large number, showing all the digits but in C#. However I am unable to solve.

There is no special magic that allows you to calculate the sum of the digits, as far as I am concerned.
It shouldn't be that hard to create your own BigInteger class anyway - you only need to implement the long multiplication algorithm from 3rd grade.

If your goal is to calculate the sum of the digits of N!, and if N is reasonably bounded, you can do the following without a BigInteger type:
Find a list of factorial values online (table lookup will be much more efficient than calculating from scratch, and does not require BigInteger)
Store as a string data type
Parse each character in the string as an integer
Add the resulting integers

There are two performance shortcuts that you can use for whatever implementation you choose.
Chop off any zeros from the numbers.
If the number is evenly divisible by 5^n, divide it by 10^n.
in this way,
16*15*14*13*12*11*10*9*8*7*6*5*4*3*2 = 20,922,789,888,000
//-->
16*1.5*14*13*12*11*1*9*8*7*6*0.5*4*3*2 = 20,922,789,888 //Sum of 63
Also, it feels like there should be some algorithm without reverting to calculating it all out. Going to 18!, the sums of the digits are:
2,6,6,3,9,9,9,27,27,36,27,27,45,45,63,63,63
//the sums of the resulting digits are:
2,6,6,3,9,9,9,9,9,9,9,9,9,9,9,9,9
and notably, the sum of the digits of 1500! is 16749 (the sum of whose digits are 27)

Here's some working code. Some components can be improved upon to increase efficiency. The idea is to use whatever multiplication algorithm I was told in school, and to store long integers as strings.
As an afterthought, I think it would be smarter to represent large numbers with List<int>() instead of string. But I'll leave that as an exercise to the reader.
Code Sample
static string Mult(string a, string b)
{
int shift = 0;
List<int> result = new List<int>();
foreach (int aDigit in a.Reverse().Select(c => int.Parse(c.ToString())))
{
List<int> subresult = new List<int>();
int store = 0;
foreach (int bDigit in b.Reverse().Select(c => int.Parse(c.ToString())))
{
int next = aDigit*bDigit + store;
subresult.Add(next%10);
store = next/10;
}
if (store != 0) subresult.Add(store);
subresult.Reverse();
for (int i = 0; i < shift; ++i) subresult.Add(0);
subresult.Reverse();
int newResult = new List<int>();
store = 0;
for (int i = 0; i < subresult.Count; ++i)
{
if (result.Count >= i + 1)
{
int next = subresult[i] + result[i] + store;
if (next >= 10)
newResult.Add(next % 10);
else newResult.Add(next);
store = next / 10;
}
else
{
int next = subresult[i] + store;
newResult.Add(next % 10);
store = next / 10;
}
}
if (store != 0) newResult.Add(store);
result = newResult;
++shift;
}
result.Reverse();
return string.Join("", result);
}
static int FactorialSum(int n)
{
string result = "1";
for (int i = 2; i <= n; i++)
result = Mult(i.ToString(), result);
return result.Sum(r => int.Parse(r.ToString()));
}
Code Testing
Assuming the code snippet above is in the same class as your Main method, call it thusly.
Input
static void Main(string[] args)
{
Console.WriteLine(FactorialSum(1500));
}
Output
16749

Here's a port of the C++ code you reference in one of your comments. One thing to realize when porting from C++ to C# is that integers that are zero evaluate to false and integers that are non-zero evaluate to true when used in a Boolean comparison.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ArbitraryFactorial
{
class Program
{
const int max = 5000;
static void display(int[] arr)
{
int ctr = 0;
for (int i = 0; i < max; i++)
{
if (ctr == 0 && arr[i] != 0) ctr = 1;
if (ctr != 0)
Console.Write(arr[i]);
}
}
static void factorial(int[] arr, int n)
{
if (n == 0) return;
int carry = 0;
for (int i = max - 1; i >= 0; --i)
{
arr[i] = (arr[i] * n) + carry;
carry = arr[i] / 10;
arr[i] %= 10;
}
factorial(arr, n - 1);
}
static void Main(string[] args)
{
int[] arr = new int[max];
arr[max - 1] = 1;
int num;
Console.Write("Enter the number: ");
num = int.Parse(Console.ReadLine());
Console.Write("Factorial of " + num + " is: ");
factorial(arr, num);
display(arr);
}
}
}

you can find the source code at : http://codingloverlavi.blogspot.in/2013/03/here-is-one-more-interesting-program.html
#include<stdio.h>
#include<conio.h>
#include<iostream.h>
#include<time.h>
#define max 5000
void multiply(long int *,long int);
void factorial(long int *,long int);
int main()
{
clrscr();
cout<<"PROGRAM TO CALCULATE FACTORIAL OF A NUMBER";
cout<<"\nENTER THE NUMBER\n";
long int num;
cin>>num;
long int a[max];
for(long int i=0;i<max;i++)
a[i]=0;
factorial(a,num);
clrscr();
//PRINTING THE FINAL ARRAY...:):):)
cout<<"THE FACTORIAL OF "<<num<<" is "<<endl<<endl;
long int flag=0;
int ans=0;
for(i=0;i<max;i++)
{
if(flag||a[i]!=0)
{
flag=1;
cout<<a[i];
ans=ans+a[i];
}
}
cout<<endl<<endl<<"the sum of all digits is: "<<ans;
getch();
return 1;
}
void factorial(long int *a,long int n)
{
long int lavish;
long int num=n;
lavish=n;
for(long int i=max-1;i>=0&&n;i--)
{
a[i]=n%10;
n=n/10;
}
for(i=2;i<(lavish);i++)
{
multiply(a,num-1);
num=num-1;
}
}
void multiply(long int *a,long int n)
{
for(long int i=0;i<max;i++)
a[i]=a[i]*n;
for(i=max-1;i>0;i--)
{
a[i-1]=a[i-1]+(a[i]/10);
a[i]=a[i]%10;
}
}

You can't use these numbers at all without a BigInteger type.
No algorithm or procedure can squeeze numbers larger than 264 into a long.
You need to find a BigInteger implementation for .Net 3.5.

Related

Algorithm Faster than QuickSort

I'm a beginner coder and I came up with an algorithm for sorting (DexSort) that typically works much faster than a standard Quicksort. This is assuming the number of ALL POSSIBLE values in a set/array is less than N^2, where N is the number of items I am trying to sort. I'm trying to find a way to optimize it so it doesn't necessarily have to depend on ALL POSSIBLE VALUES and just a subset of values that are relevant.
For example....say I have an array of random numbers where array.length = 10 million. My algorithm is only faster than Quicksort (on average) when the total number of all possible values is less than N^2 (i.e. 10^7 * 10^7 = 10 ^ 14). Now, say there are 10^14 actual values that can be found in an array. In this instant, my algorithm will run at roughly O(10^14). Can anyone think of a way to where I could reduce this?
Here is my code in Java:
package sort;
import java.util.*;
public class DexSort {
public static Comparable[] dexSort(Comparable[] c, int max){
//The variable int max is the maximum number of possible values
//E.g. If you are trying to sort 7-digit phone numbers, max = Math.pow(10,8) - 1, or 10^8 - 1
int size = c.length;
Comparable[] sorted = new Comparable[size];
int[] array = new int[max+1];
for (int i = 0; i < size; i++){
int val = (int) c[i];
int count = array[val];
count++;
array[val] = count;
}
int next = 0;
while (next < size){
for (int i = 0; i <= max; i++){
int count = array[i];
if (count > 0){
for (int j = 0; j < count; j++){
sorted[next] = i;
next++;
}
}
}
}
return sorted;
}
public static void main(String[] args){
Random r = new Random(7);
for (double n = 4; n < 8; n++){
double size = Math.pow(10, n);
System.out.println("---------------------------------------------");
System.out.println("Filling array size: 10^" + n);
System.out.println("---------------------------------------------\n");
Comparable[] array = fillArray((int)size, r); //Create array of random numbers of specified size
System.out.println("Array filled"); //Tests different array sizes by incrementing a power of 10
System.out.println("---------------------------------------------\n");
double max = size; //Arbitrarily set the maximum value possible as the array size
//Runtime will depend heavily on max if max>>>> size (See dexSort method)
//Overall, runtime will be O(max) when max >>>>> size
double t0 = System.nanoTime();
array = dexSort(array, (int) max);
double tF = System.nanoTime();
double nanoSecs = tF - t0;
double secs = nanoSecs/Math.pow(10, 9);
System.out.println("DEX sort complete");
System.out.println("It took " + String.format("%.3f", secs) + " seconds to sort an array of size 10^" + n);
//printArray(array); //Uncomment this line to print sorted array to console
System.out.println();
System.out.println("---------------------------------------------");
System.out.println("---------------------------------------------\n\n");
}
}
public static Comparable[] fillArray(int size, Random r){
Comparable[] c = new Comparable[size];
for (int i = 0; i < size; i++){
/*if ((i+1)%10000000 == 0){
System.out.println(((i+1)/1000000) + " million filled");
}*/
c[i] = r.nextInt(size)+1;
}
return c;
}
public static void printArray(Comparable[] c){
for (int i = 0; i < c.length; i++){
if (i%10 == 0){
System.out.println();
}
System.out.print(c[i] + "\t");
}
}
}

Fibonacci Series using Dynamic Programming

Let us consider the implementation of Fibonacci series using dynamic programming.
// Fibonacci Series using Dynamic Programming
class fibonacci
{
static int fib(int n)
{
/* Declare an array to store Fibonacci numbers. */
int f[] = new int[n+1];
int i;
/* 0th and 1st number of the series are 0 and 1*/
f[0] = 0;
f[1] = 1;
for (i = 2; i <= n; i++)
{
/* Add the previous 2 numbers in the series
and store it */
f[i] = f[i-1] + f[i-2];
}
return f[n];
}
public static void main (String args[])
{
int n = 9;
System.out.println(fib(n));
}
}
We use the dynamic programming so that the repetition of the recursive work does not occur. But here when every time the function has been called,a new array will be generated. So how could this algorithm is said to be more optimized ?
one optimization would be only save the last 2 values instead of all results. You don't need to store all your results.
you also can write the fibonacci series recursively in O(n):
int fib(int n1, int n2, int counter)
{
if(counter == 0)
{
return n2;
}
else
{
return fib(n2,n2 + n1,counter-1);
}
}
//to start:
int result = fib(0,1,100); //gives you the 100 fibonacci value
This code runs recursively and is easy to read. You don't have to initialize an array or other stuff.
alternatively you can use the nonrecursive option:
int fib(int number)
{
int n1 = 0;
int n2 = 1;
int temp;
for(int i = 0; i< number;i++)
{
temp = n1 + n2;
n1 = n2;
n2 = temp;
}
return n2;
}
If you want to store your results, you have to initialize the array outside of your fib function:
// Fibonacci Series using Dynamic Programming
class fibonacci
{
/* Declare an array to store Fibonacci numbers. */
int f[];
static void init(int n)
{ /* 0th and 1st number of the series are 0 and 1*/
f = new int[n+1];
f[0] = 0;
f[1] = 1;
}
static int fib(int n)
{
int i;
for (i = 2; i <= n; i++)
{
/* Add the previous 2 numbers in the series
and store it */
f[i] = f[i-1] + f[i-2];
}
return f[n];
}
public static void main (String args[])
{
int n = 9;
init(n);
System.out.println(fib(n));
}
}
We use Memoization to prevent further recursion with Dynamic Programming. Memoization is the way to store already calculated values ex - let say fib(m) for index m is calculated and stored in memoization table. Further in upcoming recursions if fib(m) reoccur for calculation, then we take it from memoization table instead of doing again fib(m-1)+fib(m-2) i.e. avoid unnecessary recursions...Note - this will keep the complexity linear i.e. O(n).
We can implement this memoization in many ways for faster search. However here for Fibonacci we can implement memoization as array. And yes memoization table will be initialized just once. Below code is illustration for above explanation -
Note - we have taken a variable "complexity" which will incremented whenever we cant find value in memoization table i.e. whenever we go for recursion..
package com.company.dynamicProgramming;
import java.math.BigInteger;
public class FibonacciByBigDecimal {
static int complexity = 0;
public static void main(String ...args) {
int n = 200;
BigInteger[] memoization = new BigInteger[n + 1];
System.out.println("fibonacci of "+ n + " is : " + fibByDivCon(n, memoization));
System.out.println("Complexity is "+complexity);
}
static BigInteger fibByDivCon(int n, BigInteger[] memoization){
if(memoization[n]!=null){
return memoization[n];
}
complexity++;
if (n == 1 || n== 2){
memoization[n] = BigInteger.ONE;
return BigInteger.ONE;
}
// creates 2 further entries in stack
BigInteger fibOfn = fibByDivCon(n-1, memoization).add( fibByDivCon(n-2, memoization)) ;
memoization[n] = fibOfn;
return fibOfn;
}
}
Above i am calculating Fibonacci number at index 200. When I ran above code the result is : -
fibonacci of 200 is : 280571172992510140037611932413038677189525
Complexity is 200
Process finished with exit code 0

Numbers ending in 3 have at least one multiple having all ones

Hi Here is a Q that was asked in Adobe Interview.
Numbers ending in 3 have at least one multiple having all ones. for
eg., 3 and 13 have amultiples like 111 and 111111 respectively. Given
such a no. , find the smallest such multiple of that number. The
multiple can exceed the range of int, long. You cannot use any
complex data structure.
Can you provide me with an efficient solution
got the answer now :)
int count=1, rem=1;
while(rem)
{
rem= (rem*10+1)%n; count++;
}
while(count--){ cout<<"1";}
Here is an attempt to do it more efficiently that trying 1, 11, 111, 111.. Could this pay off. Is there a more elegant answer better than trying numbers one at a time?
Write the numbers 1, 11, 111, ... as (10^k - 1) / 9, where the division is known to be exact. Given a target number in the form 10x+3 we want to find the smallest k solving (10^k - 1) / 9 = Y(10x + 3) where Y is an integer. Look for small solutions of 10^k = 1 mod 9(10x + 3). This is http://en.wikipedia.org/wiki/Discrete_logarithm except that arithmetic mod 9(10x + 3) does not necessarily form a group - however the http://en.wikipedia.org/wiki/Baby-step_giant-step algorithm should still apply and could be used to search steadily increasing ranges of k, instead of searching possible values of k one at a time.
#include <iostream>
using namespace std;
int main() {
int t;
cin>>t;
while(t--){
long long n;
cin>>n;
long long cur = 1;
while(cur%n!=0){
cur = cur*10+1;
}
cout<<cur<<endl;
}
return 0;
}
Solution independent of output size:
public String ones(int n)
{
int i, m = 1;
String num="1";
for (i = 1; i <= n; i++) {
if (m == 0)
return num;
/* Solution found */
num=num+"1";
m = (10*m + 1) % n;
}
return null; /* No solution */
}
If you are looking for a Solution in Java, here it is
public static void main(String[] args) {
int input = 13; // this can be any number ending with 3
int minAllOnesNum = 1;
int nextAllOnesNum= minAllOnesNum;
int numberof1s=1;
int count = 0;
while(true)
{
count++;
if(nextAllOnesNum%input == 0 )
{
break;
}
nextAllOnesNum = nextAllOnesNum*10 + 1;
if(nextAllOnesNum>=input) {
nextAllOnesNum%=input;
}
numberof1s++;
}
System.out.println("Number of iterations : " + count);
for(int i=1; i<=numberof1s; i++) {
System.out.print("1");
}
}
If you are looking for a Solution in Java, here it is
public static void main(String[] args) {
int input = 55333;
int minAllOnesNum = 1;
int nextAllOnesNum= minAllOnesNum;
int numberof1s=1;
int count = 0;
while(true)
{
count++;
if(nextAllOnesNum%input == 0 )
{
break;
}
nextAllOnesNum = nextAllOnesNum*10 + 1;
if(nextAllOnesNum>=input) {
nextAllOnesNum%=input;
}
numberof1s++;
}
System.out.println("Number of Iterations: " + count);
for(int i=1; i<=numberof1s; i++) {
System.out.print("1");
}
}
static int findOnes(int num){
int i = 1 ;
int power = 0;
while (i % num != 0){
i = (i * (10^power)) + 1;
}
return i;
}

Run length encoding using O(1) space

Can we do the run-length encoding in place(assuming the input array is very large)
We can do for the cases such as AAAABBBBCCCCDDDD
A4B4C4D4
But how to do it for the case such as ABCDEFG?
where the output would be A1B1C1D1E1F1G1
My first thought was to start encoding from the end, so we will use the free space (if any), after that we can shift the encoded array to the start. A problem with this approach is that it will not work for AAAAB, because there is no free space (it's not needed for A4B1) and we will try to write AAAAB1 on the first iteration.
Below is corrected solution:
(let's assume the sequence is AAABBC)
encode all groups with two or more elements and leave the rest unchanged (this will not increase length of the array) -> A3_B2C
shift everything right eliminating empty spaces after first step -> _A3B2C
encode the array from the start (reusing the already encoded groups of course) -> A3B2C1
Every step is O(n) and as far as I can see only constant additional memory is needed.
Limitations:
Digits are not supported, but that anyway would create problems with decoding as Petar Petrov mentioned.
We need some kind of "empty" character, but this can be worked around by adding zeros: A03 instead of A3_
C++ solution O(n) time O(1) space
string runLengthEncode(string str)
{
int len = str.length();
int j=0,k=0,cnt=0;
for(int i=0;i<len;i++)
{
j=i;
cnt=1;
while(i<len-1 && str[i]==str[i+1])
{
i++;
cnt++;
}
str[k++]=str[j];
string temp =to_string(cnt);
for(auto m:temp)
str[k++] = m;
}
str.resize(k);
return str;
}
null is used to indicate which items are empty and will be ignored for encoding. Also you can't encode digits (AAA2222 => A324 => 324 times 'A', but it's A3;24). Your question opens more questions.
Here's a "solution" in C#
public static void Encode(string[] input)
{
var writeIndex = 0;
var i = 0;
while (i < input.Length)
{
var symbol = input[i];
if (symbol == null)
{
break;
}
var nextIndex = i + 1;
var offset = 0;
var count = CountSymbol(input, symbol, nextIndex) + 1;
if (count == 1)
{
ShiftRight(input, nextIndex);
offset++;
}
input[writeIndex++] = symbol;
input[writeIndex++] = count.ToString();
i += count + offset;
}
Array.Clear(input, writeIndex, input.Length - writeIndex);
}
private static void ShiftRight(string[] input, int nextIndex)
{
var count = CountSymbol(input, null, nextIndex, (a, b) => a != b);
Array.Copy(input, nextIndex, input, nextIndex + 1, count);
}
private static int CountSymbol(string[] input, string symbol, int nextIndex)
{
return CountSymbol(input, symbol, nextIndex, (a, b) => a == b);
}
private static int CountSymbol(string[] input, string symbol, int nextIndex, Func<string, string, bool> cmp)
{
var count = 0;
var i = nextIndex;
while (i < input.Length && cmp(input[i], symbol))
{
count++;
i++;
}
return count;
}
The 1st solution does not take care of single characters. For example - 'Hi!' will not work. I've used totally different approach, used 'insert()' functions to add inplace. This take care of everything, whether the total 'same' character is > 10 or >100 or = 1.
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
string name = "Hello Buddy!!";
int start = 0;
char distinct = name[0];
for(int i=1;i<name.length()+1;){
if(distinct!=name[i]){
string s = to_string(i-start);
name.insert(start+1,s);
name.erase(name.begin() + start + 1 + s.length(),name.begin() + s.length() + i);
i=start+s.length()+1;
start=i;
distinct=name[start];
continue;
}
i++;
}
cout<<name;
}
Suggest me if you find anything incorrect.
O(n), in-place RLE, I couldn't think better than this. It will not place a number, if chars occurence is just 1. Will also place a9a2, if the character comes 11 times.
void RLE(char *str) {
int len = strlen(str);
int count = 1, j = 0;
for (int i = 0; i < len; i++){
if (str[i] == str[i + 1])
count++;
else {
int times = count / 9;
int rem = count % 9;
for (int k = 0; k < times; k++) {
str[j++] = str[i];
_itoa(9, &str[j++], 10);
count = count - 9;
}
if (count > 1) {
str[j++] = str[i];
_itoa(rem, &str[j++], 10);
count = 1;
}
else
str[j++] = str[i];
}
}
cout << str;
}
I/P => aaabcdeeeefghijklaaaaa
O/P => a3bcde4fghijkla5
Inplace solution using c++ ( assumes length of encoding string is not more than actual string length):
#include <bits/stdc++.h>
#include<stdlib.h>
using namespace std;
void replacePattern(char *str)
{
int len = strlen(str);
if (len == 0)
return;
int i = 1, j = 1;
int count;
// for each character
while (str[j])
{
count = 1;
while (str[j] == str[j-1])
{
j = j + 1;
count++;
}
while(count > 0) {
int rem = count%10;
str[i++] = to_string(rem)[0];
count = count/10;
}
// copy character at current position j
// to position i and increment i and j
if (str[j])
str[i++] = str[j++];
}
// add a null character to terminate string
if(str[len-1] != str[len-2]) {
str[i] = '1';
i++;
}
str[i] = '\0';
}
// Driver code
int main()
{
char str[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabccccc";
replacePattern(str);
cout << str;
return 0;
}

what is the fastest way to find the gcd of n numbers?

what is the fastest way to compute the greatest common divisor of n numbers?
Without recursion:
int result = numbers[0];
for(int i = 1; i < numbers.length; i++){
result = gcd(result, numbers[i]);
}
return result;
For very large arrays, it might be faster to use the fork-join pattern, where you split your array and calculate gcds in parallel. Here is some pseudocode:
int calculateGCD(int[] numbers){
if(numbers.length <= 2){
return gcd(numbers);
}
else {
INVOKE-IN-PARALLEL {
left = calculateGCD(extractLeftHalf(numbers));
right = calculateGCD(extractRightHalf(numbers));
}
return gcd(left,right);
}
}
You may want to sort the numbers first and compute the gcd recursively starting from the smallest two numbers.
C++17
I have written this function for calculating gcd of n numbers by using C++'s inbuilt __gcd(int a, int b) function.
int gcd(vector<int> vec, int vsize)
{
int gcd = vec[0];
for (int i = 1; i < vsize; i++)
{
gcd = __gcd(gcd, vec[i]);
}
return gcd;
}
To know more about this function visit this link .
Also refer to Dijkstra's GCD algorithm from the following link. It works without division. So it could be slightly faster (Please correct me if I am wrong.)
You should use Lehmer's GCD algorithm.
How about the following using Euclidean algorithm by subtraction:
function getGCD(arr){
let min = Math.min(...arr);
let max= Math.max(...arr);
if(min==max){
return min;
}else{
for(let i in arr){
if(arr[i]>min){
arr[i]=arr[i]-min;
}
}
return getGCD(arr);
}
}
console.log(getGCD([2,3,4,5,6]))
The above implementation takes O(n^2) time. There are improvements that can be implemented but I didn't get around trying these out for n numbers.
If you have a lot of small numbers, factorization may be actually faster.
//Java
int[] array = {60, 90, 45};
int gcd = 1;
outer: for (int d = 2; true; d += 1 + (d % 2)) {
boolean any = false;
do {
boolean all = true;
any = false;
boolean ready = true;
for (int i = 0; i < array.length; i++) {
ready &= (array[i] == 1);
if (array[i] % d == 0) {
any = true;
array[i] /= d;
} else all = false;
}
if (all) gcd *= d;
if (ready) break outer;
} while (any);
}
System.out.println(gcd);
(works for some examples, but not really tested)
Use the Euclidean algorithm :
function gcd(a, b)
while b ≠ 0
t := b;
b := a mod b;
a := t;
return a;
You apply it for the first two numbers, then the result with the third number, etc... :
read(a);
read(b);
result := gcd(a, b);
i := 3;
while(i <= n){
read(a)
result := gcd(result, a);
}
print(result);
Here below is the source code of the C program to find HCF of N numbers using Arrays.
#include<stdio.h>
int main()
{
int n,i,gcd;
printf("Enter how many no.s u want to find gcd : ");
scanf("%d",&n);
int arr[n];
printf("\nEnter your numbers below :- \n ");
for(i=0;i<n;i++)
{
printf("\nEnter your %d number = ",i+1);
scanf("%d",&arr[i]);
}
gcd=arr[0];
int j=1;
while(j<n)
{
if(arr[j]%gcd==0)
{
j++;
}
else
{
gcd=arr[j]%gcd;
i++;
}
}
printf("\nGCD of k no.s = %d ",gcd);
return 0;
}
For more refer to this website for further clarification.......
You can use divide and conquer. To calculate gcdN([]), you divide the list into first half and second half. if it only has one num for each list. you calculate using gcd2(n1, n2).
I just wrote a quick sample code. (assuming all num in the list are positive Ints)
def gcdN(nums):
n = len(nums)
if n == 0: return "ERROR"
if n == 1: return nums[0]
if n >= 2: return gcd2(gcdN(nums[:n//2]), gcdN(nums[n//2:]))
def gcd2(n1, n2):
for num in xrange(min(n1, n2), 0, -1):
if n1 % num == 0 and n2 % num == 0:
return num
Here's a gcd method that uses the property that gcd(a, b, c) = gcd(a, gcd(b, c)).
It uses BigInteger's gcd method since it is already optimized.
public static BigInteger gcd(BigInteger[] parts){
BigInteger gcd = parts[0];
for(int i = 1; i < parts.length; i++)
gcd = parts[i].gcd(gcd);
return gcd;
}
//Recursive solution to get the GCD of Two Numbers
long long int gcd(long long int a,long long int b)<br>
{
return b==0 ? a : gcd(b,a%b);
}
int main(){
long long int a,b;
cin>>a>>b;
if(a>b) cout<<gcd(a,b);
else cout<<gcd(b,a);
return 0;
}
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
class GCDArray{
public static int [] extractLeftHalf(int [] numbers)
{
int l =numbers.length/2;
int arr[] = Arrays.copyOf(numbers, l+1);
return arr;
}
public static int [] extractRightHalf(int [] numbers)
{
int l =numbers.length/2;
int arr[] = Arrays.copyOfRange(numbers,l+1, numbers.length);
return arr;
}
public static int gcd(int[] numbers)
{
if(numbers.length==1)
return numbers[0];
else {
int x = numbers[0];
int y = numbers[1];
while(y%x!=0)
{
int rem = y%x;
y = x;
x = rem;
}
return x;
}
}
public static int gcd(int x,int y)
{
while(y%x!=0)
{
int rem = y%x;
y = x;
x = rem;
}
return x;
}
public static int calculateGCD(int[] numbers){
if(numbers.length <= 2){
return gcd(numbers);
}
else {
int left = calculateGCD(extractLeftHalf(numbers));
int right = calculateGCD(extractRightHalf(numbers));
return gcd(left,right);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int arr[] = new int[n];
for(int i=0;i<n;i++){
arr[i]=sc.nextInt();
}
System.out.println(calculateGCD(arr));
}
}
**
Above is the java working code ..... the pseudo code of which is
already mention by https://stackoverflow.com/users/7412/dogbane
**
A recursive JavaScript (ES6) one-liner for any number of digits.
const gcd = (a, b, ...c) => b ? gcd(b, a % b, ...c) : c.length ? gcd(a, ...c) : Math.abs(a);
This is what comes off the top of my head in Javascript.
function calculateGCD(arrSize, arr) {
if(!arrSize)
return 0;
var n = Math.min(...arr);
for (let i = n; i > 0; i--) {
let j = 0;
while(j < arrSize) {
if(arr[j] % i === 0) {
j++;
}else {
break;
}
if(j === arrSize) {
return i;
}
}
}
}
console.log(generalizedGCD(4, [2, 6, 4, 8]));
// Output => 2
Here was the answer I was looking for.
The best way to find the gcd of n numbers is indeed using recursion.ie gcd(a,b,c)=gcd(gcd(a,b),c). But I was getting timeouts in certain programs when I did this.
The optimization that was needed here was that the recursion should be solved using fast matrix multiplication algorithm.

Resources