Помогите решить задачу javascript
Дана функция с тремя целыми числами. Задача - нужно отнимать от первого числа второе до тех пор пока значение не станет меньше третьего. Функция должна вернуть получившиеся значение, которое меньше третьего числа
function sum (a, b, c) {
do {
a = a - b;
} while (c < a);
return a;
}
sum(20, 3, 10);
При тестировании, решение проходит 3 теста из 5, что не так и как можно улучшить?
Ответы (5 шт):
// Дана функция с тремя целыми числами.
function f() {
console.log(123)
return 10 * 14
}
// нужно отнимать от первого числа второе до тех пор пока значение не станет меньше третьего
// Функция должна вернуть получившиеся значение, которое меньше третьего числа
function solve() {
var [a, b, c] = ("" + f).match(/-?\d+/g)
return Math.min(+a, (a % b + Math.trunc(c / b) * b) % c)
}
// Проверяем
console.log(solve())
function solution(a, b, c) {
// Если третье число больше, то ничего не нужно выполнять,
// возвращаем первое число
if (a < c) return a;
// Если первое и третье числа равны, то вернём первое - второе.
if (a == c) return a - b;
// для остальных случаев мы упростим вычисление, без циклов
// находим разницу между первым и третьим
// Добавляем единицу, чтобы результат был для числа меньшего, чем третье
const dif = a - c + 1;
// Вычислим сколько раз нужно отнять второе число из первого.
const num = Math.ceil(dif / b);
// и отнимем сразу без цикла сколько нужно раз второе число из первого.
let result = a - b * num;
return result;
}
function sum (a, b, c) {
while(a >= c){
a -= b;
}
return a;
}
console.log(sum(20, 3, 10)); // 8
Тест:
console.log(sum(20, 1, 10));
10
А должно быть меньше чем десять.
Тест:
console.log(sum(5, 1, 10));
4
А должно быть пять. Зачем вычитать если с самого начала a < c?
Если править ваш вариант, то будет так:
function sum(a, b, c) {
// do/while заменён на обычный while
// в условии нестрогое неравенство
while (c <= a) {
a = a - b;
}
return a;
}
Можно решить без цикла вовсе. (a - c + 1) - сколько единиц надо отнять минимум. Если меньше нуля, то ставим ноль: Math.max(0, ...).
(a - c + 1) / b - сколько шагов надо сделать. Округлять надо вверх: Math.ceil. Целое число шагов умножаем на b и вычитаем из a:
function sum(a, b, c) {
const f = Math.ceil(Math.max(0, a - c + 1) / b);
return a - f * b;
}
console.log(sum(20, 2, 10));
console.log(sum(5, 2, 10));
8 5
P.S. в предположении что b > 0. Иначе решение есть не всегда.
Прежде всего хочу сказать, что тестировать удобно тоже циклом. Если задать изменения числа а в пределах, скажем, от 5 до 30, а числа b и c оставлять без изменения, то можно будет отследить, какая будет разница в выполнении задачи с помощью цикла do while и цикла while:
function sum (a, b, c) {
do {
a = a - b;
} while (c < a);
return a;
}
function sum2(a, b, c) {
while (a >= c) {
a -= b;
}
return a;
}
let array = [];
for(i = 5; i < 20; i ++){
array.push(sum(i, 2, 10));
}
console.log(array);
array = [];
for(i = 5; i < 20; i ++){
array.push(sum2(i, 2, 10));
}
console.log(array);
Не трудно заметить, что с помощью do while даже если изначально а < c, то всё равно а не остаётся без изменений. А всё из-за того, что условие в do while проверяется после того, как происходит действие, значит получается, что действие должно выполниться как минимум один раз. От сюда вывод - цикл do while для решения этой задачи не очень подходит. Нужен цикл while.