how can i compare two arrays in Javascript by using binarysearch? - javascript

How can i use a binary search to compare two arrays and count the number of times it matched, i did find some here where one item was compared to an array..follwing is regular one for example ..thanx for the help.
var a = ["1", "2", "3", "4", "5", "6", "7"];
var b = ["8", "1", "3", "9", "4", "6", "8"];
var count = 0;
for (i = 0; i < a.length; i++) {
for (j = 0; j < b.length; j++) {
if (a[i] == b[j]) count += 1;
}
}
document.write(count);
I tried to do this ..
for (i = 0; i < a.length; i++) {
var left = 0;
var right = b.length - 1;
while (left <= right) {
var mid = parseInt((left + right) / 2);
if (b[mid] == a[i]) {
count += 1;
} else if (b[mid] < a[i]) {
left = mid + 1;
}
else {
right = mid - 1;
}
}
}
document.write(count);

Linearly go through the b array and use a binary search of the a array.
function binarySearch(a, value) {
var left = 0;
var right = a.length - 1;
while (left <= right) {
var mid = (left + right) >> 1;
if (a[mid] === value) {
return mid;
} else if (a[mid] < value) {
left = mid + 1;
}
else {
right = mid - 1;
}
}
return -1;
}
var a = ["1", "2", "3", "4", "5", "6", "7"];
var b = ["8", "1", "3", "9", "4", "6", "8"];
var count = 0;
b.forEach(function(value) { if (binarySearch(a, value) >= 0) ++count; });

Related

Sudoku solver in Javascript using backtracking and recursion

I try to write a sudoku solver in Javascript but can't seem to make it work.
Every time my solve function returns undefined, it seems that when the code meets a dead end, it does not try another z in the previous function called and just gives up at some point after multiple tries on the same case
var solve = () => {
//iterate through the lines of the grid
for (y = 0; y < 9; y++) {
//iterate through each column of the grid
for (x = 0; x < 9; x++) {
//if a case is empty, we can try some numbers
if (grid[y][x] === "") {
//our answer must be between 1 to 9 to be correct
for (z = 1; z < 10; z++) {
if (possible(x, y, z)) {
grid[y][x] = z.toString();
solve();
if (isComplete()) {
return grid;
}
else {
grid[y][x] = "";
}
}
}
//if there is no answer, we go back to our precedent function call and try another number
return;
}
}
}
}
//get all the values of the vertical line of a particular value
var getVerticalLine = (x, y) => {
let verticalLine = [];
//iterate through every line of the grid and add the value at the index except the one from the line where the value is taken from
for (let line of grid) {
if (line != grid[y]) {
verticalLine.push(line[x]);
}
}
return verticalLine;
}
var getSquareValues = (x, y) => {
let squareValue = [];
//check in which square our value is and create an array with each value from the square except our own
if (x < 3 && y < 3) {
//iterate through line 1 to 3
for (let line = 0; line < 3; line++) {
//iterate through columns 1 to 3
for (let column = 0; column < 3; column++) {
//check that we don't include our own value
if (!(line === y && column === x)) {
squareValue.push(grid[line][column]);
}
}
}
return squareValue;
} else if (x < 6 && y < 3) {
//iterate through line 1 to 3
for (let line = 0; line < 3; line++) {
//iterate through columns 4 to 6
for (let column = 3; column < 6; column++) {
//check that we don't include our own value
if (!(line === y && column === x)) {
squareValue.push(grid[line][column]);
}
}
}
return squareValue;
} else if (x < 9 && y < 3) {
//iterate through line 1 to 3
for (let line = 0; line < 3; line++) {
//iterate through columns 6 to 9
for (let column = 6; column < 9; column++) {
//check that we don't include our own value
if (!(line === y && column === x)) {
squareValue.push(grid[line][column]);
}
}
}
return squareValue;
} else if (x < 3 && y < 6) {
//iterate through line 4 to 6
for (let line = 4; line < 7; line++) {
//iterate through columns 1 to 3
for (let column = 0; column < 3; column++) {
//check that we don't include our own value
if (!(line === y && column === x)) {
squareValue.push(grid[line][column]);
}
}
}
return squareValue;
} else if (x < 6 && y < 6) {
//iterate through line 4 to 6
for (let line = 3; line < 6; line++) {
//iterate through columns 4 to 6
for (let column = 4; column < 6; column++) {
//check that we don't include our own value
if (!(line === y && column === x)) {
squareValue.push(grid[line][column]);
}
}
}
return squareValue;
} else if (x < 9 && y < 6) {
//iterate through line 4 to 6
for (let line = 3; line < 6; line++) {
//iterate through columns 6 to 9
for (let column = 6; column < 9; column++) {
//check that we don't include our own value
if (!(line === y && column === x)) {
squareValue.push(grid[line][column]);
}
}
}
return squareValue;
} else if (x < 3 && y < 9) {
//iterate through line 6 to 9
for (let line = 6; line < 9; line++) {
//iterate through columns 1 to 3
for (let column = 0; column < 3; column++) {
//check that we don't include our own value
if (!(line === y && column === x)) {
squareValue.push(grid[line][column]);
}
}
}
return squareValue;
} else if (x < 6 && y < 9) {
//iterate through line 6 to 9
for (let line = 6; line < 9; line++) {
//iterate through columns 1 to 3
for (let column = 3; column < 6; column++) {
//check that we don't include our own value
if (!(line === y && column === x)) {
squareValue.push(grid[line][column]);
}
}
}
return squareValue;
} else if (x < 9 && y < 9) {
//iterate through line 6 to 9
for (let line = 6; line < 9; line++) {
//iterate through columns 1 to 3
for (let column = 6; column < 9; column++) {
//check that we don't include our own value
if (!(line === y && column === x)) {
squareValue.push(grid[line][column]);
}
}
}
return squareValue;
} else {
return "Some fuckery went there";
}
}
var possible = (x, y, z) => {
x = x.toString();
y = y.toString();
z = z.toString();
if (!(grid[y].includes(z)) && !(getVerticalLine(x, y).includes(z)) && !(getSquareValues(x, y).includes(z))) {
return true;
}
else {
return false;
}
}
var isComplete = () => {
for (let y = 0; y < 9; y++) {
//iterate through each column of the grid
for (let x = 0; x < 9; x++) {
if (grid[y][x] === "") {
return false;
}
}
}
return true;
}
var setExemple1 = () => {
grid = [["3", "", "6", "5", "", "8", "4", "", ""],
["5", "2", "", "", "", "", "", "", ""],
["", "8", "7", "", "", "", "", "3", "1"],
["", "", "3", "", "1", "", "", "8", ""],
["9","", "", "8", "6", "3", "", "", "5"],
["", "", "", "", "9", "", "6", "", ""],
["1", "3", "", "", "", "", "2", "5", ""],
["", "", "", "", "", "", "", "7", 4],
["", "", "5", "2", "", "6", "3", "", ""]];
}
Thank you for your help !
EDIT : One of the problems was just that I forgot to declare my variables in my for loops ... I can't say how much time I spend looking at my code trying to understand where I did made a mistake when it was just this, thank you really much it seems to work better. I'm now able to complete the empty grid, there seems to be another problem trying to solve my example, I'll take a look into it
LAST EDIT : Finally made my code work ! There was a problem with my getSquareValues, at some point I made a mistake in the values used, there was a 4 and a 7 that I forgot instead of a 3 and a 6 and it made the function goes wrong :
//get all the values of the vertical line of a particular value
let getVerticalLine = (x, y) => {
let verticalLine = [];
//iterate through every line of the grid and add the value at the index except the one from the line where the value is taken from
for (let line of grid) {
if (line != grid[y]) {
verticalLine.push(line[x]);
}
}
return verticalLine;
}
let getSquareValues = (x, y) => {
let squareValue = [];
let bx = Math.floor(x / 3);
let by = Math.floor(y / 3);
for (let line = by * 3; line < by * 3 + 3; line++) {
for (let column = bx * 3; column < bx * 3 + 3; column++) {
if (!(line === y && column === x)) {
squareValue.push(grid[line][column]);
}
}
}
return squareValue;
}
let possible = (x, y, z) => {
x = x.toString();
y = y.toString();
z = z.toString();
if (!(grid[y].includes(z)) && !(getVerticalLine(x, y).includes(z)) && !(getSquareValues(x, y).includes(z))) {
return true;
}
else {
return false;
}
}
let isComplete = () => {
for (let y = 0; y < 9; y++) {
//iterate through each column of the grid
for (let x = 0; x < 9; x++) {
if (grid[y][x] === "") {
return false;
}
}
}
return true;
}
let solve = () => {
//iterate through the lines of the grid
for (let y = 0; y < 9; y++) {
//iterate through each column of the grid
for (let x = 0; x < 9; x++) {
//if a case is empty, we can try some numbers
if (grid[y][x] === "") {
//our answer must be between 1 to 9 to be correct
for (let z = 1; z < 10; z++) {
if (possible(x, y, z)) {
grid[y][x] = z.toString();
solve();
if (isComplete()) {
return grid;
}
else {
grid[y][x] = "";
}
}
}
//if there is no answer, we go back to our precedent function call and try another number
return;
}
}
}
}
let setExemple1 = () => {
grid = [
["3", "", "6", "5", "", "8", "4", "", ""],
["5", "2", "", "", "", "", "", "", ""],
["", "8", "7", "", "", "", "", "3", "1"],
["", "", "3", "", "1", "", "", "8", ""],
["9","", "", "8", "6", "3", "", "", "5"],
["", "5", "", "", "9", "", "6", "", ""],
["1", "3", "", "", "", "", "2", "5", ""],
["", "", "", "", "", "", "", "7", "4"],
["", "", "5", "2", "", "6", "3", "", ""]
];
}
let setExemple2 = () => {
grid = [
["", "", "", "2", "6", "", "7", "", "1"],
["6", "8", "", "", "7", "", "", "9", ""],
["1", "9", "", "", "", "4", "5", "", ""],
["8", "2", "", "1", "", "", "", "4", ""],
["", "", "4", "6", "", "2", "9", "", ""],
["", "5", "", "", "", "3", "", "2", "8"],
["", "", "9", "3", "", "", "", "7", "4"],
["", "4", "", "", "5", "", "", "3", "6"],
["7", "", "3", "", "1", "8", "", "", ""]
];
}

Trying to find the index values of an array which consist of objects

why is it that i am unable to find the index values of the 'deck' array using deck[0] but this notation works for suits[0]
I am trying to find the index values of my 'deck' array but i am unsure why i keep getting 'undefined'.
var deck = [];
var suits = ["diamonds","hearts","clubs","spades"];
var value = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"];
function genDeck()
{
for(var i = 0; i < suits.length; i++)
{
for(var x = 0; x < value.length; x++){
var card = {Value:value[x], Suit:suits[i]};
deck.push(card);
}
}
return deck;
}
window.onload = function () {
genDeck();
};
var randomNum = Math.floor(Math.random() * 52);
You aren't adding anything to the deck array. You need to call
deck.push(card)
EDIT: Here's the working example code:
var deck = [];
var suits = ["diamonds","hearts","clubs","spades"];
var value = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"];
function genDeck()
{
for(var i = 0; i < suits.length; i++)
{
for(var x = 0; x < value.length; x++){
var card = {Value:value[x], Suit:suits[i]};
deck.push(card);
}
}
return deck;
}
window.onload = function () {
genDeck();
console.log('First Item: ', deck[0])
};
var randomNum = Math.floor(Math.random() * 52);
Note that you have to call console.log after you've called genDeck in your window.onload function.

How to find second most frequent element in an array? I have found most frequent element pls modify without any loops [duplicate]

This question already has answers here:
Get the element with the highest occurrence in an array
(42 answers)
Closed 3 years ago.
I'm looking for an elegant way of determining which element has the second highest occurrence element in a JavaScript array.
For example, in
array = [4,5,6,2,1,3,3,5,3,7,3,9,2,2]
Output : 2 ( most occurring is '3' count is 4 and second most occurring is '2' count is 3)
<html>
<body>
<script>
var array= '45621335373922'
var b =[];
b=array.split('');// convert to array
console.log(b);//["4", "5", "6", "2", "1", "3", "3", "5", "3", "7", "3", "9", "2", "2"]
// find most frequent number
let max = 0, letter;
for (let i = 0; i < array.length; i++ ) {
let count = 0;
for (let j = 0; j < array.length; j++ ) {
if (array[i] === array[j]) {
++count;
}
}
if (max < count) { max = count; letter = array[i] }
}
console.log(letter + ' : ' + max + ' times' );
//remove most frequent number
for (let i=0; i<max;i++)
{
var index = b.indexOf(letter);
if (index > -1) {
b.splice(index, 1);
}
}
console.log(b);
//find second most frequent number
let max1 = 0, letter1;
for (let i = 0; i < b.length; i++ ) {
let count1 = 0;
for (let j = 0; j < b.length; j++ ) {
if (b[i] === b[j]) {
++count1;
}
}
if (max1 < count1) { max1 = count1; letter1 = b[i] }
}
console.log(letter1 + ' : ' + max1 + ' times' );
</script>
</body>
</html>
Count the total of individual elements using an object. Sort it based on repetency and return the second element in array
var array = [4,5,6,2,1,3,3,5,3,7,3,9,2,2]
var obj={};
array.forEach(function(e){
if(obj.hasOwnProperty(e))
obj[e]++;
else
obj[e]=1;
})
console.log(Object.keys(obj).sort(function(a,b){return obj[b]-obj[a]})[1])

loop minute in javascript

I have code like this:
var hour = 7;
for (var i = 0;i <= 1; i++ ){
var minute = 0;
console.log((i + hour) % 24);
}
when I run it, I get result like this:
7
8
my question: how to add the value in format minute ex: 0-59
so I wanna loop the data like this:
7:0
7:1
7:2
s.d
7:59
8:0
You could use a new array to store all your unique values. You will need to look into the new "uniques" array, if the value alreay exists and then use the default value:
var number= ["1", "2", "3", "4", "5", "6", "6"];
var default = 0;
var uniques = [];
var result = [];
for(var i=0; i < number.length; i++) {
if(!inArray(number[i], uniques) {
uniques.push(number[i]);
result.push(number[i]);
console.log(number[i]);
} else {
console.log(default);
result.push(default);
}
}
function inArray(needle, haystack) {
var length = haystack.length;
for(var i = 0; i < length; i++) {
if(haystack[i] == needle) return true;
}
return false;
}
You could use Array#indexOf and check against the actual index. If you get the same index, then show the element, otherwise use a default value instead.
var number= ["1", "2", "3", "4", "5", "6", "6"];
for (var i = 0; i < number.length;i++) {
console.log(number.indexOf(number[i]) === i ? number[i] : undefined);
}
Use map to get the new array, and in the callback store each item in a set to know if it's a duplicate or not.
var number = ["1", "2", "3", "4", "5", "6", "6"];
var s = new Set();
console.log(number.map(n => s.has(n) ? undefined : s.add(n) && n));
If the non-equality of your values is respected by stringification, you can use a plain object, without needing ES6 features:
var number = ["1", "2", "3", "4", "5", "6", "6"];
var s = Object.create(null);
console.log(number.map(function(n) {
if (n in s) return undefined;
s[n] = true;
return n;
}));

Sort Objects in Array by Multiple Properties

I am new to js and trying to sort an array of objects by two fields - starting with the first property, and then by the second property. Both properties are numbers.
The data is:
var homes = [{
"h_id": "3",
"minimumorder": "12",
"price": "17"
}, {
"h_id": "4",
"minimumorder": "1",
"price": "20"
}, {
"h_id": "5",
"minimumorder": "1",
"price": "18.10"
}
There are more objects in the array, this is a simplified example. The below code ALMOST gets me there, but for the minimumorder property it puts 12 after 1 instead of after 6:
cmp = function(a, b) {
parseFloat(a);
parseFloat(b);
if (a > b) return +1;
if (a < b) return -1;
return 0;
}
homes.sort(function(a, b) {
return cmp(a.minimumorder,b.minimumorder) || cmp(a.price,b.price)
})
jsFiddle here.
Any help would be HUGELY appreciated, as I've been googling and tinkering for hours trying to figure this out.
You need to reassign the parsed value back to a and b:
a = parseFloat(a);
b = parseFloat(b);
Otherwise it ends up comparing strings, and 12 occurs after 1 lexically, just like the word at comes after a in the dictionary.
Updated fiddle.
Well,
You should use a code like this:
function sortHomes(homes)
{
var temp_homes = new Array();
var new_homes = new Array();
for(var i = 0; i < homes.length; i++) temp_homes[i] = homes[i];
var maximum = 0, minimum;
for(i = 0; i < temp_homes.length; i++) maximum = Math.max(maximum, temp_homes.minimumorder);
var min_price, j, k, indexes, price_indexes;
for(i = 0; i < temp_homes.length; i++){
minimum = maximum;
for(j = 0; j < temp_homes.length; j++){
minimum = Math.min(minimum, temp_homes[j].minimumorder);
}
indexes = getIndexes(temp_homes, minimum, "minimumorder");
if(indexes.length == 1){
new_homes.push(temp_homes[indexes[0]]);
temp_homes[indexes[0]].minimumorder = maximum + 1;
}
else{
for(j = 0; j < indexes.length; j++){
min_price = maximum;
for(k = 0; k < indexes.length; k++){
min_price = Math.min(min_price, temp_homes[indexes[k]].price);
}
price_indexes = getIndexes(temp_homes, min_price, "price");
for(k = 0; k < price_indexes.length; k++){
new_homes.push(temp_homes[price_indexes[k]]);
temp_homes[price_indexes[k]].price = maximum + 1;
}
}
}
}
}
function getIndexes(arr, el, name)
{
var indexes = new Array();
for(var i = 0; i < arr.length; i++) if(arr[i][name] == el) indexes.push(i);
return indexes;
}
It should work.
If it doesn't, please inform me about it.
Oh, and in order to sort homes, just use:
homes = sortHomes(homes);

Categories