40
\$\begingroup\$

Your input will be a integer between 1970 and 2090 (inclusive), representing a year. Your program should output the next year on which New Years Day falls on the same day of the week as the input year.

Test Cases:

Below are the sample inputs and outputs

2001 => 2007
2047 => 2058
2014 => 2020
1970 => 1976
1971 => 1982
1977 => 1983
2006 => 2012

20% Bonus: Output the day of the week of New Years Day

2001 => 2007 (Mon)
2047 => 2058 (Tue)
2014 => 2020 (Wed)
1970 => 1976 (Thu)
1971 => 1982 (Fri)
1977 => 1983 (Sat)
2006 => 2012 (Sun)

30% Bonus: Output Advance Happy New Year, <year>

2010 => Advance Happy New Year, 2016

50% Bonus: Do both above bonuses

2010 => Advance Happy New Year, 2016 (Fri)

Write a program which reads input from STDIN or accepts command line arguments, or a function which takes an argument.

Note: Please add a link to test your code if possible.

Leaderboard:

    var QUESTION_ID=66656,OVERRIDE_USER=16196;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/66656/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
    body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}#answer-list{padding-right: 100px}
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

\$\endgroup\$
  • 6
    \$\begingroup\$ I feel like every single dates challenge requires doing the leap years calculation as a subproblem, and it's getting stale. \$\endgroup\$ – xnor Dec 15 '15 at 10:35
  • \$\begingroup\$ Related: this question. \$\endgroup\$ – Addison Crump Dec 15 '15 at 11:09
  • \$\begingroup\$ @xnor If that wasn't the case, it would have been just a +7. I.e. "too broad" \$\endgroup\$ – Erik the Outgolfer Sep 11 '16 at 1:08
  • \$\begingroup\$ @EriktheGolfer No. When I wrote that comment, my answer was the accepted one. \$\endgroup\$ – Dennis Sep 11 '16 at 1:37

32 Answers 32

1
\$\begingroup\$

Jelly, 9 bytes

%4*3%7+5+

This is a monadic chain that takes an integer command-line argument as input. It uses my (x+5+(x%4)**3%7) algorithm.

Try it here. Although that's the current version of Jelly, it also works in this version, which predates the challenge. (Thanks @Dennis!)

\$\endgroup\$
  • \$\begingroup\$ This is amazing! I can confirm that it works with this revision of the Jelly interpreter, which predates the challenge. \$\endgroup\$ – Dennis Jan 6 '16 at 22:21
31
\$\begingroup\$

Mathematica, 45 37 27 24 bytes

#+5[6,6,11][[#~Mod~4]]&

Improvements thanks to @MartinBüttner (10 bytes), and @ChipHurst (a further 3 bytes).

\$\endgroup\$
  • 7
    \$\begingroup\$ Oh, wow. Nobody seems to have noticed this pattern, but it works out. \$\endgroup\$ – Lynn Dec 15 '15 at 13:46
  • 4
    \$\begingroup\$ Here's a slightly shorter version: #+5[6,6,11][[#~Mod~4]]& \$\endgroup\$ – Chip Hurst Dec 15 '15 at 19:34
  • \$\begingroup\$ @ChipHurst very clever with 5[6, 6, 11][[0]] :) \$\endgroup\$ – martin Dec 15 '15 at 19:40
18
\$\begingroup\$

CJam, 21 12 11 bytes

{_9587Cb=+}

@martin found a very simple method!

Try it here.

EDIT: Thanks, Dennis!

\$\endgroup\$
  • 1
    \$\begingroup\$ @Mauris Could you add an explanation? \$\endgroup\$ – Vasu Adari Dec 16 '15 at 13:16
  • \$\begingroup\$ @Vasu: This code is an anonymous function that implements the same 5 6 6 11 trick used in other answers, but the list is encoded as "the digits of 9587 in base 12". \$\endgroup\$ – Lynn Dec 16 '15 at 19:10
  • \$\begingroup\$ Got it thanks. I wanted you to add an explanation so people who checks your answer can understand how it works w.r.t language. \$\endgroup\$ – Vasu Adari Dec 17 '15 at 5:10
10
\$\begingroup\$

gs2, 12 bytes

V@¶4☻s%☺♀i50

Translation of my CJam answer. Encoded in CP437 as usual. Try it online!

\$\endgroup\$
  • \$\begingroup\$ The link goes to code that produces 2spooky4me, and if I cut and paste the code above, I get the wrong year: imgur.com/VAkXT0k (by "wrong year", I mean I get one year earlier than the intended year) \$\endgroup\$ – question_asker Dec 15 '15 at 13:03
  • \$\begingroup\$ I'd forgotten a byte. Try now. \$\endgroup\$ – Lynn Dec 15 '15 at 13:04
  • \$\begingroup\$ I edited the link, too. \$\endgroup\$ – Lynn Dec 15 '15 at 13:05
  • \$\begingroup\$ Cool, it works now \$\endgroup\$ – question_asker Dec 15 '15 at 13:05
8
\$\begingroup\$

JavaScript (ES6), 50 49 20 bytes (no bonuses)

a=>a+[5,6,6,11][a%4]

The algorithm by @martin proves to be much smaller, so I went with it.

I chose a mathematical approach because JavaScript tends to be verbose. The code is short enough that bonuses only make it longer.

Here is my previous answer (49 bytes), and my original answer (50 bytes):

F=(a,b=a)=>((a+--a/4|0)-(b++/4+b|0))%7?F(++a,b):b

F=(a,b=a)=>(f=c=>(c--+c/4|0)%7)(a)-f(++b)?F(a,b):b

They work by taking the year and calculating a number (0-6) to represent the "starting day of year". Because the date range for this challenge is within the range of years that follow simple leap year rules (no skipping on 2000), it's fairly straightforward to calculate. Then it's just a matter of comparing forward to find years that start with the same value. Recursion proved to be the most concise way to do this.

\$\endgroup\$
7
\$\begingroup\$

Pyth, 14 12 11 bytes

+QC@"♣♠♠♂"Q

The four bytes in the string should be 05 06 06 0B.

EDIT: Thanks, FryAmTheEggman!

EDIT: Thanks, Dennis!

\$\endgroup\$
6
\$\begingroup\$

JavaScript (ES6), 104 bytes - 50% bonus = 52

y=>eval('for(a=0;a!=(b=(new Date(""+y++)+"").slice(0,3));a=a||b)`Advance Happy New Year, ${y} (`')+b+")"

Explanation

y=>
  eval(`                  // eval enables for loop without {} or return
    for(
      a=0;                // a = first day of input year
      a!=                 // check if the day of the current year is equal to the first
        (b=(new Date(     // b = day of current year
          ""+y++)+"")     // cast everything as strings!
            .slice(0,3)); // the first 3 letters of the date string are the day name
      a=a||b              // set a to the day on the first iteration
    )

      // return the string
      \`Advance Happy New Year, \${y} (\`
  `)+b+")"

Test

var solution = y=>eval('for(a=0;a!=(b=(new Date(""+y++)+"").slice(0,3));a=a||b)`Advance Happy New Year, ${y} (`')+b+")"
<input type="text" id="input" value="2001" />
<button onclick="result.textContent=solution(+input.value)">Go</button>
<pre id="result"></pre>

\$\endgroup\$
6
\$\begingroup\$

Z80 machine code, 12 bytes

A Z80 procedure to be stored at 0000h, called with the input in HL, and all other registers clear:

.org 0000h
              ; Bytes   ; Explanation
  ;---------------------------------------------------------------
  DEC B       ; 05      ; 
  LD B, 6     ; 06 06   ;   
  DEC BC      ; 0B      ;
  LD A, 3     ; 3E 03   ;   A = 3
  AND L       ; A5      ;   A = input & 3
  LD E, A     ; 5F      ;   A = input & 3     DE = input & 3
  LD A, (DE)  ; 1A      ;   A = [input & 3]   DE = input & 3
  LD E, A     ; 5F      ;   A = [input & 3]   DE = [input & 3]
  ADD HL, DE  ; 19      ;   HL = input + offset
  RET         ; C9      ;

The first three instructions are "NOPs", but are indexed as data later in the code. Upon returning, the output is in HL.

\$\endgroup\$
  • \$\begingroup\$ Yep, I've added it to the post. \$\endgroup\$ – Lynn Dec 15 '15 at 15:15
  • \$\begingroup\$ Doesn't look right for years 2097 and 2098, which need additions of 7 and 12, respectively. \$\endgroup\$ – Toby Speight Dec 15 '15 at 15:17
  • 1
    \$\begingroup\$ The OP says the input year is guaranteed to be in the 1970-2090 range. \$\endgroup\$ – Lynn Dec 15 '15 at 15:18
  • 6
    \$\begingroup\$ I really don't like questions that are changed after I've answered! \$\endgroup\$ – Toby Speight Dec 15 '15 at 15:19
  • 2
    \$\begingroup\$ Are you allowed to specify that the input is in DE and therefore you can use LD A, 3; AND E; LD L, A; LD L, (HL);? \$\endgroup\$ – Neil Dec 16 '15 at 0:42
5
\$\begingroup\$

Python 3, 140 100 102 84.5 154 * 0.5 = 77 bytes

I could probably write a better solution with Sakamoto's algorithm, but this will do for now

I was right. Here's an implementation using Sakamoto's algorithm.

def s(y):
 d=lambda j:(j+j//4)%7
 for i in range(y,y+15):
  if d(i)==d(y-1):return"Advance Happy New Year, %d (%s)"%(-~i,"SMTWTFSuouehranneduit"[d(i)::7])

Explanation:

def day_of_the_week(year):
    return (year + year//4 - 1 + 0 + 1) % 7
    # The month code for January is 0, and you add 1 from January *1*.
    # The -1 is to correct for starting on Saturday 
    # and so that it cancels out the 1 from January 1.

def new_years(this_year):
# But in Sakamoto's algorithm, if the month is January or February, we must subtract 1.
    weekdays = "SunMonTueWedThuFriSat"
    for item in range(this_year, this_year + 15):
        if day_of_the_week(this_year - 1) == day_of_the_week(item):
            day = weekdays[day_of_the_week(item)*3 : day_of_the_week(item)*3+3]
            return "Advance Happy New Year, %d (%s)"%(item + 1, day)
        # So we subtract from every year we check, including this_year
        # And add 1 back in at the end
        # And print the greeting, the year, and the corresponding day of the week
\$\endgroup\$
  • \$\begingroup\$ I have updated the question. You need not check for century years. \$\endgroup\$ – Vasu Adari Dec 15 '15 at 10:58
  • 1
    \$\begingroup\$ How about w="SMTWTFSuouehranneduit" and then printing w[d(i)::7]? \$\endgroup\$ – Lynn Dec 15 '15 at 12:14
4
\$\begingroup\$

Seriously, 35 17 bytes

[5,6,6,11] trick saves the day.

4,;)%[5,6,6,11]E+

Try it online

Explanation:

4,;)%[5,6,6,11]E+
4,;)%              push input, input % 4
     [5,6,6,11]E   push (input % 4)th element of [5,6,6,11]
                +  add to the input

Old version:

,;;D`45/*≈7@%`;╝ƒ╗35*r+`╛ƒ╜=`M1@íu+

Try it online

Explanation:

,;;D`45/*≈7@%`;╝ƒ╗35*r+`╛ƒ╜=`M1@íu+
,;;                                  push 3 copies of the input (n)
   D                                 decrement the top copy of n
    `45/*≈7@%`;╝                     push Sakamoto's algorithm as a function and save a copy in register 1
                ƒ╗                   call Sakamoto's algorithm function and save result in register 0
                  35*r+              push [n, n+1, ..., n+14]
                       `    `M       map the function:
                        ╛ƒ╜=           push Sakamoto's algorithm, call, push 1 if equal to value in register 0 else 0
                              1@í    get the index of the first 1
                                 u+  increment and add n

Sakamoto's algorithm:

45/*≈7@%
45/*      multiply by 5/4
    ≈     floor
     7@%  mod 7
\$\endgroup\$
4
\$\begingroup\$

C, 31 bytes

Following the edit to the question that restricts the input range to 1970-2090, this becomes pretty trivial:

f(x){return"\5\6\6\13"[x%4]+x;}

Without the non-leap century years, there's a simple 5,6,6,11 sequence of intervals for the first repeat of the same day.

Complete solution to original problem (not constrained to 2090), 90 bytes:

f(x){return(x-1)%100>89&&(x+9)/100%4?"\6\14\5\6\6\6\6\7\14\6"[x%10]+x:"\5\6\6\13"[x%4]+x;}

Test program:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    while (*++argv)
        printf("Advance Happy New Year, %d\n", f(atoi(*argv)));
    return !argc;
}

Test run:

$ ./66656 2001 2047 2014 1970 1971 1977 2006
Advance Happy New Year, 2007
Advance Happy New Year, 2058
Advance Happy New Year, 2020
Advance Happy New Year, 1976
Advance Happy New Year, 1982
Advance Happy New Year, 1983
Advance Happy New Year, 2012
\$\endgroup\$
4
\$\begingroup\$

R, 143 136 * 0.5 = 68 bytes

G=function(y)strftime(paste(y,1,1,sep='-'),'%a')
d=seq(y<-scan(),y+14);sprintf("Advance Happy New Year, %i (%s)",d[G(d)==(w=G(y))][2],w)

Use %A for full day name instead of `%a, depend on desired state.

R, 120 * 0.7 = 84 bytes

G=function(y)as.POSIXlt(paste(y,1),,"%Y %j")$wday
d=seq(y<-scan(),y+14);cat("Advance Happy New Year,",d[G(d)==G(y)][2])

R, 90 bytes

G=function(y)as.POSIXlt(paste(y,1),,"%Y %j")$wday
d=seq(y<-scan(),y+14);d[G(d)==G(y)][2]

All answers above are derivative work based on @plannapus answer. Using the ; separator to avoid needing to source the file or run it as script on command line.

\$\endgroup\$
  • 1
    \$\begingroup\$ +1 I completely forgot about weekdays, nice. \$\endgroup\$ – plannapus Dec 17 '15 at 9:19
  • \$\begingroup\$ @plannapus Thanks :) (I counted the newlines, asked the file system in fact, as I'm under windows it's 2 bytes but I've no newline at end which a POSIX file should have, so it's fair to keep it like this actually) \$\endgroup\$ – Tensibai Dec 17 '15 at 9:36
3
\$\begingroup\$

R, 145 bytes -50% -> 72.5

y=scan();F=function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%a");x=y+1;while(F(x)!=F(y))x=x+1;sprintf("Advance Happy New Year, %i (%s)",x,F(x))

Examples:

> y=scan();F=function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%a");x=y+1;while(F(x)!=F(y))x=x+1;sprintf("Advance Happy New Year, %i (%s)",x,F(x))
1: 2006
2: 
Read 1 item
[1] "Advance Happy New Year, 2012 (Sun)"
> y=scan();F=function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%a");x=y+1;while(F(x)!=F(y))x=x+1;sprintf("Advance Happy New Year, %i (%s)",x,F(x))
1: 1977
2: 
Read 1 item
[1] "Advance Happy New Year, 1983 (Sat)"
> y=scan();F=function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%a");x=y+1;while(F(x)!=F(y))x=x+1;sprintf("Advance Happy New Year, %i (%s)",x,F(x))
1: 2014
2: 
Read 1 item
[1] "Advance Happy New Year, 2020 (Wed)"

R, 97 bytes (without bonus)

y=scan();F=function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%w");x=y+1;while(F(x)!=F(y))x=x+1;x

Indented, with new lines:

y = scan() #Takes input from stdin
F = function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%w") #Year to Weekday
x = y+1
while(F(x) != F(y)) x = x+1
x

Test cases:

> y=scan();F=function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%w");x=y+1;while(F(x)!=F(y))x=x+1;x
1: 1977
2: 
Read 1 item
[1] 1983
> y=scan();F=function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%w");x=y+1;while(F(x)!=F(y))x=x+1;x
1: 2006
2: 
Read 1 item
[1] 2012
> y=scan();F=function(y)format(as.POSIXct(paste(y,1),,"%Y %j"),"%w");x=y+1;while(F(x)!=F(y))x=x+1;x
1: 2016
2: 
Read 1 item
[1] 2021
\$\endgroup\$
  • \$\begingroup\$ I don't understand this wish of getting on one ugly line, a carriage return is not most costly than a ; ... \$\endgroup\$ – Tensibai Dec 16 '15 at 17:19
  • \$\begingroup\$ you can save 1 char by removing the first y=scan; and using x=y<-scan()+1 I think \$\endgroup\$ – Tensibai Dec 16 '15 at 17:25
  • \$\begingroup\$ and you can save seven more by using as.POSIXlt(paste(y,1),,"%Y %j")$wday as your function body \$\endgroup\$ – Tensibai Dec 16 '15 at 17:53
  • \$\begingroup\$ @Tensibai if you don t put it on one single line and paste it directly to the console, scan will read in the second line as the input. x=y<-scan()+1 with 2014 as stdin will give you x=2015 and y=2015 ( i. e. the assignment is y <- scan()+1) and if you try to do x=1+y<-scan() it will give you an error (Error in 1 + y <- scan() : target of assignment expands to non-language object) because it's trying to assign scan() to 1+y. \$\endgroup\$ – plannapus Dec 17 '15 at 7:47
  • \$\begingroup\$ @Tensibai As for your last advice, the results of ...$wday is the weekday number: but here i need the weekday name so that i can print Advance Happy New Year, 2012 (Sun) \$\endgroup\$ – plannapus Dec 17 '15 at 7:51
3
\$\begingroup\$

VBA, 130 * 0.50 = 65 Bytes

Sub k(y)
i=1
Do While Weekday(y+i)<>Weekday(y)
i=i+1
Loop
MsgBox "Advance Happy New Year," &y+i &WeekdayName(Weekday(y+i))
End Sub

VBA makes finding week days so easy.... If only it wasn't so Verbose about it.

\$\endgroup\$
3
\$\begingroup\$

PHP, 120 139 bytes - 50% = 60 bytes

A functional approach:

$s=strtotime;for($d=date(D,$s(($y=$argv[1]).$_="-1-1"));$d!=date(D,$s(++$y.$_)););echo"Advance Happy New Year, $y ($d)";

Takes one input from command line, like:

$ php ahny.php 2001

The OOP way seems to be longer, as always (143 bytes):

$s=strtotime;for($d=date(D,$s($x=($y=$argv[1])."-1-1"));$d!=date(D,$s(++$y."-1-1")););echo"Advance Happy New Year, $y ($d)";

Edits

  • Saved 18 bytes. Instead of adding one year using the PHP modifier +1year, I now simply increment the given year.
  • Saved 1 byte by storing -1-1 in a variable.
\$\endgroup\$
3
\$\begingroup\$

C, score 53 52 (104 bytes)

f(x){x+="0116"[x%4];printf("Advance Happy New Year, %d (%.3s)",x-43,"MonTueWedThuFriSatSun"+x*5/4%7*3);}

Idea borrowed from Toby Speight; added the bonus display of weekday.

Shortened the string by shifting the character codes to a more comfortable range. Had to choose the right shifting amount (e.g. 43) to make the short weekday calculation code x*5/4%7 work.

\$\endgroup\$
  • \$\begingroup\$ I take it your character code stuff restricts this to ASCII-compatible encodings? \$\endgroup\$ – Toby Speight Dec 16 '15 at 11:53
  • \$\begingroup\$ Yes. The codes should be greater than 31, so the minimal number to add to the codes would be 27, giving the string " !!&". \$\endgroup\$ – anatolyg Dec 16 '15 at 12:16
2
\$\begingroup\$

Mathematica, 145 * 50% = 74 73.5 72.5 bytes

d=DateValue;StringForm["Advance Happy New Year, `` (``)",NestWhile[#+1&,(a=#)+1,#!=#2&@@DateObject@{{a},{#}}~d~"DayName"&],{a}~d~"DayNameShort"]&

Uses standard date functions.

\$\endgroup\$
2
\$\begingroup\$

Pyth, 23 bytes

L%+/b4b7.VQIqyby-Q1+1bB

Doesn't qualify for any of the bonuses.

Try it here.

Similar to the pure python answer.

                        - Q = eval(input()) (autoassigned)
L                       - y = lambda b:
   /b4                  - b floordiv 4
  +   b                 - + b
 %     7                - mod 7


        .VQ             - for b in range(Q, infinate):
           Iqyby-Q1     - if y(b) == y(Q-1):
                   +1b  - print b+1
                      B - break
\$\endgroup\$
2
\$\begingroup\$

Java, (1-.2)*323 (1-.5)*350 348 339 = 258.4 175 174 169.5 bytes

import java.text.*;class D{public static void main(String[]a){long y=new Long(a[0]);int i=0;for(;!s(y).equals(s(y+(++i))););System.out.printf("Advance Happy New Year, %d (%s)",y+i,s(y+i));}static String s(long y){try{return new SimpleDateFormat("E").format(new SimpleDateFormat("d/M/yyyy").parse("1/1/"+y));}catch(Exception e){}return"";}}

Ugh.

Ungolfed:

import java.text.*;
class D{
    public static void main(String[]a){
        long y=new Long(a[0]);
        int i=0;
        for(;!s(y).equals(s(y+(++i))););
        System.out.printf("Advance Happy New Year, %i (%s)",y+i,s(y+i));
    }
    static String s(long y){
        try{
            return new SimpleDateFormat("E").format(new SimpleDateFormat("d/M/yyyy").parse("1/1/"+y));
        }catch(Exception e){}
        return"";
    }
}

Try it online!

Thanks to @Kenney for pointing out that I could shorten with new Long and printf! :D

\$\endgroup\$
  • \$\begingroup\$ long y=new Long(a[0]) saves 6 (12) bytes, and using printf saves another 3 (6). \$\endgroup\$ – Kenney Dec 15 '15 at 14:28
2
\$\begingroup\$

GNU coreutils, 52 51 49 bytes

(98 bytes program - 50% bonus)

seq -f$1-1-1\ %gyear 28|date -f- +'Advance Happy New Year, %Y (%a)'|sed /`date -d$1-1-1 +%a`/!d\;q

Input is from command-line argument, and output is to stdout.

Explanation

# generate 28 input years from $1 + 1 onwards (28 is always enough)
seq -f '$1-1-1 %g year' 28
|
# convert all of these as potential outputs
date -f- +'Advance Happy New Year, %Y (%a)'
|
 # Select the first one where the dayname matches that of input year
sed "/`date -d$1-1-1 +%a`/!d;q"

Test run:

All locale settings can be C or POSIX.

$ for i in 2001 2047 2014 1970 1971 1977 2006; do ./66656.sh $i; done
Advance Happy New Year, 2007 (Mon)
Advance Happy New Year, 2058 (Tue)
Advance Happy New Year, 2020 (Wed)
Advance Happy New Year, 1976 (Thu)
Advance Happy New Year, 1982 (Fri)
Advance Happy New Year, 1983 (Sat)
Advance Happy New Year, 2012 (Sun)

Limitation: this only works up to year 2147485519 (though the question is now changed to permit a lower limit).

\$\endgroup\$
2
\$\begingroup\$

MATL, 28 bytes

i0:14+t1tI$YO8H$XO!st1)=f2))

Example

>> matl i0:14+t1tI$YO8H$XO!st1)=f2))
> 1970
1976

Code explained

i           % input year
0:14+       % vector with that year and the next 14
t1tI$YO     % first day of each year
8H$XO       % transform into three letters specifying weekday
!s          % sum those three letters to reduce to unique numbers
t1)         % get first of those numbers (corresponding to input year)
=f2)        % find index of second matching
)           % index with that to obtain output year
\$\endgroup\$
2
\$\begingroup\$

Perl 6,  70  23 bytes

{($^a+1...{[==] ($a,$_).map: {Date.new(:year($_)).day-of-week}})[*-1]} # 70 bytes

{($_ X+5,6,6,11)[$_%4]} # 23 bytes

usage:

for «2001 2047 2014 1970 1971 1977 2006 2010» {
  printf "%d => %d\n", $_, {($_ X+5,6,6,11)[$_%4]}( $_ )
}
2001 => 2007
2047 => 2058
2014 => 2020
1970 => 1976
1971 => 1982
1977 => 1983
2006 => 2012
2010 => 2016
\$\endgroup\$
2
\$\begingroup\$

J, 14 bytes

+5 6 6 11{~4&|
\$\endgroup\$
2
+50
\$\begingroup\$

Japt, 12 bytes

U+"♣♠♠♂"cU%4

As with the Pyth answer, the four bytes in the string should be 05 06 06 0B. Try it online!

U+"♣♠♠♂"cU%4  // Implicit: U = input integer
  "♣♠♠♂"      // Take this string.
        cU%4  // Take the char code at U%4.
U+            // Add U.
              // Implicit: output last expression
\$\endgroup\$
  • 2
    \$\begingroup\$ Thanks for this Christmas gift of a bounty! But can someone tell me how I earned it? \$\endgroup\$ – ETHproductions Dec 25 '15 at 13:08
  • \$\begingroup\$ I looked through the history. Apparently the OP attempted to bounty an answer, but forgot to award the bounty, so Community chose to pass half the reputation onto this answer (I think it bases its choice on recent upvotes). \$\endgroup\$ – user62131 May 9 '17 at 7:15
2
\$\begingroup\$

Jelly, 14 bytes

%4=0,3×-,5S++6

Try it online!

Until today, Jelly had no array indexing, so the above will have to do. Since the latest commit, array indexing has been implemented as , giving the following solution (10 bytes).

ị6,6,11,5+

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ I think Jelly can spare 7 characters for 10~16 constants. \$\endgroup\$ – lirtosiast Dec 16 '15 at 1:36
2
\$\begingroup\$

Pyth, 35 bytes

Iq%Q4 3=+Q11).?Iq%Q4 0=+Q5).?=+Q6;Q

Try it online.

\$\endgroup\$
1
\$\begingroup\$

C# (6.0) .Net Framework 4.6 173 Bytes - 30% = 121.1 Bytes

void n(int y)=>Console.Write($"Advance Happy New Year, {Enumerable.Range(1,15).Select(i=>new DateTime(y+i,1,1)).First(x=>x.DayOfWeek==new DateTime(y,1,1).DayOfWeek).Year}");
\$\endgroup\$
1
+200
\$\begingroup\$

Javascript ES7, 17 bytes

a=>a+5+(a%4)**3%7

It's my first time using JS. I found this using a Python script, and I believe it to be optimal. It works because 0**3 is 0 mod 7, 1**3 and 2**3 are both 1, and 3**3 is 6.

\$\endgroup\$
1
\$\begingroup\$

Python, 23 bytes

lambda a:a+5+(a%4)**3%7

A port of my JavaScript answer.

\$\endgroup\$
1
\$\begingroup\$

Pyth, 12 bytes

++5%^%Q4 3 7

Try it online! or Check out the Test Suite.

Pyth, 18 bytes

This second approach is mainly a golf of @wizzwizz4's Pyth answer.

J%Q4+?q3J11?qJZ5 6

Try it online! or Check out the Test Suite.


Explanation

++5%^%Q4 3 7Q  - Q means evaluated input and is implicit at the end.

     %Q4       - Input mod 4.
    ^    3     - Cubed.
   %       7   - Mod 7.
 +5            - Plus 5
+           Q  - Plus the input.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.