Related
I was trying to solve this problem:
Write a function:
class Solution { public int solution(int[] A); }
that, given an array A of N integers, returns the smallest positive
integer (greater than 0) that does not occur in A.
For example, given A = [1, 3, 6, 4, 1, 2], the function should return
5.
Given A = [1, 2, 3], the function should return 4.
Given A = [−1, −3], the function should return 1.
Assume that:
N is an integer within the range [1..100,000]; each element of array A
is an integer within the range [−1,000,000..1,000,000]. Complexity:
expected worst-case time complexity is O(N); expected worst-case space
complexity is O(N) (not counting the storage required for input
arguments).
I wrote the solution below which gives a low performance, however, I can't see the bug.
public static int solution(int[] A) {
Set<Integer> set = new TreeSet<>();
for (int a : A) {
set.add(a);
}
int N = set.size();
int[] C = new int[N];
int index = 0;
for (int a : set) {
C[index++] = a;
}
for (int i = 0; i < N; i++) {
if (C[i] > 0 && C[i] <= N) {
C[i] = 0;
}
}
for (int i = 0; i < N; i++) {
if (C[i] != 0) {
return (i + 1);
}
}
return (N + 1);
}
The score is provided here,
I will keep investigating myself, but please inform me if you can see better.
If the expected running time should be linear, you can't use a TreeSet, which sorts the input and therefore requires O(NlogN). Therefore you should use a HashSet, which requires O(N) time to add N elements.
Besides, you don't need 4 loops. It's sufficient to add all the positive input elements to a HashSet (first loop) and then find the first positive integer not in that Set (second loop).
int N = A.length;
Set<Integer> set = new HashSet<>();
for (int a : A) {
if (a > 0) {
set.add(a);
}
}
for (int i = 1; i <= N + 1; i++) {
if (!set.contains(i)) {
return i;
}
}
100% result solution in Javascript:
function solution(A) {
// only positive values, sorted
A = A.filter(x => x >= 1).sort((a, b) => a - b)
let x = 1
for(let i = 0; i < A.length; i++) {
// if we find a smaller number no need to continue, cause the array is sorted
if(x < A[i]) {
return x
}
x = A[i] + 1
}
return x
}
My code in Java, 100% result in Codility
import java.util.*;
class Solution {
public int solution(int[] arr) {
Arrays.sort(arr);
int smallest = 1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == smallest) {
smallest++;
}
}
return smallest;
}
}
Here is an efficient python solution:
def solution(A):
m = max(A)
if m < 1:
return 1
A = set(A)
B = set(range(1, m + 1))
D = B - A
if len(D) == 0:
return m + 1
else:
return min(D)
JS:
filter to get positive non zero numbers from A array
sort above filtered array in ascending order
map to iterate loop of above stored result
if to check x is less than the current element then return
otherwise, add 1 in the current element and assign to x
function solution(A) {
let x = 1
A.filter(x => x >= 1)
.sort((a, b) => a - b)
.map((val, i, arr) => {
if(x < arr[i]) return
x = arr[i] + 1
})
return x
}
console.log(solution([3, 4, -1, 1]));
console.log(solution([1, 2, 0]));
No need to store anything. No need for hashsets. (Extra memory), You can do it as you
move through the array. However, The array has to be sorted. And we know the very most minimum value is 1
import java.util.Arrays;
class Solution {
public int solution(int[] A) {
Arrays.sort(A);
int min = 1;
/*
for efficiency — no need to calculate or access the
array object’s length property per iteration
*/
int cap = A.length;
for (int i = 0; i < cap; i++){
if(A[i] == min){
min++;
}
/*
can add else if A[i] > min, break;
as suggested by punit
*/
}
/*
min = ( min <= 0 ) ? 1:min;
which means: if (min <= 0 ){
min =1} else {min = min}
you can also do:
if min <1 for better efficiency/less jumps
*/
return min;
}
}
Here is my PHP solution, 100% Task Score, 100% correctness, and 100% performance. First we iterate and we store all positive elements, then we check if they exist,
function solution($A) {
$B = [];
foreach($A as $a){
if($a > 0) $B[] = $a;
}
$i = 1;
$last = 0;
sort($B);
foreach($B as $b){
if($last == $b) $i--; // Check for repeated elements
else if($i != $b) return $i;
$i++;
$last = $b;
}
return $i;
}
I think its one of the clears and simples functions here, the logic can be applied in all the other languages.
For Swift 4
public func solution(_ A : inout [Int]) -> Int {
let positive = A.filter { $0 > 0 }.sorted()
var x = 1
for val in positive {
// if we find a smaller number no need to continue, cause the array is sorted
if(x < val) {
return x
}
x = val + 1
}
return x
}
I achieved 100% on this by the below solution in Python:-
def solution(A):
a=frozenset(sorted(A))
m=max(a)
if m>0:
for i in range(1,m):
if i not in a:
return i
else:
return m+1
else:
return 1
This solution is in c# but complete the test with 100% score
public int solution(int[] A) {
// write your code in C# 6.0 with .NET 4.5 (Mono)
var positives = A.Where(x => x > 0).Distinct().OrderBy(x => x).ToArray();
if(positives.Count() == 0) return 1;
int prev = 0;
for(int i =0; i < positives.Count(); i++){
if(positives[i] != prev + 1){
return prev + 1;
}
prev = positives[i];
}
return positives.Last() + 1;
}
My answer in Ruby
def smallest_pos_integer(arr)
sorted_array = arr.select {|x| x >= 1}.sort
res = 1
for i in (0..sorted_array.length - 1)
if res < sorted_array[i]
return res
end
res = sorted_array[i] + 1
end
res
end
In Kotlin with %100 score
Detected time complexity: O(N) or O(N * log(N))
fun solution(A: IntArray): Int {
var min = 1
val b = A.sortedArray()
for (i in 0 until b.size) {
if (b[i] == min) {
min++
}
}
return min
}
JavaScript ES6 Solution:
function solution(A) {
if (!A.includes(1)) return 1;
return A.filter(a => a > 0)
.sort((a, b) => a - b)
.reduce((p, c) => c === p ? c + 1 : p, 1);
}
console.log(solution([1, 3, 6, 4, 1, 2]));
console.log(solution([1, 2, 3]));
console.log(solution([-1, -3]));
console.log(solution([4, 5, 6]));
console.log(solution([1, 2, 4]));
This answer gives 100% in Python. Worst case complexity O(N).
The idea is that we do not care about negative numbers in the sequence, since we want to find the smallest positive integer not in the sequence A.
Hence we can set all negative numbers to zero and keep only the unique positive values. Then we check iteratively starting from 1 whether the number is in the set of positive values of sequence A.
Worst case scenario, where the sequence is an arithmetic progression with constant difference 1, leads to iterating through all elements and thus O(N) complexity.
In the extreme case where all the elements of the sequence are negative (i.e. the maximum is negative) we can immediately return 1 as the minimum positive number.
def solution(A):
max_A=max(A)
B=set([a if a>=0 else 0 for a in A ])
b=1
if max_A<=0:
return(1)
else:
while b in B:
b+=1
return(b)
Javascript solution:
function solution(A) {
A = [...new Set(A.sort( (a,b) => a-b))];
// If the initial integer is greater than 1 or the last integer is less than 1
if((A[0] > 1) || (A[A.length - 1] < 1)) return 1;
for (let i in A) {
let nextNum = A[+i+1];
if(A[i] === nextNum) continue;
if((nextNum - A[i]) !== 1) {
if(A[i] < 0 ) {
if(A.indexOf(1) !== -1) continue;
return 1;
}
return A[i] + 1;
}
}
}
0. Introduction
A) Languages allowed
The Codility skills assessment demo test allows for solutions
written in 18 different languages: C, C++, C#, Go, Java 8, Java 11, JavaScript, Kotlin, Lua, Objective-C, Pascal, PHP, Perl, Python, Ruby, Scala, Swift 4, Visual Basic.
B) Some remarks on your question
I write the solution below which gives a low performance
There is no reason to worry about performance until you have a
correct solution.
Always make sure the solution is correct before you even think about
how fast or slow your algorithm/code is!
expected worst-case time complexity is O(N)
Well, as the asker of the question, it is your decision what
requirements should be met in an answer.
But if the goal is to score 100% in the Codility (performance) test,
then there is no need to demand O(N).
There are plenty of solutions in the answers here which are O(N log N)
and not O(N), but still pass all 4 performance tests.
This proves that the O(N) requirement on time complexity is
unnecessarily harsh (if the sole aim is to score 100% on the Codility
test).
C) About the solutions presented here
All of the solutions presented here are either refactored versions of
already published answers, or inspired by such answers.
All solutions here score 100% in the Codility skills assessment
demo test.
1
I have striven to
explicitly reference each original answer/solution,
provide a runnable jdoodle link for each
solution,
use the same 8 tests (chosen by myself) for all the solutions,
choose solutions that score 100% (meaning 5 of 5 for correctness and
4 of 4 for performance/speed),
make it easy to copy-paste the answers directly into the Codility
skills assessment demo test,
focus on some of the most used languages.
1. Java: the Codility test for correctness is incorrect (!)
I will use one of the existing answers to demonstrate that the Codility
test for correctness is flawed for the edge case when the given array
is empty.
In an empty array, the smallest positive missing integer is clearly 1.
Agreed?
But the Codility test suite seems to accept just about any answer for
the empty array.
In the code below, I deliberately return -99 for the empty array,
which is obviously incorrect.
Yet, Codility gives me a 100% test score for my flawed solution. (!)
import java.util.Arrays;
/**
https://app.codility.com/demo/take-sample-test 100%
https://stackoverflow.com/a/57067307
https://jdoodle.com/a/3B0D
To run the program in a terminal window:
javac Solution.java && java Solution && rm Solution.class
Terminal command to run the combined formatter/linter:
java -jar ../../../checkstyle-8.45.1.jar -c ../../../google_checks.xml *.java
*/
public class Solution {
/** Returns the smallest positive integer missing in intArray. */
public static int solution(int[] intArray) {
if (intArray.length == 0) { // No elements at all.
return -99; // So the smallest positive missing integer is 1.
}
Arrays.sort(intArray);
// System.out.println(Arrays.toString(intArray)); // Temporarily uncomment?
if (intArray[0] >= 2) { // Smallest positive int is 2 or larger.
return 1; // Meaning smallest positive MISSING int is 1.
}
if (intArray[intArray.length - 1] <= 0) { // Biggest int is 0 or smaller.
return 1; // Again, smallest positive missing int is 1.
}
int smallestPositiveMissing = 1;
for (int i = 0; i < intArray.length; i++) {
if (intArray[i] == smallestPositiveMissing) {
smallestPositiveMissing++;
} // ^^ Stop incrementing if intArray[i] > smallestPositiveMissing. ^^
} // Because then the smallest positive missing integer has been found:
return smallestPositiveMissing;
}
/** Demo examples. --> Expected output: 1 2 3 4 1 2 3 1 (but vertically). */
public static void main(String[] args) {
System.out.println("Hello Codility Demo Test for Java, B");
int[] array1 = {-1, -3};
System.out.println(solution(array1));
int[] array2 = {1, -1};
System.out.println(solution(array2));
int[] array3 = {2, 1, 2, 5};
System.out.println(solution(array3));
int[] array4 = {3, 1, -2, 2};
System.out.println(solution(array4));
int[] array5 = {};
System.out.println(solution(array5));
int[] array6 = {1, -5, -3};
System.out.println(solution(array6));
int[] array7 = {1, 2, 4, 5};
System.out.println(solution(array7));
int[] array8 = {17, 2};
System.out.println(solution(array8));
}
}
Below is a screen dump of the result from the test.
As the solution is clearly wrong, of course it should not score 100%!
2
2. JavaScript
Below is a JavaScript solution.
This one has not been posted before, but is inspired by
one of the previous answers.
/**
https://app.codility.com/demo/take-sample-test 100%
(c) Henke 2022 https://stackoverflow.com/users/9213345
https://jdoodle.com/a/3AZG
To run the program in a terminal window:
node CodilityDemoJS3.js
Terminal command to run the combined formatter/linter:
standard CodilityDemoJS3.js
https://github.com/standard/standard
*/
function solution (A) {
/// Returns the smallest positive integer missing in the array A.
let smallestMissing = 1
// In the following .reduce(), the only interest is in `smallestMissing`.
// I arbitrarily return '-9' because I don't care about the return value.
A.filter(x => x > 0).sort((a, b) => a - b).reduce((accumulator, item) => {
if (smallestMissing < item) return -9 // Found before end of the array.
smallestMissing = item + 1
return -9 // Found at the end of the array.
}, 1)
return smallestMissing
}
// Demo examples. --> Expected output: 1 2 3 4 1 2 3 1 (but vertically).
// Note! The following lines need to be left out when running the
// Codility Demo Test at https://app.codility.com/demo/take-sample-test :
console.log('Hello Codility Demo Test for JavaScript, 3.')
console.log(solution([-1, -3]))
console.log(solution([1, -1]))
console.log(solution([2, 1, 2, 5]))
console.log(solution([3, 1, -2, 2]))
console.log(solution([]))
console.log(solution([1, -5, -3]))
console.log(solution([1, 2, 4, 5]))
console.log(solution([17, 2]))
.as-console-wrapper { max-height: 100% !important; top: 0; }
3. Python
Python has come to compete with Java as one of the most used
programming languages worldwide.
The code below is a slightly rewritten version of this answer.
#!/usr/bin/env python3
'''
https://app.codility.com/demo/take-sample-test 100%
https://stackoverflow.com/a/58980724
https://jdoodle.com/a/3B0k
To run the program in a terminal window:
python codility_demo_python_a.py
Command in the terminal window to run the linter:
py -m pylint codility_demo_python_a.py
https://pypi.org/project/pylint/
Dito for autopep8 formatting:
autopep8 codility_demo_python_a.py --in-place
https://pypi.org/project/autopep8/
'''
def solution(int_array):
'''
Returns the smallest positive integer missing in int_array.
'''
max_elem = max(int_array, default=0)
if max_elem < 1:
return 1
int_array = set(int_array) # Reusing int_array although now a set
# print(int_array) # <- Temporarily uncomment at line beginning
all_ints = set(range(1, max_elem + 1))
diff_set = all_ints - int_array
if len(diff_set) == 0:
return max_elem + 1
return min(diff_set)
# Demo examples. --> Expected output: 1 2 3 4 1 2 3 1 (but vertically).
# Note! The following lines need to be commented out when running the
# Codility Demo Test at https://app.codility.com/demo/take-sample-test :
print('Hello Codility Demo Test for Python3, a.')
print(solution([-1, -3]))
print(solution([1, -1]))
print(solution([2, 1, 2, 5]))
print(solution([3, 1, -2, 2]))
print(solution([]))
print(solution([1, -5, -3]))
print(solution([1, 2, 4, 5]))
print(solution([17, 2]))
4. C#
Here a solution for C#, inspired by a previous answer.
using System;
using System.Linq;
/// https://app.codility.com/demo/take-sample-test 100%
/// (c) 2021 Henke, https://stackoverflow.com/users/9213345
/// https://jdoodle.com/a/3B0Z
/// To initialize the program in a terminal window, only ONCE:
/// dotnet new console -o codilityDemoC#-2 && cd codilityDemoC#-2
/// To run the program in a terminal window:
/// dotnet run && rm -rf obj && rm -rf bin
/// Terminal command to run 'dotnet-format':
/// dotnet-format --include DemoC#_2.cs && rm -rf obj && rm -rf bin
public class Solution {
/// Returns the smallest positive integer missing in intArray.
public int solution(int[] intArray) {
var sortedSet =
intArray.Where(x => x > 0).Distinct().OrderBy(x => x).ToArray();
// Console.WriteLine("[" + string.Join(",", sortedSet) + "]"); // Uncomment?
if (sortedSet.Length == 0) return 1; // The set is empty.
int smallestMissing = 1;
for (int i = 0; i < sortedSet.Length; i++) {
if (smallestMissing < sortedSet[i]) break; // The answer has been found.
smallestMissing = sortedSet[i] + 1;
} // Coming here means all of `sortedSet` had to be traversed.
return smallestMissing;
}
/// Demo examples. --> Expected output: 1 2 3 4 1 2 3 1 (but vertically).
/// NOTE! The code below must be removed before running the Codility test.
static void Main(string[] args) {
Console.WriteLine("Hello Codility Demo Test for C#, 2.");
int[] array1 = { -1, -3 };
Console.WriteLine((new Solution()).solution(array1));
int[] array2 = { 1, -1 };
Console.WriteLine((new Solution()).solution(array2));
int[] array3 = { 2, 1, 2, 5 };
Console.WriteLine((new Solution()).solution(array3));
int[] array4 = { 3, 1, -2, 2 };
Console.WriteLine((new Solution()).solution(array4));
int[] array5 = { };
Console.WriteLine((new Solution()).solution(array5));
int[] array6 = { 1, -5, -3 };
Console.WriteLine((new Solution()).solution(array6));
int[] array7 = { 1, 2, 4, 5 };
Console.WriteLine((new Solution()).solution(array7));
int[] array8 = { 17, 2 };
Console.WriteLine((new Solution()).solution(array8));
}
}
5. Swift
Here is a solution for Swift, taken from this answer.
/**
https://app.codility.com/demo/take-sample-test 100%
https://stackoverflow.com/a/57063839
https://www.jdoodle.com/a/4ny5
*/
public func solution(_ A : inout [Int]) -> Int {
/// Returns the smallest positive integer missing in the array A.
let positiveSortedInts = A.filter { $0 > 0 }.sorted()
// print(positiveSortedInts) // <- Temporarily uncomment at line beginning
var smallestMissingPositiveInt = 1
for elem in positiveSortedInts{
// if(elem > smallestMissingPositiveInt) then the answer has been found!
if(elem > smallestMissingPositiveInt) { return smallestMissingPositiveInt }
smallestMissingPositiveInt = elem + 1
}
return smallestMissingPositiveInt // This is if the whole array was traversed.
}
// Demo examples. --> Expected output: 1 2 3 4 1 2 3 1 (but vertically).
// Note! The following lines need to be left out when running the
// Codility Demo Test at https://app.codility.com/demo/take-sample-test :
print("Hello Codility Demo Test for Swift 4, A.")
var array1 = [-1, -3]
print(solution(&array1))
var array2 = [1, -1]
print(solution(&array2))
var array3 = [2, 1, 2, 5]
print(solution(&array3))
var array4 = [3, 1, -2, 2]
print(solution(&array4))
var array5 = [] as [Int]
print(solution(&array5))
var array6 = [1, -5, -3]
print(solution(&array6))
var array7 = [1, 2, 4, 5]
print(solution(&array7))
var array8 = [17, 2]
print(solution(&array8))
6. PHP
Here a solution for PHP, taken from this answer.
<?php
/**
https://app.codility.com/demo/take-sample-test 100%
https://stackoverflow.com/a/60535808
https://www.jdoodle.com/a/4nB0
*/
function solution($A) {
$smallestMissingPositiveInt = 1;
sort($A);
foreach($A as $elem){
if($elem <=0) continue;
if($smallestMissingPositiveInt < $elem) return $smallestMissingPositiveInt;
else $smallestMissingPositiveInt = $elem + 1;
}
return $smallestMissingPositiveInt;
}
// Demo examples. --> Expected output: 1 2 3 4 1 2 3 1 .
// Note! The starting and ending PHP tags are needed when running
// the code from the command line in a *.php file, but they and
// the following lines need to be left out when running the Codility
// Demo Test at https://app.codility.com/demo/take-sample-test :
echo "Hello Codility Demo Test for PHP, 1.\n";
echo solution([-1, -3]) . " ";
echo solution([1, -1]) . " ";
echo solution([2, 1, 2, 5]) . " ";
echo solution([3, 1, -2, 2]) . " ";
echo solution([]) . " ";
echo solution([1, -5, -3]) . " ";
echo solution([1, 2, 4, 5]) . " ";
echo solution([17, 2]) . " ";
?>
References
The Codility skills assessment demo test
The LeetCode playground
A correct Java solution
A correct JavaScript solution
A correct Python 3 solution
A correct C# solution
A correct Swift 4 solution
A correct PHP solution
1
This is true even for the first solution – the Java solution –
despite the the fact that this solution is wrong!
2 You can try running the test yourself at
https://app.codility.com/demo/take-sample-test.
You will have to sign up to do so.
Simply copy-paste all of the code from the snippet.
The default is Java 8, so you won't need to change the language
for the first solution.
My solution in JavaScript, using the reduce() method
function solution(A) {
// the smallest positive integer = 1
if (!A.includes(1)) return 1;
// greater than 1
return A.reduce((accumulator, current) => {
if (current <= 0) return accumulator
const min = current + 1
return !A.includes(min) && accumulator > min ? min : accumulator;
}, 1000000)
}
console.log(solution([1, 2, 3])) // 4
console.log(solution([5, 3, 2, 1, -1])) // 4
console.log(solution([-1, -3])) // 1
console.log(solution([2, 3, 4])) // 1
https://codesandbox.io/s/the-smallest-positive-integer-zu4s2
I figured an easy way to do this was to use a BitSet.
just add all the positive numbers to the BitSet.
when finished, return the index of the first clear bit after bit 0.
public static int find(int[] arr) {
BitSet b = new BitSet();
for (int i : arr) {
if (i > 0) {
b.set(i);
}
}
return b.nextClearBit(1);
}
JavaScript solution without sort, 100% score and O(N) runtime. It builds a hash set of the positive numbers while finding the max number.
function solution(A) {
set = new Set()
let max = 0
for (let i=0; i<A.length; i++) {
if (A[i] > 0) {
set.add(A[i])
max = Math.max(max, A[i])
}
}
for (let i=1; i<max; i++) {
if (!set.has(i)) {
return i
}
}
return max+1
}
Here is a simple and fast code in PHP.
Task Score: 100%
Correctness: 100%
Performance: 100%
Detected time complexity: O(N) or O(N * log(N))
function solution($A) {
$x = 1;
sort($A);
foreach($A as $i){
if($i <=0) continue;
if($x < $i) return $x;
else $x = $i+1;
}
return $x;
}
Performance tests
100% solution in Swift, I found it here, it is really beautiful than my algo... No need to turn array as ordered, instead using dictionary [Int: Bool] and just check the positive item in dictionary.
public func solution(_ A : inout [Int]) -> Int {
var counter = [Int: Bool]()
for i in A {
counter[i] = true
}
var i = 1
while true {
if counter[i] == nil {
return i
} else {
i += 1
}
}
}
My solution having 100% result in codility with Swift 4.
func solution(_ A : [Int]) -> Int {
let positive = A.filter { $0 > 0 }.sorted()
var x = 1
for val in positive{
if(x < val) {
return x
}
x = val + 1
}
return x
}
My simple and (time) efficient Java solution:
import java.util.*;
class Solution {
public int solution(int[] A) {
Set<Integer> set=new TreeSet<>();
for (int x:A) {
if (x>0) {
set.add(x);
}
}
int y=1;
Iterator<Integer> it=set.iterator();
while (it.hasNext()) {
int curr=it.next();
if (curr!=y) {
return y;
}
y++;
}
return y;
}
}
First let me explain about the algorithm down below.
If the array contains no elements then return 1,
Then in a loop check if the current element of the array is larger then the previous element by 2 then there is the first smallest missing integer, return it.
If the current element is consecutive to the previous element then the current smallest missing integer is the current integer + 1.
Array.sort(A);
if(A.Length == 0) return 1;
int last = (A[0] < 1) ? 0 : A[0];
for (int i = 0; i < A.Length; i++)
{
if(A[i] > 0){
if (A[i] - last > 1) return last + 1;
else last = A[i];
}
}
return last + 1;
This my implementation in Swift 4 with 100% Score. It should be a pretty similar code in Java. Let me know what you think.
public func solution(_ A : inout [Int]) -> Int {
let B = A.filter({ element in
element > 0
}).sorted()
var result = 1
for element in B {
if element == result {
result = result + 1
} else if element > result {
break
}
}
return result
}
This is the solution in C#:
using System;
// you can also use other imports, for example:
using System.Collections.Generic;
// you can write to stdout for debugging purposes, e.g.
// Console.WriteLine("this is a debug message");
class Solution {
public int solution(int[] A) {
// write your code in C# 6.0 with .NET 4.5 (Mono)
int N = A.Length;
HashSet<int> set =new HashSet<int>();
foreach (int a in A) {
if (a > 0) {
set.Add(a);
}
}
for (int i = 1; i <= N + 1; i++) {
if (!set.Contains(i)) {
return i;
}
}
return N;
}
}
This is for C#, it uses HashSet and Linq queries and has 100% score on Codility
public int solution(int[] A)
{
var val = new HashSet<int>(A).Where(x => x >= 1).OrderBy((y) =>y).ToArray();
var minval = 1;
for (int i = 0; i < val.Length; i++)
{
if (minval < val[i])
{
return minval;
}
minval = val[i] + 1;
}
return minval;
}
You're doing too much. You've create a TreeSet which is an order set of integers, then you've tried to turn that back into an array. Instead go through the list, and skip all negative values, then once you find positive values start counting the index. If the index is greater than the number, then the set has skipped a positive value.
int index = 1;
for(int a: set){
if(a>0){
if(a>index){
return index;
} else{
index++;
}
}
}
return index;
Updated for negative values.
A different solution that is O(n) would be to use an array. This is like the hash solution.
int N = A.length;
int[] hashed = new int[N];
for( int i: A){
if(i>0 && i<=N){
hashed[i-1] = 1;
}
}
for(int i = 0; i<N; i++){
if(hash[i]==0){
return i+1;
}
}
return N+1;
This could be further optimized counting down the upper limit for the second loop.
I find another solution to do it with additional storage,
/*
* if A = [-1,2] the solution works fine
* */
public static int solution(int[] A) {
int N = A.length;
int[] C = new int[N];
/*
* Mark A[i] as visited by making A[A[i] - 1] negative
* */
for (int i = 0; i < N; i++) {
/*
* we need the absolute value for the duplicates
* */
int j = Math.abs(A[i]) - 1;
if (j >= 0 && j < N && A[j] > 0) {
C[j] = -A[j];
}
}
for (int i = 0; i < N; i++) {
if (C[i] == 0) {
return i + 1;
}
}
return N + 1;
}
//My recursive solution:
class Solution {
public int solution(int[] A) {
return next(1, A);
}
public int next(int b, int[] A) {
for (int a : A){
if (b==a)
return next(++b, A);
}
return b;
}
}
Given an array of integers (each <=10^6) what is the fastest way to find the sum of powers of prime factors of each integer?
Ex:-
array: 4 6 12 7
4 -> 2^2 -> 2
6 -> 2^1 * 3^1 -> 1+1 -> 2
12 -> 2^2 * 3^1 -> 2+1 -> 3
7 -> 7^1 -> 1
Answer: 2+2+3+1 = 8
Check this out and try to adapt something from there. Happy mathing!
// Print the number of 2s that divide n
while (n%2 == 0)
{
printf("%d ", 2);
n = n/2;
}
// n must be odd at this point. So we can skip
// one element (Note i = i +2)
for (int i = 3; i <= sqrt(n); i = i+2)
{
// While i divides n, print i and divide n
while (n%i == 0)
{
printf("%d ", i);
n = n/i;
}
}
// This condition is to handle the case when n
// is a prime number greater than 2
if (n > 2)
printf ("%d ", n);
You could possibly use the above algorithm on the product of all the integers in your array and obtain the same result, potentially faster due to saving time on all the add operations on the individual level.
You can reduce the time for finding the prime-factors of a number using sieve algorithm. For your question, some modification in the sieve algorithm will work.
You can do this,
// For Globally storing the sum of power of prime factors
public static int powerSum[] = new int[1000001];
// For Identifying the factor is prime or not
public static boolean prime[] = new boolean[1000001];
public static void sieve()
{
powerSum[0] = 0;
powerSum[1] = 1;
Arrays.fill(prime , true);
prime[0] = false;
prime[1] = false;
for(int i = 2 ; i <= 1000000 ; i++) // sieve algorithm
{
if(prime[i]) // Consider the factor for calculation only if it is prime
{
for(int j = i ; j <= 1000000 ; j += i)
{
int tempJ = j;
while(tempJ != 0 && tempJ%i == 0)// Counting number of occurance of the factor
{
powerSum[j]++;
tempJ /= i;
}
prime[j] = false;
}
}
}
}
In the sieve method, I'm pre calculating the sum of powers of prime factors of every number between given range. I use the simple sieve method for considering only prime factors, and for counting the occurrence of that factor, I apply while loop.
Now you can use this method for finding the sum of power of prime factors for any number in given range by this way,
public static void main(String args[])
{
sieve();
int ans = powerSum[4] + powerSum[6] + powerSum[7] + powerSum[12];
System.out.println(ans);
}
Say we have
string a = "abc"
string b = "abcdcabaabccbaa"
Find location of all permutations of a in b. I am trying to find an effective algorithm for this.
Pseudo code:
sort string a // O(a loga)
for windows of length a in b // O(b)?
sort that window of b // O(~a loga)?
compare to a
if equal
save the index
So would this be a correct algorithm? Run time would be around O(aloga + ba loga) ~= O(a loga b)? How efficient would this be? Possibly way to reduce to O(a*b) or better?
sorting is very expensive, and doesn't use the fact you move along b with a sliding window.
I would use a comparison method that is location agnostic (since any permutation is valid) - assign each letter a prime number, and each string will be the multiplication of its letter values.
this way, as you go over b, each step requires just dividing by the letter you remove from he left, and multiplying with the next letter.
You also need to convince yourself that this indeed matches uniquely for each string and covers all permutations - this comes from the uniqueness of prime decomposition. Also note that on larger strings the numbers get big so you may need some library for large numbers
There is no need to hash, you can just count frequencies on your sliding window, and check if it matches. Assuming the size of your alphabet is s, you get a very simple O(s(n + m)) algorithm.
// a = [1 .. m] and b = [1 .. n] are the input
cnta = [1 .. s] array initialized to 0
cntb = [1 .. s] array initialized to 0
// nb_matches = the number of i s.t. cnta[i] = cntb[i]
// thus the current subword = a iff. nb_matches = s
nb_matches = s
for i = 1 to m:
if cntb[a[i]] = 0: nb_matches -= 1
cntb[a[i]] += 1
ans = 0
for i = 1 to n:
if cntb[b[i]] = cnta[b[i]]: nb_matches -= 1
cntb[b[i]] += 1
if nb_matches = s: ans += 1
if cntb[b[i]] = cnta[b[i]]: nb_matches += 1
if i - m + 1 >= 1:
if cntb[b[i - m + 1]] = cnta[b[i - m + 1]]: nb_matches -= 1
cntb[b[i - m + 1]] += 1
if cntb[b[i - m + 1]] = cnta[b[i - m + 1]]: nb_matches += 1
cntb[b[i - m + 1]] -= 1
return ans
Write a function strcount() to count the number of occurrences of character ch in a string or sub-sring str.
Then just pass through the search string.
for(i=0;i<haystacklenN-NeedleN+1;i++)
{
for(j=0;j<needleN;j++)
if(strcount(haystack + i, Nneedle, needle[j]) != strcount(needles, needlesN, needle[j])
break
}
if(j == needleN)
/* found a permuatation */
Below is my solution. The space complexity is just O(a + b), and the running time (if I can calculate correctly..) is O(b*a), as for each character in b, we may do a recursion a levels deep.
md5's answer is a good one and will be faster!!
public class FindPermutations {
public static void main(String[] args) {
System.out.println(numPerms(new String("xacxzaa"),
new String("fxaazxacaaxzoecazxaxaz")));
System.out.println(numPerms(new String("ABCD"),
new String("BACDGABCDA")));
System.out.println(numPerms(new String("AABA"),
new String("AAABABAA")));
// prints 4, then 3, then 3
}
public static int numPerms(final String a, final String b) {
int sum = 0;
for (int i = 0; i < b.length(); i++) {
if (permPresent(a, b.substring(i))) {
sum++;
}
}
return sum;
}
// is a permutation of a present at the start of b?
public static boolean permPresent(final String a, final String b) {
if (a.isEmpty()) {
return true;
}
if (b.isEmpty()) {
return false;
}
final char first = b.charAt(0);
if (a.contains(b.substring(0, 1))) {
// super ugly, but removes first from a
return permPresent(a.substring(0, a.indexOf(first)) + a.substring(a.indexOf(first)+1, a.length()),
b.substring(1));
}
return false;
}
}
For searchability's sake, I arrive on this page afer looking for other solutions to compare mine to, with the problem originating from watching this clip: https://www.hackerrank.com/domains/tutorials/cracking-the-coding-interview. The original problem statement was something like 'find all permutations of s in b'.
Use 2 hash tables and with a sliding window of size = length of smaller string:
int premutations_of_B_in_A(string large, string small) {
unordered_map<char, int> characters_in_large;
unordered_map<char, int> characters_in_small;
int ans = 0;
for (char c : small) {
characters_in_small[c]++;
}
for (int i = 0; i < small.length(); i++) {
characters_in_large[large[i]]++;
ans += (characters_in_small == characters_in_large);
}
for (int i = small.length(); i < large.length(); i++) {
characters_in_large[large[i]]++;
if (characters_in_large[large[i - small.length()]]-- == 1)
characters_in_large.erase(large[i - small.length()]);
ans += (characters_in_small == characters_in_large);
}
return ans;
}
This is almost solution but will help you to count occurrences of permutations of small strings into larger string
made for only lower case chars
This solution having --
Time Complexity - O(L)
where L is length of large input provided to problem, the exact would be to include 26 too for every char present in Large array but by ignoring constant terms, I will solely stand for this.
Space Complexity - O(1)
because 26 is also constant and independent of how large input would be.
int findAllPermutations(string small, string larger) {
int freqSmall[26] = {0};
//window size
int n = small.length();
//to return
int finalAns = 0;
for (char a : small) {
freqSmall[a - 97]++;
}
int freqlarger[26]={0};
int count = 0;
int j = 0;
for (int i = 0; larger[i] != '\0'; i++) {
freqlarger[larger[i] - 97]++;
count++;
if (count == n) {
count = 0;
int i;
for (i = 0; i < 26; i++) {
if (freqlarger[i] != freqSmall[i]) {
break;
}
}
if (i == 26) {
finalAns++;
}
freqlarger[larger[j] - 97]--;
j++;
}
}
return finalAns;
}
int main() {
string s, t;
cin >> s >> t;
cout << findAllPermutations(s, t) << endl;
return 0;
}
Question link: http://codeforces.com/contest/2/problem/B
There is a square matrix n × n, consisting of non-negative integer numbers. You should find such a way on it that
starts in the upper left cell of the matrix;
each following cell is to the right or down from the current cell;
the way ends in the bottom right cell.
Moreover, if we multiply together all the numbers along the way, the result should be the least "round". In other words, it should end in the least possible number of zeros.
Input
The first line contains an integer number n (2 ≤ n ≤ 1000), n is the size of the matrix. Then follow n lines containing the matrix elements (non-negative integer numbers not exceeding 10^9).
Output
In the first line print the least number of trailing zeros. In the second line print the correspondent way itself.
I thought of the following: In the end, whatever the answer will be, it should contain minimum powers of 2's and 5's. Therefore, what I did was, for each entry in the input matrix, I calculated the powers of 2's and 5's and stored them in separate matrices.
for (i = 0; i < n; i++)
{
for ( j = 0; j < n; j++)
{
cin>>foo;
matrix[i][j] = foo;
int n1 = calctwo(foo); // calculates the number of 2's in factorisation of that number
int n2 = calcfive(foo); // calculates number of 5's
two[i][j] = n1;
five[i][j] = n2;
}
}
After that, I did this:
for (i = 0; i < n; i++)
{
for ( j = 0; j < n; j++ )
{
dp[i][j] = min(two[i][j],five[i][j]); // Here, dp[i][j] will store minimum number of 2's and 5's.
}
}
But the above doesn't really a valid answer, I don't know why? Have I implemented the correct approach? Or, is this the correct way of solving this question?
Edit: Here are my functions of calculating the number of two's and number of five's in a number.
int calctwo (int foo)
{
int counter = 0;
while (foo%2 == 0)
{
if (foo%2 == 0)
{
counter++;
foo = foo/2;
}
else
break;
}
return counter;
}
int calcfive (int foo)
{
int counter = 0;
while (foo%5 == 0)
{
if (foo%5 == 0)
{
counter++;
foo = foo/5;
}
else
break;
}
return counter;
}
Edit2: I/O Example as given in the link:
Input:
3
1 2 3
4 5 6
7 8 9
Output:
0
DDRR
Since you are interested only in the number of trailing zeroes you need only to consider the powers of 2, 5 which you could keep in two separate nxn arrays. So for the array
1 2 3
4 5 6
7 8 9
you just keep the arrays
the powers of 2 the powers of 5
0 1 0 0 0 0
2 0 1 0 1 0
0 3 0 0 0 0
The insight for the problem is the following. Notice that if you find a path which minimizes the sum of the powers of 2 and a path which minimizes the number sum of the powers of 5 then the answer is the one with lower value of those two paths. So you reduce your problem to the two times application of the following classical dp problem: find a path, starting from the top-left corner and ending at the bottom-right, such that the sum of its elements is minimum. Again, following the example, we have:
minimal path for the
powers of 2 value
* * - 2
- * *
- - *
minimal path for the
powers of 5 value
* - - 0
* - -
* * *
so your answer is
* - -
* - -
* * *
with value 0
Note 1
It might seem that taking the minimum of the both optimal paths gives only an upper bound so a question that may rise is: is this bound actually achieved? The answer is yes. For convenience, let the number of 2's along the 2's optimal path is a and the number of 5's along the 5's optimal path is b. Without loss of generality assume that the minimum of the both optimal paths is the one for the power of 2's (that is a < b). Let the number of 5's along the minimal path is c. Now the question is: are there as much as 5's as there are 2's along this path (i.e. is c >= a?). Assume that the answer is no. That means that there are less 5's than 2's along the minimal path (that is c < a). Since the optimal value of 5's paths is b we have that every 5's path has at least b 5's in it. This should also be true for the minimal path. That means that c > b. We have that c < a so a > b but the initial assumption was that a < b. Contradiction.
Note 2
You might also want consider the case in which there is an element 0 in your matrix. I'd assume that number of trailing zeroes when the product is 1. In this case, if the algorithm has produced a result with a value more than 1 you should output 1 and print a path that goes through the element 0.
Here is the code. I've used pair<int,int> to store factor of 2 and 5 in the matrix.
#include<vector>
#include<iostream>
using namespace std;
#define pii pair<int,int>
#define F first
#define S second
#define MP make_pair
int calc2(int a){
int c=0;
while(a%2==0){
c++;
a/=2;
}
return c;
}
int calc5(int a){
int c=0;
while(a%5==0){
c++;
a/=5;
}
return c;
}
int mini(int a,int b){
return a<b?a:b;
}
pii min(pii a, pii b){
if(mini(a.F,a.S) < mini(b.F,b.S))
return a;
return b;
}
int main(){
int n;
cin>>n;
vector<vector<pii > > v;
vector<vector<int> > path;
int i,j;
for(i=0;i<n;i++){
vector<pii > x;
vector<int> q(n,0);
for(j=0;j<n;j++){
int y;cin>>y;
x.push_back(MP(calc2(y),calc5(y))); //I store factors of 2,5 in the vector to calculate
}
x.push_back(MP(100000,100000)); //padding each row to n+1 elements (to handle overflow in code)
v.push_back(x);
path.push_back(q); //initialize path matrix to 0
}
vector<pii > x(n+1,MP(100000,100000));
v.push_back(x); //pad 1 more row to handle index overflow
for(i=n-1;i>=0;i--){
for(j=n-1;j>=0;j--){ //move from destination to source grid
if(i==n-1 && j==n-1)
continue;
//here, the LHS of condition in if block is the condition which determines minimum number of trailing 0's. This is the same condition that is used to manipulate "v" for getting the same result.
if(min(MP(v[i][j].F+v[i+1][j].F,v[i][j].S+v[i+1][j].S), MP(v[i][j].F+v[i][j+1].F,v[i][j].S+v[i][j+1].S)) == MP(v[i][j].F+v[i+1][j].F,v[i][j].S+v[i+1][j].S))
path[i][j] = 1; //go down
else
path[i][j] = 2; //go right
v[i][j] = min(MP(v[i][j].F+v[i+1][j].F,v[i][j].S+v[i+1][j].S), MP(v[i][j].F+v[i][j+1].F,v[i][j].S+v[i][j+1].S));
}
}
cout<<mini(v[0][0].F, v[0][0].S)<<endl; //print result
for(i=0,j=0;i<=n-1 && j<=n-1;){ //print path (I don't know o/p format)
cout<<"("<<i<<","<<j<<") -> ";
if(path[i][j]==1)
i++;
else
j++;
}
return 0;
}
This code gives fine results as far as the test cases I checked. If you have any doubts regarding this code, ask in comments.
EDIT:
The basic thought process.
To reach the destination, there are only 2 options. I started with destination to avoid the problem of path ahead calculation, because if 2 have same minimum values, then we chose any one of them. If the path to destination is already calculated, it does not matter which we take.
And minimum is to check which pair is more suitable. If a pair has minimum 2's or 5's than other, it will produce less 0's.
Here is a solution proposal using Javascript and functional programming.
It relies on several functions:
the core function is smallest_trailer that recursively goes through the grid. I have chosen to go in 4 possible direction, left "L", right "R", down "D" and "U". It is not possible to pass twice on the same cell. The direction that is chosen is the one with the smallest number of trailing zeros. The counting of trailing zeros is devoted to another function.
the function zero_trailer(p,n,nbz) assumes that you arrive on a cell with a value p while you already have an accumulator n and met nbz zeros on your way. The function returns an array with two elements, the new number of zeros and the new accumulator. The accumulator will be a power of 2 or 5. The function uses the auxiliary function pow_2_5(n) that returns the powers of 2 and 5 inside n.
Other functions are more anecdotical: deepCopy(arr) makes a standard deep copy of the array arr, out_bound(i,j,n) returns true if the cell (i,j) is out of bound of the grid of size n, myMinIndex(arr) returns the min index of an array of 2 dimensional arrays (each subarray contains the nb of trailing zeros and the path as a string). The min is only taken on the first element of subarrays.
MAX_SAFE_INTEGER is a (large) constant for the maximal number of trailing zeros when the path is wrong (goes out of bound for example).
Here is the code, which works on the example given in the comments above and in the orginal link.
var MAX_SAFE_INTEGER = 9007199254740991;
function pow_2_5(n) {
// returns the power of 2 and 5 inside n
function pow_not_2_5(k) {
if (k%2===0) {
return pow_not_2_5(k/2);
}
else if (k%5===0) {
return pow_not_2_5(k/5);
}
else {
return k;
}
}
return n/pow_not_2_5(n);
}
function zero_trailer(p,n,nbz) {
// takes an input two numbers p and n that should be multiplied and a given initial number of zeros (nbz = nb of zeros)
// n is the accumulator of previous multiplications (a power of 5 or 2)
// returns an array [kbz, k] where kbz is the total new number of zeros (nbz + the trailing zeros from the multiplication of p and n)
// and k is the new accumulator (typically a power of 5 or 2)
function zero_aux(k,kbz) {
if (k===0) {
return [1,0];
}
else if (k%10===0) {
return zero_aux(k/10,kbz+1);
}
else {
return [kbz,k];
}
}
return zero_aux(pow_2_5(p)*n,nbz);
}
function out_bound(i,j,n) {
return !((i>=0)&&(i<n)&&(j>=0)&&(j<n));
}
function deepCopy(arr){
var toR = new Array(arr.length);
for(var i=0;i<arr.length;i++){
var toRi = new Array(arr[i].length);
for(var j=0;j<arr[i].length;j++){
toRi[j] = arr[i][j];
}
toR[i] = toRi;
}
return toR;
}
function myMinIndex(arr) {
var min = arr[0][0];
var minIndex = 0;
for (var i = 1; i < arr.length; i++) {
if (arr[i][0] < min) {
minIndex = i;
min = arr[i][0];
}
}
return minIndex;
}
function smallest_trailer(grid) {
var n = grid.length;
function st_aux(i,j,grid_aux, acc_mult, nb_z, path) {
if ((i===n-1)&&(j===n-1)) {
var tmp_acc_nbz_f = zero_trailer(grid_aux[i][j],acc_mult,nb_z);
return [tmp_acc_nbz_f[0], path];
}
else if (out_bound(i,j,n)) {
return [MAX_SAFE_INTEGER,[]];
}
else if (grid_aux[i][j]<0) {
return [MAX_SAFE_INTEGER,[]];
}
else {
var tmp_acc_nbz = zero_trailer(grid_aux[i][j],acc_mult,nb_z) ;
grid_aux[i][j]=-1;
var res = [st_aux(i+1,j,deepCopy(grid_aux), tmp_acc_nbz[1], tmp_acc_nbz[0], path+"D"),
st_aux(i-1,j,deepCopy(grid_aux), tmp_acc_nbz[1], tmp_acc_nbz[0], path+"U"),
st_aux(i,j+1,deepCopy(grid_aux), tmp_acc_nbz[1], tmp_acc_nbz[0], path+"R"),
st_aux(i,j-1,deepCopy(grid_aux), tmp_acc_nbz[1], tmp_acc_nbz[0], path+"L")];
return res[myMinIndex(res)];
}
}
return st_aux(0,0,grid, 1, 0, "");
}
myGrid = [[1, 25, 100],[2, 1, 25],[100, 5, 1]];
console.log(smallest_trailer(myGrid)); //[0,"RDDR"]
myGrid = [[1, 2, 100],[25, 1, 5],[100, 25, 1]];
console.log(smallest_trailer(myGrid)); //[0,"DRDR"]
myGrid = [[1, 10, 1, 1, 1],[1, 1, 1, 10, 1],[10, 10, 10, 10, 1],[10, 10, 10, 10, 1],[10, 10, 10, 10, 1]];
console.log(smallest_trailer(myGrid)); //[0,"DRRURRDDDD"]
This is my Dynamic Programming solution.
https://app.codility.com/demo/results/trainingAXFQ5B-SZQ/
For better understanding we can simplify the task and assume that there are no zeros in the matrix (i.e. matrix contains only positive integers), then the Java solution will be the following:
class Solution {
public int solution(int[][] a) {
int minPws[][] = new int[a.length][a[0].length];
int minPws2 = getMinPws(a, minPws, 2);
int minPws5 = getMinPws(a, minPws, 5);
return min(minPws2, minPws5);
}
private int getMinPws(int[][] a, int[][] minPws, int p) {
minPws[0][0] = pws(a[0][0], p);
//Fullfill the first row
for (int j = 1; j < a[0].length; j++) {
minPws[0][j] = minPws[0][j-1] + pws(a[0][j], p);
}
//Fullfill the first column
for (int i = 1; i < a.length; i++) {
minPws[i][0] = minPws[i-1][0] + pws(a[i][0], p);
}
//Fullfill the rest of matrix
for (int i = 1; i < a.length; i++) {
for (int j = 1; j < a[0].length; j++) {
minPws[i][j] = min(minPws[i-1][j], minPws[i][j-1]) + pws(a[i][j], p);
}
}
return minPws[a.length-1][a[0].length-1];
}
private int pws(int n, int p) {
//Only when n > 0
int pws = 0;
while (n % p == 0) {
pws++;
n /= p;
}
return pws;
}
private int min(int a, int b) {
return (a < b) ? a : b;
}
}
How do you calculate the least common multiple of multiple numbers?
So far I've only been able to calculate it between two numbers. But have no idea how to expand it to calculate 3 or more numbers.
So far this is how I did it
LCM = num1 * num2 / gcd ( num1 , num2 )
With gcd is the function to calculate the greatest common divisor for the numbers. Using euclidean algorithm
But I can't figure out how to calculate it for 3 or more numbers.
You can compute the LCM of more than two numbers by iteratively computing the LCM of two numbers, i.e.
lcm(a,b,c) = lcm(a,lcm(b,c))
In Python (modified primes.py):
def gcd(a, b):
"""Return greatest common divisor using Euclid's Algorithm."""
while b:
a, b = b, a % b
return a
def lcm(a, b):
"""Return lowest common multiple."""
return a * b // gcd(a, b)
def lcmm(*args):
"""Return lcm of args."""
return reduce(lcm, args)
Usage:
>>> lcmm(100, 23, 98)
112700
>>> lcmm(*range(1, 20))
232792560
reduce() works something like that:
>>> f = lambda a,b: "f(%s,%s)" % (a,b)
>>> print reduce(f, "abcd")
f(f(f(a,b),c),d)
Here's an ECMA-style implementation:
function gcd(a, b){
// Euclidean algorithm
while (b != 0){
var temp = b;
b = a % b;
a = temp;
}
return a;
}
function lcm(a, b){
return (a * b / gcd(a, b));
}
function lcmm(args){
// Recursively iterate through pairs of arguments
// i.e. lcm(args[0], lcm(args[1], lcm(args[2], args[3])))
if(args.length == 2){
return lcm(args[0], args[1]);
} else {
var arg0 = args[0];
args.shift();
return lcm(arg0, lcmm(args));
}
}
I would go with this one (C#):
static long LCM(long[] numbers)
{
return numbers.Aggregate(lcm);
}
static long lcm(long a, long b)
{
return Math.Abs(a * b) / GCD(a, b);
}
static long GCD(long a, long b)
{
return b == 0 ? a : GCD(b, a % b);
}
Just some clarifications, because at first glance it doesn't seams so clear what this code is doing:
Aggregate is a Linq Extension method, so you cant forget to add using System.Linq to your references.
Aggregate gets an accumulating function so we can make use of the property lcm(a,b,c) = lcm(a,lcm(b,c)) over an IEnumerable. More on Aggregate
GCD calculation makes use of the Euclidean algorithm.
lcm calculation uses Abs(a*b)/gcd(a,b) , refer to Reduction by the greatest common divisor.
Hope this helps,
I just figured this out in Haskell:
lcm' :: Integral a => a -> a -> a
lcm' a b = a`div`(gcd a b) * b
lcm :: Integral a => [a] -> a
lcm (n:ns) = foldr lcm' n ns
I even took the time to write my own gcd function, only to find it in Prelude! Lots of learning for me today :D
Some Python code that doesn't require a function for gcd:
from sys import argv
def lcm(x,y):
tmp=x
while (tmp%y)!=0:
tmp+=x
return tmp
def lcmm(*args):
return reduce(lcm,args)
args=map(int,argv[1:])
print lcmm(*args)
Here's what it looks like in the terminal:
$ python lcm.py 10 15 17
510
Here is a Python one-liner (not counting imports) to return the LCM of the integers from 1 to 20 inclusive:
Python 3.5+ imports:
from functools import reduce
from math import gcd
Python 2.7 imports:
from fractions import gcd
Common logic:
lcm = reduce(lambda x,y: x*y // gcd(x, y), range(1, 21))
Note that in both Python 2 and Python 3, operator precedence rules dictate that the * and // operators have the same precedence, and so they apply from left to right. As such, x*y // z means (x*y) // z and not x * (y//z). The two typically produce different results. This wouldn't have mattered as much for float division but it does for floor division.
Here it is in Swift.
// Euclid's algorithm for finding the greatest common divisor
func gcd(_ a: Int, _ b: Int) -> Int {
let r = a % b
if r != 0 {
return gcd(b, r)
} else {
return b
}
}
// Returns the least common multiple of two numbers.
func lcm(_ m: Int, _ n: Int) -> Int {
return m / gcd(m, n) * n
}
// Returns the least common multiple of multiple numbers.
func lcmm(_ numbers: [Int]) -> Int {
return numbers.reduce(1) { lcm($0, $1) }
}
Here is a C# port of Virgil Disgr4ce's implemenation:
public class MathUtils
{
/// <summary>
/// Calculates the least common multiple of 2+ numbers.
/// </summary>
/// <remarks>
/// Uses recursion based on lcm(a,b,c) = lcm(a,lcm(b,c)).
/// Ported from http://stackoverflow.com/a/2641293/420175.
/// </remarks>
public static Int64 LCM(IList<Int64> numbers)
{
if (numbers.Count < 2)
throw new ArgumentException("you must pass two or more numbers");
return LCM(numbers, 0);
}
public static Int64 LCM(params Int64[] numbers)
{
return LCM((IList<Int64>)numbers);
}
private static Int64 LCM(IList<Int64> numbers, int i)
{
// Recursively iterate through pairs of arguments
// i.e. lcm(args[0], lcm(args[1], lcm(args[2], args[3])))
if (i + 2 == numbers.Count)
{
return LCM(numbers[i], numbers[i+1]);
}
else
{
return LCM(numbers[i], LCM(numbers, i+1));
}
}
public static Int64 LCM(Int64 a, Int64 b)
{
return (a * b / GCD(a, b));
}
/// <summary>
/// Finds the greatest common denominator for 2 numbers.
/// </summary>
/// <remarks>
/// Also from http://stackoverflow.com/a/2641293/420175.
/// </remarks>
public static Int64 GCD(Int64 a, Int64 b)
{
// Euclidean algorithm
Int64 t;
while (b != 0)
{
t = b;
b = a % b;
a = t;
}
return a;
}
}'
And the Scala version:
def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
def gcd(nums: Iterable[Int]): Int = nums.reduce(gcd)
def lcm(a: Int, b: Int): Int = if (a == 0 || b == 0) 0 else a * b / gcd(a, b)
def lcm(nums: Iterable[Int]): Int = nums.reduce(lcm)
Function to find lcm of any list of numbers:
def function(l):
s = 1
for i in l:
s = lcm(i, s)
return s
Using LINQ you could write:
static int LCM(int[] numbers)
{
return numbers.Aggregate(LCM);
}
static int LCM(int a, int b)
{
return a * b / GCD(a, b);
}
Should add using System.Linq; and don't forget to handle the exceptions ...
you can do it another way -
Let there be n numbers.Take a pair of consecutive numbers and save its lcm in another array. Doing this at first iteration program does n/2 iterations.Then next pick up pair starting from 0 like (0,1) , (2,3) and so on.Compute their LCM and store in another array. Do this until you are left with one array.
(it is not possible to find lcm if n is odd)
In R, we can use the functions mGCD(x) and mLCM(x) from the package numbers, to compute the greatest common divisor and least common multiple for all numbers in the integer vector x together:
library(numbers)
mGCD(c(4, 8, 12, 16, 20))
[1] 4
mLCM(c(8,9,21))
[1] 504
# Sequences
mLCM(1:20)
[1] 232792560
ES6 style
function gcd(...numbers) {
return numbers.reduce((a, b) => b === 0 ? a : gcd(b, a % b));
}
function lcm(...numbers) {
return numbers.reduce((a, b) => Math.abs(a * b) / gcd(a, b));
}
Just for fun, a shell (almost any shell) implementation:
#!/bin/sh
gcd() { # Calculate $1 % $2 until $2 becomes zero.
until [ "$2" -eq 0 ]; do set -- "$2" "$(($1%$2))"; done
echo "$1"
}
lcm() { echo "$(( $1 / $(gcd "$1" "$2") * $2 ))"; }
while [ $# -gt 1 ]; do
t="$(lcm "$1" "$2")"
shift 2
set -- "$t" "$#"
done
echo "$1"
try it with:
$ ./script 2 3 4 5 6
to get
60
The biggest input and result should be less than (2^63)-1 or the shell math will wrap.
i was looking for gcd and lcm of array elements and found a good solution in the following link.
https://www.hackerrank.com/challenges/between-two-sets/forum
which includes following code. The algorithm for gcd uses The Euclidean Algorithm explained well in the link below.
https://www.khanacademy.org/computing/computer-science/cryptography/modarithmetic/a/the-euclidean-algorithm
private static int gcd(int a, int b) {
while (b > 0) {
int temp = b;
b = a % b; // % is remainder
a = temp;
}
return a;
}
private static int gcd(int[] input) {
int result = input[0];
for (int i = 1; i < input.length; i++) {
result = gcd(result, input[i]);
}
return result;
}
private static int lcm(int a, int b) {
return a * (b / gcd(a, b));
}
private static int lcm(int[] input) {
int result = input[0];
for (int i = 1; i < input.length; i++) {
result = lcm(result, input[i]);
}
return result;
}
Here is the PHP implementation:
// https://stackoverflow.com/q/12412782/1066234
function math_gcd($a,$b)
{
$a = abs($a);
$b = abs($b);
if($a < $b)
{
list($b,$a) = array($a,$b);
}
if($b == 0)
{
return $a;
}
$r = $a % $b;
while($r > 0)
{
$a = $b;
$b = $r;
$r = $a % $b;
}
return $b;
}
function math_lcm($a, $b)
{
return ($a * $b / math_gcd($a, $b));
}
// https://stackoverflow.com/a/2641293/1066234
function math_lcmm($args)
{
// Recursively iterate through pairs of arguments
// i.e. lcm(args[0], lcm(args[1], lcm(args[2], args[3])))
if(count($args) == 2)
{
return math_lcm($args[0], $args[1]);
}
else
{
$arg0 = $args[0];
array_shift($args);
return math_lcm($arg0, math_lcmm($args));
}
}
// fraction bonus
function math_fraction_simplify($num, $den)
{
$g = math_gcd($num, $den);
return array($num/$g, $den/$g);
}
var_dump( math_lcmm( array(4, 7) ) ); // 28
var_dump( math_lcmm( array(5, 25) ) ); // 25
var_dump( math_lcmm( array(3, 4, 12, 36) ) ); // 36
var_dump( math_lcmm( array(3, 4, 7, 12, 36) ) ); // 252
Credits go to #T3db0t with his answer above (ECMA-style code).
GCD needs a little correction for negative numbers:
def gcd(x,y):
while y:
if y<0:
x,y=-x,-y
x,y=y,x % y
return x
def gcdl(*list):
return reduce(gcd, *list)
def lcm(x,y):
return x*y / gcd(x,y)
def lcml(*list):
return reduce(lcm, *list)
How about this?
from operator import mul as MULTIPLY
def factors(n):
f = {} # a dict is necessary to create 'factor : exponent' pairs
divisor = 2
while n > 1:
while (divisor <= n):
if n % divisor == 0:
n /= divisor
f[divisor] = f.get(divisor, 0) + 1
else:
divisor += 1
return f
def mcm(numbers):
#numbers is a list of numbers so not restricted to two items
high_factors = {}
for n in numbers:
fn = factors(n)
for (key, value) in fn.iteritems():
if high_factors.get(key, 0) < value: # if fact not in dict or < val
high_factors[key] = value
return reduce (MULTIPLY, ((k ** v) for k, v in high_factors.items()))
We have working implementation of Least Common Multiple on Calculla which works for any number of inputs also displaying the steps.
What we do is:
0: Assume we got inputs[] array, filled with integers. So, for example:
inputsArray = [6, 15, 25, ...]
lcm = 1
1: Find minimal prime factor for each input.
Minimal means for 6 it's 2, for 25 it's 5, for 34 it's 17
minFactorsArray = []
2: Find lowest from minFactors:
minFactor = MIN(minFactorsArray)
3: lcm *= minFactor
4: Iterate minFactorsArray and if the factor for given input equals minFactor, then divide the input by it:
for (inIdx in minFactorsArray)
if minFactorsArray[inIdx] == minFactor
inputsArray[inIdx] \= minFactor
5: repeat steps 1-4 until there is nothing to factorize anymore.
So, until inputsArray contains only 1-s.
And that's it - you got your lcm.
LCM is both associative and commutative.
LCM(a,b,c)=LCM(LCM(a,b),c)=LCM(a,LCM(b,c))
here is sample code in C:
int main()
{
int a[20],i,n,result=1; // assumption: count can't exceed 20
printf("Enter number of numbers to calculate LCM(less than 20):");
scanf("%d",&n);
printf("Enter %d numbers to calculate their LCM :",n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
result=lcm(result,a[i]);
printf("LCM of given numbers = %d\n",result);
return 0;
}
int lcm(int a,int b)
{
int gcd=gcd_two_numbers(a,b);
return (a*b)/gcd;
}
int gcd_two_numbers(int a,int b)
{
int temp;
if(a>b)
{
temp=a;
a=b;
b=temp;
}
if(b%a==0)
return a;
else
return gcd_two_numbers(b%a,a);
}
Method compLCM takes a vector and returns LCM. All the numbers are within vector in_numbers.
int mathOps::compLCM(std::vector<int> &in_numbers)
{
int tmpNumbers = in_numbers.size();
int tmpMax = *max_element(in_numbers.begin(), in_numbers.end());
bool tmpNotDividable = false;
while (true)
{
for (int i = 0; i < tmpNumbers && tmpNotDividable == false; i++)
{
if (tmpMax % in_numbers[i] != 0 )
tmpNotDividable = true;
}
if (tmpNotDividable == false)
return tmpMax;
else
tmpMax++;
}
}
clc;
data = [1 2 3 4 5]
LCM=1;
for i=1:1:length(data)
LCM = lcm(LCM,data(i))
end
For anyone looking for quick working code, try this:
I wrote a function lcm_n(args, num) which computes and returns the lcm of all the numbers in the array args. The second parameternum is the count of numbers in the array.
Put all those numbers in an array args and then call the function like lcm_n(args,num);
This function returns the lcm of all those numbers.
Here is the implementation of the function lcm_n(args, num):
int lcm_n(int args[], int num) //lcm of more than 2 numbers
{
int i, temp[num-1];
if(num==2)
{
return lcm(args[0], args[1]);
}
else
{
for(i=0;i<num-1;i++)
{
temp[i] = args[i];
}
temp[num-2] = lcm(args[num-2], args[num-1]);
return lcm_n(temp,num-1);
}
}
This function needs below two functions to work. So, just add them along with it.
int lcm(int a, int b) //lcm of 2 numbers
{
return (a*b)/gcd(a,b);
}
int gcd(int a, int b) //gcd of 2 numbers
{
int numerator, denominator, remainder;
//Euclid's algorithm for computing GCD of two numbers
if(a > b)
{
numerator = a;
denominator = b;
}
else
{
numerator = b;
denominator = a;
}
remainder = numerator % denominator;
while(remainder != 0)
{
numerator = denominator;
denominator = remainder;
remainder = numerator % denominator;
}
return denominator;
}
int gcd(int a, int b) {
if (b == 0) return a;
return gcd(b, a%b);
}
int lcm(int[] a, int n) {
int res = 1, i;
for (i = 0; i < n; i++) {
res = res*a[i]/gcd(res, a[i]);
}
return res;
}
In python:
def lcm(*args):
"""Calculates lcm of args"""
biggest = max(args) #find the largest of numbers
rest = [n for n in args if n != biggest] #the list of the numbers without the largest
factor = 1 #to multiply with the biggest as long as the result is not divisble by all of the numbers in the rest
while True:
#check if biggest is divisble by all in the rest:
ans = False in [(biggest * factor) % n == 0 for n in rest]
#if so the clm is found break the loop and return it, otherwise increment factor by 1 and try again
if not ans:
break
factor += 1
biggest *= factor
return "lcm of {0} is {1}".format(args, biggest)
>>> lcm(100,23,98)
'lcm of (100, 23, 98) is 112700'
>>> lcm(*range(1, 20))
'lcm of (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) is 232792560'
This is what I used --
def greater(n):
a=num[0]
for i in range(0,len(n),1):
if(a<n[i]):
a=n[i]
return a
r=input('enter limit')
num=[]
for x in range (0,r,1):
a=input('enter number ')
num.append(a)
a= greater(num)
i=0
while True:
while (a%num[i]==0):
i=i+1
if(i==len(num)):
break
if i==len(num):
print 'L.C.M = ',a
break
else:
a=a+1
i=0
for python 3:
from functools import reduce
gcd = lambda a,b: a if b==0 else gcd(b, a%b)
def lcm(lst):
return reduce(lambda x,y: x*y//gcd(x, y), lst)
In Ruby, it's as simple as:
> [2, 3, 4, 6].reduce(:lcm)
=> 12
> [16, 32, 96].reduce(:gcd)
=> 16
(tested on Ruby 2.2.10 and 2.6.3.)