# 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, 2015 at 10:35
• Related: this question. Dec 15, 2015 at 11:09
• @xnor If that wasn't the case, it would have been just a +7. I.e. "too broad" Sep 11, 2016 at 1:08
• @EriktheGolfer No. When I wrote that comment, my answer was the accepted one. Sep 11, 2016 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, 2015 at 13:46
• Here's a slightly shorter version: #+5[6,6,11][[#~Mod~4]]& Dec 15, 2015 at 19:34
• @ChipHurst very clever with 5[6, 6, 11][[0]] :) Dec 15, 2015 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, 2015 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, 2015 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, 2015 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, 2015 at 13:03
• I'd forgotten a byte. Try now.
– Lynn
Dec 15, 2015 at 13:04
• I edited the link, too.
– Lynn
Dec 15, 2015 at 13:05
• Cool, it works now Dec 15, 2015 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+")"

## 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> # 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. • Yep, I've added it to the post. – Lynn Dec 15, 2015 at 15:15 • Doesn't look right for years 2097 and 2098, which need additions of 7 and 12, respectively. Dec 15, 2015 at 15:17 • The OP says the input year is guaranteed to be in the 1970-2090 range. – Lynn Dec 15, 2015 at 15:18 • I really don't like questions that are changed after I've answered! Dec 15, 2015 at 15:19 • 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);? – Neil Dec 16, 2015 at 0:42 # Python 3, 14010010284.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 • I have updated the question. You need not check for century years. Dec 15, 2015 at 10:58 • How about w="SMTWTFSuouehranneduit" and then printing w[d(i)::7]? – Lynn Dec 15, 2015 at 12:14 ## 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: ,;;D45/*≈7@%;╝ƒ╗35*r+╛ƒ╜=M1@íu+ Try it online Explanation: ,;;D45/*≈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 # 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

## 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, 2015 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, 2015 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, 2015 at 17:19
• you can save 1 char by removing the first y=scan; and using x=y<-scan()+1 I think Dec 16, 2015 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, 2015 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, 2015 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, 2015 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, 2015 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, 2015 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, 2015 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, 2016 at 13:20
• @insertusernamehere Fixed. Jan 5, 2016 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.