[Question]
  [
[Halley's Comet](https://en.wikipedia.org/wiki/Halley%27s_Comet) is the only comet that may appear (i.e. become visible to the naked eye on Earth) twice in a human lifetime. The orbital period of Halley's Comet is not constant: it has varied between 75 to 79 Earth years since the first definite apparition was recorded in 240 BCE. This variability is mainly driven by gravitational interactions between the comet and the planets of the Solar System. For the three millennia up to the year 3000, Halley's Comet appeared, or is projected to appear, in the following years:
66, 141, 218, 295, 374, 451, 530, 607, 684, 760, 837, 912, 989, 1066, 1145, 1222, 1301, 1378, 1456, 1531, 1607, 1682, 1758, 1835, 1910, 1986, 2061, 2134, 2209, 2284, 2358, 2430, 2504, 2579, 2653, 2726, 2795, 2863, 2931, 3000
Apparitions beyond 2134 predicted using this [orbit simulator](http://orbitsimulator.com/gravitySimulatorCloud/simulations/1452654910254_halley.html). The simulations account for gravitational perturbations due to the planets but not for other effects, such as changes in the comet's outgassing rate, that also affect its orbit. See [here](https://forum.cosmoquest.org/showthread.php?164509-Future-apparitions-of-Comet-Halley) for further discussion.
### Task
Write a program or function that takes as input a positive integer up to 3000 (inclusive), representing a year, and outputs/returns the number of years until the next apparition of Halley's Comet. In other words, if the input year is \$y\$ and Halley's Comet next appears in year \$y\_\text{H}\ge y\$, find \$y\_\text{H}-y\$. The shortest code (in bytes) in each language wins.
### Test cases
```
   1 -> 65
1066 ->  0
1067 -> 78
1986 ->  0
1987 -> 74 
2021 -> 40
```
  
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), 74 bytes
```
n=>Buffer("BKMMOMOMMLMKMMOMOMNKLKLMKLKIKKJHJKJIEDDE").every(c=>(n-=c)>0)-n
```
[Try it online!](https://tio.run/##y0osSyxOLsosKNHNy09J/Z9m@z/P1s6pNC0ttUhDycnb19cfCH19fKEsP28fbyDHx9vT29vLw8vby9PVxcVVSVMvtSy1qFIj2dZOI0/XNlnTzkBTN@9/cn5ecX5Oql5OfrpGmoaCgoKhpqaCvr6CmSkXqpShgZkZRErBAFPKHCJlboEuZWmBU5elBUyXiQKanJGBEdQdJgb/AQ "JavaScript (Node.js) – Try It Online")
### Commented
```
n =>              // n = input year
  Buffer(         // build a buffer consisting of
    "BKMM...EDDE" // the year deltas encoded as ASCII codes
  )               // 'B' -> 66, + 'K' (75) -> 141, etc.
  .every(c =>     // for each value c in there:
    (n -= c)      //   subtract c from n
    > 0           //   and go on while the result is positive
  )               // end of every(), which yields false
  - n             // return -n
```
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 35 bytes
Uses second-order differences to reconstruct the years, which is 1 byte shorter than [first-order differences](https://tio.run/##AUUAuv9vc2FiaWX//@KAojnDisO6w4FEZVRjw4zigJrFkynDjsSARcWhy4bDjuKAojEy0LI2OCsuwqU2NitJLS7OlGT//zIwMjE).
```
•6?É@fô]öÔMƵ4^-•7в4-.¥75+.¥66+I-.Δd
```
[Try it online!](https://tio.run/##yy9OTMpM/f//UcMiM/vDnQ5ph7fEHt52eIrvsa0mcbpAUfMLm0x09Q4tNTfVBpJmZtqeunrnpqT8/29kYGQIAA "05AB1E – Try It Online")
```
•6...-•                    # compressed integer
       7в                  # convert to base 7
         4-                # subtract 4 from each
           .¥              # un-delta: cumulative sum with a 0 prepended
             75+           # add 75 to each; this is now the list of years between appearances
                .¥         # un-delta
                  66+      # add 66 to each; this is now the list of years of appearances
                     I-    # subtract the input year
                       .Δd # find the first non-negative integer
```
[Try it with step-by-step output!](https://tio.run/##jZHBSsNAEIbvPsVPrjallnQDBdGrBx9BYZOdNAvNbtidrXgQvHrvEwi@gKgPYMCj@Ay@SIxWWhotdI7DN//8/4z1MtPUtp@39@KkuTstmqeL5qVZnr89J5dx10WU26p25D0paMM0IzdFNDiOosFB@vGI7eposyDHYItMekK6hpO4z/qQsZM5I0HhbAWSebnGh68PfT6YWNGc5RR5qMJcsl4QfKhwpbmExAid0ZqMIrWxODnsqUilkE6@De6/75cR4j8xIf6Ine3OyiV1d6wD45rk5pTD96W62R4ptFE/eKGdZxhrYkOzVereJ9p2PBoffQE)
The part `.¥75+.¥66+` can be written with a loop at the same length as `„KBÇv.¥y+}`.
[Answer]
# [R](https://www.r-project.org/), ~~87~~ 81 bytes
```
(z=cumsum(utf8ToInt("BKMMOMOMMLMKMMOMOMNKLKLMKLKIKKJHJKJIEDDE"))-scan())[z>=0][1]
```
[Try it online!](https://tio.run/##K/r/X6PKNrk0t7g0V6O0JM0iJN8zr0RDycnb19cfCH19fKEsP28fbyDHx9vT29vLw8vby9PVxcVVSVNTtzg5MU9DUzO6ys7WIDbaMPa/kYGR4X8A "R – Try It Online")
[Answer]
# [MATL](https://github.com/lmendo/MATL), ~~45~~ 44 bytes
```
66 75'#AeXj=*pq5 Oe>3-u'F7Za4-,hYs]i-t0<~)X<
```
[Try it online!](https://tio.run/##y00syfn/38xMwdxUXdkxNSLLVqug0FTBP9XOWLdU3c08KtFEVycjsjg2U7fEwKZOM8Lm/38jAyNDAA) Or [verify all test cases](https://tio.run/##y00syfmf8N/MTMHcVF3ZMTUiy1aroNBUwT/Vzli3VN3NPCrRRFcnI7I4NlO3xMCmTjPC5r9LVEXIf0MuQwMzMxBhzmVoaWEGIsy5jAyMDAE).
### Explanation
This uses the *second*-order consecutive differences to compress the list of years.
```
66                   % Push 66
75                   % Push 75
'#AeXj=*pq5 Oe>3-u'  % Push this string
F7Za                 % Uncompress from base94 (printable ASCII except quote) to base 7
4-                   % Subtract 4. This is the 2nd-order difference of the list of years
,                    % Do twice
  h                  %   Concatenate (first time with 75, second time with 66)
  Ys                 %   Cumulative sum
]                    % End
i-                   % Subtract input element-wise
t                    % Duplicate
0<~                  % Logical index of non-negative values
)                    % Apply index to keep only non-negative values
X<                   % Minimum. Implicitly display 
```
[Answer]
# [Perl 5](https://www.perl.org/) `-p`, 73 bytes
```
$,=EDDEIJKJHJKKIKLKMLKLKNMOMOMMKMLMMOMOMMKB;$_-=ord chop$,while$_>0;s/-//
```
[Try it online!](https://tio.run/##K0gtyjH9/19Fx9bVxcXV08vby8PL29vT28fb1wdI@Pn6A6EvkOMLZTlZq8Tr2uYXpSgkZ@QXqOiUZ2TmpKrE2xlYF@vr6uv//2/IZWbIZWhpYcb1L7@gJDM/r/i/rq@pnoGhwX/dghwA "Perl 5 – Try It Online")
Uses the popular ASCII encoding but puts the first appearance (year 66) at the right side.
[Answer]
# [J](http://jsoftware.com/), 61 bytes
```
(3+/\@u:'BKMMOMOMMLMKMMOMOMNKLKLMKLKIKKJHJKJIEDDE')&(]-~I.{[)
```
[Try it online!](https://tio.run/##y/qvpKeepmBrpaCuoKNgoGAFxLp6Cs5BPm7/NYy19WMcSq3Unbx9ff2B0NfHF8ry8/bxBnJ8vD29vb08vLy9PF1dXFzVNdU0YnXrPPWqozX/a3JxpSZn5CuYmSrYKqQpAIEhRABoA0jA0MDMDCJgbgETMEdVYWkBU2ECE4CqMIGoMDIwMuT6DwA "J – Try It Online")
Noticed I independently came up with the same long constant Arnauld used in his answer, which is 66 prepended to the differences of the years, converted to Unicode code points `u:`.
The J code then converts back to a list of numbers `3 u:`, and scan sums those numbers `+/\@` to recover the original list of comet years.
We then find the "insert before" index `I.` of the program input within the list of comet years, and subtract the program input `]-~` from the actual comet list value at that same index `I.{[`.
[Answer]
# [Pyth](https://github.com/isaacg1/pyth), ~~85~~ ~~42~~ 41 bytes
```
-hg#Qt.u+NYCM+\B."BOÅ>+‘¸h`bÊ¹¹dtg"Z
```
[Try it online!](https://tio.run/##K6gsyfj/XzcjXTmwRK9U2y/S2Vc7xklPycmf/3CrnfahiYd2ZCQksR/uOrTz0E7hFL6S9HqlqP//jQyMDAE "Pyth – Try It Online")
---
Managed to shed 44 bytes by using [Arnauld](https://codegolf.stackexchange.com/users/58563/arnauld)'s delta string.
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), 80 bytes
```
-Fold[If[#>0,#-#2,#]&,#,36^^9cyu7y4a7m84jq6pihqeoy2jutbhh4~IntegerDigits~15+65]&
```
[Try it online!](https://tio.run/##HczBCoMgAIDhu68hdJmBurI6LHYYg26DHaPANU1j2Wp2kDFf3UWXj//0j9wqMXKrOx7kKcTX6fWsK1nDEiMYQ4pgEyGIjqxti86tmUt4NubJMLO3VrOYHB1W@1Aq8ZWxohfLRffafjxJDyxtonBbtLE1jEt53k7@3nHjv4AgQDBju9lmkbPdrSmmBPzCHw "Wolfram Language (Mathematica) – Try It Online")
The comet should be visible near its periapsis. Unfortunately, [`CometData`](https://reference.wolfram.com/language/ref/CometData.html) only includes the dates of the previous and next periapses (5 Feb 1986 and 31 May 2061).
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 42 bytes
```
Ｉ⌊Φ⁻ＥφΣＥ…”$↷↥CⅉＷＦ3⊖n↧JＮω∕υ³*Ｈ↨{Ｗ”⊕ι℅λＮ¬‹ι⁰
```
[Try it online!](https://tio.run/##LY1NDsIgGESvQrr6SDDRbt3Z1kiB1sQTIMWUhNKGHxNPj9Q4s3lvNqNm6dUqbc53b1yERoYIwjizpAWuxkbtd00BhNzgRdCj7Ds2H2V1M68bVBcmxFgquPjTwDgrwhllrL/1rKdd23YVQdQprxftop7AYEzQ6CfjpAWL8a7UbSkOaXmW292HNQLXIYAh6Ih/OedcH@tTPrztFw "Charcoal – Try It Online") Link is to verbose version of code. Also uses @Arnauld's string, although I didn't realise until I read @Jonah's answer. Explanation:
```
     φ                  Predefined variable 1000 (shorter than 40)
    Ｅ                   Map over implicit range
         ”...”          Compressed form of @Arnauld's string
        …               Truncate to length
               ι        Current index
              ⊕         Incremented
       Ｅ                Map over characters
                 λ      Current character
                ℅       Take the ordinal
      Σ                 Summed
   ⁻                    Vectorised subtract
                  Ｎ     Input year
  Φ                     Filter where
                     ι  Current value
                   ¬‹ ⁰ Is non-negative
 ⌊                      Take the minimum
Ｉ                       Cast to string
                        Implicitly print
```
[Answer]
# [Husk](https://github.com/barbuz/Husk), 47 bytes
```
-⁰ḟ≥⁰∫m+66ΘB14B95mo-30c"(p_45Ux2|!uvrA(C$TDL3W 
```
[Try it online!](https://tio.run/##yygtzv7/X/dR44aHO@Y/6lwKZDzqWJ2rbWZ2boaToYmTpWluvq6xQbKSRkG8iWlohVGNYmlZkaOGs0qIi49xuML///@NDIwMAQ "Husk – Try It Online")
No built-in numeric compression in [Husk](https://github.com/barbuz/Husk), so we encode the differences between Halley years as printable ASCII values.
Halley year differences are then reconstructed by subtracting 30 from the ASCII values, converting to base 95, getting base 14 digits and adding 66.
The Halley years are the cumulative sum of this: altogether `∫m+66ΘB14B95mo-30c"(p_45Ux2|!uvrA(C$TDL3W`  (where `"(p_45Ux2|!uvrA(C$TDL3W "` is the encoding string).
We then just retrive the first element greater-or-equal to the input (`ḟ≥⁰`), and subtract the input from this (`-⁰`).
[Answer]
# [Zsh](https://www.zsh.org/), 78 bytes
```
for ((a=-$1;a<0;a+=##$s[++i]))s=BKMMOMOMMLMKMMOMOMNKLKLMKLKIKKJHJKJIEDDE;<<<$a
```
[Try it online!](https://tio.run/##hVNNb9pAEL37V4xipGC@RDlic0gapBID6aGHSlUkL/aAVzK7rndoSqP@djrrdUnaAFnLnzPz9s28518mP6zbwfNhrStot8Wk3/oQimgYiu7E91vmW7crH4PATG7jxeKBj8V80Twt43nML/N4Fsf3n@7j@9n07m4aRlHUEoff4VMuC4QKRQbfw0zDGlr2rtDzxlF0Pf36eX6zvPkye1hee957uw8GAwfcZIJdYXMeVxAcv9vlw8e@oT2zsEWF1qXnAm4fuLx8kEqSFIU0CIlIgDRQjvy13FEPFG4EYea9LrHMLyK6mVgwaaBAYxhRKBh6l6m4/o8oBgkScyRkqJJqcxaCR3iqtbTCLSoGkgm0DYmKDAiCIchtWchUUrEPTmOyLHx9fIO5YVqWDyNSDmkuKpESVqDXlu0pLN8/N6i/WKnOsNSSeardduXAeGT0Av8Gl61zXgCRZa6eZ8cyvDN356bad7aYCSkoK8vG1nqdzlITdjpjmDmnFHuYQc6GT5xizqv8FATjGqZKoG/lIxYMzL8Cwgo5H9kPWQ/4UodWOtu7ntGzBuYkm5qMWTT@p5SmnN@DAdzuCAyriv@X1b63dsOfmO7Ysc0@dYyrqwzSQuzY46/z23bDKxRpDpKHLEhqdQUluyRw5J44X3G/ttB6UapGlxqrZ@MpO5t/lZdww4u7NuIHwghWe0IzOIyGo6H3Bw "Zsh – Try It Online")
I've had this answer prepared since this question was in the sandbox and I'm annoyed I missed it being posted
Explanation:
```
for ((a=-$1;a<0;a+=##$s[++i]))s=...;<<<$a
for ((     ;   ;            ))     ;       # C-style for loop
      a=-$1;                               # initialise `a` to the input, negated
            a<0;                           # while `a` is less than 0
                              s=...;       # set `s` to the string
                        ++i                # increment `i` (starts at 0 implicitly)
                     $s[   ]               # get the `i`th character of `s`
                   ##                      # get the codepoint number of that character
                a+=                        # add that to `a`
                                   ;<<<$a  # then print `a`
```
**Note**: Initially I had `s=...;for ((...)):;<<<$r` - setting s to the string beforehand, and the body of the
loop being `:` (do nothing). But since the body of the loop is executed before the third clause of the loop (the
"each iteration" part), and we only use `s` in that clause, we can put `s` in the body to save 2 bytes.
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal), 37 bytes
```
ɾ»«Ẏ⅛Ṁß)∞'₌›ṫh⁰ḟ†ṙ←⁰»12τ68+¦0p66+$Fhε
```
[Try it Online!](https://vyxal.pythonanywhere.com/#WyIiLCIiLCLJvsK7wqvhuo7ihZvhuYDDnyniiJ4n4oKM4oC64bmraOKBsOG4n+KAoOG5meKGkOKBsMK7MTLPhDY4K8KmMHA2NiskRmjOtSIsIiIsIjY3Il0=)
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 71 bytes
```
•1Ò}MKX…иv½ι„qā·&à©Dà|ãвìkPn…(l2ßrÏyO;¬VÕÏcw÷©ûëтÎBʒNdãA₄ΩΓ•3001вʒI@}αW
```
[Try it online!](https://tio.run/##AXwAg/9vc2FiaWX//@KAojHDkn1NS1jigKbQuHbCvc654oCeccSBwrcmw6DCqUTDoHzDo9Cyw6xrUG7igKYobDLDn3LDj3lPO8KsVsOVw49jd8O3wqnDu8Or0YLDjkLKkk5kw6NB4oKEzqnOk@KAojMwMDHQssqSSUB9zrFX//8x "05AB1E – Try It Online")
I know there's a shorter 05AB1E answer, but this uses a different method, so I thought it'd be interesting to see the comparison in byte lengths.
## Explained
```
•...•3001в          # Pushed compressed list of all years
          ʒI@}      # Keep only those >= the input year
              αW    # Push the smallest absolute difference amongst those values
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 34 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
“¡AMzⱮ⁽ƑẸÑ[NṀtR“¦Ṛ’b8+"6FŻ+66ÄḟḶḢ_
```
**[Try it online!](https://tio.run/##AUwAs/9qZWxsef//4oCcwqFBTXrisa7igb3GkeG6uMORW07huYB0UuKAnMKm4bma4oCZYjgrIjZGxbsrNjbDhOG4n@G4tuG4ol////8xMDY3 "Jelly – Try It Online")**
### How?
```
“...“¦Ṛ’b8+"6FŻ+66ÄḟḶḢ_ - Link: year
“...“¦Ṛ’                - list of base 250 integers = [18853782274514630143915309466833, 1683]
        b8              - convert to base 8  = [[3, 5, 5, 7, ..., 2, 1], [3, 2, 2, 3]]
            6           - six
          +"            - zip (implicitly wrapped 6 = [6]) with addition
                                             = [[9,11,11,13, ..., 8, 7], [3, 2, 2, 3]]
             F          - flatten            = [ 9,11,11,13, ..., 8, 7,   3, 2, 2, 3]
              Ż         - prepend zero    = [ 0, 9,11,11,13, ..., 8, 7,   3, 2, 2, 3]
               +66      - add 66          = [66,75,77,77,79, ...,74,73,  69,68,68,69]
                  Ä     - cumulative sums = [66,141,218,295,374, ...,2653,2726,2795,2863,2931,3000]
                    Ḷ   - lowered range (year) = [0,1,2,...,year-1] 
                   ḟ    - filter discard  - e.g. if year = 2860 then [2863,2931,3000]
                     Ḣ  - head                                        2863
                      _ - subtract (year)                                3
```
---
FWIW a port of [ovs's](https://codegolf.stackexchange.com/users/64121/ovs) [05AB1E answer](https://codegolf.stackexchange.com/a/217252/53748) using the second-difference (and also using the filter-out-lowered range technique above) is also 34:
```
“¬V>ƭṘḌƘH*O⁵i²Ọ’b7_4ÄŻ+75ÄŻ+66ḟḶḢ_
```
[Answer]
# [Core Maude](http://maude.cs.illinois.edu/w/index.php/The_Maude_System), ~~266~~ ~~263~~ ~~262~~ 204 bytes
```
mod H is pr LIST{Nat}. op n : Nat ~> Nat . vars A B C : Nat . eq n(A)= n(A 66
5710855311372188087909795024940117969860147607). eq n(A B C)= if A > B then
n(A(B +(C & 15)+ 68)(C >> 4))else sd(A,B)fi . endm
```
### Example Session
```
Maude> red n(1) .  --- Ex: 65
result NzNat: 65
Maude> red n(1066) .  --- Ex: 0
result Zero: 0
Maude> red n(1067) .  --- Ex: 78
result NzNat: 78
Maude> red n(1986) .  --- Ex: 0
result Zero: 0
Maude> red n(2021) .  --- Ex: 40
result NzNat: 40
Maude> red n(3000) .  --- Ex: 0
result Zero: 0
```
### Ungolfed
```
mod H is
    pr LIST{Nat} .
    op n : Nat ~> Nat .
    vars A B C : Nat .
    eq n(A) = n(A 66 5710855311372188087909795024940117969860147607) .
    eq n(A B C) =
        if A > B
            then n(A (B + (C & 15) + 68) (C >> 4))
            else sd(A, B)
        fi .
endm
```
The answer is obtained by reducing the function `n`, which takes the input year.
The large number encodes the differences between successive years (e.g., 141 - 66 = 75) *minus* 68, packed into a bitstring with 4 bits per value.
---
Shaved off 3 bytes by replacing two conditional equations with a single equation using `if_then_else_fi`.
Saved one more byte by deduplicating a long enough repeated sublist using a condition.
Saved 58 bytes by encoding the year differences as a bitstring (and a few other tweaks).
[Answer]
# [Python 2](https://docs.python.org/2/), 83 bytes
```
f=lambda y,t=0x46ba1298ab6f2234037bc64abb247ba8e61402:f(y-t%14-66,t/14)if y>0else-y
```
[Try it online!](https://tio.run/##PY3RjoMgFETf@Yr7sqkm0AJlUZvov0DFLAkqkbtJ@Xor3Y1vc@eemYkZf9ZF7vvUBzPb0UCm2POX0tYI2bXG6knKu@L3xj61MtZK1VjTOi0Ul4@pygy/hGJaU7wJVfsJ8sBdSI7l3c9x3RBSToRM6wbBLw78UoxrwtEvDwLHHrhXdE90I/Qwm1j5BemHvaYYPFYXNlzq@kA3l34DHtQxW@64Hejp9mcPLaUlRf@fOwAIYAPobyK41kUCL7IpsmmJ6NrT7do/VwGRXH5yir8B "Python 2 – Try It Online")
Stores the differences between the years (minus 66) as digits in a base-14 number `t`. Repeatedly subtracts the differences from the given year `y` until we gets a non-positive number (overshoot), in which case the answer is `-y`.
]