我们正在做这个编程练习:一个办公空间#2 -离Twos最近的三个。声明如下:
你喜欢在办公室听音乐。 你经常需要改变耳机的音量,这要归功于你健谈的同事,你发现自己是用键盘上的+和-来这样做的。按键每击一次,音量增加和减少2。只有一个问题--你更喜欢被3整除的数字。 有时你的同事很大声,而其他时候,他们在午餐或工作迟到-相应地调整音量! 编写一个函数,接收当前卷,并输出您必须按键盘上的-或+键的次数,以使音量成为一个可被3除的数字。 在这个存在的平面上,音乐不能低于0。 例:音量=8:输出=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.
我们如何将这两个递归调用合并到一个一般的答案中?
我们读到:
发布于 2020-03-22 10:24:42
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);
}
发布于 2020-03-22 11:16:53
您可以使用一种方法,通过测试、递减、增强、然后递增来推进递归调用。
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; }
https://stackoverflow.com/questions/60798063
复制相似问题