Нахождение точного количества часов, минут, секунд от медианы массива общего количества секунд - PullRequest
0 голосов
/ 13 апреля 2019

Часть общей задачи, мне нужен мой код, чтобы найти медиану массива чисел (с четным или нечетным числом элементов), представляющих общее количество секунд, и преобразовать это число в массив, содержащий часы, минуты и секунды изобщее количество секунд.Код работает хорошо, но он не проходит тесты, особенно случайные тесты.В каждом случае общее количество секунд оказывается на единицу меньше или на единицу больше, чем показывает тест.

Как я могу решить эту проблему с помощью текущего кода или я должен сделать что-то совершенно другое?

Я пытался манипулировать кодом с помощью различных методов Math, но я все еще испытываю проблему, заключающуюся в том, что секунды на единицу выше или ниже правильного ответа.

Вот мой код:

concatInt = [ 3432, 4331, 7588, 8432 ]

let rawMedian = function (){

    if(concatInt.length === 0) return 0;

    concatInt.sort(function(a,b){
    return a-b;
    });

    var half = Math.floor(concatInt.length / 2);

    if (concatInt.length % 2)
    return concatInt[half];

    return (concatInt[half - 1] + concatInt[half]) / 2.0;
}

let toStopwatch = function(){
    let hours;
    let minutes;
    let seconds;

    if (rawMedian()/3600 > 1){
    hours = Math.floor(rawMedian()/3600);
    minutes = ((rawMedian() % 3600)/60);
    seconds = Math.floor((minutes - Math.floor(minutes)) * 60);

        if (seconds === 60){
            seconds = seconds -1;
        }

    } else {
    hours = 0;

    if (rawMedian() > 60){
        minutes = (rawMedian()/60);
        seconds = Math.floor((minutes - Math.floor(minutes)) * 60);

        if (seconds === 60){
            seconds = seconds -1;
        }

    } else {
        minutes = 0;
        seconds = rawMedian()
    }
    }

    let timesArr = [];

    timesArr.push(`${hours.toString()}`, `${Math.floor(minutes).toString()}`, `${seconds.toString()}`);
    return timesArr;
}

Результатом этого кода является ["1", "39", "19"].Однако в тестах Codewars Kata приведенный выше код показывает, что он некорректен, поскольку количество секунд на одну больше или меньше ожидаемого количества секунд.Я рад предоставить мой полный код и конкретное Ката, включенное по запросу, но приведенный выше код, очевидно, вызывает проблему.

1 Ответ

0 голосов
/ 13 апреля 2019

Есть несколько проблем, но первые две могут объяснить, почему вы получаете разницу в одну секунду:

  • Если массив concatInt имеет четное количество значений, медиана будет иметь полсекунды. Вы не сказали, что должно произойти с этой половиной секунды, но вы, кажется, усекаете это. Вполне может быть, что требование состоит в том, чтобы округлить это.

  • Способ вычисления секунд подвержен ошибкам с плавающей запятой:

    Math.floor((minutes - Math.floor(minutes)) * 60)
    

    Например, если minutes равно 8,6, то это выражение - до применения Math.floor - приведет к: 35.99999999999998 вместо 36. Вам следует избегать умножения на 60 там. Вместо этого вы можете просто получить количество секунд, подобное этому:

    median % 60
    
  • Вы звоните rawMedian несколько раз, что является пустой тратой времени. Просто вызовите его один раз и сохраните результат в переменной для дальнейшего использования.

  • Никогда не может быть, чтобы условие if (seconds === 60) выполнялось. Этот код можно удалить.
  • Другие конструкции if, которые вы использовали, также не нужны. Значение медианы больше 1 не имеет значения для расчета.
  • Кажется странным, что часы, минуты и секунды должны возвращаться в виде строк, а не чисел. Если это действительно так, то использование литералов шаблонов и , вызывающих метод toString(), является излишним. Достаточно одной из обеих стратегий.

Итак, предположив, что медиана должна быть округлена , вот как может выглядеть код:

const toStopwatch = function() {
    // Call rawMedian only once.
    // Round it (or if it needs to be truncated, use Math.floor).
    const median = Math.round(rawMedian());
    // Calculation of seconds should just be a modulo 60.
    // No special cases need to be distinguished.
    // Do not cast to strings, unless explicitly required
    return [
        Math.floor(median / 3600),        // hours
        Math.floor((median % 3600) / 60), // minutes
        median % 60                       // seconds
    ];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...