闰年功能;这个解决方案是如何工作的?

Leap year function; how does this solution work?

问题是这样的:

给定一个年份,报告它是否是闰年。

这里棘手的是公历中出现闰年:

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

我的问题是,为什么这会以某种方式起作用?

我不确定我为什么不使用 && 操作数,但话又说回来它不会那样工作

让我们看一下谓词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 整除;等等。

所以你的结论不太正确,因为它暗示所有模运算之间的逻辑 "and"。

我来技术解答

令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 具有相同的真值,因此您的代码有效。

一般来说,公式之间并不等价,但在这种情况下,你没问题。