What year is it?

9

0

It is December 2014, and 2015 has almost started. However, it appears not everyone has realized this.

Jon: “2009 has sure been a long year” | Garfield looks at calendar | Garfield: “We gotta get a new calendar”

But the people of PPCG come to the rescue!

Input

Your program is given a grid like the one one the wall, where days that are in the month December look different from those in November and January. Each week starts with Sunday and ends with Saturday.

Days within the month are represented by a #. Days that fall outside the month are represented by a (space, ASCII code 32). Each week is on a separate line. Lines are separated by a newline character (\n). Your program may require either the ommission or inclusion of a newline at the end of the input.

For example, this is the input for December 2009:

  #####
#######
#######
#######
#####  

The calendar is always of the month December.

Task

Given the input, you must find the year associated with the calendar. Since there are multiple years for which a calendar matches, you must return the year (before 2015) that is the closest to 2015. (Excluding 2015 itself.)

Your program must produce the correct output for any year < 2015, excluding those which have a calendar layout for December that is equal to that of another year (before 2015) closer to 2015.

If the year is < 2014, you must also calculate the difference of the year to 2014. For example, for 2012 the difference is 2.

Output

Your program's output must be:

  • The text: Your calendar is for <year>. (Note: since this was originally spelled as “calender“, I’ll accept that spelling as well.)
  • Followed by a newline (\n or \r\n).
  • Followed by the text: It's almost 2015.
  • If the year is < 2014, this must be followed by the text: You're <difference> years behind. This must be on a separate line.
  • Followed by a newline (\n or \r\n).
  • Followed by the text: Go buy a new calendar!
  • Optionally followed by a newline (\n or \r\n).

Rules

  • You can choose whether you want to receive the calendar as a command-line argument (e.g. yourprogram.exe <calendar>) or prompt for user input.
  • You may assume your program won't receive invalid input. Invalid input includes calendar layout for which there exists no year.
  • The shortest code (in bytes, in any language) wins.
  • Any non-standard command-line arguments (arguments that aren't normally required to run a script) count towards the total character count.

  • What your program must not do:

    • Depend on any external resources.
    • Depend on having a specific file name.
    • Output anything other than the required output.
    • Take exceptionally long to run. If your program runs over a minute on an average home user's computer, it's invalid.
  • Your program must not be written in a programming language for which there did not exist a publicly available compiler / interpreter before this challenge was posted.

Examples

Input:

  #####
#######
#######
#######
#####  

Output:

Your calendar is for 2009.
It's almost 2015.
You're 5 years behind.
Go buy a new calendar!

Input:

 ######
#######
#######
#######
####   

Output:

Your calendar is for 2014.
It's almost 2015.
Go buy a new calendar!

Input:

      #
#######
#######
#######
#######
##     

Output:

Your calendar is for 2012.
It's almost 2015.
You're 2 years behind.
Go buy a new calendar!

user2428118

Posted 2014-12-31T23:59:54.007

Reputation: 2 000

Phew. Managed to post it 6 seconds before 2014 was over in UTC (which is used by SE). Also, Happy new year everybody! – user2428118 – 2015-01-01T00:00:50.153

Say, hypothetically, that 2016 and 2009 have the same shape. Then which one is the closest? (i.e. do you mean closest by absolute distance, or closest but earlier than 2015?) – Sp3000 – 2015-01-01T00:06:14.413

@SP3000 The latter. I've edited the post to clarify. – user2428118 – 2015-01-01T00:07:26.100

For the second test case, Dec 1 2014 was on a Monday but your calendar shows it start from a Sunday. Is this correct? – Sp3000 – 2015-01-01T00:21:09.250

@Sp3000 That was an error. I've fixed it, thanks. – user2428118 – 2015-01-01T00:33:15.537

2Is it really necessary to spell calendar two different ways in the output? – feersum – 2015-01-01T02:54:19.757

3"You can choose whether you want to receive the fraction as a command-line argument (e.g. yourprogram.exe 2/5)"... What? – feersum – 2015-01-01T06:18:51.120

@feersum Both were errors. The second one is because I copied some of the rules from this question of mine. I'll fix them.

– user2428118 – 2015-01-01T13:04:53.273

@feersum That looks like an old mistake that wasn't corrected in the examples yet. The text: Your calendar is for <year>. (Note: since this was originally spelled as “calender“, I’ll accept that spelling as well.) – nyuszika7h – 2015-01-02T10:08:58.003

@nyuszika7h I've already corrected those errors. I added the text you cite because the change would otherwise invalidate existing answers. – user2428118 – 2015-01-02T20:23:07.720

@user2428118 I know that's why you added it. But the examples still said "calender" in a few places. – nyuszika7h – 2015-01-03T14:17:43.390

adding kolmorogov-complexity tag because over half the bytes in the best entries are dedicated to representing the static strings. – Sparr – 2018-12-29T18:28:30.310

Answers

2

CJam, 126 bytes

"Your calendar is for "2e3q'##"DE9AB6C"=~+".
It's almost "2015_(".
You're 5 years behind"9@5$-:TtTg*".
Go buy a new calendar!"

jimmy23013

Posted 2014-12-31T23:59:54.007

Reputation: 34 042

3

Python 3, 178 bytes

s=input();i=42157313>>s.index("#")*4&15;print("Your calendar is for %d.\nIt's almost 2015.\n%sGo buy a new calendar!"%(2014-i,(i>0)*("You're %d year%s behind.\n"%(i,"s"*(i>1)))))

A simple lookup table based on the location of the first #.

Expanded:

s=input()
i=42157313>>s.index("#")*4&15
print("Your calendar is for %d.\nIt's almost 2015.\n%sGo buy a new calendar!"\
    %(2014-i,(i>0)*("You're %d year%s behind.\n"%(i,"s"*(i>1)))))

Sp3000

Posted 2014-12-31T23:59:54.007

Reputation: 58 729

2

Perl - 187

$ARGV[0]=~/^( *)/;my@a=(7,8,3..5,0,6);my$b=($a[length$1]+2006);print"Your calendar is for $b.\nIt's almost 2015.\n".($b<2014?"You're ".2014-$b." years behind.\nGo buy a new calendar!":"")

KSFT

Posted 2014-12-31T23:59:54.007

Reputation: 1 527

"." and "-" have the same operator precedence, so you need parenthesis around "2014-$b". – nutki – 2015-01-01T11:32:13.490

The output for at least 2014 is incorrect.

– user2428118 – 2015-01-01T13:10:03.590

@nutki Aah, I thought I fixed that already. – KSFT – 2015-01-01T13:59:45.703

2

Perl 5: 137 143

#!perl -p
$_="Your calendar is for ".(2014-($%=w834506&s/#/?/r)).".
It's almost 2015.
".("You're $% years behind.
")x!!$%."Go buy a new calendar!"

Previous approach:

#!perl -p
/#/;$_="Your calendar is for ".(2014-($b=1558279/9**"@-"%9)).".
It's almost 2015.
".("You're $b years behind.
")x!!$b."Go buy a new calendar!"

Calendar on standard input (only the first line is significant of course)

perl 2014.pl <<<" ######"

nutki

Posted 2014-12-31T23:59:54.007

Reputation: 3 634

2

C#, 384, 363 325 Bytes

C# Time, please tell me if i missed out on one of the rules etc.

string a(string s){var l=s.IndexOf('#');var x=(DayOfWeek)Enum.Parse(typeof(DayOfWeek),""+l);l=1;for(;;){var y=DateTime.Now.Year-l;var t=(new DateTime(y,12,1).DayOfWeek==x)?"Your calendar is for "+y+"\nIt's almost 2015\n"+((y < 2014)?"You're "+--l+"years behind\n":"")+"Go buy a new calendar":null;if(t!=null){return t;}l++;}}

Input

" ######" 
"#######"  
"#######" 
"#######" 
"#####  "

Output

"Your calendar is for 2014
 It's almost 2015
 Go buy a new calendar

Input 2

"  #####"
"#######"  
"#######"
"#######" 
"#####  "

Output 2

"Your calendar is for 2009
 It's almost 2015
 You're 5 years behind
 Go buy a new calendar"

Edit: Updated, managed to remove some bytes

Darren Breen

Posted 2014-12-31T23:59:54.007

Reputation: 31

The punctuation is missing from your output. – Titus – 2018-10-27T02:19:42.750

2

C# 235

minified:

class P{static void Main(string[] a){var y=new[]{1,0,5,4,3,8,2}[a[0].IndexOf('#')];var z=2014-y;System.Console.Write("Your calendar is for "+z+"\nIt's almost 2015.\n"+(z>0?"You're "+z+" years behind.":"")+"\nGo buy a new calendar!");}}

Ungolfed

class P
{
    static void Main(string[] a)
    {
        var y = new[]{1,0,5,4,3,8,2}[a[0].IndexOf('#')];
        var z = 2014-y; 
        System.Console.Write("Your calendar is for "+z+"\nIt's almost 2015.\n"+(z>0 ? "You're "+z+" years behind.":"")+"\nGo buy a new calendar!");
    }
}

Well, the language is verbose :)

Manuel Schweigert

Posted 2014-12-31T23:59:54.007

Reputation: 121

1Your class and Main don't have to be public. Also, you can easily rename Program to P. That should save you some characters :) – ProgramFOX – 2015-01-02T15:20:04.780

20 characters indeed, thanks :) – Manuel Schweigert – 2015-01-02T15:24:28.973

1You can save a few characters by changing how y is computed, if you index a string you can save the syntax required to describe the array (i.e. var y = "1054382"[index]-48 (0 is ASCII 48)). y can also be inlined into the z calculation for further savings. – VisualMelon – 2015-01-03T16:20:19.880

2

Java, 243 bytes

It's a verbose language :-)

class A{public static void main(String[]s){int y=2005+new int[]{8,9,4,5,0,6,7}[s[0].indexOf("#")],d=2014-y;System.out.print("Your calendar is for "+y+".\nIt's almost 2015.\n"+(d>0?"You're "+d+" years behind.\n":"")+"Go buy a new calendar!");}}

Unminified

class A {
    public static void main(String[] s) {
        int y = 2005 + new int[]{8,9,4,5,0,6,7}[s[0].indexOf("#")],
            d = 2014 - y;
        System.out.print("Your calendar is for " + y + ".\nIt's almost 2015.\n"
            + (d > 0 ? "You're " + d + " years behind.\n" : "") + "Go buy a new calendar!");
    }
}

rink.attendant.6

Posted 2014-12-31T23:59:54.007

Reputation: 2 776

1

PHP, 145 bytes

two linebreaks behind the closing tag because PHP will ignore the first one

Your calendar is for <?=2014-$y=_1054382[1+strspn($argv[1]," ")],".
It´s almost 2015.",$y?"
You're $y years behind.":""?>

Go buy a new calendar!

takes input from command line argument;

requires PHP 5.6 (released 18th Dec 2014) or later for indexing the string literal.

Titus

Posted 2014-12-31T23:59:54.007

Reputation: 13 814

1

SmileBASIC, 159 bytes

DEF C C
Y=VAL("2834501"[INSTR(C,"#")])?"Your calender is for ";2014-Y;".
?"It's almost 2015.
IF Y THEN?"You're ";Y;" years behind.
?"Go buy a new calendar!
END

12Me21

Posted 2014-12-31T23:59:54.007

Reputation: 6 110

1

C# (Visual C# Interactive Compiler), 178 175 172 bytes

s=>{int p=2014,a=p-"1054382"[s.IndexOf("#")]+48;Write($"Your calendar is for {a}.\nIt's almost 2015.{(p-a>0?$"\nYou're {p-a} years behind.":"")}\nGo buy a new calendar!");}

Try it online!

Embodiment of Ignorance

Posted 2014-12-31T23:59:54.007

Reputation: 7 014

1

PHP, 215 181 bytes

Lookup table, 181 bytes

Due to short array syntax, only works on PHP 5.4+:

function a($i){$y=2005+[8,9,4,5,0,6,7][strpos($i,'#')];$f=2014-$y;echo "Your calendar is for $y.\nIt's almost 2015.\n".($f?"You're $f years behind.\n":'')."Go buy a new calendar!";}

Unminified

function a($input) {
    $year = 2005 + [8,9,4,5,0,6,7][strpos($input, '#')];
    $difference = 2014 - $year;
    echo "Your calendar is for $year.\nIt's almost 2015.\n" . ($difference ? "You're $difference years behind.\n" : '') . "Go buy a new calendar!";
}

Original, 215 bytes

Works with most (if not all) versions of PHP 5:

<?function a($c){$y=2015;$f=-1;do{$f++;$d=strtotime(--$y."-12-1");}while(date(w,$d)!=strpos($c,'#'));echo"Your calendar is for $y.\nIt's almost 2015.\n".($f?"You're $f years behind.\n":'')."Go buy a new calendar!";}

Unminified

<?php

function a($input) {
    $year = 2015;
    $difference = -1;
    do {
        $difference++;
        $date = strtotime(--$year . "-12-1");
    } while (date('w', $date) != strpos($input, '#'));
    echo "Your calendar is for $year.\nIt's almost 2015.\n" . ($difference ? "You're $difference years behind.\n" : '') . "Go buy a new calendar!";
}

rink.attendant.6

Posted 2014-12-31T23:59:54.007

Reputation: 2 776

1

CoffeeScript, 211 177 bytes

Similar to my PHP answer, but CoffeeScript doesn't have do-while loops nor does it have a short ternary operator:

a=(i)->y=2015;f=-1;loop(f++;d=new Date y--+"-12-01";break if d.getDay()==i.indexOf '#');"Your calendar is for "+y+".\nIt's almost 2015.\n"+(if f then"You're "+f+" years behind.\n"else'')+'Go buy a new calendar!'

Unminifed

a = (i)->
    y = 2015
    f = -1
    loop
        f++
        d = new Date y-- + "-12-01"
        break if d.getDay() == i.indexOf '#'
    "Your calendar is for " + y + ".\nIt's almost 2015.\n" + (if f then "You're " + f + " years behind.\n" else '') + 'Go buy a new calendar!'

Shortened by using a lookup table:

a=(i)->y=[8,9,4,5,0,6,7][i.indexOf '#']+2005;f=2014-y;"Your calendar is for "+y+".\nIt's almost 2015.\n"+(if f then"You're "+f+" years behind.\n"else'')+'Go buy a new calendar!'

rink.attendant.6

Posted 2014-12-31T23:59:54.007

Reputation: 2 776

1

JavaScript (ES6), 199 170 bytes

I'm not used to writing ES6 yet so any tips would be appreciated:

Lookup table, 170 bytes

a=(i)=>{y=[8,9,4,5,0,6,7][i.search('#')]+2005,f=2014-y;return`Your calendar is for ${y}.\nIt's almost 2015.\n${f?`You're ${f} years behind.\n`:''}Go buy a new calendar!`}

Original, 199 bytes

a=i=>{y=2015,f=-1;do{f++;d=new Date(`${y--}-12-01`)}while(d.getDay()!=i.search('#'))return`Your calendar is for ${y}.\nIt's almost 2015.\n${f?`You're ${f} years behind.\n`:''}Go buy a new calendar!`}

Unminified

a = i => {
    y = 2015;
    f = -1;
    do {
        f++;
        d = new Date(`${y--}-12-01`);
    } while (d.getDay() != i.search('#'));
    return `Your calendar is for ${y}.\nIt's almost 2015.\n${f ? `You're ${f} years behind.\n` : ''}Go buy a new calendar!`;
}

JavaScript (ES5), 212 182 bytes

I've also included my original version below

Lookup array, 182 bytes

function a(i){y=[8,9,4,5,0,6,7][i.indexOf('#')]+2005,f=2014-y;return"Your calendar is for "+y+".\nIt's almost 2015.\n"+(f?"You're "+f+" years behind.\n":'')+"Go buy a new calendar!"}

Unminified

function a(i) {
    y = [8,9,4,5,0,6,7][i.indexOf('#')] + 2005;
    f = 2014 - y;
    return "Your calendar is for " + y + ".\nIt's almost 2015.\n" + (f ? "You're " + f + " years behind.\n" : '') + "Go buy a new calendar!";
}

Original, 212 bytes

function a(i){y=2015,f=-1;do{f++;d=new Date(y--+"-12-01")}while(d.getDay()!=i.indexOf('#'));return"Your calendar is for "+y+".\nIt's almost 2015.\n"+(f?"You're "+f+" years behind.\n":'')+"Go buy a new calendar!"}

Unminified

function a(i) {
    y = 2015;
    f = -1;
    do {
        f++;
        d = new Date(y-- + "-12-01");
    } while (d.getDay() != i.indexOf('#'));
    return "Your calendar is for "+y+".\nIt's almost 2015.\n" + (f ? "You're "+f+" years behind.\n" : '') + "Go buy a new calendar!";
}

rink.attendant.6

Posted 2014-12-31T23:59:54.007

Reputation: 2 776

1

Ruby, 174

def a(i)y=2005+[8,9,4,5,0,6,7][i.index('#')];d=2014-y;puts"Your calendar is for #{y}.\nIt's almost 2015.\n"+(d>0?"You're #{d} years behind.\n":'')+"Go buy a new calendar!"end

rink.attendant.6

Posted 2014-12-31T23:59:54.007

Reputation: 2 776