Hackerrank Repeated String infinite loop problem - javascript

I am solving this hackerrank problem for counting the number of 'a's in a given string.
My solution was to store the string in a pattern variable. While the length of the pattern is less than n, it will just add the string to itself. Then I would loop over the pattern and add the number of 'a's in the string.
This solution works fine when n < 1000000. But add one more 0 and when n = 10000000, I get a RangeError for my string in hackerrank because it's too damn long.
Is there a way to get around this RangeError problem? I know there are other ways to solve this problem, but I just want to know how I could edit my code to make it pass the hackerrank test.
function repeatedString(s, n) {
let pattern = s;
let count = 0;
while (pattern.length < n) {
pattern += pattern;
}
for (let i = 0; i < n; i++) {
if (pattern[i] === 'a') {
count++;
}
}
return count;
}

You could do math on this rather than consume the memory and calculation on string concatenation and loop
The total number of a would be the number of a in s times the repeated number of s that has total length not exceed n, plus the remainder (left substring) of s that fill the n
For example, with the input
s = 'aba'
n = 10
It could be simply visually in the below
aba aba aba a(ba)
|______3______| |1|
First 3 repeated of aba equals n divided by length of s (i.e 10 / 3 = 3)
The leftover a (skips bc to equals with n) is the result of s sliced with the length equals remainder of n divided by length of s (i.e 10 % 3 = 1)
Plus two of these then we get the result
numberOfA(s) * (n div len(s)) + numberOfA(substr(s, 0, n mod len(s)))
function repeatedString(s, n) {
const numberOfA = str => str.split('').filter(char => char === 'a').length
return (
numberOfA(s) * Math.floor(n / s.length) +
numberOfA(s.substring(0, n % s.length))
)
}
console.log(repeatedString('aba', 10))
console.log(repeatedString('a', 1000000000000))

php solution for repeated String
function repeatedString($s, $n) {
$len = strlen($s);
$occurence = substr_count($s, "a");
$mul = floor ($n / $len);
$reminder = $n % $len;
$su = substr($s,0,$reminder);
return ($occurence * $mul) + substr_count($su,"a");
}

Related

Sorting algorithm complexity [duplicate]

This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
I have an array of numbers from 1 to 100 (both inclusive). The size of the array is 100. The numbers are randomly added to the array, but there is one random empty slot in the array.
What is the quickest way to find that slot as well as the number that should be put in the slot? A Java solution is preferable.
You can do this in O(n). Iterate through the array and compute the sum of all numbers. Now, sum of natural numbers from 1 to N, can be expressed as Nx(N+1)/2. In your case N=100.
Subtract the sum of the array from Nx(N+1)/2, where N=100.
That is the missing number. The empty slot can be detected during the iteration in which the sum is computed.
// will be the sum of the numbers in the array.
int sum = 0;
int idx = -1;
for (int i = 0; i < arr.length; i++)
{
if (arr[i] == 0)
{
idx = i;
}
else
{
sum += arr[i];
}
}
// the total sum of numbers between 1 and arr.length.
int total = (arr.length + 1) * arr.length / 2;
System.out.println("missing number is: " + (total - sum) + " at index " + idx);
We can use XOR operation which is safer than summation because in programming languages if the given input is large it may overflow and may give wrong answer.
Before going to the solution, know that A xor A = 0. So if we XOR two identical numbers the value is 0.
Now, XORing [1..n] with the elements present in the array cancels the identical numbers. So at the end we will get the missing number.
// Assuming that the array contains 99 distinct integers between 1..99
// and empty slot value is zero
int XOR = 0;
for(int i=0; i<100; i++) {
if (ARRAY[i] != 0) // remove this condition keeping the body if no zero slot
XOR ^= ARRAY[i];
XOR ^= (i + 1);
}
return XOR;
//return XOR ^ ARRAY.length + 1; if your array doesn't have empty zero slot.
Let the given array be A with length N. Lets assume in the given array, the single empty slot is filled with 0.
We can find the solution for this problem using many methods including algorithm used in Counting sort. But, in terms of efficient time and space usage, we have two algorithms. One uses mainly summation, subtraction and multiplication. Another uses XOR. Mathematically both methods work fine. But programatically, we need to assess all the algorithms with main measures like
Limitations(like input values are large(A[1...N]) and/or number of
input values is large(N))
Number of condition checks involved
Number and type of mathematical operations involved
etc. This is because of the limitations in time and/or hardware(Hardware resource limitation) and/or software(Operating System limitation, Programming language limitation, etc), etc. Lets list and assess the pros and cons of each one of them.
Algorithm 1 :
In algorithm 1, we have 3 implementations.
Calculate the total sum of all the numbers(this includes the unknown missing number) by using the mathematical formula(1+2+3+...+N=(N(N+1))/2). Here, N=100. Calculate the total sum of all the given numbers. Subtract the second result from the first result will give the missing number.
Missing Number = (N(N+1))/2) - (A[1]+A[2]+...+A[100])
Calculate the total sum of all the numbers(this includes the unknown missing number) by using the mathematical formula(1+2+3+...+N=(N(N+1))/2). Here, N=100. From that result, subtract each given number gives the missing number.
Missing Number = (N(N+1))/2)-A[1]-A[2]-...-A[100]
(Note:Even though the second implementation's formula is derived from first, from the mathematical point of view both are same. But from programming point of view both are different because the first formula is more prone to bit overflow than the second one(if the given numbers are large enough). Even though addition is faster than subtraction, the second implementation reduces the chance of bit overflow caused by addition of large values(Its not completely eliminated, because there is still very small chance since (N+1) is there in the formula). But both are equally prone to bit overflow by multiplication. The limitation is both implementations give correct result only if N(N+1)<=MAXIMUM_NUMBER_VALUE. For the first implementation, the additional limitation is it give correct result only if Sum of all given numbers<=MAXIMUM_NUMBER_VALUE.)
Calculate the total sum of all the numbers(this includes the unknown missing number) and subtract each given number in the same loop in parallel. This eliminates the risk of bit overflow by multiplication but prone to bit overflow by addition and subtraction.
//ALGORITHM
missingNumber = 0;
foreach(index from 1 to N)
{
missingNumber = missingNumber + index;
//Since, the empty slot is filled with 0,
//this extra condition which is executed for N times is not required.
//But for the sake of understanding of algorithm purpose lets put it.
if (inputArray[index] != 0)
missingNumber = missingNumber - inputArray[index];
}
In a programming language(like C, C++, Java, etc), if the number of bits representing a integer data type is limited, then all the above implementations are prone to bit overflow because of summation, subtraction and multiplication, resulting in wrong result in case of large input values(A[1...N]) and/or large number of input values(N).
Algorithm 2 :
We can use the property of XOR to get solution for this problem without worrying about the problem of bit overflow. And also XOR is both safer and faster than summation. We know the property of XOR that XOR of two same numbers is equal to 0(A XOR A = 0). If we calculate the XOR of all the numbers from 1 to N(this includes the unknown missing number) and then with that result, XOR all the given numbers, the common numbers get canceled out(since A XOR A=0) and in the end we get the missing number. If we don't have bit overflow problem, we can use both summation and XOR based algorithms to get the solution. But, the algorithm which uses XOR is both safer and faster than the algorithm which uses summation, subtraction and multiplication. And we can avoid the additional worries caused by summation, subtraction and multiplication.
In all the implementations of algorithm 1, we can use XOR instead of addition and subtraction.
Lets assume, XOR(1...N) = XOR of all numbers from 1 to N
Implementation 1 => Missing Number = XOR(1...N) XOR (A[1] XOR A[2] XOR...XOR A[100])
Implementation 2 => Missing Number = XOR(1...N) XOR A[1] XOR A[2] XOR...XOR A[100]
Implementation 3 =>
//ALGORITHM
missingNumber = 0;
foreach(index from 1 to N)
{
missingNumber = missingNumber XOR index;
//Since, the empty slot is filled with 0,
//this extra condition which is executed for N times is not required.
//But for the sake of understanding of algorithm purpose lets put it.
if (inputArray[index] != 0)
missingNumber = missingNumber XOR inputArray[index];
}
All three implementations of algorithm 2 will work fine(from programatical point of view also). One optimization is, similar to
1+2+....+N = (N(N+1))/2
We have,
1 XOR 2 XOR .... XOR N = {N if REMAINDER(N/4)=0, 1 if REMAINDER(N/4)=1, N+1 if REMAINDER(N/4)=2, 0 if REMAINDER(N/4)=3}
We can prove this by mathematical induction. So, instead of calculating the value of XOR(1...N) by XOR all the numbers from 1 to N, we can use this formula to reduce the number of XOR operations.
Also, calculating XOR(1...N) using above formula has two implementations. Implementation wise, calculating
// Thanks to https://a3nm.net/blog/xor.html for this implementation
xor = (n>>1)&1 ^ (((n&1)>0)?1:n)
is faster than calculating
xor = (n % 4 == 0) ? n : (n % 4 == 1) ? 1 : (n % 4 == 2) ? n + 1 : 0;
So, the optimized Java code is,
long n = 100;
long a[] = new long[n];
//XOR of all numbers from 1 to n
// n%4 == 0 ---> n
// n%4 == 1 ---> 1
// n%4 == 2 ---> n + 1
// n%4 == 3 ---> 0
//Slower way of implementing the formula
// long xor = (n % 4 == 0) ? n : (n % 4 == 1) ? 1 : (n % 4 == 2) ? n + 1 : 0;
//Faster way of implementing the formula
// long xor = (n>>1)&1 ^ (((n&1)>0)?1:n);
long xor = (n>>1)&1 ^ (((n&1)>0)?1:n);
for (long i = 0; i < n; i++)
{
xor = xor ^ a[i];
}
//Missing number
System.out.println(xor);
This was an Amazon interview question and was originally answered here: We have numbers from 1 to 52 that are put into a 51 number array, what's the best way to find out which number is missing?
It was answered, as below:
1) Calculate the sum of all numbers stored in the array of size 51.
2) Subtract the sum from (52 * 53)/2 ---- Formula : n * (n + 1) / 2.
It was also blogged here: Software Job - Interview Question
Here is a simple program to find the missing numbers in an integer array
ArrayList<Integer> arr = new ArrayList<Integer>();
int a[] = { 1,3,4,5,6,7,10 };
int j = a[0];
for (int i=0;i<a.length;i++)
{
if (j==a[i])
{
j++;
continue;
}
else
{
arr.add(j);
i--;
j++;
}
}
System.out.println("missing numbers are ");
for(int r : arr)
{
System.out.println(" " + r);
}
Recently I had a similar (not exactly the same) question in a job interview and also I heard from a friend that was asked the exactly same question in an interview.
So here is an answer to the OP question and a few more variations that can be potentially asked.
The answers example are given in Java because, it's stated that:
A Java solution is preferable.
Variation 1:
Array of numbers from 1 to 100 (both inclusive) ... The numbers are randomly added to the array, but there is one random empty slot in the array
public static int findMissing1(int [] arr){
int sum = 0;
for(int n : arr){
sum += n;
}
return (100*(100+1)/2) - sum;
}
Explanation:
This solution (as many other solutions posted here) is based on the formula of Triangular number, which gives us the sum of all natural numbers from 1 to n (in this case n is 100). Now that we know the sum that should be from 1 to 100 - we just need to subtract the actual sum of existing numbers in given array.
Variation 2:
Array of numbers from 1 to n (meaning that the max number is unknown)
public static int findMissing2(int [] arr){
int sum = 0, max = 0;
for(int n : arr){
sum += n;
if(n > max) max = n;
}
return (max*(max+1)/2) - sum;
}
Explanation:
In this solution, since the max number isn't given - we need to find it. After finding the max number - the logic is the same.
Variation 3:
Array of numbers from 1 to n (max number is unknown), there is two random empty slots in the array
public static int [] findMissing3(int [] arr){
int sum = 0, max = 0, misSum;
int [] misNums = {};//empty by default
for(int n : arr){
sum += n;
if(n > max) max = n;
}
misSum = (max*(max+1)/2) - sum;//Sum of two missing numbers
for(int n = Math.min(misSum, max-1); n > 1; n--){
if(!contains(n, arr)){
misNums = new int[]{n, misSum-n};
break;
}
}
return misNums;
}
private static boolean contains(int num, int [] arr){
for(int n : arr){
if(n == num)return true;
}
return false;
}
Explanation:
In this solution, the max number isn't given (as in the previous), but it can also be missing of two numbers and not one. So at first we find the sum of missing numbers - with the same logic as before. Second finding the smaller number between missing sum and the last (possibly) missing number - to reduce unnecessary search. Third since Javas Array (not a Collection) doesn't have methods as indexOf or contains, I added a small reusable method for that logic. Fourth when first missing number is found, the second is the subtract from missing sum.
If only one number is missing, then the second number in array will be zero.
Variation 4:
Array of numbers from 1 to n (max number is unknown), with X missing (amount of missing numbers are unknown)
public static ArrayList<Integer> findMissing4(ArrayList<Integer> arr){
int max = 0;
ArrayList<Integer> misNums = new ArrayList();
int [] neededNums;
for(int n : arr){
if(n > max) max = n;
}
neededNums = new int[max];//zero for any needed num
for(int n : arr){//iterate again
neededNums[n == max ? 0 : n]++;//add one - used as index in second array (convert max to zero)
}
for(int i=neededNums.length-1; i>0; i--){
if(neededNums[i] < 1)misNums.add(i);//if value is zero, than index is a missing number
}
return misNums;
}
Explanation:
In this solution, as in the previous, the max number is unknown and there can be missing more than one number, but in this variation, we don't know how many numbers are potentially missing (if any). The beginning of the logic is the same - find the max number. Then I initialise another array with zeros, in this array index indicates the potentially missing number and zero indicates that the number is missing. So every existing number from original array is used as an index and its value is incremented by one (max converted to zero).
Note
If you want examples in other languages or another interesting variations of this question, you are welcome to check my Github repository for Interview questions & answers.
(sum of 1 to n) - (sum of all values in the array) = missing number
int sum = 0;
int idx = -1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 0) idx = i; else sum += arr[i];
}
System.out.println("missing number is: " + (5050 - sum) + " at index " + idx);
On a similar scenario, where the array is already sorted, it does not include duplicates and only one number is missing, it is possible to find this missing number in log(n) time, using binary search.
public static int getMissingInt(int[] intArray, int left, int right) {
if (right == left + 1) return intArray[right] - 1;
int pivot = left + (right - left) / 2;
if (intArray[pivot] == intArray[left] + (intArray[right] - intArray[left]) / 2 - (right - left) % 2)
return getMissingInt(intArray, pivot, right);
else
return getMissingInt(intArray, left, pivot);
}
public static void main(String args[]) {
int[] array = new int[]{3, 4, 5, 6, 7, 8, 10};
int missingInt = getMissingInt(array, 0, array.length-1);
System.out.println(missingInt); //it prints 9
}
Well, use a bloom filter.
int findmissing(int arr[], int n)
{
long bloom=0;
int i;
for(i=0; i<;n; i++)bloom+=1>>arr[i];
for(i=1; i<=n, (bloom<<i & 1); i++);
return i;
}
This is c# but it should be pretty close to what you need:
int sumNumbers = 0;
int emptySlotIndex = -1;
for (int i = 0; i < arr.length; i++)
{
if (arr[i] == 0)
emptySlotIndex = i;
sumNumbers += arr[i];
}
int missingNumber = 5050 - sumNumbers;
The solution that doesn't involve repetitive additions or maybe the n(n+1)/2 formula doesn't get to you at an interview time for instance.
You have to use an array of 4 ints (32 bits) or 2 ints (64 bits). Initialize the last int with (-1 & ~(1 << 31)) >> 3. (the bits that are above 100 are set to 1) Or you may set the bits above 100 using a for loop.
Go through the array of numbers and set 1 for the bit position corresponding to the number (e.g. 71 would be set on the 3rd int on the 7th bit from left to right)
Go through the array of 4 ints (32 bit version) or 2 ints(64 bit version)
public int MissingNumber(int a[])
{
int bits = sizeof(int) * 8;
int i = 0;
int no = 0;
while(a[i] == -1)//this means a[i]'s bits are all set to 1, the numbers is not inside this 32 numbers section
{
no += bits;
i++;
}
return no + bits - Math.Log(~a[i], 2);//apply NOT (~) operator to a[i] to invert all bits, and get a number with only one bit set (2 at the power of something)
}
Example: (32 bit version) lets say that the missing number is 58. That means that the 26th bit (left to right) of the second integer is set to 0.
The first int is -1 (all bits are set) so, we go ahead for the second one and add to "no" the number 32. The second int is different from -1 (a bit is not set) so, by applying the NOT (~) operator to the number we get 64. The possible numbers are 2 at the power x and we may compute x by using log on base 2; in this case we get log2(64) = 6 => 32 + 32 - 6 = 58.
Hope this helps.
I think the easiest and possibly the most efficient solution would be to loop over all entries and use a bitset to remember which numbers are set, and then test for 0 bit. The entry with the 0 bit is the missing number.
This is not a search problem. The employer is wondering if you have a grasp of a checksum. You might need a binary or for loop or whatever if you were looking for multiple unique integers, but the question stipulates "one random empty slot." In this case we can use the stream sum. The condition: "The numbers are randomly added to the array" is meaningless without more detail. The question does not assume the array must start with the integer 1 and so tolerate with the offset start integer.
int[] test = {2,3,4,5,6,7,8,9,10, 12,13,14 };
/*get the missing integer*/
int max = test[test.length - 1];
int min = test[0];
int sum = Arrays.stream(test).sum();
int actual = (((max*(max+1))/2)-min+1);
//Find:
//the missing value
System.out.println(actual - sum);
//the slot
System.out.println(actual - sum - min);
Success time: 0.18 memory: 320576 signal:0
I found this beautiful solution here:
http://javaconceptoftheday.com/java-puzzle-interview-program-find-missing-number-in-an-array/
public class MissingNumberInArray
{
//Method to calculate sum of 'n' numbers
static int sumOfNnumbers(int n)
{
int sum = (n * (n+1))/ 2;
return sum;
}
//Method to calculate sum of all elements of array
static int sumOfElements(int[] array)
{
int sum = 0;
for (int i = 0; i < array.length; i++)
{
sum = sum + array[i];
}
return sum;
}
public static void main(String[] args)
{
int n = 8;
int[] a = {1, 4, 5, 3, 7, 8, 6};
//Step 1
int sumOfNnumbers = sumOfNnumbers(n);
//Step 2
int sumOfElements = sumOfElements(a);
//Step 3
int missingNumber = sumOfNnumbers - sumOfElements;
System.out.println("Missing Number is = "+missingNumber);
}
}
function solution($A) {
// code in PHP5.5
$n=count($A);
for($i=1;$i<=$n;$i++) {
if(!in_array($i,$A)) {
return (int)$i;
}
}
}
Finding the missing number from a series of numbers. IMP points to remember.
the array should be sorted..
the Function do not work on multiple missings.
the sequence must be an AP.
public int execute2(int[] array) {
int diff = Math.min(array[1]-array[0], array[2]-array[1]);
int min = 0, max = arr.length-1;
boolean missingNum = true;
while(min<max) {
int mid = (min + max) >>> 1;
int leftDiff = array[mid] - array[min];
if(leftDiff > diff * (mid - min)) {
if(mid-min == 1)
return (array[mid] + array[min])/2;
max = mid;
missingNum = false;
continue;
}
int rightDiff = array[max] - array[mid];
if(rightDiff > diff * (max - mid)) {
if(max-mid == 1)
return (array[max] + array[mid])/2;
min = mid;
missingNum = false;
continue;
}
if(missingNum)
break;
}
return -1;
}
One thing you could do is sort the numbers using quick sort for instance. Then use a for loop to iterate through the sorted array from 1 to 100. In each iteration, you compare the number in the array with your for loop increment, if you find that the index increment is not the same as the array value, you have found your missing number as well as the missing index.
Below is the solution for finding all the missing numbers from a given array:
public class FindMissingNumbers {
/**
* The function prints all the missing numbers from "n" consecutive numbers.
* The number of missing numbers is not given and all the numbers in the
* given array are assumed to be unique.
*
* A similar approach can be used to find all no-unique/ unique numbers from
* the given array
*
* #param n
* total count of numbers in the sequence
* #param numbers
* is an unsorted array of all the numbers from 1 - n with some
* numbers missing.
*
*/
public static void findMissingNumbers(int n, int[] numbers) {
if (n < 1) {
return;
}
byte[] bytes = new byte[n / 8];
int countOfMissingNumbers = n - numbers.length;
if (countOfMissingNumbers == 0) {
return;
}
for (int currentNumber : numbers) {
int byteIndex = (currentNumber - 1) / 8;
int bit = (currentNumber - byteIndex * 8) - 1;
// Update the "bit" in bytes[byteIndex]
int mask = 1 << bit;
bytes[byteIndex] |= mask;
}
for (int index = 0; index < bytes.length - 2; index++) {
if (bytes[index] != -128) {
for (int i = 0; i < 8; i++) {
if ((bytes[index] >> i & 1) == 0) {
System.out.println("Missing number: " + ((index * 8) + i + 1));
}
}
}
}
// Last byte
int loopTill = n % 8 == 0 ? 8 : n % 8;
for (int index = 0; index < loopTill; index++) {
if ((bytes[bytes.length - 1] >> index & 1) == 0) {
System.out.println("Missing number: " + (((bytes.length - 1) * 8) + index + 1));
}
}
}
public static void main(String[] args) {
List<Integer> arrayList = new ArrayList<Integer>();
int n = 128;
int m = 5;
for (int i = 1; i <= n; i++) {
arrayList.add(i);
}
Collections.shuffle(arrayList);
for (int i = 1; i <= 5; i++) {
System.out.println("Removing:" + arrayList.remove(i));
}
int[] array = new int[n - m];
for (int i = 0; i < (n - m); i++) {
array[i] = arrayList.get(i);
}
System.out.println("Array is: " + Arrays.toString(array));
findMissingNumbers(n, array);
}
}
Lets say you have n as 8, and our numbers range from 0-8 for this example
we can represent the binary representation of all 9 numbers as follows
0000
0001
0010
0011
0100
0101
0110
0111
1000
in the above sequence there is no missing numbers and in each column the number of zeros and ones match, however as soon as you remove 1 value lets say 3 we get a in balance in the number of 0's and 1's across the columns. If the number of 0's in a column is <= the number of 1's our missing number will have a 0 at this bit position, otherwise if the number of 0's > the number of 1's at this bit position then this bit position will be a 1. We test the bits left to right and at each iteration we throw away half of the array for the testing of the next bit, either the odd array values or the even array values are thrown away at each iteration depending on which bit we are deficient on.
The below solution is in C++
int getMissingNumber(vector<int>* input, int bitPos, const int startRange)
{
vector<int> zeros;
vector<int> ones;
int missingNumber=0;
//base case, assume empty array indicating start value of range is missing
if(input->size() == 0)
return startRange;
//if the bit position being tested is 0 add to the zero's vector
//otherwise to the ones vector
for(unsigned int i = 0; i<input->size(); i++)
{
int value = input->at(i);
if(getBit(value, bitPos) == 0)
zeros.push_back(value);
else
ones.push_back(value);
}
//throw away either the odd or even numbers and test
//the next bit position, build the missing number
//from right to left
if(zeros.size() <= ones.size())
{
//missing number is even
missingNumber = getMissingNumber(&zeros, bitPos+1, startRange);
missingNumber = (missingNumber << 1) | 0;
}
else
{
//missing number is odd
missingNumber = getMissingNumber(&ones, bitPos+1, startRange);
missingNumber = (missingNumber << 1) | 1;
}
return missingNumber;
}
At each iteration we reduce our input space by 2, i.e N, N/2,N/4 ... = O(log N), with space O(N)
//Test cases
[1] when missing number is range start
[2] when missing number is range end
[3] when missing number is odd
[4] when missing number is even
Solution With PHP $n = 100;
$n*($n+1)/2 - array_sum($array) = $missing_number
and array_search($missing_number) will give the index of missing number
Here program take time complexity is O(logn) and space complexity O(logn)
public class helper1 {
public static void main(String[] args) {
int a[] = {1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12};
int k = missing(a, 0, a.length);
System.out.println(k);
}
public static int missing(int[] a, int f, int l) {
int mid = (l + f) / 2;
//if first index reached last then no element found
if (a.length - 1 == f) {
System.out.println("missing not find ");
return 0;
}
//if mid with first found
if (mid == f) {
System.out.println(a[mid] + 1);
return a[mid] + 1;
}
if ((mid + 1) == a[mid])
return missing(a, mid, l);
else
return missing(a, f, mid);
}
}
public class MissingNumber {
public static void main(String[] args) {
int array[] = {1,2,3,4,6};
int x1 = getMissingNumber(array,6);
System.out.println("The Missing number is: "+x1);
}
private static int getMissingNumber(int[] array, int i) {
int acctualnumber =0;
int expectednumber = (i*(i+1)/2);
for (int j : array) {
acctualnumber = acctualnumber+j;
}
System.out.println(acctualnumber);
System.out.println(expectednumber);
return expectednumber-acctualnumber;
}
}
Use sum formula,
class Main {
// Function to ind missing number
static int getMissingNo (int a[], int n) {
int i, total;
total = (n+1)*(n+2)/2;
for ( i = 0; i< n; i++)
total -= a[i];
return total;
}
/* program to test above function */
public static void main(String args[]) {
int a[] = {1,2,4,5,6};
int miss = getMissingNo(a,5);
System.out.println(miss);
}
}
Reference http://www.geeksforgeeks.org/find-the-missing-number/
simple solution with test data :
class A{
public static void main(String[] args){
int[] array = new int[200];
for(int i=0;i<100;i++){
if(i != 51){
array[i] = i;
}
}
for(int i=100;i<200;i++){
array[i] = i;
}
int temp = 0;
for(int i=0;i<200;i++){
temp ^= array[i];
}
System.out.println(temp);
}
}
//Array is shorted and if writing in C/C++ think of XOR implementations in java as follows.
int num=-1;
for (int i=1; i<=100; i++){
num =2*i;
if(arr[num]==0){
System.out.println("index: "+i+" Array position: "+ num);
break;
}
else if(arr[num-1]==0){
System.out.println("index: "+i+ " Array position: "+ (num-1));
break;
}
}// use Rabbit and tortoise race, move the dangling index faster,
//learnt from Alogithimica, Ameerpet, hyderbad**
If the array is randomly filled, then at the best you can do a linear search in O(n) complexity. However, we could have improved the complexity to O(log n) by divide and conquer approach similar to quick sort as pointed by giri given that the numbers were in ascending/descending order.
This Program finds missing numbers
<?php
$arr_num=array("1","2","3","5","6");
$n=count($arr_num);
for($i=1;$i<=$n;$i++)
{
if(!in_array($i,$arr_num))
{
array_push($arr_num,$i);print_r($arr_num);exit;
}
}
?>
Now I'm now too sharp with the Big O notations but couldn't you also do something like (in Java)
for (int i = 0; i < numbers.length; i++) {
if(numbers[i] != i+1){
System.out.println(i+1);
}
}
where numbers is the array with your numbers from 1-100.
From my reading of the question it did not say when to write out the missing number.
Alternatively if you COULD throw the value of i+1 into another array and print that out after the iteration.
Of course it might not abide by the time and space rules. As I said. I have to strongly brush up on Big O.
========Simplest Solution for sorted Array===========
public int getMissingNumber(int[] sortedArray)
{
int missingNumber = 0;
int missingNumberIndex=0;
for (int i = 0; i < sortedArray.length; i++)
{
if (sortedArray[i] == 0)
{
missingNumber = (sortedArray[i + 1]) - 1;
missingNumberIndex=i;
System.out.println("missingNumberIndex: "+missingNumberIndex);
break;
}
}
return missingNumber;
}
Another homework question. A sequential search is the best that you can do. As for a Java solution, consider that an exercise for the reader. :P

Codility Ladder javascript - not understanding a detail that jumps the answer from 37 to 100%

I'm trying to solve all the lessons on codility but I failed to do so on the following problem: Ladder by codility
I've searched all over the internet and I'm not finding a answer that satisfies me because no one answers why the max variable impacts so much the result.
So, before posting the code, I'll explain the thinking.
By looking at it I didn't need much time to understand that the total number of combinations it's a Fibonacci number, and removing the 0 from the Fibonacci array, I'd find the answer really fast.
Now, afterwards, they told that we should return the number of combinations modulus 2^B[i].
So far so good, and I decided to submit it without the var max, then I got a score of 37%.. I searched all over the internet and the 100% result was similar to mine but they added that max = Math.pow(2,30).
Can anyone explain to me how and why that max influences so much the score?
My Code:
// Powers 2 to num
function pow(num){
return Math.pow(2,num);
}
// Returns a array with all fibonacci numbers except for 0
function fibArray(num){
// const max = pow(30); -> Adding this max to the fibonaccy array makes the answer be 100%
const arr = [0,1,1];
let current = 2;
while(current<=num){
current++;
// next = arr[current-1]+arr[current-2] % max;
next = arr[current-1]+arr[current-2]; // Without this max it's 30 %
arr.push(next);
}
arr.shift(); // remove 0
return arr;
}
function solution(A, B) {
let f = fibArray(A.length + 1);
let res = new Array(A.length);
for (let i = 0; i < A.length; ++i) {
res[i] = f[A[i]] % (pow(B[i]));
}
return res;
}
console.log(solution([4,4,5,5,1],[3,2,4,3,1])); //5,1,8,0,1
// Note that the console.log wont differ in this solution having max set or not.
// Running the exercise on Codility shows the full log with all details
// of where it passed and where it failed.
The limits for input parameters are:
Assume that:
L is an integer within the range [1..50,000];
each element of array A is an integer within the range [1..L];
each element of array B is an integer within the range [1..30].
So the array f in fibArray can be 50,001 long.
Fibonacci numbers grow exponentially; according to this page, the 50,000th Fib number has over 10,000 digits.
Javascript does not have built-in support for arbitrary precision integers, and even doubles only offer ~14 s.f. of precision. So with your modified code, you will get "garbage" values for any significant value of L. This is why you only got 30%.
But why is max necessary? Modulo math tells us that:
(a + b) % c = ([a % c] + [b % c]) % c
So by applying % max to the iterative calculation step arr[current-1] + arr[current-2], every element in fibArray becomes its corresponding Fib number mod max, without any variable exceeding the value of max (or built-in integer types) at any time:
fibArray[2] = (fibArray[1] + fibArray[0]) % max = (F1 + F0) % max = F2 % max
fibArray[3] = (F2 % max + F1) % max = (F2 + F1) % max = F3 % max
fibArray[4] = (F3 % max + F2 % max) = (F3 + F2) % max = F4 % max
and so on ...
(Fn is the n-th Fib number)
Note that as B[i] will never exceed 30, pow(2, B[i]) <= max; therefore, since max is always divisible by pow(2, B[i]), applying % max does not affect the final result.
Here is a python 100% answer that I hope offers an explanation :-)
In a nutshell; modulus % is similar to 'bitwise and' & for certain numbers.
eg any number % 10 is equivalent to the right most digit.
284%10 = 4
1994%10 = 4
FACTS OF LIFE:
for multiples of 2 -> X % Y is equivalent to X & ( Y - 1 )
precomputing (2**i)-1 for i in range(1, 31) is faster than computing everything in B when super large arrays are given as args for this particular lesson.
Thus fib(A[i]) & pb[B[i]] will be faster to compute than an X % Y style thingy.
https://app.codility.com/demo/results/trainingEXWWGY-UUR/
And for completeness the code is here.
https://github.com/niall-oc/things/blob/master/codility/ladder.py
Here is my explanation and solution in C++:
Compute the first L fibonacci numbers. Each calculation needs modulo 2^30 because the 50000th fibonacci number cannot be stored even in long double, it is so big. Since INT_MAX is 2^31, the summary of previously modulo'd numbers by 2^30 cannot exceed that. Therefore, we do not need to have bigger store and/or casting.
Go through the arrays executing the lookup and modulos. We can be sure this gives the correct result since modulo 2^30 does not take any information away. E.g. modulo 100 does not take away any information for subsequent modulo 10.
vector<int> solution(vector<int> &A, vector<int> &B)
{
const int L = A.size();
vector<int> fibonacci_numbers(L, 1);
fibonacci_numbers[1] = 2;
static const int pow_2_30 = pow(2, 30);
for (int i = 2; i < L; ++i) {
fibonacci_numbers[i] = (fibonacci_numbers[i - 1] + fibonacci_numbers[i - 2]) % pow_2_30;
}
vector<int> consecutive_answers(L, 0);
for (int i = 0; i < L; ++i) {
consecutive_answers[i] = fibonacci_numbers[A[i] - 1] % static_cast<int>(pow(2, B[i]));
}
return consecutive_answers;
}

factorial with trailing zeros, but without calculating factorial

I'm calculating the trailing zeros of a factorial. My solution is to calculate the factorial then determine how many trailing zeros it has. As you can imagine this isn't very scalable. How can I solve this without calculating the factorial?
I've found these pages on SO:
Trailing zeroes in a Factorial
Calculating the factorial without trailing zeros efficiently?
However, neither are in Javascript. If you downvote this question please let me know why. Thank-you for your time and feedback.
My solution:
function zeros(n) {
var result = [];
var count = 0;
for (var i = 1; i <= n; i++) {
result.push(i);
} //generating range for factorial function
var factorial = result.reduce(function(acc, el) {
return acc * el;
}, 1); //calculating factorial
factorial = factorial.toString().split('');
for (var j = factorial.length - 1; j > 0; j--) {
if (parseInt(factorial[j]) === 0) {
count += 1;
} else {
break;
}
} //counting trailing zeros
return count;
}
Knowing the number of trailing zeroes in a number comes down to knowing how many times it can be divided by 10, i.e. by both 5 and 2.
With factorial numbers that is quite easy to count:
f! = 1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16. ... .f
^ ^ ^
The places where a factor 5 gets into the final product are marked. It is clear that factors of 2 occur more often, so the count of factors of 5 are determining the number of trailing zeroes.
Now, when the factor 25 occurs, it should be counted for 2; likewise 125 should count for 3 factors of 5, etc.
You can cover for that with a loop like this:
function zeros(n) {
var result = 0;
while (n = Math.floor(n / 5)) result += n;
return result;
}
public static void main(String[] args) {
int n=23;
String fact= factorial(BigInteger.valueOf(23)).toString();
System.out.format("Factorial value of %d is %s\n", n,fact);
int len=fact.length();
//Check end with zeros
if(fact.matches(".*0*$")){
String[] su=fact.split("0*$");
//Split the pattern from whole string
System.out.println(Arrays.toString(fact.split("0*$")));
//Subtract from the total length
System.out.println("Count of trailing zeros "+(len-su[0].length()));
}
}
public static BigInteger factorial(BigInteger n) {
if (n.equals(BigInteger.ONE) || n.equals(BigInteger.ZERO)) {
return BigInteger.ONE;
}
return n.multiply(factorial(n.subtract(BigInteger.ONE)));
}
You don't really need to calculate the factorial product to count the trailing zeroes.
Here a sample to count the number of trailing zeroes in n!
temp = 5;
zeroes = 0;
//counting the sum of multiples of 5,5^2,5^3....present in n!
while(n>=temp){
fives = n/temp;
zeroes = zeroes + fives;
temp = temp*5;
}
printf("%d",zeroes);
Note that each multiple of 5 in the factorial product will contribute 1 to the number of trailing zeros. On top of this, each multiple of 25 will contribute an additional 1 to the number of trailing zeros. Then, each multiple of 125 will contribute another 1 to the number of trailing zeros, and so on.
Here's a great link to understand the concept behind this: https://brilliant.org/wiki/trailing-number-of-zeros/
I came across this algorithm somewhere on here can not remember now, but it looks like this,
def zeros(n)
return 0 if n.zero?
k = (Math.log(n)/Math.log(5)).to_i
m = 5**k
n*(m-1)/(4*m)
end
This very effiecient as it does not need a loop.
You can further optimize it to look like this.
def zeros(n)
return 0 if n.zero?
n*(n-1)/(4*n)
end
A javascript translation of this will be.
function zeros(n) {
if (n == 0) return 0;
return n * (n-1)/(4*n);
}
Note that this algorithm is correct till about n >= 1000000000, in which case the return value has an error margin of +1, and this error margin increases by +1 every n * 10000.

javaScript - Find the sum of all divisors of a given integer

i'm doing some coding exercises and i'm not being able to solve this one.
Find the sum of all divisors of a given integer.
For n = 12, the input should be
sumOfDivisors(n) = 28.
example: 1 + 2 + 3 + 4 + 6 + 12 = 28.
Constraints:
1 ≤ n ≤ 15.
how can i solve this exercise? i'm not being able to.
function(n){
var arr = [],
finalSum;
if(n <= 1 || n => 16){
return false ;
}
for(var i = 0; i < n; i++){
var tmp= n/2;
arr.push(tmp)
// i need to keep on dividing n but i can't get the way of how to
}
return finalSum;
}
This is another way to do it:
var divisors = n=>[...Array(n+1).keys()].slice(1)
.reduce((s, a)=>s+(!(n % a) && a), 0);
console.log(divisors(12));
JSFiddle: https://jsfiddle.net/32n5jdnb/141/
Explaining:
n=> this is an arrow function, the equivalent to function(n) {. You don't need the () if there's only one parameter.
Array(n+1) creates an empty array of n+1 elements
.keys() gets the keys of the empty array (the indexes i.e. 0, 1, 2) so this is a way to create a numeric sequence
[...Array(n+1)].keys()] uses the spread (...) operator to transform the iterator in another array so creating an array with the numeric sequence
.slice(1) removes the first element thus creating a sequence starting with 1. Remember the n+1 ?
.reduce() is a method that iterates though each element and calculates a value in order to reduce the array to one value. It receives as parameter a callback function to calculate the value and the initial value of the calculation
(s, a)=> is the callback function for reduce. It's an arrow function equivalent to function(s, a) {
s+(!(n % a) && a) is the calculation of the value.
s+ s (for sum) or the last value calculated +
!(n % a) this returns true only for the elements that have a 0 as modular value.
(!(n % a) && a) is a js 'trick'. The case is that boolean expressions in javascript don't return true or false. They return a 'truthy' or 'falsy' value which is then converted to boolean. So the actual returned value is the right value for && (considering both have to be truthy) and the first thuthy value found for || (considering only one need to be truthy). So this basically means: if a is a modular value (i.e. != 0) return a to add to the sum, else return 0.
, 0 is the initial value for the reduce calculation.
Reduce documentation: https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
Edit
Answering to Tristan Forward:
var divisorsList = [];
var divisors = (n)=>[...Array(n+1).keys()].slice(1)
.reduce((s, a)=>{
var divisor = !(n % a) && a;
if (divisor) divisorsList.push(divisor);
return s+divisor;
}, 0);
console.log('Result:', divisors(12));
console.log('Divisors:', divisorsList);
You have to check if specified number is or not a divisor of given integer. You can use modulo % - if there's no rest, specified number is the divisor of the given integer - add it to the sum.
function sumDivisors(num){
var sum = 0;
for (var i = 1; i <= num; i++){
if (!(num % i)) {
sum += i;
}
}
console.log(sum);
}
sumDivisors(6);
sumDivisors(10);
Here is a solution with better algorithm performance (O(sqrt(largest prime factor of n)))
divisors = n => {
sum = 1
for (i = 2; n > 1; i++) {
i * i > n ? i = n : 0
b = 0
while (n % i < 1) {
c = sum * i
sum += c - b
b = c
n /= i
}
}
return sum
}
since n / i is also a devisor this can be done more efficiently.
function sumDivisors(num) {
let sum = 1;
for (let i = 2; i < num / i; i++) {
if (num % i === 0) {
sum += i + num / i;
}
}
const sqrt = Math.sqrt(num);
return num + (num % sqrt === 0 ? sum + sqrt : sum);
}
function countDivisors(n){
let counter = 1;
for(let i=1; i <= n/2; i++){
n % i === 0 ? counter++ : null;
}
return counter
}
in this case, we consider our counter as starting with 1 since by default all numbers are divisible by 1. Then we half the number since numbers that can be able to divide n are less or equal to half its value

How to create a function that converts a Number to a Bijective Hexavigesimal?

Maybe i am just not that good enough in math, but I am having a problem in converting a number into pure alphabetical Bijective Hexavigesimal just like how Microsoft Excel/OpenOffice Calc do it.
Here is a version of my code but did not give me the output i needed:
var toHexvg = function(a){
var x='';
var let="_abcdefghijklmnopqrstuvwxyz";
var len=let.length;
var b=a;
var cnt=0;
var y = Array();
do{
a=(a-(a%len))/len;
cnt++;
}while(a!=0)
a=b;
var vnt=0;
do{
b+=Math.pow((len),vnt)*Math.floor(a/Math.pow((len),vnt+1));
vnt++;
}while(vnt!=cnt)
var c=b;
do{
y.unshift( c%len );
c=(c-(c%len))/len;
}while(c!=0)
for(var i in y)x+=let[y[i]];
return x;
}
The best output of my efforts can get is: a b c d ... y z ba bb bc - though not the actual code above. The intended output is suppose to be a b c ... y z aa ab ac ... zz aaa aab aac ... zzzzz aaaaaa aaaaab, you get the picture.
Basically, my problem is more on doing the ''math'' rather than the function. Ultimately my question is: How to do the Math in Hexavigesimal conversion, till a [supposed] infinity, just like Microsoft Excel.
And if possible, a source code, thank you in advance.
Okay, here's my attempt, assuming you want the sequence to be start with "a" (representing 0) and going:
a, b, c, ..., y, z, aa, ab, ac, ..., zy, zz, aaa, aab, ...
This works and hopefully makes some sense. The funky line is there because it mathematically makes more sense for 0 to be represented by the empty string and then "a" would be 1, etc.
alpha = "abcdefghijklmnopqrstuvwxyz";
function hex(a) {
// First figure out how many digits there are.
a += 1; // This line is funky
c = 0;
var x = 1;
while (a >= x) {
c++;
a -= x;
x *= 26;
}
// Now you can do normal base conversion.
var s = "";
for (var i = 0; i < c; i++) {
s = alpha.charAt(a % 26) + s;
a = Math.floor(a/26);
}
return s;
}
However, if you're planning to simply print them out in order, there are far more efficient methods. For example, using recursion and/or prefixes and stuff.
Although #user826788 has already posted a working code (which is even a third quicker), I'll post my own work, that I did before finding the posts here (as i didnt know the word "hexavigesimal"). However it also includes the function for the other way round. Note that I use a = 1 as I use it to convert the starting list element from
aa) first
ab) second
to
<ol type="a" start="27">
<li>first</li>
<li>second</li>
</ol>
:
function linum2int(input) {
input = input.replace(/[^A-Za-z]/, '');
output = 0;
for (i = 0; i < input.length; i++) {
output = output * 26 + parseInt(input.substr(i, 1), 26 + 10) - 9;
}
console.log('linum', output);
return output;
}
function int2linum(input) {
var zeros = 0;
var next = input;
var generation = 0;
while (next >= 27) {
next = (next - 1) / 26 - (next - 1) % 26 / 26;
zeros += next * Math.pow(27, generation);
generation++;
}
output = (input + zeros).toString(27).replace(/./g, function ($0) {
return '_abcdefghijklmnopqrstuvwxyz'.charAt(parseInt($0, 27));
});
return output;
}
linum2int("aa"); // 27
int2linum(27); // "aa"
You could accomplish this with recursion, like this:
const toBijective = n => (n > 26 ? toBijective(Math.floor((n - 1) / 26)) : "") + ((n % 26 || 26) + 9).toString(36);
// Parsing is not recursive
const parseBijective = str => str.split("").reverse().reduce((acc, x, i) => acc + ((parseInt(x, 36) - 9) * (26 ** i)), 0);
toBijective(1) // "a"
toBijective(27) // "aa"
toBijective(703) // "aaa"
toBijective(18279) // "aaaa"
toBijective(127341046141) // "overflow"
parseBijective("Overflow") // 127341046141
I don't understand how to work it out from a formula, but I fooled around with it for a while and came up with the following algorithm to literally count up to the requested column number:
var getAlpha = (function() {
var alphas = [null, "a"],
highest = [1];
return function(decNum) {
if (alphas[decNum])
return alphas[decNum];
var d,
next,
carry,
i = alphas.length;
for(; i <= decNum; i++) {
next = "";
carry = true;
for(d = 0; d < highest.length; d++){
if (carry) {
if (highest[d] === 26) {
highest[d] = 1;
} else {
highest[d]++;
carry = false;
}
}
next = String.fromCharCode(
highest[d] + 96)
+ next;
}
if (carry) {
highest.push(1);
next = "a" + next;
}
alphas[i] = next;
}
return alphas[decNum];
};
})();
alert(getAlpha(27)); // "aa"
alert(getAlpha(100000)); // "eqxd"
Demo: http://jsfiddle.net/6SE2f/1/
The highest array holds the current highest number with an array element per "digit" (element 0 is the least significant "digit").
When I started the above it seemed a good idea to cache each value once calculated, to save time if the same value was requested again, but in practice (with Chrome) it only took about 3 seconds to calculate the 1,000,000th value (bdwgn) and about 20 seconds to calculate the 10,000,000th value (uvxxk). With the caching removed it took about 14 seconds to the 10,000,000th value.
Just finished writing this code earlier tonight, and I found this question while on a quest to figure out what to name the damn thing. Here it is (in case anybody feels like using it):
/**
* Convert an integer to bijective hexavigesimal notation (alphabetic base-26).
*
* #param {Number} int - A positive integer above zero
* #return {String} The number's value expressed in uppercased bijective base-26
*/
function bijectiveBase26(int){
const sequence = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const length = sequence.length;
if(int <= 0) return int;
if(int <= length) return sequence[int - 1];
let index = (int % length) || length;
let result = [sequence[index - 1]];
while((int = Math.floor((int - 1) / length)) > 0){
index = (int % length) || length;
result.push(sequence[index - 1]);
}
return result.reverse().join("")
}
I had to solve this same problem today for work. My solution is written in Elixir and uses recursion, but I explain the thinking in plain English.
Here are some example transformations:
0 -> "A", 1 -> "B", 2 -> "C", 3 -> "D", ..
25 -> "Z", 26 -> "AA", 27 -> "AB", ...
At first glance it might seem like a normal 26-base counting system
but unfortunately it is not so simple.
The "problem" becomes clear when you realize:
A = 0
AA = 26
This is at odds with a normal counting system, where "0" does not behave
as "1" when it is in a decimal place other than then unit.
To understand the algorithm, consider a simpler but equivalent base-2 system:
A = 0
B = 1
AA = 2
AB = 3
BA = 4
BB = 5
AAA = 6
In a normal binary counting system we can determine the "value" of decimal places by
taking increasing powers of 2 (1, 2, 4, 8, 16) and the value of a binary number is
calculated by multiplying each digit by that digit place's value.
e.g. 10101 = 1 * (2 ^ 4) + 0 * (2 ^ 3) + 1 * (2 ^ 2) + 0 * (2 ^ 1) + 1 * (2 ^ 0) = 21
In our more complicated AB system, we can see by inspection that the decimal place values are:
1, 2, 6, 14, 30, 62
The pattern reveals itself to be (previous_unit_place_value + 1) * 2.
As such, to get the next lower unit place value, we divide by 2 and subtract 1.
This can be extended to a base-26 system. Simply divide by 26 and subtract 1.
Now a formula for transforming a normal base-10 number to special base-26 is apparent.
Say the input is x.
Create an accumulator list l.
If x is less than 26, set l = [x | l] and go to step 5. Otherwise, continue.
Divide x by 2. The floored result is d and the remainder is r.
Push the remainder as head on an accumulator list. i.e. l = [r | l]
Go to step 2 with with (d - 1) as input, e.g. x = d - 1
Convert """ all elements of l to their corresponding chars. 0 -> A, etc.
So, finally, here is my answer, written in Elixir:
defmodule BijectiveHexavigesimal do
def to_az_string(number, base \\ 26) do
number
|> to_list(base)
|> Enum.map(&to_char/1)
|> to_string()
end
def to_09_integer(string, base \\ 26) do
string
|> String.to_charlist()
|> Enum.reverse()
|> Enum.reduce({0, nil}, fn
char, {_total, nil} ->
{to_integer(char), 1}
char, {total, previous_place_value} ->
char_value = to_integer(char + 1)
place_value = previous_place_value * base
new_total = total + char_value * place_value
{new_total, place_value}
end)
|> elem(0)
end
def to_list(number, base, acc \\ []) do
if number < base do
[number | acc]
else
to_list(div(number, base) - 1, base, [rem(number, base) | acc])
end
end
defp to_char(x), do: x + 65
end
You use it simply as BijectiveHexavigesimal.to_az_string(420). It also accepts on optional "base" arg.
I know the OP asked about Javascript but I wanted to provide an Elixir solution for posterity.
I have published these functions in npm package here:
https://www.npmjs.com/package/#gkucmierz/utils
Converting bijective numeration to number both ways (also BigInt version is included).
https://github.com/gkucmierz/utils/blob/main/src/bijective-numeration.mjs

Categories