Criar calculadora (JS)
Tenho uma linha calc(2).add(3).add(5).res()e preciso escrever uma solução para que eu tenha 10como resultado. Eu tentei isso
class Calc{
constructor(num){
this.num = num
}
add(a){
this.num += a;
return this;
}
res() {
return this.num;
}
}
let calc = new Calc(2)
console.log(calc.add(3).add(5).res())
mas no meu caso eu passo 2em new Calc(2), não in calc(2). Como posso mudá-lo?
Ficarei muito grato por qualquer ajuda!
Respostas
Você pode ter uma solução elegante aproveitando o poder das tampas:
function calc(x) {
return {
res: function() {
return x;
},
add: function(y) {
return calc(x + y)
}
}
}
test(
10,
calc(10).res()
);
test(
10,
calc(3).add(7).res()
);
test(
10,
calc(8).add(2).res()
);
test(
10,
calc(2).add(3).add(5).res()
);
function test(expected, actual) {
console.log(
`result is: ${actual} correct: ${actual === expected}
`)
}
A calcfunção pega o número inicial chamado xe retorna um objeto com dois métodos:
res()apenas retorna o númeroadd()pegará um parâmetroy, somará comxe chamarácalcnovamente com o resultado.
Portanto, sua interface é totalmente consistente: calc(10)será igual a calc(3).add(7)ou calc(8).add(2)ou calc(2).add(3).add(5). Você pode encadear as addchamadas quantas vezes quiser e sempre será o mesmo. Chamando res()vai acabar na cadeia e apenas dar-lhe o número que calcatualmente ocupa - se você fez calc(10).res()ou calc(2).add(3).add(5).res().
O código pode ser muito reduzido usando as funções de seta:
const calc = x => ({
res: () => x,
add: y => calc(x + y)
});
test(
10,
calc(10).res()
);
test(
10,
calc(3).add(7).res()
);
test(
10,
calc(8).add(2).res()
);
test(
10,
calc(2).add(3).add(5).res()
);
function test(expected, actual) {
console.log(
`result is: ${actual} correct: ${actual === expected}
`)
}
Outras operações também podem ser facilmente adicionadas usando o mesmo padrão:
const calc = x => ({
res: () => x,
add: y => calc(x + y),
sub: y => calc(x - y),
mul: y => calc(x * y),
div: y => calc(x / y)
});
test(
2,
calc(5).add(5).mul(2).sub(4).div(8).res()
// (((5 + 5) * 2) - 4) / 8 =
// ((10 * 2) - 4) / 8 =
// (20 - 4) / 8 =
// 16 / 8 = 2
);
function test(expected, actual) {
console.log(
`result is: ${actual} correct: ${actual === expected}
`)
}
Observe que, como cada operação é executada imediatamente, a única precedência que você tem atualmente é a que vem primeiro.
Se eu entendi bem, esta seria uma maneira de fazer isso:
class Calc{
constructor(num){
this.num = num
}
add(a){
this.num += a;
return this;
}
res() {
return this.num;
}
}
let calc = function(num){ return new Calc(num) }
console.log(calc(2).add(3).add(5).res())
Você pode definir uma calcfunção que retorna o objeto Calc.
class Calc{
constructor(num){
this.num = num
}
add(a){
this.num += a;
return this;
}
res() {
return this.num;
}
}
const calc = (input) => new Calc(input);
console.log(calc(2).add(3).add(5).res())