9
\$\begingroup\$

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!
\$\endgroup\$
  • \$\begingroup\$ Phew. Managed to post it 6 seconds before 2014 was over in UTC (which is used by SE). Also, Happy new year everybody! \$\endgroup\$ – user2428118 Jan 1 '15 at 0:00
  • \$\begingroup\$ 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?) \$\endgroup\$ – Sp3000 Jan 1 '15 at 0:06
  • \$\begingroup\$ @SP3000 The latter. I've edited the post to clarify. \$\endgroup\$ – user2428118 Jan 1 '15 at 0:07
  • 2
    \$\begingroup\$ Is it really necessary to spell calendar two different ways in the output? \$\endgroup\$ – feersum Jan 1 '15 at 2:54
  • 3
    \$\begingroup\$ "You can choose whether you want to receive the fraction as a command-line argument (e.g. yourprogram.exe 2/5)"... What? \$\endgroup\$ – feersum Jan 1 '15 at 6:18

14 Answers 14

2
\$\begingroup\$

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!"
\$\endgroup\$
3
\$\begingroup\$

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)))))
\$\endgroup\$
2
\$\begingroup\$

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!":"")
\$\endgroup\$
  • \$\begingroup\$ "." and "-" have the same operator precedence, so you need parenthesis around "2014-$b". \$\endgroup\$ – nutki Jan 1 '15 at 11:32
  • \$\begingroup\$ The output for at least 2014 is incorrect. \$\endgroup\$ – user2428118 Jan 1 '15 at 13:10
  • \$\begingroup\$ @nutki Aah, I thought I fixed that already. \$\endgroup\$ – KSFT Jan 1 '15 at 13:59
2
\$\begingroup\$

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 <<<" ######"
\$\endgroup\$
2
\$\begingroup\$

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 :)

\$\endgroup\$
  • 1
    \$\begingroup\$ Your class and Main don't have to be public. Also, you can easily rename Program to P. That should save you some characters :) \$\endgroup\$ – ProgramFOX Jan 2 '15 at 15:20
  • \$\begingroup\$ 20 characters indeed, thanks :) \$\endgroup\$ – Manuel Schweigert Jan 2 '15 at 15:24
  • 1
    \$\begingroup\$ You 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. \$\endgroup\$ – VisualMelon Jan 3 '15 at 16:20
2
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ The punctuation is missing from your output. \$\endgroup\$ – Titus Oct 27 '18 at 2:19
2
\$\begingroup\$

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!");
    }
}
\$\endgroup\$
1
\$\begingroup\$

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!";
}
\$\endgroup\$
1
\$\begingroup\$

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!'
\$\endgroup\$
1
\$\begingroup\$

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!";
}
\$\endgroup\$
1
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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.

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

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
\$\endgroup\$
1
\$\begingroup\$

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!

\$\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.