Related
function tribonacci(signature, n) {
var myArray = [];
var lenArray = 0;
var i = 0;
var outPut = 0;
var x = 0;
if (n > 0) {
while (i < 3) {
myArray.push(signature[i]);
i++;
}
lenArray = myArray.length - 1;
i = 0;
while (lenArray < n) {
while (x < 3) {
var v = x + i;
outPut += myArray[v];
x++;
}
i++;
lenArray = myArray.length - 1;
myArray.push(outPut);
}
return myArray;
} else {
return [];
};
}
console.log(tribonacci([1, 1, 1], 10));
First, I tried to push first 3 items into "myArray".
Second, in the "while" loop, while it's less than "n" (number of items needed to be in the array), add the last 3 items in "myArray" until "myArray" reaches the needed "n" amount.
e.g. tribonacci([1,1,1],10)
Return should be [1,1,1,3,5,9,17,31,57,105]
Adding the last 3 items continuously until it reaches 10 items in an array.
Instead I get as result:
[1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3]
I have no idea why it's stuck on 3s.
I tried "i++" below the 2nd "while" loop so that it can start adding the last 3 items every time "myArray" grows by one, but that doesn't seem to be the issue. Is the "outPut" being stuck on 3?
var v = x + i; uses x to calculate the correct index.
After adding those 3 numbers, x needs to be reset.
Also, outPut is reused in the next iteration, but it keeps adding values, so your output will get to high. This needs to be reset to 0 after the 3-loop.
Add outPut = x = 0 after pushing outPut into myArray
function tribonacci(signature, n) {
var myArray = [];
var lenArray = 0;
var i = 0;
var outPut = 0;
var x = 0;
if (n > 0) {
while (i < 3) {
myArray.push(signature[i]);
i++;
}
lenArray = myArray.length - 1;
i = 0;
while (lenArray < n) {
while (x < 3) {
var v = x + i;
outPut += myArray[v];
x++;
}
i++;
lenArray = myArray.length - 1;
myArray.push(outPut);
outPut = x = 0
}
return myArray;
} else {
return [];
};
}
console.log(tribonacci([1, 1, 1], 10));
[
1,
1,
1,
3,
5,
9,
17,
31,
57,
105,
193,
355
]
Some bonus-tips to improve the readabilty:
Use (...) spread operator to replace the first while:
var myArray = [ ...signature ];
Use myArray.length - 1 instead off defining a variable with the same value
Use myArray[x + i] instead off defining another varible
Return on n < 0 to you don't need to intent that much
Applying those will give:
function tribonacci(signature, n) {
var myArray = [ ...signature ];
var i = 0;
var x = 0;
var outPut = 0;
if (n < 0) {
return [];
}
while ((myArray.length - 1) < n) {
while (x < 3) {
outPut += myArray[x + i];
x++;
}
i++;
myArray.push(outPut);
outPut = x = 0;
}
return myArray;
}
Hey there are you doing this for homework on while loops? If so refer to #0stone0 's answer which solves it right!
If on the other hand you want to dive into JS a little more, I'd suggest you a more coincise solution with some cool Array function:
function tribonacci(signature, size) {
const output = signature;
while(output.length < size) {
output.push(output.slice(-3).sum());
}
return output;
}
console.log({ result: tribonacci([1, 1, 1], 10) });
Some version of JS don't include the Array.sum function which would be something like this:
Array.prototype.sum = function() {
return this.reduce((sum, curr) => sum + curr, 0);
}
I encountered this question:
Find longest decrease sequence in an array
So basically, if [3,1,4,3,2,1,2,3] is given, it will return [4,3,2,1] as the longest sequence within it. I was able to solve this question with O(n^2) time complexity but I feel like I can do O(n).
I know I am probably making a giant logic mistake but this is how I approach with 2 pointers method.
function findDecreaseSubArray(arr) {
let subList = [arr[0]];
// let maxLength= 0;
let left = 0;
for (let right = 1; right < arr.length; right++) {
// maxLength = (maxLength, windowEnd - windowStart + 1);
if (arr[left] > arr[right]) {
subList.push(arr[right]);
}else{
subList.shift();
left = right-1;
}
}
}
What I am trying to accomplish is moving left and right pointers if left element is larger than right, and if so, push both elements into sublist array.
My brain starts giving 404 error after this, so there are 2 subarrays that are decreasing, one of them is [3,1] and the other one is [4,3,2,1].
How could I track one subarray is larger than the other subarray? Or there is a better way to approach this solution?
Any hints, hands, code snippet would highly appreciated. (And sorry about my code snippet, I know it is shitty but I just wanted to display some of my thoughts on code)
You just have to iterate over the array once, but keep track of the start and length of the longest sequence as you progress through it:
var arr = [3,1,4,3,2,1,2,3];
function findDecreaseSubArray(arr) {
let startIndex = 0;
let length = 1;
let longestSequence = {
startIndex: 0,
length: 1
}
arr.forEach((element, index, arr) => {
if (index === 0) return;
if (element < arr[index -1]) {
length += 1;
} else {
length = 1;
startIndex = index;
}
if (length > longestSequence.length) {
longestSequence.length = length;
longestSequence.startIndex = startIndex;
}
})
return longestSequence;
}
console.log(findDecreaseSubArray(arr));
This approach supports VLAZ's comment and uses only the indices of the array.
function longestDecreasing(array) {
var longest,
start = 0,
i;
for (i = 0; i < array.length; i++) {
if (!i || array[i] < array[i - 1]) continue;
if (!longest || longest[1] - longest[0] < i - start) longest = [start, i];
start = i;
}
return array.slice(...longest && longest[1] - longest[0] > i - start
? longest
: [start, i]);
}
console.log(longestDecreasing([3, 1, 4, 3, 2, 1, 2, 3]))
It would probably be easier to iterate normally, from the first index to the end, while pushing sequential sequences to an array, which gets reset when a number greater than the last is found. When resetting, assign the resulting sequence array to a more permanent variable if it's longer than the array in that permanent variable:
const findDecreaseSubArray = (arr) => {
let longestSoFar = [];
let currentSequence = [];
const reset = (newItem) => {
if (currentSequence.length > longestSoFar.length) {
longestSoFar = currentSequence;
}
currentSequence = [newItem];
};
for (const item of arr) {
if (currentSequence.length && item > currentSequence[currentSequence.length - 1]) {
reset(item);
} else {
currentSequence.push(item);
}
}
reset();
return longestSoFar;
};
console.log(findDecreaseSubArray([3,1,4,3,2,1,2,3]));
Here is my code.
function getLongestDecreaseSequence(arr) {
if (
Object.prototype.toString.call(arr) !== "[object Array]" ||
arr.length == 0
) {
return arr;
}
let longestArr = [];
let tmpArr = [],
lastTmpIndex = -1;
arr.forEach((value, i) => {
if (arr[lastTmpIndex] < value) {
tmpArr = [];
}
// no matter what, I will put it in tmpArray
lastTmpIndex = i;
tmpArr.push(value);
if (longestArr.length < tmpArr.length) {
longestArr = tmpArr;
}
});
return longestArr;
}
console.log(getLongestDecreaseSequence([3, 1, 4, 3, 2, 1, 2, 3]));
This looks like a reducing job.
var a = [3,1,4,3,2,1,2,3],
r = a.reduce( function(r,e){
var l = r[r.length-1];
return l[l.length-1] > e ? ( l.push(e)
, r
)
: ( r.push([e])
, r
);
}
, [[]]
)
.reduce((p,c) => p.length > c.length ? p : c);
console.log(r);
I'm trying to solve a basic problem in Hackerearth Given an array A of size N, you need to find the number of ordered pairs (i,j) such that i < j and A[i] > A[j].
I was able to find out an idea actually implemented it by having a global variable. But having a global value is not a good practice, hence I tried to pass it as parameter and I couldn't able to solve it. Am stuck with keeping an already returned value and adding an updated value to it.
// let ans = 0;
let mergeSort = (left, right, arr, ans) => {
let i = 0,
j = 0,
k = 0;
let leftLen = left.length,
rightLen = right.length;
while (i < leftLen && j < rightLen) {
if (left[i] <= right[j]) {
arr[k] = left[i];
i++;
} else {
arr[k] = right[j];
ans += leftLen - i;
j++;
}
k++;
}
while (i < leftLen) {
arr[k] = left[i];
i++;
k++;
}
while (j < rightLen) {
arr[k] = right[j];
j++;
k++;
}
return { arr, ans };
};
let divideArray = (arr, ans) => {
if (arr.length < 2) return { arr, ans };
let N = arr.length;
let mid = Math.round(N / 2);
let left = arr.slice(0, mid);
let right = arr.slice(mid, N);
ans = ans;
divideArray(left, ans);
divideArray(right, ans);
let blabla = mergeSort(left, right, arr, ans);
return blabla;
};
let merge = (arr, ans) => {
let res = divideArray(arr, ans);
return res;
};
function main(input) {
let arr = [1, 4, 3, 2, 5];
let ans = 0;
let output = merge(arr, ans);
console.log('Final', output);
}
main();
In mergeSort function When the input of the left array is [1,4] and the right array is [3] the ans will be updated as 1, also when the left array is [1,3,4] and right is [2,5] the ans will be updated as 2. I would like to add both this ans values and return it as 3. But somewhere am making a mistake while returning. Any help will be appreciated.
JsFiddle
EDIT:
Please note that am trying to achieve it via MergeSort and recursion i know in lot of other ways i can solve this problem for instance i have clearly mentioned i had solved it by having a global variable,which is not a good practice so please provide me a solution only via recursion and merge sort
There is no need to pass an inversion count to divideArray(), it only needs to return a sub_count = left_count + right_count + merged_count. The sub_counts originate from each instance of merging and will be accumulated as recursion returns sub-counts back up the call chain to produce a total_count.
Example of an optimized top down merge sort updated to return an inversion count. A helper function (mergesort()) does a one time allocation of an auxiliary array (aux). To avoid unneeded copying of data, two mutually recursive functions are used, sortarrtoarr() sorts data from arr[] back to arr[], while sortarrtoaux() sorts data from arr[] to aux[]. Each of the mutually recursive functions calls the other in order to change the direction of merge based on the level of recursion.
function merge(arr, aux, bgn, mid, end) {
var i = bgn;
var j = mid;
var k = bgn;
var cnt = 0; // count of inversions
while(true){
if(arr[i] <= arr[j]){ // if left element <= right element
aux[k++] = arr[i++]; // copy left element
if(i < mid) // if not end of left run
continue; // continue back to while
do // else copy rest of right run
aux[k++] = arr[j++]; // and break
while(j < end);
break;
} else { // else left element > right element
cnt += mid - i; // arr.slice(i,mid) is > arr[j]
aux[k++] = arr[j++]; // copy right element
if(j < end) // if not end of right run
continue; // continue back to while
do // else copy rest of left run
aux[k++] = arr[i++]; // and break
while(i < mid);
break;
}
}
return cnt; // return inversion count
}
// sort from arr[] to aux[]
function sortarrtoaux(arr, aux, bgn, end) {
if ((end-bgn) < 2){ // if only 1 element
aux[bgn] = arr[bgn]; // copy it to aux
return 0; // return inversion count == 0
}
var cnt = 0; // inversion count = 0
var mid = Math.floor(bgn + (end - bgn) / 2);
cnt += sortarrtoarr(arr, aux, bgn, mid); // sort left arr back to arr
cnt += sortarrtoarr(arr, aux, mid, end); // sort right arr back to arr
cnt += merge(arr, aux, bgn, mid, end); // merge arr to aux
return cnt; // return inversion count
}
// sort from arr[] back to arr[]
function sortarrtoarr(arr, aux, bgn, end) {
if ((end-bgn) < 2) // if only 1 element
return 0; // return inversion count == 0
var cnt = 0; // inversion count = 0
var mid = Math.floor(bgn + (end - bgn) / 2);
cnt += sortarrtoaux(arr, aux, bgn, mid); // sort left arr to aux
cnt += sortarrtoaux(arr, aux, mid, end); // sort right arr to aux
cnt += merge(aux, arr, bgn, mid, end); // merge aux to arr
return cnt; // return inversion count
}
// entry function for mergesort
function mergesort(arr) {
if(arr.length < 2) // if less than 2 elements
return 0; // return inversion count == 0
var aux = new Array(arr.length); // allocate aux[] and start merge sort
return sortarrtoarr(arr, aux, 0, arr.length);
}
var arr = [8, 6, 7, 5, 3, 0, 9];
var cnt = mergesort(arr);
console.log(cnt);
for (i = 1; i < arr.length; i++) {
if(arr[i-1] > arr[i]){
console.log('error');
break;
}
}
Scott's answer offers a functional approach. Generators, function* below, offer another capable and flexible way of encoding this kind of problem -
const descendingPairs = function* (a = [])
{ for (const i of range(0, a.length)) // for all (0 <= i < a.length)
for (const j of range(0, a.length)) // for all (0 <= i < a.length)
if (i < j) // such that i < j
if (a[i] > a[j]) // and a[i] > a[j]
yield [ a[i], a[j] ] // output descending pair
}
We can optimise this by using i as the input for the j range's start -
const descendingPairs = function* (a = [])
{ for (const i of range(0, a.length)) // for all (0 < i < a.length)
for (const j of range(i + 1, a.length)) // for all (i < j < a.length)
if (a[i] > a[j]) // such that a[i] > a[j]
yield [ a[i], a[j] ] // output descending pair
}
range is nicely-encoded using a generator as well -
const range = function* (start = 0, stop = 0)
{ for (let x = start; x < stop; x++)
yield x
}
We can output the results of each descending pair -
const input =
[ 1, 4, 3, 2, 5 ]
for (const pair of descendingPairs(input))
console.log(pair)
// [ 4, 3 ]
// [ 4, 2 ]
// [ 3, 2 ]
Or we can collect all pairs into an array -
Array.from(descendingPairs(input))
// => [ [ 4, 3 ], [ 4, 2 ], [ 3, 2 ] ]
Or we can simply count them -
Array.from(descendingPairs(input)).length
// => 3
Expand the snippet below to verify the results in your own browser -
const range = function* (start = 0, stop = 0)
{ for (let x = start; x < stop; x++)
yield x
}
const descendingPairs = function* (a = [])
{ for (const i of range(0, a.length))
for (const j of range(i, a.length))
if (a[i] > a[j])
yield [ a[i], a[j] ]
}
const input =
[ 1, 4, 3, 2, 5 ]
console.log(Array.from(descendingPairs(input)))
// [ [ 4, 3 ], [ 4, 2 ], [ 3, 2 ] ]
console.log(Array.from(descendingPairs(input)).length)
// 3
I'm having a hard time figuring why you are writing this with code that's all about a mergesort. It seems to me that all you need to do is to generate the index pairs where j > i (a fairly easy task) and then count those for which A[i] > A[j]. Recursion is a fine way (though by no means the only easy way) to create those index pairs. The rest is a filter/length combination or a reduce.
Here's one variation:
const countDescendingPairs = (xs) =>
xs .map ((x, i) => xs .slice (i + 1) .filter(y => x > y) .length)
.reduce ((a, b) => a + b, 0)
console .log (
countDescendingPairs ([8, 6, 7, 5, 3, 0, 9])
)
But there are many simple alternatives.
And if you wanted to retrieve those pairs, it's a straightforward modification:
const descendingPairs = (xs) =>
xs .flatMap (
(x, i) =>
xs .slice (i + 1)
.filter (y => x > y)
.map ((y) => ({x, y}))
)
console .log (
descendingPairs ([8, 6, 7, 5, 3, 0, 9])
)
Updated to add flatMap and to remove the incorrect indices from the second version. (You can't filter, then expect the old index to still work!)
https://codepen.io/Santhoshsanz/pen/dybedgm?editors=1112
// let ans = 0;
let mergeSort = (left, right, arr, ans) => {
// console.log(left)
// console.log("*****")
// console.log(right)
// console.log("*****£££")
let i = 0,
j = 0,
k = 0;
let leftLen = left.length,
rightLen = right.length;
while (i < leftLen && j < rightLen) {
if (left[i] <= right[j]) {
arr[k] = left[i];
i++;
} else {
arr[k] = right[j];
ans += leftLen - i;
j++;
}
k++;
}
while (i < leftLen) {
arr[k] = left[i];
i++;
k++;
}
while (j < rightLen) {
arr[k] = right[j];
j++;
k++;
}
return { arr, ans };
};
let divideArray = (arr, ans) => {
if (arr.length < 2) return { arr, ans };
let N = arr.length;
let mid = Math.round(N / 2);
let left = arr.slice(0, mid);
let right = arr.slice(mid, N);
ans = ans;
let lans=divideArray(left, ans).ans;
let bAns=divideArray(right, ans).ans;
// console.log(bAns)
let blabla= mergeSort(left, right, arr, lans+bAns);
return blabla
};
let merge = (arr, ans) => {
let res=0+ divideArray(arr, ans).ans;
// console.log("asdad")
// console.log(res)
return res;
};
function main(input) {
let arr = [1,4,3,2,5];
let ans = 0;
let output = merge(arr, ans);
console.log('Final', output);
}
main();
I have persisted the count val inside your divide array and used it to merge the 2 counts from the split array i.e left and right direction split
Given an array of integers, find the pair of adjacent elements that has the largest product and return that product.
and here is my code
function adjacentElementsProduct(inputArray) {
var arr = inputArray;
var x=0;
var y=0;
var p=0;
for(var i=0;i<arr.length;i++){
x=arr[i];
y=arr[i+1];
if(x*y>p){
p=x*y;
};
};
return p;
};
the problem is all the tests works fine but except the array with the negative product as it shown in the attached photo
can anyone help .. and thanks in advance
You could start with a really large negative value, instead of zero.
var p = -Infinity;
You are initializing the variable p to zero. That means any multiplication values smaller than that are not accepted. Rather set it to the smallest possible integer value:
var p = Number.MIN_SAFE_INTEGER;
function adjacentElementsProduct(inputArray) {
var arr = inputArray;
var x = 0;
var y = 0;
var p = Number.MIN_SAFE_INTEGER;
for (var i = 0; i < arr.length; i++) {
x = arr[i];
y = arr[i + 1];
if (x * y > p) {
p = x * y;
};
};
return p;
};
console.log(adjacentElementsProduct([-23, 4, -3, 8, -12]));
This is quite simple actually
function adjacentElementsProduct(inputArray) {
let max = -Infinity;
for (let i = 1; i < inputArray.length; i++) {
max = Math.max(inputArray[i] * inputArray[i - 1], max);
}
return max;
}
This is quite simple actually
const solution = (inputArray) => Math.max(...inputArray.slice(0, -1).map((n, index) => n * inputArray[index + 1]))
console.log(solution([3, 6, -2, -5, 7, 3]))
function solution(inputArray: number[]): number {
var max = -Infinity;
for(var i=0; i+1<inputArray.length; i++)
{
if(max<(inputArray[i]*inputArray[i+1])){
max=inputArray[i]*inputArray[i+1];
}
}
return max;
}
console.log(solution([2,3,6]))
I had the same problem at first, defining the first max as 0. Then i came up with this:
function solution(inputArray) {
let products = inputArray.map(function(x, index){
return inputArray[index+1] != undefined? x *inputArray[index+1] : -Infinity;
})
return Math.max(...products);
}
Problem:
Given an array of integers, find the pair of adjacent elements that has the largest product and return that product. #javascript #arraymethods
function solution(inputArray) {
let productsArr = []; // to hold the products of adjacent elements
let n = 0;
for (let i = 0; i < inputArray.length; i++) {
if (i < inputArray.length - 1)
{
productsArr[n] = inputArray[i] * inputArray[i + 1];
n++;
}
}
return productsArr.reduce((aggr, val) => Math.max(aggr, val)); // to find out the biggest product
}
Here's a very simple implementation without using any additional variables (actually less), and no special values. Just simple logic.
function adjacentElementsProduct(inputArray) {
var c =inputArray[0]*inputArray[1];
var p = c;
for(var i=1;i<inputArray.length;i++){
console.log(c);
var c=inputArray[i]*inputArray[i+1];
if(c > p){
p=c;
};
};
return p;
};
console.log("minimum product = " + adjacentElementsProduct([-23,4,-3,8,-12]));
What I did was, initialize a variable c (current product) with the product of first two elements of the array. And then I declared the variable p and initialize it to c. This way, all other products are compared to this product. Rest is simple.
Hope it helps. :)
you can try to initialize a integer as negative infinity value -math.inf and then use the python ternary operator var=true if condition else false to find the maximum value
code in python
def adjacentarray(a):
maximum=-math.inf
for i,in range(0,len(a)-1):
maximum=a[i]*a[i+1] if a[i]*a[i+1]>maximum else maximum
return maximum
code in javascript
function adjacentElementsProduct(a) {
var maximum=-Infinity;
for (var i=0;i<a.length-1;i++){
maximum= a[i]*a[i+1]>maximum?a[i]*a[i+1]:maximum;
}
return maximum;
}
function solution(inputArray) {
let first, second, sum = []
inputArray.map((arr,index)=>{
first = arr;
second = inputArray[index+1]
if(second == undefined){
return second
}
return sum.push(first * second)
})
let last = sum.sort().reduce((pre,next)=> {
return pre > next ? pre : next
})
return last;
}
//Kotlin
fun solution(inputArray: MutableList<Int>): Int {
var result: Int = Int.MIN_VALUE
for (i in 0..inputArray.size - 2) {
if (inputArray[i] * inputArray[i + 1] > result)
result = inputArray[i] * inputArray[i + 1]
}
return result
}
import 'dart:math';
int solution(List<int> inputArray) {
//assumption for highest number
int highestNumber = inputArray[0] * inputArray[1] ;
//we'll go through the array to campare the highestNumber
//with next index
for(var i = 1 ; i < inputArray.length ; i++){
highestNumber = max(highestNumber, inputArray[i] * inputArray[i - 1]);
}
return highestNumber;
}
In Javascript, you could use the reduce method from an array to avoid iterating in a for loop, just like this.
function solution(inputArray) {
let maxProd = []
inputArray.reduce((accumulator, currentValue) => {
maxProd.push(accumulator*currentValue)
return currentValue
},
);
return Math.max(...maxProd)
}
Once you have in the maxProd array the products, you use the spread operator to get the numbers and using Math.max() you get the largest
python solution
You can make a loop from 1 to end of your list and do the following arithmetic operations
def solution(inputArray):
list1 =[]
for i in range(1,len(inputArray)):
list1.append(inputArray[i]*inputArray[i-1])
return max(list1)
Here is a solution in PHP that is quite simple.
function solution($inputArray) {
$largest = null;
$pos = null;
for($i = 0; $i < count($inputArray) -1; $i++){
$pos = ($inputArray[$i] * $inputArray[$i+1]);
if($largest < $pos){
$largest = $pos;
}
}
return $largest ?? 0;
}
You can try to create a new array of length (arr.length-1) inside the function and append the products of adjacent numbers to this new array. Then find the largest number in the array and return it. This will solve the problem with negative product.
function adjacentElementsProduct(inputArray) {
var arr = inputArray;
var prodArr[];
var p;
for (var i = 0; i < arr.length-1; i++) {
prodArr[i] = arr[i]*arr[i+1];
};
for (j=prodArr.length; j--){
if (prodArr[j] > p) {
p = prodArr[j];
};
return p;
};
console.log(adjacentElementsProduct([-23, 4, -3, 8, -12]));
The var p which saves the max product should be initialized as small as possible instead of a 0. So that when the product is negative, it will still meet the if condition and save the value.
Here is a C# solution:
static void Main(string[] args)
{
int[] arr = { 1, -4, 3, -6, -7, 0 };
Console.WriteLine(FindMaxProduct(arr));
Console.ReadKey();
}
static int FindMaxProduct(int[] arr) {
int currentProduct = 0;
int maxProduct = int.MinValue;
int a=0, b = 0;
for (int i = 0, j = i + 1; i < arr.Length - 1 && j < arr.Length; i++, j++)
{
currentProduct = arr[i] * arr[j];
if (currentProduct>maxProduct) {
a = arr[i];
b = arr[j];
maxProduct = currentProduct;
}
}
Console.WriteLine("The max product is {0}, the two nums are {1} and {2}.",maxProduct,a,b);
return maxProduct;
}
function solution(inputArray) {
let f, s, arr = []
for(let i=0; i<inputArray.length; i++){
f = inputArray[i]
s = inputArray[i+1]
arr.push(f*s)
}
let max = arr.sort((a, b) => b - a)
return max[0]
}
console.log(solution([3, 6, -2, -5, 7, 3]))
This should help, wrote it in python. Concept: Pass an empty list, for every consecutive product keep storing it in the list. Then just return the max value.
def consecutive_product_max(a):
lst2 = []
for i in range(0, len(a)-1):
x = a[i] * a[i+1]
lst2.append(x)
return max(lst2)
I'm trying to solve this exercise of finding the number that appears an odd number of times in an array. I have this so far but the output ends up being an integer that appears an even number of times. For example, the number 2 appears 3 times and the number 4 appears 6 times, but the output is 4 because it counts it as appearing 5 times. How can it be that it returns the first set that it finds as odd? Any help is appreciated!
function oddInt(array) {
var count = 0;
var element = 0;
for(var i = 0; i < array.length; i++) {
var tempInt = array[i];
var tempCount = 0;
for(var j = 0; j <array.length; j++) {
if(array[j]===tempInt) {
tempCount++;
if(tempCount % 2 !== 0 && tempCount > count) {
count = tempCount;
element = array[j];
}
}
}
}
return element;
}
oddInt([1,2,2,2,4,4,4,4,4,4,5,5]);
function findOdd(numbers) {
var count = 0;
for(var i = 0; i<numbers.length; i++){
for(var j = 0; j<numbers.length; j++){
if(numbers[i] == numbers[j]){
count++;
}
}
if(count % 2 != 0 ){
return numbers[i];
}
}
};
console.log(findOdd([20,1,-1,2,-2,3,3,5,5,1,2,4,20,4,-1,-2,5])); //5
console.log(findOdd([1,1,1,1,1,1,10,1,1,1,1])); //10
First find the frequencies, then find which ones are odd:
const data = [1,2,2,2,4,4,4,4,4,4,5,5]
const freq = data.reduce(
(o, k) => ({ ...o, [k]: (o[k] || 0) + 1 }),
{})
const oddFreq = Object.keys(freq).filter(k => freq[k] % 2)
// => ["1", "2"]
If we are sure only one number will appear odd number of times, We can XOR the numbers and find number occurring odd number of times in n Comparisons.XOR of two bits is 1 if they are different else it will be 0. Truth table is below.
A B A^B
0 0 0
0 1 1
1 0 1
1 1 0
So when we do XOR of all the numbers, final number will be the number appearing odd number of times.
Let's take a number and XOR it with the same number(Appearing two times). Result will be 0 as all the bits will be same. Now let's do XOR of result with same number. Now result will be that number because all the bits of previous result are 0 and only the set bits of same number will be set in the result. Now expanding it to an array of n numbers, numbers appearing even number of times will give result 0. The odd appearance of the number result in that number in the final result.
func oddInt(numbers: [Int]) -> Int {
var result = 0
for aNumber in numbers {
result = result ^ aNumber
}
return result
}
Here is a solution with O(N) or O(N*log(N))
function findOdd(A) {
var count = {};
for (var i = 0; i < A.length; i++) {
var num = A[i];
if (count[num]) {
count[num] = count[num] + 1;
} else {
count[num] = 1;
}
}
var r = 0;
for (var prop in count) {
if (count[prop] % 2 != 0) {
r = prop;
}
}
return parseInt(r); // since object properies are strings
}
#using python
a=array('i',[1,1,2,3,3])
ans=0
for i in a:
ans^=i
print('The element that occurs odd number of times:',ans)
List item
output:
The element that occurs odd number of times: 2
Xor(^)operator when odd number of 1's are there,we can get a 1 in the output
Refer Xor Truth table:
https://www.electronicshub.org/wp-content/uploads/2015/07/TRUTH-TABLE-1.jpg
function oddInt(array) {
// first: let's count occurences of all the elements in the array
var hash = {}; // object to serve as counter for all the items in the array (the items will be the keys, the counts will be the values)
array.forEach(function(e) { // for each item e in the array
if(hash[e]) hash[e]++; // if we already encountered this item, then increments the counter
else hash[e] = 1; // otherwise start a new counter (initialized with 1)
});
// second: we select only the numbers that occured an odd number of times
var result = []; // the result array
for(var e in hash) { // for each key e in the hash (the key are the items of the array)
if(hash[e] % 2) // if the count of that item is an odd number
result.push(+e); // then push the item into the result array (since they are keys are strings we have to cast them into numbers using unary +)
}
return result;
}
console.log(oddInt([1, 2, 2, 2, 4, 4, 4, 4, 4, 4, 5, 5]));
Return only the first:
function oddInt(array) {
var hash = {};
array.forEach(function(e) {
if(hash[e]) hash[e]++;
else hash[e] = 1;
});
for(var e in hash) { // for each item e in the hash
if(hash[e] % 2) // if this number occured an odd number of times
return +e; // return it and stop looking for others
}
// default return value here
}
console.log(oddInt([1, 2, 2, 2, 4, 4, 4, 4, 4, 4, 5, 5]));
That happens because you are setting the element variable each time it finds an odd number, so you are setting it when it find one, three and five 4.
Let's check the code step by step:
function oddInt(array) {
// Set the variables. The count and the element, that is going to be the output
var count = 0;
var element = 0;
// Start looking the array
for(var i = 0; i < array.length; i++) {
// Get the number to look for and restart the tempCount variable
var tempInt = array[i];
var tempCount = 0;
console.log("");
console.log(" * Looking for number", tempInt);
// Start looking the array again for the number to look for
for(var j = 0; j <array.length; j++) {
// If the current number is the same as the one that we are looking for, sum it up
console.log("Current number at position", j, "is", array[j]);
if(array[j]===tempInt) {
tempCount++;
console.log("Number found. Current count is", tempCount);
// Then, if currently there are an odd number of elements, save the number
// Note that you are calling this altough you don't have looped throgh all the array, so the console will log 3 and 5 for the number '4'
if(tempCount % 2 !== 0 && tempCount > count) {
console.log("Odd count found:", tempCount);
count = tempCount;
element = array[j];
}
}
}
}
return element;
}
oddInt([1,2,2,2,4,4,4,4,4,4,5,5]);
What we want to do is to check for the count AFTER looping all the array, this way:
function oddInt(array) {
// Set the variables. The count and the element, that is going to be the output
var count = 0;
var element = 0;
// Start looking the array
for(var i = 0; i < array.length; i++) {
// Get the number to look for and restart the tempCount variable
var tempInt = array[i];
var tempCount = 0;
console.log("");
console.log(" * Looking for number", tempInt);
// Start looking the array again for the number to look for
for(var j = 0; j <array.length; j++) {
// If the current number is the same as the one that we are looking for, sum it up
console.log("Current number at position", j, "is", array[j]);
if(array[j]===tempInt) {
tempCount++;
console.log("Number found. Current count is", tempCount);
}
}
// After getting all the numbers, then we check the count
if(tempCount % 2 !== 0 && tempCount > count) {
console.log("Odd count found:", tempCount);
count = tempCount;
element = tempInt;
}
}
return element;
}
oddInt([1,2,2,2,4,4,4,4,4,4,5,5]);
By the way, this is only for you to understand where was the problem and learn from it, although this is not the most optimized way of doing this, as you may notice that you are looking for, let's say, number 2 three times, when you already got the output that you want the first time. If performance is part of the homework, then you should think another way :P
This is because your condition if(tempCount % 2 !== 0 && tempCount > count) is true when the 5th 4 is checked. This updates the count and element variables.
When the 6th 4 is checked, the condition is false.
To fix, move the condition outside the innermost loop so that it's checked only after all the numbers in the array are counted.
function oddInt(array, minCount, returnOne) {
minCount = minCount || 1;
var itemCount = array.reduce(function(a, b) {
a[b] = (a[b] || 0) + 1;
return a;
}, {});
/*
itemCount: {
"1": 1,
"2": 3,
"4": 6,
"5": 2,
"7": 3
}
*/
var values = Object.keys(itemCount).filter(function(k) {
return itemCount[k] % 2 !== 0 && itemCount[k]>=minCount;
});
return returnOne?values[0]:values;
}
var input = [1, 2, 2, 2, 4, 4, 4, 4, 4, 4, 5, 5, 7, 7, 7];
console.log(oddInt(input, 3, true));
console.log(oddInt(input, 1, true));
console.log(oddInt(input, 2, false));
"A" is the array to be checked.
function findOdd(A) {
var num;
var count =0;
for(i=0;i<A.length;i++){
num = A[i]
for(a=0;a,a<A.length;a++){
if(A[a]==num){
count++;
}
} if(count%2!=0){
return num;
}
}
}
function oddOne (sorted) {
let temp = sorted[0];
let count = 0;
for (var i = 0; i < sorted.length; i++) {
if (temp === sorted[i]) {
count++;
if (i === sorted.length - 1) {
return sorted[i];
}
} else {
if (count % 2 !== 0) {
return temp;
}
count = 1;
temp = sorted[i];
}
}
}
function oddInt(array) {
let result = 0;
for (let element of array) {
result ^= element
}
return result
}
var oddNumberTimes = (arr) => {
let hashMap = {};
for (let i = 0; i < arr.length; i++) {
hashMap[arr[i]] = hashMap[arr[i]] + 1 || 1;
}
for (let el in hashMap) {
if (hashMap[el] % 2 !== 0) {
return el;
}
}
return -1;
};
You can use bitwise XOR:
function oddInt(array) {
return array.reduce(function(c, v) {
return c ^ v;
}, 0);
}
console.log(oddInt([20, 1, -1, 2, -2, 3, 3, 5, 5, 1, 2, 4, 20, 4, -1, -2, 5]) == 5);
console.log(oddInt([1, 1, 1, 1, 1, 1, 10, 1, 1, 1, 1]) == 10);
Had to implement a solution for a similar problem and here it is:
function findtheOddInt(A) {
let uniqueValues = [...new Set(A)]; // Get the unique values from array A
const odds = [];
uniqueValues.forEach(element => {
const count = A.reduce((acc, cur) => cur === element ? acc + 1: acc, 0) // count the occurrences of the element in the array A
if (count % 2 === 1) {
odds.push(element);
}
});
return odds[0]; // Only the first odd occurring element
}
var arr=[1,2,2,2,2,3,4,3,3,3,4,5,5,9,9,10];
var arr1=[];
for(let i=0;i
{
var count=0;
for(let j=0;j<arr.length;j++)
{
if(arr[i]==arr[j])
{
count++;
}
}
if(count%2 != 0 )
{
arr1.push(arr[i]);
}
}
console.log(arr1);