[英]How could we get min of two recursive calls, one which adds, another which subtracts?
我们正在做这个编程练习:办公空间 #2 - 距离最近的三个。 声明是:
你喜欢在办公室听音乐。
由于您的同事健谈,您经常需要更改耳机的音量,而您发现自己使用键盘上的 + 和 - 来这样做。 每次击键时,这些键将音量增加和减少 2。 只有一个问题 - 您更喜欢可被 3 整除的数字。
有时您的同事很吵,有时他们正在吃午饭或上班迟到 - 相应地调整音量!
编写一个函数,接收当前音量并输出您必须按键盘上的 - 或 + 键的次数,以使音量成为可被 3 整除的数字。
在这个存在平面上,音乐不能低于 0 音量。
例如:volume = 8 : output = 1(按 - 键会带你到 6,它可以被 3 整除,而不是按两次 + 键会得到 12)
我们编写了以下代码:
function musicalOCD(volume) {
console.log("\n\nvolume: "+volume);
if(volume%3==0) return 0;
return Math.min(1+musicalOCD(volume+2),1+musicalOCD(volume-2));
}
然而,它仅通过基本案例测试,当体积可被 13 整除时。
如果我们传入其他卷,它会输出:
RangeError: Maximum call stack size exceeded
at Socket.Readable.removeListener (_stream_readable.js:852:47)
at write (console.js:172:12)
at Console.log (console.js:200:3)
at musicalOCD (test.js:5:11)
at musicalOCD (test.js:7:21)
作为踪迹:
volume: 2
volume: 4
volume: 6
volume: 2
volume: 4
volume: 6
所以我们可以编写代码来进行递归调用,将值添加到音量:
function musicalOCD(volume) {
console.log("\n\nvolume: "+volume);
if(volume%3==0) return 0;
return 1+musicalOCD(volume+2);
}
但是在以下测试中:
describe("Fixed tests", function() {
const testing = (volume, exp) => it(`Testing for ${volume}`, () => assert.strictEqual(musicalOCD(volume), exp));
testing(4, 1);
testing(12, 0);
testing(20, 1);
testing(22, 1);
testing(68, 1);
});
测试 20 和 68 将输出 2 而不是 1...
如果我们反过来做:
function musicalOCD(volume) {
console.log("\n\nvolume: "+volume);
if(volume%3==0) return 0;
return 1+musicalOCD(volume-2);
}
然后测试 22 和 4 将输出 2 而不是 1 ...
我们如何将两个递归调用结合到一个通用答案中?
我们已阅读:
const testing = (volume, exp) => { console.assert(musicalOCD(volume) === exp, 'Testing for ${volume} - failure'); }; testing(4, 1); testing(12, 0); testing(20, 1); testing(22, 1); testing(68, 1); console.log('Run tests - done'); function musicalOCD(volume) { return Math.min( // <------- will return min value of two tests _musicalOCD(volume, +2), _musicalOCD(volume, -2) ); } function _musicalOCD(volume, mod) { if (volume < 0) return 0; if (volume >= 100) return 0; //console.log("\\n\\nvolume: " + volume); if (volume % 3 == 0) return 0; return 1 + _musicalOCD(volume + mod, mod); }
您可以使用一种方法,通过测试递减forst然后递增来分叉递归调用。
function musicalOCD(volume) { if (volume % 3 === 0) return 0; return 1 + (musicalOCD(volume - 2) && musicalOCD(volume + 2)); } [[4, 1], [12, 0], [20, 1], [22, 1], [68, 1]].forEach(([v, r]) => console.log(v, musicalOCD(v), r));
带有测试说明。
function musicalOCD(volume, dir) { console.log(dir); if (volume % 3 === 0) return 0; return 1 + (musicalOCD(volume - 2, 'down') && musicalOCD(volume + 2, 'up')); } [[4, 1], [12, 0], [20, 1], [22, 1], [68, 1]].forEach(([v, r]) => console.log(v, musicalOCD(v), r));
.as-console-wrapper { max-height: 100% !important; top: 0; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.