| Bytes | Lang | Time | Link |
|---|---|---|---|
| 185 | Setanta | 240720T204031Z | bb94 |
| 104 | Bash using only builtins | 240720T150100Z | Martin K |
| 087 | Lua | 231118T123135Z | bluswimm |
| 067 | Bash +GNU date | 181226T144652Z | Nahuel F |
| 091 | Julia 1.0 | 221116T223248Z | Ashlin H |
| 178 | Go | 231116T145547Z | bigyihsu |
| 038 | Japt S | 221117T130504Z | Shaggy |
| 060 | jq jn | 221117T162346Z | pmf |
| 081 | 05AB1E | 190103T123837Z | Kevin Cr |
| 053 | q | 221117T052714Z | cillianr |
| 061 | Bash | 181226T183848Z | user4180 |
| 088 | TSQL | 181225T200049Z | Neil |
| 088 | JavaScript | 181225T235827Z | targumon |
| 123 | Scala | 181227T131700Z | V. Court |
| 059 | Excel formula | 181225T133344Z | Richard |
| 118 | Lua | 181231T040823Z | Tae Hana |
| 077 | JavaScript | 181229T202343Z | Vadim |
| 091 | MATLAB | 181229T153920Z | Anthony |
| 113 | Scala | 181228T220841Z | Kjetil S |
| 089 | C# Visual C# Interactive Compiler | 181225T075211Z | dana |
| 106 | Python 3 | 181228T222936Z | Albert C |
| 068 | Perl 5 | 181228T192237Z | Kjetil S |
| 1283 | Python 2 | 181225T054249Z | iBug |
| 076 | Red | 181225T081945Z | Galen Iv |
| 066 | Groovy | 181225T145810Z | bdkosher |
| 067 | SmileBASIC | 181225T113752Z | 12Me21 |
| 063 | Windows PowerShell | 181226T124055Z | briantis |
| 103 | Python 2 | 181226T211258Z | Triggern |
| 047 | Perl 6 | 181225T032035Z | Sean |
| 108 | VBA Excel | 181226T234546Z | Barranka |
| 072 | R | 181225T015604Z | ngm |
| 157 | C gcc | 181226T005101Z | ErikF |
| 102 | MySQL | 181225T205503Z | Titus |
| 141 | C# Visual C# Interactive Compiler | 181225T043719Z | Gymhgy |
| 061 | PHP | 181225T200114Z | Titus |
| 080 | Ruby | 181225T132605Z | iBug |
| 063 | APL Dyalog Unicode | 181225T084325Z | Adá |
Setanta, 199 185 bytes
Setanta doesn’t have any way to get the current date or time, so this is a function that takes a [year, month, day] list as an argument.
And yes, for some reason, | has higher precedence than & in Setanta.
gniomh(d){p:=[360,329,301,270,240,209,179,148,117,86,56,26]b:=d[0]+1m:=d[1]l:=d[2]c:=391-l y:=0ma m<12|l<26{y=m>2b-=1c=p[m-1]-l}toradh"Christmas"+" Eve"*(c-(y|b%4|(b%100<1&b%400)|0&1))}
Bash using only built-ins, 104 bytes
x=$(printf %\*s $((365-$(printf '%(%-j)T' $((EPOCHSECONDS+32054400)))%366)));echo Christmas ${x//?/ Eve}
Expanded
x=$(
printf %\*s $((
365 - $(
printf '%(%-j)T' \
$(( EPOCHSECONDS + (6+365)*24*60*60 ))
) % 366
))
)
echo Christmas ${x//?/ Eve}
Logic
$EPOCHSECONDS is a Bash special variable that gives us the current time as seconds since 1-Jan-1970,00:00UTC.
printf '%(...)T' interprets its next parameter as such, and outputs it using the ... as a strftime() formatter (the same as GNU date).
In particular printf '%(%-j)T' gives us the day-of-the-year (1..366) of the given time.
However instead of using "now", we advance by 6 days, so that 26 Dec becomes day 1; we then advance by a further 365 days, effectively retarding by a day when the following year is a leap year.
At this point we have a number in the range 0...366; we need to treat 366 as 0, so we take mod 366 (%366).
We then subtract the resulting day number from 365 to get the count of days until Christmas.
We then use printf '%*s' count to generate a string with count spaces, and store that in the variable x.
Lastly, we replace every symbol in $x with the word Eve, and output the result prefaced by Christmas.
Separate challenge from just "Bash"
This answer does not compete on diminution with other Bash answers; avoidance of external commands makes it rather larger but also faster.
Lua, 87 bytes
w=io.write w'Christmas't=os.time()while os.date('%d%m',t)~='2512'do t=t+86400w' Eve'end
Bash +GNU date, 72, 73, 67 bytes
for((d=7;`date +%-j -d$d\day`-1;d++));{ x+=\ Eve;};echo Christmas$x
- one byte saved replacing
!=with- - another removing extra space
- fix -3 bytes
d=0, becausedate -ddayis date+1 and doesn't work on 25/12 - 6 bytes saved thanks to Toby Speight using %-j format to avoid 0 padding (and octal conversion) and shorter than %d%m compared to 2512
Julia 1.0, 91 bytes
using Dates
t=today()
print(:Christmas," Eve"^~-(tonext(==((12,26))∘monthday,t)-t).value)
- -1 byte thanks to @MarcMush: Substitute
1>0fortrue - -5 bytes thanks to @MarcMush: Substitute
_.valueforDates.value(_) - -1 byte thanks to @amelies: print symbol
:Christmasrather than string"Christmas" - -1 byte thanks to @MarcMush: compose functions with
∘ - -7 bytes thanks to @MarcMush: use Boxing Day as the end date and subtract one in order to eliminate the
same=trueparameter
Go, 178 bytes
import(."time";."strings")
func f()string{n:=Now()
y:=n.Year()
if n.Month()>11&&n.Day()>25{y++}
return"Christmas"+Repeat(" Eve",int(Date(y,12,25,0,0,0,0,UTC).Sub(n).Hours())/24)}
And a variant that takes a Time as input, 175 bytes:
import(."time";."strings")
func f(n Time)string{y:=n.Year()
if n.Month()>11&&n.Day()>25{y++}
return"Christmas"+Repeat(" Eve",int(Date(y,12,25,0,0,0,0,UTC).Sub(n).Hours())/24)}
Japt -S, 39 38 bytes
Ð
f
@f1V° UζB©25¶Uf}a Æ"Eve"Ãi`CËItµs
Ð\nf\n@f1V° UζB©25¶Uf}a Æ"Eve"Ãi`CËItµs
Ð :Create date object for current date
\n :Assign to variable U
f :Get date value of U
\n :Assign to variable V
@ :Function taking an integer X as argument
f1 : Set the date of U to (modifies U)
V° : V, postfix incremented
UÎ : 0-based month value of modified U
¶ : Check equality with
B : 11
© : Logical AND with
25¶ : Check equality between 25 and
Uf : Date value of modified U
} :End function
a :Return the first value of X>=0 that returns true
Æ :Map the range [0,result)
"Eve" : Literal string
à :End map
i :Prepend
`CËItµs : Compressed string "Christmas"
:Implicit output joined with spaces
05AB1E, 93 89 87 81 bytes
'ŒÎžfže«Ž9Ú.S©DΘžg+т‰0Kθ4ÖUi390že-X+ë®_i0ë•ΘÏF•º11£®ª₂+ā2QX*+13žf-.£Ože-]Fð'»ˆ}J™
Try it online or Try it online with an emulated self-specified date of 'today'.
Old 93 89 87 bytes approach that loops over the days one by one:
žežfžg)V'ŒÎ[Y¨JŽ9ÚQ#Y`т‰0Kθ4ÖUD<i\28X+ë<7%É31α}‹iY¬>0ëY1¾ǝDÅsD12‹i>1ë\1Dǝ¤>2}}ǝVð'»ˆ}J™
Try it online or Try it online with an emulated self-specified date of 'today'.
Explanation:
05AB1E doesn't have any builtins for dates, except for receiving the current year/month/day/hours/minutes/seconds/microseconds, so most bytes are used for manual calculations.
'ŒÎ '# Push dictionary string "christmas"
žfže« # Append the current month and current day together
.S # Compare it with
Ž9Ú # Compressed integer 1225
# (1 if >1225; 0 if ==1225; -1 if <1225)
© # Store this comparison in variable `®` (without popping)
D # Duplicate it
Θ # Check if it's equal to 1 (1 if 1; 0 if 0 or -1)
žf+ # Add the current year to it
т‰0Kθ4Ö # Check if this is a leap year:
т‰ # Divmod it by 100
0K # Remove the 0s
θ # Only leave the last item
4Ö # Check if it's divisible by 4
U # Pop and store this is_leap_year in variable `X`
i # If the comparison is 1:
390že- # Push 390 minus the current day
# (390 is 31 for days in December and 259 for days of Christmas Day)
X+ # Add the is_leap_year check from variable `X`
ë®_i # Else if the comparison is 0:
0 # Push 0
ë # Else (the comparison is -1):
•ΘÏF• # Push compressed integer 5254545
º # Mirror it to 52545455454525
11£ # Only leave the first 11: 52545455454
®ª # Convert it to a list of digits, and append the -1:
# [5,2,5,4,5,4,5,5,4,5,4,-1]
₂+ # Add 26 to each: [31,28,31,30,31,30,31,31,30,31,30,25]
ā # Push a list in the range [1,length] (without popping):
# [1,2,3,4,5,6,7,8,9,10,11,12]
2Q # Check which is equal to 2: [0,1,0,0,0,0,0,0,0,0,0,0]
X* # Multiply each by the is_leap_year check of variable `X`
+ # Add the values at the same positions in the lists together
13žf- # Push 13 minus the current month
.£ # Only leave that many items from the end of the list
O # Sum them together
že- # Subtract the current day
] # Close the if-else statements
F # Loop that many times:
ð # Push a space character " "
'»ˆ '# Push dictionary string "eve"
}J # After the loop: join the entire stack together
™ # Titlecase each word
# (after which the result is output implicitly)
žežfžg)V # Get the current [day,month,year] and save it in variable `Y`
'ŒÎ '# Push dictionary string "christmas"
[ # Start an infinite loop:
Y¨J # Remove the year, and join the month and day together
Q # Check if this is equal to
Ž9Ú # Compressed integer 1225
# # If this is truthy (thus it's December 25th): stop the infinite loop
Y`т‰0Kθ4ÖUD<i\28X+ë<7%É31α}‹iY¬>0ëY1¾ǝDÅsD12‹i>1ë\1Dǝ¤>2}}ǝV
# Go to the next day, and set `Y` to it
ð # Push a space " "
'»ˆ '# Push dictionary string "eve"
}J # After the infinite loop: join the entire stack together
™ # Titlecase each word
# (after which the result is output implicitly)
See this 05AB1E answer of mine to understand the is_leap_year check.
See this 05AB1E answer of mine to understand how we go to the next day (with the second longer approach).
See this 05AB1E tip of mine (sections How to use the dictionary? and How to compress large integers?) to understand why '»ˆ is "eve"; 'ŒÎ is "christmas"; Ž9Ú is 1225; and •ΘÏF• is 5254545.
q, 53 bytes
"Christmas",(4*(not 12 25~`mm`dd$.z.d+)(1+)/0)#" Eve"
k, 50 bytes
"Christmas",(4*(~12 25~`mm`dd$.z.d+)(1+)/0)#" Eve"
Increment counter while the date is not Dec 25th, then take that number of copies of " Eve" and append to "Christmas".
Bash, 68 65 61 bytes
Golfed 4 bytes thanks to Nahuel Fouilleul by using `` command substitution and eval in place of sed e and xargs
echo Christmas `eval date\ -d{0..366}day\;|sed /c.25/Q\;cEve`
Inside the `` command substitution, we have
eval run the following string as shell commands
date\ -d{0..366}day\;under brace expansion of{0..366}, this results in the stringdate -d0day; date -d1day; date -d2day; ... date -d366day;, each command in this string computing the date between 0 and 366 days from present resulting in output of the formatWed Dec 26 18:22:33 UTC 2018, with each in its own line
|sed upon which, call the following sed commands
/c.25/Qif the regex/c.25/is matched,Quit without printing\;cEveotherwise change the line toEve
All the required number of Eves are produced each on its own line. This output is captured in ``, and is subject to word splitting where words are split on newlines. Each word is fed as an argument to echo.
echo Christmas ...
Each argument to echo is printed by being separated by spaces, resulting in the desired output.
T-SQL, 92 88 bytes
PRINT'Christmas'+REPLICATE(' Eve',DATEDIFF(D,GETDATE(),STR(YEAR(GETDATE()+6))+'-12-25'))
Edit: Saved 4 bytes thanks to @BradC.
JavaScript, 135 131 121 92 88 bytes
My first (naïve) solution (135b):
t=new Date();n=new Date();n.setMonth(11);n.setDate(25);'Christmas'+' Eve'.repeat((n>=t?n-t:(n.setFullYear(n.getFullYear()+1)-t))/864e5)
It sets 2 dates: now and Xmas of this year. If the latter hasn't passed yet, it just diffs them, if it has passed, diffs to next year's Xmas. Uses either diffs for the number of repeats.
(Trying to) Think Outside the Box (131b):
i=0;f=_=>{t=new Date();if(t.getMonth()!=11||t.getDate()!=25){i++;setTimeout(f,864e5)}else{alert('Christmas'+' Eve'.repeat(i))}};f()
The challange specifies WHICH output is required when running the program on a given day, but doesn't specify WHEN to return it...
This will just 'sleep' for a day, increment a counter by 1, and repeat till it's Xmas in order to give the output.
Since JavaScript doesn't guarantee the 'sleep' time, the actual result might be off.
It is also ugly for using the alert function, which means wer'e actually not dealing with pure JavaScript, but with browser APIs as well (we can use console.log at the cost of 6 extra bytes).
A better approach (121b):
t=new Date();i=0;while(t.getMonth()!=11||t.getDate()!=25){t=new Date(t.valueOf()+864e5);i++};'Christmas'+' Eve'.repeat(i)
Starting from today, increment the date by a day until it's Xmas, then use that loop's counter for the number of repeats required.
Improving (including going through a minifier and using 12Me21's trick to shave extra 5b) (92b):
for(s='Christmas',t=new Date;t.getMonth()/t.getDate()-.44;)t=new Date(t*1+864e5),s+=' Eve';s
Final touches (88b):
for(s='Christmas',t=new Date;t.getMonth()/(d=t.getDate())-.44;t.setDate(d+1))s+=' Eve';s
- For all of the above, REPL is assumed.
- See Vadim's submission - much better than mine!
Scala, 123 bytes
Thanks to ASCII-only's work.
print("Christmas")
var d=new java.util.Date
while(d.getMonth()<11||d.getDate()!=25){print(" Eve");d.setDate(d.getDate()+1)}
Scala + Joda-Time, 140 bytes
import org.joda.time._
var s="Christmas"
var d=DateTime.now
while(d!=d.withDate(d.year().get(),12,25)){d=d.plusDays(1);s+=" Eve"};println(s)
Does not run in TIO since it requires Joda-Time library.
Excel formula, 59 bytes
="Christmas"&REPT(" Eve",DATE(YEAR(NOW()+6),12,25)-TODAY())
Lua, 137 118 bytes.
118 bytes
t,d,month,day=os.time,os.date,1,-6year=d"%Y"+(d"%D">"12/25"and 2or 1)print("Christmas",d" Eve":rep(d("%j",t(_G)-t())))
137 bytes (previous)
t,d=os.time,os.date a=d"*t"a.year,a.month,a.day=a.year+(d"%m%d">"1225"and 1 or 0),12,25 print("Christmas",("Eve "):rep((t(a)-t())/86400))
It's worth noting that it doesn't work in LuaJIT (syntax error)
JavaScript, 86 77 bytes
Using REPL it would be
for(c='Christmas',d=new Date;!/c 25/.test(d);d=new Date(+d+864e5))c+=' Eve';c
Kudos to ASCII-only for -9 bytes
MATLAB, 91 bytes
n=datetime
x=datetime(year(n+6),12,25)
s='Christmas'
while days(x-n)>=1 n=n+1 s=[s,' Eve'] end
MATLAB Non-looper, 100 bytes
x=datenum(datetime(floor((now+5)/365.2425),12,25))
d=x-now
['Christmas' repmat(' Eve',1,min(d(d>=0)))]
Scala, 116 113 bytes
var d=new java.util.Date
print("Christmas")
while(!(""+d).contains("c 25")){print(" Eve");d.setDate(d.getDate+1)}
Where c 25 is short for Dec 25.
C# (Visual C# Interactive Compiler), 89 bytes
Write("Christmas");for(var t=DateTime.Now;$"{t:Md}"!="1225";t=t.AddDays(1))Write(" Eve");
-3 bytes thanks to @JeppeStigNielsen!
My strategy is pretty straightforward:
- Initialize a loop variable
tto the current date - Print
Eveiftis not Christmas - Add a day to
tand repeat
I tried some fancier things, but this way required the fewest bytes.
Python 3, 106 Bytes
from datetime import*
d=date.today()
print("Christmas"+" Eve"*(date((d+timedelta(6)).year,12,25)-d).days)
Perl 5, 68 bytes
print"Christmas";print" Eve"while localtime($i++*86400+time)!~/c 25/
Where c 25 is short for Dec 25.
Python 2, 128 bytes / Python 3, 130 bytes
of course, two less bytes with Python 2
from datetime import date as D
T=D.today()
Y=T.year
a=(D(Y,12,25)-T).days
print("Christmas"+" Eve"*[a,(D(Y+1,12,25)-T).days][a<0])
Red, 89 86 84 78 76 bytes
-10 bytes thanks to ASCII-only!
does[a: now prin"Christmas"while[a/3 * 31 + a/4 <> 397][prin" Eve"a: a + 1]]
Groovy, 66 bytes
d=[]as Date
print'Christmas'+' Eve'*(new Date((d+6).year,11,25)-d)
Courtesy of @ASCII-only
SmileBASIC, 73 71 67 bytes
?"Christmas";
@L?" Eve"*(D!=P);
P=D
DTREAD OUT,M,D
IF M/D-.48GOTO@L
The program prints "Christmas", then prints " Eve" every time a day passes, until it is December 25th. (12/25 = 0.48)
May take up to a year to run.
Windows PowerShell, 67 64 63 bytes
for(;1225-'{0:Md}'-f(date|% *ys $i)){$i++}'Christmas'+' eve'*$i
Managed to shave off 3 bytes 4 bytes (thanks Cows quack) by using the -format operator instead of .ToString(), and then subtracting the date string from the numerical value 1225 instead of doing a comparison with -ne. The resulting integer will be interpreted as a boolean for the conditional where 0 (which will happen on Christmas) is interpreted as False (don't enter the loop), and any other value is interpreted as True (enter the loop).
Since the integer is on the left now, the date string will be converted to the integer and math will be done, as opposed to the previous version where the 1225 integer was converted to string for the comparison.
Original Version
Windows PowerShell, 67 bytes
for(;(date|% *ys $i|% tost* Md)-ne1225){$i++};'Christmas'+' eve'*$i
Using a for loop as a while loop basically, because it's shorter. In the loop condition we check the current date (date, a shortened form of Get-Date), piped to ForEach-Object's alias %, using the form that can invoke a method by wildcarded name; in this case the method is AddDays() on the DateTime object, and the value we give it is $i.
This gets piped to ForEach-Object again to invoke the ToString() method, with format string Md (month, then day, minimal digits since we don't care for what comes next). This string is then tested to see if it's not equal -ne to the number 1225, which will be converted to a string for the comparison, saving me the quotes.
This is why it doesn't matter that the months and days are single digits, it will never be ambiguous because there's no other day of the year that would stringify to 1225.
The loop continues until the string is 1225. At the beginning of the program, $i will be zero so it will be comparing today's date, and the loop will never execute, but for any other day $i gets incremented in the loop body, so that we will have a count of how many days until the next Christmas, automatically accounting for leap years and whether or not Christmas passed this year.
After the loop we just output the string Christmas concatenated with the result of multiplying the string eve times the value of $i (which, on Christmas day, will be 0, resulting in no eves).
Python 2, 111 103 bytes
from datetime import*
d=date.today()
print"Christmas"+" Eve"*(date((d+timedelta(6)).year,12,25)-d).days
Update inspired by Richard Crossley's answer.
Explanation:
from datetime import*
# get today as a date, so we don't have to worry about rounding errors due to time
d=date.today()
# get the year of the Christmas to compare to
# if the current date is after this year's Christmas, the 6 day offset will give the next year
# otherwise, returns this year
(d+timedelta(6)).year
# next Christmas minus the current date
date(.....................,12,25)-d
# Christmas, plus (number of days until next Christmas) " Eve"s
print"Christmas"+" Eve"*(...................................).days
Perl 6, 61 47 bytes
say 'Christmas'~' Eve'x(Date.today...^{.month==12&&.day==25})
say 'Christmas'~' Eve'x(Date.today...^/12\-25/)
-14 bytes (!) thanks to Jo King
Date.today ...^ /12\-25/ is the sequence of dates starting today and ending the day before Christmas. (The regular expression /12\-25/ is matched against the string representation of the dates.) The string " Eve" is replicated a number of times equal to the length of that sequence, and is output after the string "Christmas".
VBA (Excel), 108 bytes
Copy in a blank module. Prints to the Immediate window:
Sub X:s="Christmas":d=Now:For t=1 To (DateSerial(Year(d+6),12,25)-d):s=s &" Eve":Next:Debug.Print s:End Sub
Note: Using : instead of line breaks saves two bytes per line.
Notice that the VBA editor will insert additional spaces between keywords, operators, etc... and parenthesis after the Sub definition, but if you copy and paste this code it will work (I couldn't get rid of that space before the &).
Not bad for VBA (for once).
R, 112 106 72 bytes
Via @digEmAll and @J.Doe
x=Sys.Date()-1;cat('Christmas');while(!grepl('12-25',x<-x+1))cat(' Eve')
My original answer was prior to the clarification that the code was to take the date on which the code is run as input. It could be modified as above to save many bytes but I won't bother.
function(x,z=as.Date(paste0(strtoi(format(x,"%Y"))+0:1,"-12-25"))-x)cat("Christmas",rep("Eve",z[z>=0][1]))
Explanation: everyone's at church so I have time to do this. Extract the year, coerce to integer. Make vector of that year's Xmas and the next year's Xmas and subtract the input date to get a vector of two differences between the input date and those two Xmases.
Pick the non-negative one and cat "Christmas" with that many "Eves".
C (gcc), 157 bytes
I thought that I would be able to avoid including time.h but that just gave segment faults.
#include <time.h>
*t,u;f(){time(&u);t=localtime(&u);t[5]+=t[4]>10&t[3]>25;t[4]=11;t[3]=25;u-=mktime(t);printf("Christmas");for(u/=86400;u++;printf(" Eve"));}
MySQL, 102 bytes
pretty much the same as Neil´s T-SQL answer. There seems to be no shorter way in SQL.
select concat("Christmas",repeat(" Eve",datediff(concat(year(now()+interval 6 day),"-12-25"),now())));
C# (Visual C# Interactive Compiler), 141 bytes
var g=DateTime.Now;Write("Christmas"+string.Concat(Enumerable.Repeat(" Eve",(new DateTime(g.Year+(g.Day>25&g.Month>11?1:0),12,25)-g).Days)));
PHP, 61 bytes
Christmas<?for($t=time();date(md,$t+=86400)-1226;)echo" Eve";
Run with -n or try it online.
Ruby, 80 bytes
require'date'
t=Date.today
puts'Christmas'+' Eve'*(Date.new((t+6).year,12,25)-t)
Thanks to tsh for his idea
APL (Dyalog Unicode), 76 63 bytesSBCS
Full program. Assumes ⎕IO←0 (zero-indexing).
⎕CY'dfns'
'Christmas',' Eve'⍴⍨4×12 25⍳⍨⍉2↑1↓⍉date(⍳366)+days⎕TS
⎕CY'dfns' copy in the dfns library
⎕TS current time stamp as [year,month,day,hour,min,sec,ms]
days[c] find the number of days[n] since 1899-12-31 00:00:00.000
(⍳366) add the first 366 integers (0…365) to that
date[c] find the dates[n] that correspond to those numbers (366×7 table; one column per unit)
⍉ transpose (7×366 table; one row per unit)
1↓ drop one row (the years)
2↑ take the first two rows (months and days)
12 25⍳⍨ find the index of the first Christmas
4× multiply that by four
' Eve'⍴⍨ use that to reshape the character list
'Christmas ', append that to this
[c] code of that function
[n] notes for that function