10
\$\begingroup\$

In the spirit of the holidays, and as someone already started the winter theme(Build a snowman!) I propose a new challenge.

Print the number of days, hours, minutes, and seconds until Christmas(midnight(00:00:00) December 25th) on a stand alone window(not a console) in any unambiguous format you see fit, and continually update it as these values change.

Input - nothing, must read system time.

Shortest code wins :) The strings "Days", "Hours", "Minutes", "Seconds", and "Until Christmas" are free code. You can also flavour them up if you like. Flavouring them up is sheerly for the purpose of producing a nice output. You can not flavour strings for the purpose of making a magic number to save code.

\$\endgroup\$
8
  • \$\begingroup\$ What exactly do you mean by "flavour them up"? Are "days", "hours", "minutes", "seconds", and "until Christmas" required in the output, or just free options? How much "flavouring" of those strings is free? \$\endgroup\$
    – Iszi
    Commented Dec 6, 2013 at 18:03
  • 2
    \$\begingroup\$ No console?? Console coders revolt! Just kidding. Nice idea. Happy holidays. \$\endgroup\$ Commented Dec 6, 2013 at 18:05
  • \$\begingroup\$ @Iszi They are not required. I just gave them free so that if people want to make an actual nice output they won't lose so many characters. \$\endgroup\$
    – Cruncher
    Commented Dec 6, 2013 at 18:08
  • 1
    \$\begingroup\$ Isn't Christmas midnight is the end of Christmas? \$\endgroup\$
    – DavidC
    Commented Dec 6, 2013 at 21:54
  • 2
    \$\begingroup\$ No, typically midnight is the zeroth instant of the new day. "Midnight Christmas" is when Christmas begins. \$\endgroup\$
    – breadbox
    Commented Dec 6, 2013 at 22:54

8 Answers 8

5
\$\begingroup\$

Ruby with Shoes, 96 - 33 = 63

Shoes.app{p=para
animate{p.text="0 days 0 hours 0 minutes #{1387951200-Time.new.to_f} seconds"}}

Well, you never said we couldn't. ;)

screenshot

Updates once every frame.

The magic number 1387951200 is Christmas - Dec 25, 2013 00:00.

Sample IRB session for where I got the numbers:

irb(main):211:0> "0 days 0 hours 0 minutes  seconds".size
=> 33
irb(main):212:0> Time.new(2013,12,25,00,00,00).to_i
=> 1387951200
irb(main):213:0>
\$\endgroup\$
2
  • \$\begingroup\$ Dec 25, 2013 00:00 is midnight. \$\endgroup\$
    – Cruncher
    Commented Dec 7, 2013 at 4:59
  • \$\begingroup\$ @Cruncher Ah, okay then. Editing out lots of the useless text then \$\endgroup\$
    – Doorknob
    Commented Dec 7, 2013 at 15:27
3
\$\begingroup\$

PowerShell: 279

Character count does not take into account any freebies. @Cruncher - please adjust accordingly.

Golfed

($t=($a='New-Object Windows.Forms')+".Label"|iex).Text=($i={((New-TimeSpan -en 12/25|Out-String)-split"`n")[2..6]});$t.Height=99;($x=iex $a".Form").Controls.Add($t);$x.Text='Time Until Christmas';($s=iex $a".Timer").add_tick({$t.Text=&$i;$x.Refresh()});$s.Start();$x.ShowDialog()

This ain't the prettiest thing, either as code or as a window, but it works.

One nice bit is that this isn't just good for 2013 - it'll work in any year, from 00:00 on January 1 until 00:00 on December 25th.

Warning: The window may become unresponsive - it will continue to update, but you might not be able to move or close it.

enter image description here

Un-golfed with comments

(
    # $t will be the label that displays our countdown clock on the form.
    $t=(
        # $a is used as a shortcut to address the Forms class later.
        $a='New-Object Windows.Forms'
    # Tack ".Label" onto the end with iex to finish making $t.
    )+".Label"|iex

# Set the text for our label.
).Text=(
    # $i will be a script block shortcut for later.
    $i={
        (
            (
                # Get the current "Time until Christmas", and output it as a string.
                New-TimeSpan -en 12/25|Out-String
            # Break the string into newline-delimeted array.
            )-split"`n"
        # Only output elements 2..6 - Days, Hours, Minutes, Seconds, Milliseconds.
        )[2..6]
    }
);

# Make sure the label is tall enough to show all the info.
$t.Height=99;

(
    # Use iex and $a as shortcut to make $x a "New-Object Windows.Forms.Form".
    $x=iex $a".Form"

# Add the label to the form.
).Controls.Add($t);

# Put 'Time Until Christmas' in the title bar for flavor.
$x.Text='Time Until Christmas';

(
    # Use iex and $a as shortcut to make $s a "New-Object Windows.Forms.Timer".
    $s=iex $a".Timer"

# Tell the timer what to do when it ticks.
).add_tick(
    {
        # Use the $i script block to update $t.Text.
        $t.Text=&$i;
        # Reload the form so the updated text displays.
        $x.Refresh()
    }
);

# Start the timer.
$s.Start();

# Show the form.
$x.ShowDialog();

# Variable cleanup - omit from golfed code.
rv t,a,x,i,s
\$\endgroup\$
3
\$\begingroup\$

Mathematica 167 - 44 = 123

The following continually updates a table showing the days, hours, minutes and seconds (in thousandths) until the beginning of Christmas day. I am unsure how to count discount for the free strings.

Dynamic[Grid[Join[{{"Countdown", "until Christmas"}}, 
{DateDifference[Date[], {2013, 12, 25, 0, 0, 0}, {"Day", "Hour", "Minute", "Second"}], 
Clock[{1, 1}, 1]}[[1]] /. d_String :> d <> "s"]] ]

countdown


A quick and dirty solution: 104-19 = 85 chars

Dynamic@{DateDifference[Date[], {2013, 12, 25, 0, 0, 0}, {"Day", "Hour", "Minute", 
 "Second"}], Clock[{1, 1}, 1]}[[1]]

{{17, "Day"}, {10, "Hour"}, {59, "Minute"}, {51.4011, "Second"}}

\$\endgroup\$
4
  • \$\begingroup\$ "Countdown to Christmas: Days" This can be free, "Day", "Hour", "Minute", "Second" can be as well. \$\endgroup\$
    – Cruncher
    Commented Dec 6, 2013 at 18:57
  • \$\begingroup\$ Thanks for the clarification. Btw, spaces outside of strings are not obligatory. They are inserted only for legibility. \$\endgroup\$
    – DavidC
    Commented Dec 6, 2013 at 19:03
  • \$\begingroup\$ Why are there "-" in front of the numbers? It may be confusing, and look like we're passed christmas already. Would they be fixed by changing the order in DateDifference? \$\endgroup\$
    – Cruncher
    Commented Dec 6, 2013 at 19:07
  • \$\begingroup\$ I removed them and improved the formatting, paying the price in characters added. \$\endgroup\$
    – DavidC
    Commented Dec 6, 2013 at 19:30
2
\$\begingroup\$

Python 136

I'm sure someone can do this better - I've never used Tkinter before. In particular I bet the l.pack() and l["text"] can are avoidable.

tk

Golfed

from Tkinter import*
from datetime import datetime as d
r=Tk()
l=Label(r)
l.pack()
while 1:
    l["text"]=d(2013,12,25)-d.now()
    r.update()
\$\endgroup\$
1
\$\begingroup\$

R

Here is a solution for R using GTK+ via the gWidgets package. This is pretty ugly code since I am not familiar with the gWidgets/GTK+ package at all.

Code

Here is the code:

library(gWidgets)
options(guiToolkit="RGtk2")

# FUNCTION compute the hours minutes and seconds from time in seconds
fnHMS = function(timeInSec) {
  hours = timeInSec %/% 3600
  minutes = (timeInSec %% 3600) %/% 60
  seconds = (timeInSec %% 3600) %% 60
  return(list(hours = hours, minutes = minutes, seconds = seconds))
}

# test the function
fnHMS(1478843)

# container for the label and the button widget
christmasCountdownContainer = gwindow('Christmas Countdown!!', visible = TRUE)
christmasCountdownGroup = ggroup(horizontal = FALSE,
                                 container = christmasCountdownContainer)
ccWidget1 = glabel(sprintf('%4.0f hours, %4.0f minutes, %4.0f seconds till Christmas!!', 
                           (liHMS <- fnHMS(as.double(difftime(as.POSIXct(strptime('25-12-2013 00:00:01', 
                                      format = '%d-%m-%Y %H:%M:%S')),
                  Sys.time(), units = 'secs'))))[[1]], liHMS[[2]], liHMS[[3]]), 
                            container = christmasCountdownGroup)

ccWidget2 = gbutton("Update!", handler = function(h, ...) {
  # retrieve the old value of the ccWidget1
  oldValue = svalue(ccWidget1)
  liHMS = fnHMS(as.double(difftime(as.POSIXct(strptime('25-12-2013 00:00:01', 
                                                       format = '%d-%m-%Y %H:%M:%S')),
                                   Sys.time(), units = 'secs')))
  svalue(ccWidget1) = sprintf('%4.0f hours, %4.0f minutes, %4.0f seconds till Christmas!!',
                              liHMS[[1]], liHMS[[2]], liHMS[[3]])
  }, container = christmasCountdownGroup)

Output

Here is what the output looks like:

enter image description here

\$\endgroup\$
1
  • \$\begingroup\$ It has to continually update - that means automatically \$\endgroup\$
    – Doorknob
    Commented Dec 8, 2013 at 5:07
1
\$\begingroup\$

Dyalog APL, 61

{⎕SM[1;]←1 1,⍨⊂⍕(1 4⍴2↓2013 12 24 23 59 59 1000-⎕TS)⍪'Days' 'Hours' 'Minutes' 'Seconds'⋄∇1}1
\$\endgroup\$
0
\$\begingroup\$

C# 128

Golfed

using D=System.DateTime;using System.Windows.Forms;class C{static void Main(){MessageBox.Show(""+(new D(2013, 12, 25)-D.Now));}}

Ungolfed

using D=System.DateTime;
using System.Windows.Forms;
class C
{
    static void Main()
    {
        MessageBox.Show(""+(new D(2013,12,25)-D.Now));
    }
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ This doesn't continually count down does it? Also, Welcome to codegolf! \$\endgroup\$
    – Cruncher
    Commented Dec 6, 2013 at 20:54
  • \$\begingroup\$ Thanks, glad to be here! I guess I misunderstood, this would only update when it is rerun. I'll edit and repost soon \$\endgroup\$
    – James C.
    Commented Dec 6, 2013 at 21:04
0
\$\begingroup\$

Python 2, 115

from datetime import datetime as d
n=d.now()
print str(24-n.day),str(23-n.hour),str(59-n.minute),str(60-n.second)

This counts newlines as 2 characters.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.