Функция високосного года; как работает это решение? - PullRequest
0 голосов
/ 06 ноября 2018

Проблема заключается в следующем:

Если указан год, сообщите, если это был високосный год.

Сложность в том, что в григорианском календаре происходит високосный год:

on every year that is evenly divisible by 4
  except every year that is evenly divisible by 100
    unless the year is also evenly divisible by 400

Мое решение (которое работает) было так:

export const isLeap = (year) => {
    const yearModFour = (year % 4) === 0 
    const yearModHundred = (year % 100) === 0
    const yearModFourHundred = (year % 400) === 0 
    const isLeapYear = yearModFour === yearModHundred === yearModFourHundred
    return isLeapYear
}

Я пришел к такому выводу, потому что скучаю по логике:

on every year that is evenly divisible by 4
  and also evenly divisible by 100
    and also evenly divisible by 400

Мой вопрос: почему это как-то работает?

Я не уверен, почему я не использовал && операнды, но опять же это не сработало бы так

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Я дам технический ответ.

Пусть A = делится на 4, B = делится на 100, C = делится на 400. Определение високосного года:

(A and (not B)) or C

Но вы написали:

(A === B) === C

Нам нужно спросить, являются ли эти формулы логически эквивалентными для всех возможных непротиворечивых значений A, B и C. Нам не нужно пробовать все комбинации A, B и C, потому что эти формулы НЕ логически эквивалентны в общем:

A  B  C   (A & !B)  (A & !B | C)    A==B   (A==B)==C
------------------------------------------------------
T  T  T     F            T          T        T
T  T  F     F            F          T        F 
T  F  T     T            T          F        F   x
T  F  F     T            T          F        T
F  T  T     F            T          F        F   x    
F  T  F     F            F          F        T   x
F  F  T     F            T          T        T 
F  F  F     F            F          T        F

ОДНАКО не все возможные значения A, B и C согласованы, так как они зависят друг от друга. Всякий раз, когда C истинно (делится на 400), остальные также должны быть. Всякий раз, когда B истинно, A также должно быть. Итак, единственные случаи, которые мы должны рассмотреть:

A  B  C   (A & !B)  (A & !B | C)    A==B   (A==B)==C
------------------------------------------------------
T  T  T     F            T          T        T
T  T  F     F            F          T        F 
T  F  F     T            T          F        T
F  F  F     F            F          T        F

Это только четыре возможных случая (TTT, TTF, TFF и FFF). В каждом из этих четырех случаев (A &! B | C) имеет то же значение истинности, что и (A == B) == C, поэтому ваш код работал.

В общем, формулы не эквивалентны друг другу, но в этом случае вы были в порядке.

0 голосов
/ 06 ноября 2018

Давайте посмотрим на предикат yearModFour === yearModHundred === yearModFourHundred и перечислим несколько чисел, которые приведут ко всем возможностям.

Для года 1 предикат оценивается как:

(False === False) === False
             True === False
                 False

Для года 4 предикат оценивается как:

(True === False) === False
           False === False
                 True

Для года 100 предикат оценивается как:

(True === True) === False
           True === False
               False

Для года 400 предикат оценивается как:

(True === True) === True
           True === True
                True

Теперь это все возможности, которых здесь больше не будет. Это потому, что любое число, делимое на 400, делится на 100, 4 и 1; все делимые на 100 тоже делятся на 4 и 1; и так далее.

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

...