# Advance Happy New Year, 2016!

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.

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

## Mathematica, 453727 24 bytes

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

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

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

# CJam, 2112 11 bytes

{_9587Cb=+}

@martin found a very simple method!

Try it here.

EDIT: Thanks, Dennis!

• @Mauris Could you add an explanation? Dec 16 '15 at 13:16
• @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".
– Lynn
Dec 16 '15 at 19:10
• 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. Dec 17 '15 at 5:10

# gs2, 12 bytes

V@¶4☻s%☺♀i50

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

• 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) Dec 15 '15 at 13:03
• I'd forgotten a byte. Try now.
– Lynn
Dec 15 '15 at 13:04
• I edited the link, too.
– Lynn
Dec 15 '15 at 13:05
• Cool, it works now Dec 15 '15 at 13:05

# JavaScript (ES6), 5049 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.

# Pyth, 1412 11 bytes

+QC@"♣♠♠♂"Q

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

EDIT: Thanks, FryAmTheEggman!

EDIT: Thanks, Dennis!

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

)+b+")"

## 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.

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.

• +1 I completely forgot about weekdays, nice. Dec 17 '15 at 9:19
• @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) Dec 17 '15 at 9:36

# 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:
[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:
[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:
[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:
[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:
[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:
[1] 2021
• I don't understand this wish of getting on one ugly line, a carriage return is not most costly than a ; ... Dec 16 '15 at 17:19
• you can save 1 char by removing the first y=scan; and using x=y<-scan()+1 I think Dec 16 '15 at 17:25
• and you can save seven more by using as.POSIXlt(paste(y,1),,"%Y %j")$wday as your function body Dec 16 '15 at 17:53 • @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. Dec 17 '15 at 7:47 • @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) Dec 17 '15 at 7:51

# 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.

# 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.

# 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.

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

## Mathematica, 145 * 50% = 7473.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.

## 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

# Java, (1-.2)*323 (1-.5)*350348 339 = 258.4175174 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

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

# GNU coreutils, 5251 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

## 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.

• Isn't the Exponentiation Operator ** an ES7 feature? Or are you using Babel? Jan 4 '16 at 13:20
• @insertusernamehere Fixed. Jan 5 '16 at 19:05

## Python, 23 bytes

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

A port of my JavaScript answer.

++5%^%Q4 3 7

# Pyth, 18 bytes

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

J%Q4+?q3J11?qJZ5 6

# 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.