Tengo este ejemplo para resolver, es bastante fácil pero hay muchos obstáculos:
/** * Write a JavaScript function to check * whether it is possible to replace $ * in a given expression x $ y = z * with one of the four signs +, -, * or / * to obtain a correct expression. */ /** * If we replace $ in input with one of + - * / * do we get a valid mathematical expression? * @param {string} input String that is tested * @returns {boolean} Whether it could be valid expression */ const isReplacable = input => { /** * Please fill in your code here */ return false; }; const TEST_STRINGS = [ '3 $ 5 = 8', '2 $ 6 = 3', '5$5=25', '2 $ 1 = 2', '3 $ 4 = 5', '6 $ 4 = 3', '3 $ 2 = 1', '4 $6= 24', '3$ 2= 6', '30$ 15 =2', ]; export const runChecks = () => { TEST_STRINGS.forEach(expression => { console.log(`${expression}: ${isReplacable(expression) ? 'VALID' : 'INVALID'}`); }); };
Intenté terminarlo así:
1, hacer analizador
function countIt(test) { const numbers = test.split(''); const target = ' '; var i = 0; while (i < numbers.length) { if (numbers[i] === target) { numbers.splice(i, 1); } else { ++i; } } newNumbers = numbers; console.log(numbers); const newTarget = '$'; var i = 0; while (i < newNumbers.length) { if (newNumbers[i] === newTarget) { newNumbers.splice(i, 1); } else { ++i; } } console.log(newNumbers); finalNumbers = newNumbers; const finalTarget = '='; var i = 0; while (i < finalNumbers.length) { if (finalNumbers[i] === finalTarget) { finalNumbers.splice(i, 1); } else { ++i; } } console.log(finalNumbers); if (finalNumbers.length) firstNumber = finalNumbers[0]; secondNumber = finalNumbers[2]; resultNumber = finalNumbers[4]; const result = parseInt(firstNumber) + parseInt(finalNumbers[1]) if (parseInt(firstNumber) + parseInt(secondNumber ) == resultNumber) { console.log('+'); } else if (parseInt(firstNumber) - parseInt(secondNumber ) == resultNumber) { console.log('-'); } else if (parseInt(firstNumber) * parseInt(secondNumber ) == resultNumber) { console.log('*'); } else if (parseInt(firstNumber) / parseInt(secondNumber ) == resultNumber) { console.log('/'); } else { console.log('false'); } }
Pero hay tantos problemas que resolver, como 2 dígitos, o espacios en blanco faltantes después de la expresión, así que creo que mi solución está demasiado diseñada y no funciona correctamente de todos modos.
¿Tienes alguna solución mejor? Gracias por tus consejos ;)
Una forma de eludir el problema de los espacios en blanco sería (ab)utilizar el hecho de que parseInt()
es indulgente e ignora los espacios en blanco. Por supuesto, esto es un truco y no la forma en que generalmente debe escribir programas, pero en este caso es una solución bastante elegante.
const isReplaceable = (input) => { const [a, b, c] = input.split(/\$|=/).map(item => parseInt(item, 10)); return ( a * b === c || a / b === c || a + b === c || a - b === c ); }
const isReplaceable = (input) => { const [a, b, c] = input.split(/\$|=/).map(item => parseInt(item, 10)); return ( a * b === c || a / b === c || a + b === c || a - b === c ); } const TEST_STRINGS = [ '3 $ 5 = 8', '2 $ 6 = 3', '5$5=25', '2 $ 1 = 2', '3 $ 4 = 5', '6 $ 4 = 3', '3 $ 2 = 1', '4 $6= 24', '3$ 2= 6', '30$ 15 =2', ]; TEST_STRINGS.forEach(item => console.log(isReplaceable(item)));
Puedes hacerlo con expresiones regulares:
Busque los tres números e ignore los espacios en blanco. Si la cadena de prueba tiene un formato no válido (por ejemplo, contiene caracteres no válidos, sin operadores, muchos o pocos números, ...) devolverá false
inmediatamente, porque la expresión regular no puede coincidir.
De lo contrario, simplemente verifique si alguna de las cuatro operaciones en los dos primeros números da como resultado el tercer número...
const isReplaceable = (input) => { let match = /^\s*(\d+)\s*\$\s*(\d+)\s*=\s*(\d+)\s*$/.exec(input); if (!match) return false; return +match[1] + +match[2] == +match[3] || +match[1] - +match[2] == +match[3] || +match[1] * +match[2] == +match[3] || +match[1] / +match[2] == +match[3] } const TEST_STRINGS = [ '3 $ 5 = 8', '2 $ 6 = 3', '5$5=25', '2 $ 1 = 2', '3 $ 4 = 5', '6 $ 4 = 3', '3 $ 2 = 1', '4 $6= 24', '3$ 2= 6', '30$ 15 =2', ]; for (let t of TEST_STRINGS) console.log(t, isReplaceable(t));
let evalBySign = (first, second, answer, sign) => eval(`(${first}) ${sign} (${second})==${answer}`); let operation = { '+': function(first, second, answer) { //Way 1 return Number(first) + Number(second) == answer; }, '-': function(first, second, answer) { //Way 2 return eval(`(${first}) - (${second})==${answer}`); }, '*': function(first, second, answer) { //Way 2 as function return evalBySign(first, second, answer, '*'); } }; ['/', '%'].forEach(sign => { operation[sign] = function(first, second, answer) { return evalBySign(first, second, answer, sign); } }); function isReplacable(input) { input = input.replace(/\s+/g, ''); let validEq = /\d+\$\d+=\d+/.test(input); if(!validEq) return false; let numbers = input.split(/[\$=]/); if(numbers.length != 3) return false; let [first, second, answer] = numbers; let operationEntries = Object.entries(operation); let isReplacelable = false; for (let entry of operationEntries) { if(entry[1](first, second, answer)) { console.log(`${input} equation matched using '${entry[0]}' sign`); isReplacelable = true; break; } } return isReplacelable; } const TEST_STRINGS = [ '3 $ 5 = 8', '2 $ 6 = 3', '5$5=25', '2 $ 1 = 2', '3 $ 4 = 5', '6 $ 4 = 3', '3 $ 2 = 1', '4 $6= 24', '3$ 2= 6', '30$ 15 =2', '3 $ = 1 4', '2 3 5' ]; const runChecks = () => { TEST_STRINGS.forEach(expression => { console.log(`${expression}: ${isReplacable(expression) ? 'VALID' : 'INVALID'}`); }); }; runChecks();