I'm building a mastermind game. In this game the player needs to guess a secret random number. To make this work I need to have a function that can compare the two arrays and check if there is a match in number and position and/or a match only in the number but not the position.
The problem: This function works well for the most part when there are not repeated numbers in the arrays, but gives me a wrong output when there are repeated numbers.
example:
Random -- arr1 = ['5', '5', '3', '4']
Guess -- arr 2 = ['5', '1', '0', '0,]
expected result
{match: true, exactMatches: 1, matchesByValue: 0}
I'm getting this wrong result:
{match: true, exactMatches: 1, matchesByValue: 1}
Important: matchesByValue means correct number in wrong position. It shouldn't consider numbers that have been already counted as exactMatches.
function compareGuessVsRandom(arr1, arr2) {
// convert the arrays to sets
const set1 = new Set(arr1);
const set2 = new Set(arr2);
let exactMatches = 0;
let matchesByValue = 0;
// check if each value in the first array has the same value and position in the second array
for (let i = 0; i < arr1.length; i ) {
if (arr1[i] == arr2[i]) {
exactMatches ;
} else if (set1.has(arr2[i])) {
matchesByValue ;
}
}
// if all checks pass, the arrays are a match
const result = {
match: true,
exactMatches: exactMatches,
matchesByValue: matchesByValue,
};
console.log(result);
return result;
}
CodePudding user response:
How do your input arrays look like in your code ? It works when declaring the arrays as blow
let arr1 = [5, 5, 3, 4];
let arr2 = [5, 1, 0, 0];
let result = compareGuessVsRandom(arr1, arr2)
console.log(result)
function compareGuessVsRandom(arr1, arr2) {
const set1 = new Set(arr1);
const set2 = new Set(arr2);
let exactMatches = 0;
let matchesByValue = 0;
// check if each value in the first array has the same value and position in the second array
for (let i = 0; i < arr1.length; i ) {
if (arr1[i] == arr2[i]) {
exactMatches ;
} else if (set1.has(arr2[i])) {
matchesByValue ;
}
}
// if all checks pass, the arrays are a match
const result = {
match: true,
exactMatches: exactMatches,
matchesByValue: matchesByValue,
};
return result;
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
CodePudding user response:
function compareGuessVsRandom (arr1, arr2) {
// The list of all the indicies at which there is an exact match
const exactMatchesList = []
// The amount of matche by value
let matchesByValue = 0
for (let i = 0; i < arr1.length; i )
if (arr1[i] === arr2[i])
exactMatchesList.push(i)
// Init sets with arrays without the exactly-matched values
const set1 = new Set(arr1.filter((_, i) => !exactMatchesList.includes(i)))
const set2 = new Set(arr2.filter((_, i) => !exactMatchesList.includes(i)))
// If set2 contains an element of set1, increment matchesByValue
for (const e of set1)
matchesByValue = set2.has(e)
// Get the amount of exact matches
const exactMatches = exactMatchesList.length
const result = {
match: exactMatches !== 0 || matchesByValue !== 0,
exactMatches,
matchesByValue
}
return result;
}
const random = [ '5', '5', '3', '4' ]
const guess = [ '5', '1', '0', '0' ]
console.log(compareGuessVsRandom(random, guess))
CodePudding user response:
The has method returns true if set1 contains the specified element. So regardless of whether an exact match has occurred or not, it will increment 'matchesByValue' even for a match at the index with the exact match.
For example, in a scenario where arr2 has [5,5,0,0]. The first '5'. will increment 'exactMatches' but the second one will also increment 'matchesByValue' by matching it with index 0 of set1.
You can eliminate duplicate matches by comparing indexes of the two types of matches.