When will Brexit happen?

28

5

Well, Brexit happened. And Sky News, being the geniuses they are, have decided to create a countdown on the side of a bus.

enter image description here

Your job is to do something similar. The UK leaves the the EU on 31st of March 2019 and you have to create a digital countdown for this that changes every second (with a 0.05 second deviation allowed).

Input

Your program should take absolutely no input. It is banned!

Output

It should output the time until Brexit in the format ddd:hh:mm:ss. Leading and trailing newlines are allowed but the display should stay in the same place each time. It should look as though it is actually decreasing in place. As pointed out by @AnthonyPham this doesn't mean printing enough newlines to "clear" the screen, this means that you must actually clear the screen.

An output like this isn't allowed:

100:20:10:05
100:20:10:04

Neither is this

100:20:10:05
*A thousand newlines*
100:20:10:04

as they're on more than one line.

You don't have to worry about after Brexit. Your program only has to work up to 31/3/2019

Rules

  • Standard loopholes are disallowed
  • This is so shortest code in bytes wins.
  • Error messages (although I can't think how) are disallowed
  • The code should be able to be run in 2 years time (when the UK leaves the EU) and should display the actual time and not start from 730 again (see below)

Countdown rule

The countdown should not be hard-coded and should be able to run at any time before Brexit finishes and still produce the correct result. When a new day is begun the hour should follow the below format

712:00:00:01
712:00:00:00
711:23:59:59

Let me say again, the date Brexit finishes is 31/3/2019 at midnight for convenience (31:3:19 00:00:00 or 31:3:2019 00:00:00 or any other format you want)

NB: I think I have everything but I didn't post this in the Sandbox, otherwise the timing could have been off. Feel free to post any suggestions for improvements because it isn't perfect.

caird coinheringaahing

Posted 2017-04-02T17:33:20.243

Reputation: 13 702

Can I run it every millisecond but still give the appearance of updating every second? This is just to make my code shorter. – David Archibald – 2017-04-02T21:47:46.717

@DavidArchibald it only says that the display has to change every second. It's just that most answers will find it easier to run every second. – caird coinheringaahing – 2017-04-02T21:49:43.790

ahh. Well I have to put 1000 if I want it to change once a second. Thanks – David Archibald – 2017-04-02T21:53:59.447

Are leading zeros required? – Shaggy – 2017-04-03T12:38:55.810

@Shaggy yes leading 0s are required. – caird coinheringaahing – 2017-04-03T12:43:21.043

does the text theoretically being shown count? my console clears the screen too fast for it to be seen, but it definitely does get printed. – colsw – 2017-04-03T20:47:03.683

@ConnorLSW I've run your program and can make out the countdown so it should be fine. – caird coinheringaahing – 2017-04-03T20:54:36.487

Half a second before Brexit, what should be the output? Are both 00:00:00:00 and 00:00:00:01 acceptable? – Eric Duminil – 2017-04-04T12:43:38.660

@EricDuminil It should be 000:00:00:01 because it still (theoretically) is still in the delay. Although in reality the world will explode at that very instant so we don't need to worry about that. – caird coinheringaahing – 2017-04-04T12:46:19.950

1Midnight what timezone: UCT or GMT? Do we have to take that into account? – Titus – 2017-04-07T10:51:50.283

Answers

12

JavaScript, 134 129 113 bytes

setInterval("d=-new Date;document.body.innerHTML=`<pre>${d/864e5+17986|0}:`+new Date(d).toJSON().slice(11,19)",1)

Edit: Saved 2 bytes thanks to @Shaggy. Saved 11 bytes thanks to @l4m2.

Neil

Posted 2017-04-02T17:33:20.243

Reputation: 95 035

Managed to beat you @Neil... by a few bytes. – David Archibald – 2017-04-03T03:35:19.193

Why not use <a id=0>? Or something like that? – Solomon Ucko – 2017-04-03T15:08:51.643

3Or even document.body.innerHTML instead of o.innerHTML – cloudfeet – 2017-04-03T15:43:40.413

1I wanted it to be monospace to ensure that the display stays in the same place, but I guess I could save a byte and use <tt>. – Neil – 2017-04-03T18:34:48.283

3You could save 2 bytes by running the code every millisecond (or 2, or 3 ...). – Shaggy – 2017-04-04T08:47:45.330

setInterval("d=-new Date;document.body.innerHTML=(d/864e5+17986|0)+':'+new Date(d).toJSON().slice(11,19)",1) – l4m2 – 2018-07-08T11:36:00.057

11

PowerShell, 70 63 55 53 Bytes

Excluded double quotes, easy -2 thanks to @Joey

for(){cls;(date 31Mar19)-(date)|% T* ddd\:hh\:mm\:ss}

Running this with sleep adds 8 bytes, but the input is mostly invisible if it is run without them, version (63 bytes) with sleep:

for(){cls;(date 31/3/19)-(date)|% T* ddd\:hh\:mm\:ss;sleep 1}

for() is an infinite loop, and within that loop..

cls to clear the screen,

get 31/3/19 as a DateTime object, and - the current date from it, to give the time remaining, then .ToString() (|% T*) that with the correct format.

this will display negative time after brexit.

colsw

Posted 2017-04-02T17:33:20.243

Reputation: 3 195

This is also sensitive to local date format. Though the UK dd/m/yy format is appropriate, imo, it won't run as-is on US machines. I'm curious how the T* works. I'm not familiar with that. – Joel Coehoorn – 2017-04-03T20:57:10.767

@JoelCoehoorn It's a nice trick, the % foreach actually picks up the ToString object, and will accept the next string as its argument. regarding the datetime format why won't it run on US machines? I thought the dd etc were culture-insensitive. – colsw – 2017-04-03T21:04:47.103

It's trying to find month #31 on my machine. Works fine if I change it to 3/31/19. Would also work 2019-03-31 anywhere, but that costs you a few bytes. – Joel Coehoorn – 2017-04-03T21:15:49.887

@JoelCoehoorn ah right - sorry I was thinking of the output, Updated to 31Mar19 instead of 31/3/19 which should hopefully fix it? – colsw – 2017-04-03T21:18:03.443

I think I get it for T*. * is a wild card that would match the first function or property starting with T, which happens to be ToString() ? – Joel Coehoorn – 2017-04-03T21:18:04.150

@JoelCoehoorn Yep! there's a nice writeup here which should explain it in detail.

– colsw – 2017-04-03T21:19:48.510

I was playing with this, and I got the carriage-return (\r) trick used by others to work, but it's back at 70 bytes: for(){[Console]::Write("``r{0:ddd\:hh\:mm\:ss}",(date 3/31/19)-(date))} – Joel Coehoorn – 2017-04-03T21:24:57.103

@JoelCoehoorn one of the issues is that powershell sticks newlines in on all 'default' outputs, so the \r only resets that line, I don't see a way of getting it shorter without using [Console]::Write or Write-Host -NoNewLine etc. – colsw – 2017-04-03T21:27:48.907

But cls;;sleep 1 is 12 bytes on it's own, which Write() would obviate if there were a shorter way to call it. Of course, skipping the ;sleep 1 helps. – Joel Coehoorn – 2017-04-03T21:33:01.137

@JoelCoehoorn I don't think you'll beat the 4 bytes of cls; - "r"` on its own is the same length, and implicit output is free compared to the minimums required for a single-line write. – colsw – 2017-04-04T09:07:08.257

1You can lose the quotes around the format string, as command argument parsing applies. – Joey – 2018-07-08T20:04:04.490

7

Excel VBA, 91 84 82 bytes

Saved 7 bytes thanks to JoeMalpass pointing out that Excel sees dates as numbers.
Saved 2 bytes thanks to JoeMalpass

Sub b()
Do
t=CDec(43555-Now)
Cells(1,1)=Int(t) &Format(t,":hh:mm:ss")
Loop
End Sub

Output is to cell A1 in the active Excel sheet.

Engineer Toast

Posted 2017-04-02T17:33:20.243

Reputation: 5 769

-6 bytes by swapping ("2019-3-31") with (43555). When I try running this in Excel however, it freezes after about 5-6 seconds... – CactusCake – 2017-04-03T14:54:46.623

1@JoeMalpass Thanks, that's a good point. It looks up after a few seconds for me, too, because it's calculating way faster than 1/second. Adding delays, though, adds bytes and the OP doesn't say it has to be able to continuously count down from now until Brexit without setting anything on fire. – Engineer Toast – 2017-04-03T16:16:42.007

Apparently Now works without the () too... – CactusCake – 2017-04-03T19:21:29.153

6

Python 3.6, 146 bytes

from datetime import*
x=datetime
while 1:d=x(2019,3,31)-x.now();s=d.seconds;a=s%3600;print(end=f"\r{d.days:03}:{s//3600:02}:{a//60:02}:{s%60:02}")

ovs

Posted 2017-04-02T17:33:20.243

Reputation: 21 408

5

C#, 173 172 156 150 127 bytes

using System;class P{static void Main(){for(;;)Console.Write($"\r{new DateTime(2019,3,31)-DateTime.Now:d\\:hh\\:mm\\:ss}  ");}}

Saved 16 bytes thanks to @Bob Saved 6 bytes thanks to @Søren D. Ptæus

Formatted version:

using System;

class P
{
    static void Main()
    {
        for (;;)
            Console.Write($"\r{new DateTime(2019, 3, 31) - DateTime.Now:d\\:hh\\:mm\\:ss}  ");
    }
}

TheLethalCoder

Posted 2017-04-02T17:33:20.243

Reputation: 6 930

Can you do (TimeSpan)0? On phone, can't test right now. You can still drop the clear as the carriage return takes care of it: it puts the cursor back at the start of the line. – Bob – 2017-04-03T08:42:55.540

2Thought: relying on the CR might fail if the length changes (less than 100 days). Fix: add two extra spaces on end. – Bob – 2017-04-03T08:45:24.873

@Bob I forgot to remove the Clear! Silly me. And no can't convert int to TimeSpan I'd already tried that one. – TheLethalCoder – 2017-04-03T08:54:02.927

You can save 6 bytes writing (t = new DateTime(2019, 3, 31) - DateTime.Now).Ticks > 0. – Søren D. Ptæus – 2017-04-03T12:14:29.570

@SørenD.Ptæus Good idea didn't even think of that one – TheLethalCoder – 2017-04-03T12:53:08.900

4

JavaScript ES5, 320 319 316 305 295 284 bytes

setInterval(function(){a=Math,b=a.floor,c=console,d=Date,e="00",f=new d(2019,2,31),g=a.abs(f-new d)/1e3,h=b(g/86400);g-=86400*h;var i=b(g/3600)%24;g-=3600*i;var j=b(g/60)%60;g-=60*j,c.clear(),c.log((e+h).slice(-3)+":"+(e+i).slice(-2)+":"+(e+j).slice(-2)+":"+(e+a.ceil(g)).slice(-2))})

Thanks to @Fels for referencing Math, @dgrcode for referencing console

Un-golfed

setInterval(function() {

  var math = Math, floor = math.floor, c = console, d = Date;

  var leadings = "00";

  // set our brexit date
  var brexit = new d(2019, 2, 31);

  // get total seconds between brexit and now
  var diff = math.abs(brexit - new d()) / 1000;

  // calculate (and subtract) whole days
  var days = floor(diff / 86400);
  diff -= days * 86400;

  // calculate (and subtract) whole hours
  var hours = floor(diff / 3600) % 24;
  diff -= hours * 3600;

  // calculate (and subtract) whole minutes
  var minutes = floor(diff / 60) % 60;
  diff -= minutes * 60;

  // what's left is seconds

  // clear the console (because OP said it must print in the same place)
  c.clear();

  // log the countdown, add the leadings and slice to get the correct leadings 0's
  c.log((leadings + days).slice(-3) + ":" + (leadings + hours).slice(-2) + ":" + (leadings + minutes).slice(-2) + ":" + (leadings + math.ceil(diff)).slice(-2));

});

cnorthfield

Posted 2017-04-02T17:33:20.243

Reputation: 181

2You can save a bit my renaming Math like g=Math; – Fels – 2017-04-03T12:08:06.440

It looks like aliasing Math can still save 2 bytes, right? – Marie – 2017-04-03T16:06:46.060

You can save a bit more by using arrow functions and getting rid of var. Also, pick shorter names for variables, like h instead of hours, or m instead of minutes. Probably doing c=console will save a couple more bytes. Also 1e3 instead of 1000 – Daniel Reina – 2017-04-03T16:44:49.440

4

PHP, 84 bytes

for(;$c=DateTime;)echo(new$c('@1553990400'))->diff(new$c)->format("\r%a:%H:%I:%S ");

Fairly straightforward. 1553990400 is the timestamp for 31-3-2019 00:00:00 in UTC. It loops infinitely, using DateTime->diff()->format() to output how much time is left. After Brexit has happened, it will start counting up from 0.

Commented / more readable version:

// Infinite loop, assign DateTime (as a string) to $class
for (; $class = DateTime;) {
    echo (new $class('@1553990400')) // Create a new DateTime object for the brexit date/time.
            ->diff(new $class) // Caulculate the difference to the current date/time.
            ->format("\r%a:%H:%I:%S "); // Format it according to the specification, starting with a \r character to move to the start of the line and overwrite the previous output.
}

chocochaos

Posted 2017-04-02T17:33:20.243

Reputation: 547

New here, and about to post my own answer. A few things: 1. Are we allowed to omit the <? tag here? 2. I think your parenthesis are wrong, right now you're calling ->diff on the echo rather than the DateTime object. 3. echo works without parenthesis anyway. 4. Even after fixing this, this doesn't work for me, but I'm new to golfing so that could just be me being an idiot. – Sworrub Wehttam – 2017-04-04T08:12:50.727

2 more things, without flushing, wouldn't this just run forever and never display anything? And if not, I'm pretty sure this would keep building a massive string rather than refreshing the timer as per the questions requirements – Sworrub Wehttam – 2017-04-04T08:16:38.320

1Just run it and see, it works fine, as per the requirements. There is no need to flush when running PHP from the command line. There's a \r at the beginning of the string to move the cursor to the start of the line, it keeps overwriting the previously outputted time. It's the same method that many other answers here are using. – chocochaos – 2017-04-04T09:17:54.627

1Sorry, I missed your first comment. Yes, we are allowed to omit the opening tags, unless there is a requirement to supply a full program. The parenthesis are just fine the way they are. Yes, echo works without it, but calling diff on the DateTime object does not work without them. It runs fine here, what PHP version are you using and how are you running the program? :) – chocochaos – 2017-04-04T09:22:20.977

1

You might want to check out some posts here: https://codegolf.meta.stackexchange.com/questions/tagged/php

– chocochaos – 2017-04-04T09:36:22.257

1That just about covers it, thanks for the insight :) – Sworrub Wehttam – 2017-04-04T09:41:37.277

I have added a more readable version of the code with some explanation. Perhaps that clear things up a bit =) – chocochaos – 2017-04-04T09:49:21.220

@SworrubWehttam omitting the <? is possible by use of php -r which implicitly adds it avywyay. Since command line flags are counted as a different language it should be added to the header: PHP + `-r` or something similar. Hope that helps! – Dom Hastings – 2018-06-21T05:26:37.763

4

CJam, 69 62 59 57 bytes

Saved 7 bytes by converting to time format differently

Saved 3 bytes thanks to Martin Ender's suggestions

Saved 2 bytes by using a carriage return instead of backspaces

{15539904e5esm1e3/{60md\}2*24md\]W%{sYTe[}%':*CTe[oDco1}g

Can't be run on TIO for obvious reasons.

It rewrites the display constantly in an infinite loop so the text kind of flashes in and out (at least in my console), although it only actually updates the time once per second.

This 70-byte version only prints once per second:

{15539904e5es:Xm1e3/{60md\}2*24md\]W%{sYTe[}%':*CTe[oDco{esXm1e3<}g1}g

Explanation

{                           e# Begin a while loop
  15539904e5                e#  The timestamp on which Brexit will occur
  es                        e#  The current timestamp
  m                         e#  Subtract
  1e3/                      e#  Integer divide by 1000, converting to seconds from ms
  {                         e#  Run this block twice
   60md                     e#   Divmod by 60
   \                        e#   Swap top elements
  }2*                       e#  (end of block) 
                            e#    This block divmods the timestamp by 60, resulting in 
                            e#    the remaining minutes and seconds. Then the minutes get 
                            e#    divmod-ed by 60, to get hours and minutes remaining
  24md\                     e#  Divmod hours remaining by 24 and swap top elements, to get
                            e#    the hours left and days left.
  ]                         e#  Wrap the entire stack in an array
  W%                        e#  Reverse it since it's currently in the wrong order
  {                         e#  Apply this block to each element of the array
   s                        e#   Cast to string (array of digit characters)
   YTe[                     e#   Pad to length 2 by adding 0s to the left
  }%                        e#  (end of map block)
  ':*                       e#  Join with colons
  CTe[                      e#  Pad to length 12 by adding 0s to the left, dealing with the
                            e#    special case of the day being 3 digits. 
  o                         e#  Pop and print the resulting string, which is the time
  Dco                       e#  Print a carriage return, moving the cursor back to the start
  1                         e#  Push 1
}g                          e# Pop 1, if it's true, repeat (infinite loop)

Business Cat

Posted 2017-04-02T17:33:20.243

Reputation: 8 927

Can't test right now, but you can probably replace Ab with s, and save a byte by doing 1e3/ first and then divide in the opposite order 60md\60md\24md\]W%. – Martin Ender – 2017-04-03T20:53:09.380

@MartinEnder Yep, they both work. Thanks – Business Cat – 2017-04-03T20:57:42.567

Oh and {60md\}2* saves another. – Martin Ender – 2017-04-03T20:58:12.153

4

AHK, 145 Bytes

This is not the shortest answer but the result gives a very nice feeling of doom, I think. I originally tried to send the keystrokes Ctrl+A followed by DEL and then whatever the time was but the refresh rate was too slow and it would destroy whatever environment you were in. Instead, then, I went with the GUI. It turned out to take less bytes to completely destroy the window and recreate it than it did to update the control over and over so I went with that. It's a nice effect.

Loop{
s=20190331000000
s-=A_Now,S
d:=t:=20000101000000
t+=s,S
d-=t,D
d*=-1
FormatTime f,%t%,:HH:mm:ss
GUI,Destroy
GUI,Add,Text,,%d%%f%
GUI,Show
}

I'm gonna sing the doom song!

Engineer Toast

Posted 2017-04-02T17:33:20.243

Reputation: 5 769

3

C#6, 149 bytes

Thanks to Bob for saving 57 bytes!

using System;class P{static void Main(){DateTime a,x=new DateTime(2019,3,31);while((a=DateTime.Now)<x)Console.Write($"\r{x-a:ddd\\:hh\\:mm\\:ss}");}}

Ungolfed program:

using System;

class P
{
    static void Main()
    {
        DateTime a,
                x = new DateTime(2019, 3, 31);
        while ( (a = DateTime.Now) < x)
            Console.Write($"\r{x-a:ddd\\:hh\\:mm\\:ss}");
    }
}

C#, 210 206 159 bytes

Thanks to Bob for saving another 47 bytes!

Thanks to Martin Smith for saving 4 bytes!

using System;class P{static void Main(){DateTime a,x=new DateTime(2019,3,31);while((a=DateTime.Now)<x)Console.Write("\r"+(x-a).ToString(@"ddd\:hh\:mm\:ss"));}}

Ungolfed program:

using System;

class P
{
    static void Main()
    {
        DateTime a,
                x = new DateTime(2019, 3, 31);
        while ( (a = DateTime.Now) < x)
            Console.Write("\r" + (x - a).ToString(@"ddd\:hh\:mm\:ss"));
    }
}

adrianmp

Posted 2017-04-02T17:33:20.243

Reputation: 1 592

1new DateTime(2019,3,31) is shorter. – Martin Smith – 2017-04-03T04:54:53.933

You can save a bit by doing namespace System{} instead of using System; (which lets you remove the System. on the sleep call). – Bob – 2017-04-03T06:25:57.967

1You can also remove the Console.Clear and instead prepend "\r" to the string, e.g. "\r"+(x-a)... – Bob – 2017-04-03T06:43:16.093

1More improvements: (x-a).ToString(@"d\:hh\:mm\:ss") is equivalent to String.Format("\r{0:d\\:hh\\:mm\\:ss}",x-a) is equivalent to $@"{x-a:d\:hh\:mm\:ss}" (shorter, interpolated string in C# 6.0). If you do that, you can then further shorten the full "\r"+$@"{x-a:d\:hh\:mm\:ss}" into $"\r{x-a:d\\:hh\\:mm\\:ss}". – Bob – 2017-04-03T06:49:19.670

@Bob The OP states that you must clear the screen. – TheLethalCoder – 2017-04-03T08:07:04.847

1@TheLethalCoder I took that as simply not allowing a "fake" multi-newline approach. A carriage return still overwrites the only thing on the screen. At least one other answer also uses this approach. Also can remove the sleep as it's only important that the display changes once per second, with non-changing updates allowed (see question comments). edit: actually, question comments also explicitly allow the CR... – Bob – 2017-04-03T08:12:55.283

1@Bob Sorry I read your suggestion as a new line, my mistake. But yeah the sleep can be removed – TheLethalCoder – 2017-04-03T08:15:37.143

@Bob I used your interpolation suggestion in my answer, it works well :) – TheLethalCoder – 2017-04-03T08:26:25.040

I think you can save bytes by using a for loop and declaring the variables in that, not sure though. – TheLethalCoder – 2017-04-03T15:09:51.427

I saved 24 more (125 total) by not caring what happens after Brexit, tightening up the loop, and using the format overload for Console.Write() rather than declaring variables. I was starting from SLC's answer and couldn't edit, so I posted it to my own answer. But it's the same basic \r trick that makes it possible, which I wouldn't have found on my own – Joel Coehoorn – 2017-04-03T20:31:43.077

3

Python 3.5 (118 Bytes)

import datetime as d,os
d=d.datetime
while 1:os.system("cls");e=str(d(2019,3,31)-d.today());print(e[:3]+':'+e[-15:-7])

officialaimm

Posted 2017-04-02T17:33:20.243

Reputation: 2 739

3

Ruby (83 bytes)

loop{h=431664-Time.now.to_r/3600;$><<['%02d']*4*?:%[h/24,h%24,h%1*60,h*3600%60]+?\r}

Ungolfed

loop do
  seconds = 1553990400 - Time.now.to_r

  print (["%02d"] * 4).join(':') % [
    seconds / 24 / 60 / 60     ,
    seconds      / 60 / 60 % 24,
    seconds           / 60 % 60,
    seconds                % 60,
  ] + "\r"
end

Basically one of the Python submissions, with some improvements. We just emit an "\r" to go beginning of the string before re-rendering. And for the string format of "%03d:%02d:%02d:%02d", we really don't care about the width on the first specifier… so we can just do "%02d"*4, and emit a backspace and a space to clear the extra unnecessary colon.

Also, I found a two-character shorter print: $><<. $> is a shorthand global for $defout, which is the output stream for print and printf and defaults to STDOUT. IO#<< writes the right hand side of it to the stream. How is that two characters shorter? Well, I can now omit the space that led before the parenthesis wrapping the format string.

At this point I genuinely think there is no possible way to shorten this program further in Ruby.

Edit: I was wrong. Instead of the first Time.new(2019,3,31), we can just use the raw UNIX time: 1553990400.

Edit 2: I've tried playing around with factoring out minutes, and dividing the UNIX timestamp by that constant, but it doesn't actually wind up saving any bytes. :(

Edit 3: Turns out caching h=3600 actually hurt me by two bytes. Whoops.

Edit 4: Saved 3 bytes thanks to @EricDuminill. He used floats, but rationals work without loss of precision!

Edit 5: Array#* as an alias for Array#join, with the Ruby ?-syntax for individual characters!

Stephen Touset

Posted 2017-04-02T17:33:20.243

Reputation: 161

Working with hours instead of seconds seems to save 3 bytes : loop{h=431664-Time.now.to_f/3600;$><<('%02d:'*4+"\b \r")%[h/24,h%24,h%1*60,3600*h%60]} Seconds might be off by 1 though, due to rounding. – Eric Duminil – 2017-04-04T12:50:18.783

Thanks! Tied with PHP now. :) I used to_r instead of to_f to preserve precision. – Stephen Touset – 2017-04-04T17:34:44.803

You're welcome. This clock might still be 1s early though, even with .to_r instead of .to_f – Eric Duminil – 2017-04-04T17:44:49.770

@StephenTouset You can move +"\r" to the right of the array. This enables you to use ['%02d']*4*?: instead of '%02d:'*4+"\b " so you can lose the parentheses, which nets you one byte. Save yet another byte by writing +?\r instead of +"\r". – Synoli – 2017-04-04T21:29:56.990

Excellent discovery! – Stephen Touset – 2017-04-04T21:41:05.073

3

C, 104 bytes

main(x){for(;x=1553990400-time(0);)printf("\n%03d:%02d:%02d:%02d\e[1A",x/86400,x/3600%24,x/60%60,x%60);}

Breakdown

main(x){
    for(;x=1553990400-time(0);)             // Seconds remaining
        printf("\n%03d:%02d:%02d:%02d\e[1A",// Move cursor and print:
            x/86400,                        // Days
            x/3600%24,                      // Hours
            x/60%60,                        // Minutes
            x%60);                          // Seconds
    puts("Now we can stop talking about it forever."); // Wishful thinking
}

Relies on time returning number of seconds since 01/01/1970, which is the case for me (using Clang/GCC on macOS) and should be the case for most UNIX stuff.

Uses bash terminal escape sequences to move the cursor around (<esc>[1A moves the cursor up 1 line). It would be nicer to be able to simply use \r, but printf won't flush until it sees a newline, and flushing it manually takes a lot more.

Probably the most CPU intensive countdown I've ever seen. Runs in a hot loop to make sure it's always as accurate as can be. If run after the deadline, it will produce some pretty weird stuff (negatives everywhere!)

Dave

Posted 2017-04-02T17:33:20.243

Reputation: 7 519

@TobySpeight sure, corrected. I think of them as bash because I always use this reference page: http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html

– Dave – 2017-04-03T15:33:57.110

Are there any rules for the form of main in C? In C90: omitting return from main causes UB in case the caller (OS) will use the return value. In standard C: main(x) is not a valid form of main, implicit int has been removed from the language. I believe the minimal, safe version is int main(){}. – Lundin – 2017-04-04T12:45:14.757

@Lundin in code golf, languages are defined by their implementation (i.e. if you can find a publicly available compiler which compiles the code how you want, you can do it, but if it needs non-standard flags setting, those flags count towards your bytecount). You're correct that this is nowhere near standards compliant (as well as the things you've noticed, there's implicitly defined functions due to no imports and the reliance on time returning a number of seconds since 01/01/1970). Take a look at meta for the (rather disperse) rules people follow around here. – Dave – 2017-04-04T17:38:57.260

Part of the fun of code golf challenges is discovering bizarre language hacks and obsolete features! – Dave – 2017-04-04T17:40:29.363

3

C#, 128 127 Bytes

using System;class P{static void Main(){for(;;)Console.Write($"\r{new DateTime(2019,3,31)-DateTime.Now:ddd\\:hh\\:mm\\:ss}");}}

Ungolfed code:

using System;
class P
{
    static void Main()
    {
        for(;;)
            Console.Write($"\r{new DateTime(2019,3,31)-DateTime.Now:ddd\\:hh\\:mm\\:ss}"); 
    }
}

I would not have figured out the \r trick without help from the other C# answers here.

For anyone looking for further improvement, you can also put the Write() expression inside the for loop. Seems like I should be able to save a byte somehow here, because that saves me the semi-colon for that statement, but it works out to the same number because you can't have a fully empty body:

using System;class P{static void Main(){for(;;Console.Write($"\r{new DateTime(2019,3,31)-DateTime.Now:ddd\\:hh\\:mm\\:ss}"));}}

Joel Coehoorn

Posted 2017-04-02T17:33:20.243

Reputation: 355

Welcome to PPCG! – Martin Ender – 2017-04-03T20:10:10.200

You can still save a single character by using an interpolated string ;) Console.Write($"\r{new DateTime(2019,3,31)-DateTime.Now:ddd\\:hh\\:mm\\:ss}"); – Bob – 2017-04-04T00:11:08.113

Well played, I tried to find a way to have a while (true) loop in the shortest possible code! I'll remember that trick. You may need to add a couple of spaces like I did though to your write otherwise when the days goes from 3 digits to 2 digits, it won't overwrite the last character of your time string and you'll get a weird output – NibblyPig – 2017-04-04T08:00:42.517

You can save a byte by using an interpolated string like in my answer. Your format of dddpads the zeroes, looks better than the two spaces method nice. – TheLethalCoder – 2017-04-04T08:25:19.647

Updated for the interpolated string. – Joel Coehoorn – 2017-04-04T18:59:20.353

2

Bash + GNU date, 128 bytes

2 bytes shaved off thanks to @muru, and 2 off earlier thanks to @This Guy.

C=:%02d;while sleep 1;do D=$[B=3600,A=24*B,1553990400-`date +%s`];printf "%03d$C$C$C\r" $[D/A] $[D%A/B] $[D%A%B/60] $[D%60];done

Ungolfed

DAY=86400
HOUR=3600
while sleep 1 ; do
 DIFF=$[1553990400-`date +%s`]
 printf "%03d:%02d:%02d:%02d\r" \
         $[DIFF/DAY] \
         $[DIFF%DAY/HOUR] \
         $[DIFF%DAY%HOUR/60] \
         $[DIFF%60]
done

steve

Posted 2017-04-02T17:33:20.243

Reputation: 2 276

1Never golfed in Bash before but can you remove the spaces at the while: while[1]? – caird coinheringaahing – 2017-04-02T19:45:51.527

Fair point, have now given that a try but it yields line 1: [1]: command not found error. Spaces are mandatory it seems :-( – steve – 2017-04-02T21:15:27.257

2Assign 3600 to a variable to save 2 bytes? You might also be able to change B=3600;A=86400 to B=3600;A=24*B for another byte? – caird coinheringaahing – 2017-04-02T22:03:24.390

3600 variable now done, thx. 24B would need `A=$[24B]` so not possible there though – steve – 2017-04-02T22:09:23.810

that's a shame. I'm used to python so... – caird coinheringaahing – 2017-04-02T22:10:23.833

1C=:%02d;printf "%03d$C$C$C\r" to save a byte? And move the assignments to A and B in the arithmetic context: D=$[B=3600,A=24*B,1553990400-`date +%s`] to save another? – muru – 2017-04-03T10:47:51.813

2

JavaScript+HTML, 136+7=143 bytes

setInterval("d=1553990400-new Date/1e3|0;w.innerText=[60,60,24,999].map(z=>(q='00'+d%z,d=d/z|0,q.slice(z<61?-2:-3))).reverse().join`:`")
<a id=w

user12864

Posted 2017-04-02T17:33:20.243

Reputation: 151

Does the score make it a... love byte?

– Engineer Toast – 2017-04-03T18:32:41.253

2

C#, 142 bytes

using System;class P{static void Main(){a:Console.Write($"\r{(new DateTime(2019,3,31)-DateTime.Now).ToString("d\\:h\\:mm\\:ss  ")}");goto a;}}

Ungolfed program:

using System;
class P
{
    static void Main()
    {
        a: Console.Write($"\r{(new DateTime(2019, 3, 31) - DateTime.Now).ToString(@"d\:h\:mm\:ss  ")}"); goto a;
    }
}

NibblyPig

Posted 2017-04-02T17:33:20.243

Reputation: 141

This won't stop printing when it hits brexit, not sure if that's a problem – TheLethalCoder – 2017-04-03T15:10:56.770

@TheLethalCoder That's legal. The instructions specifically state the code only has to work until 31/3/2019, and what happens after that doesn't matter. If you can save bytes by having weird output or even exceptions after that date, then more power to you. – Joel Coehoorn – 2017-04-03T16:46:14.867

Also: I suspect it will be possible to get this even shorting by skipping the ToString() bytes and instead build the formatting into the Write() method, or maybe an interpolated string – Joel Coehoorn – 2017-04-03T16:48:38.193

Okay... it's definitely possible. I have it down to 127 bytes. I'm appending it below your original, so you still get credit for the basic goto idea. – Joel Coehoorn – 2017-04-03T17:10:30.300

My edit go wiped :( Guess I'll have to post my own answer. – Joel Coehoorn – 2017-04-03T20:01:39.857

Have it even shorter now without the goto, so I've earned my own answer anyway. – Joel Coehoorn – 2017-04-03T20:12:50.140

Always new goto was a hidden gem of good programming – NibblyPig – 2017-04-04T07:59:31.607

@SLC I don't think code gold is good programming, just clever haha – TheLethalCoder – 2017-04-04T08:15:10.220

2

MATL, 45 bytes

737515`tZ'-tkwy-':HH:MM:SS'XOw'%03d'YDwYcDXxT

TIO apparently doesn't support clearing the output, but thankfully MATL Online does!

At 2 bytes more, a bit more CPU-friendly version that does a pause (sleep) every second:

737515`tZ'-tkwy-':HH:MM:SS'XOw'%03d'YDwYcDT&XxT

Try this on MATL Online

737515 is "31st of March 2019" represented MATLAB's default epoch format - number of days from January 0, 0000, optionally including a fractional part to represent the time of day. (I tried to shorten this by calculating it somehow, but its only factors are 5 and another six digit number (147503), and I couldn't figure out a way to do it in less than 6 bytes.)

`    % start do-while loop
tZ`- % duplicate Brexit date, get current date (& time), subtract
tk   % duplicate the difference, get the floor of it (this gives number of days left)
w    % switch stack to bring unfloored difference to top
y    % duplicate the floored value on top of that
-    % subtract to get fractional part representing time
':HH:MM:SS'XO % get a datestr (date string) formatted this way
w    % switch to bring number of days back on top
'%03d'YD      % format that to take 3 places, with 0 padding if needed
wYc  % switch to bring time string back on top, concatenate date and time
D    % display the concatenated result!
T&Xx % clear screen after a 1 second pause (the pause is optional, without it the call is `Xx`)
T    % push True on stack to continue loop

sundar - Reinstate Monica

Posted 2017-04-02T17:33:20.243

Reputation: 5 296

1

PHP, 64 bytes

while($d=1553990401-time())echo--$d/86400|0,date(":H:i:s\r",$d);

This will count exactly until 0:00:00:00 and then break/exit. Run with -r.

-2 bytes if I wouldn´t have to print the 0.

Titus

Posted 2017-04-02T17:33:20.243

Reputation: 13 814

1

RPL, 83 78 bytes

Assuming your HP48, or similar, is setup with correct (UK) time and date, mm/dd date format, and 24h time format:

WHILE 1REPEAT DATE 3.302019DDAYS":"1.1 24TIME HMS- TSTR 15 23SUB + + 1DISP END

I was surprised to be able to save 2 bytes by removing spaces around ":". 1.1 is the shortest valid date, later dumped by SUB. Be careful with emulators, the time may run faster or slower (or not at all) than your wall clock. With a real HP, you can stop this program by pressing the ON key … or wait for empty batteries.

Nacre

Posted 2017-04-02T17:33:20.243

Reputation: 81

0

PHP, 102 95 90 bytes

Saved 7 bytes thanks to @TheLethalCoder & by not factoring

Saved another 5 bytes by concatenating

<? $b=1553990400-time();echo floor($b/$d=86400).date(':H:i:s', $b%$d);header('Refresh:1');

This is my first golf, so I'm probably missing quite a few tricks, but here you are regardless.

As for @chocochaos' PHP answer that would otherwise trump this, I believe it is flawed for reasons I have explained in my comments, but as I'm new here I might be wrong. Or I'm just a newbie :)

Sworrub Wehttam

Posted 2017-04-02T17:33:20.243

Reputation: 101

You may need a closing tag? (Not sure on that). You only use $a once so might as well use the number in place. I'm not too familiar with php but looks like there could be more improvements – TheLethalCoder – 2017-04-04T08:28:24.330

What do you mean by flawed because of reasons stated in the comments? If you mean the comments on their answer, you're the only one who's commented. – caird coinheringaahing – 2017-04-04T08:32:03.990

@TheLethalCoder No closing tag needed. And nice one! – Sworrub Wehttam – 2017-04-04T08:37:11.017

@ThisGuy Yes, I mean "as shown in my comments", I'll edit to satisfy your pedantry :) – Sworrub Wehttam – 2017-04-04T08:38:15.573

1You can save ~7 bytes by using a <?= opening tag and dropping the echo, assigning $b in the place you first use it. Additionally you can save 3 bytes using ^0 instead of floor. It's bitwise or and involves a cast to int, it's the shortest way to cast to int I've seen. – user59178 – 2017-04-04T08:58:19.690

1

My answer runs just fine :) Also, you might want to read up on some posts here: https://codegolf.meta.stackexchange.com/questions/tagged/php

There's no need for opening tags either. I would really recommend to write your solution in such a way that it would run from the command line, then you would not have to mess around with headers to refresh. That refresh will also cause your solution to "miss" a second once in a while, because it does not take into account the time lost on the request itself.

– chocochaos – 2017-04-04T09:41:59.957

0

AWK, 78 bytes

BEGIN{for(;v=1552953600-systime();printf"\r%d:%s",v/86400,strftime("%T",v)){}}

Try it online!

Was longer before I realized I could precalculate the end time. Sometimes it pays to be a bit late to the game and get ideas from others.

FYI, the TIO link doesn't work very well, since it doesn't implement \r properly.

Robert Benson

Posted 2017-04-02T17:33:20.243

Reputation: 1 339

0

F#, 142 bytes

open System
let f=
 let t=DateTime(2019,3,31)
 while DateTime.Now<=t do Console.Clear();t-DateTime.Now|>printf"%O";Threading.Thread.Sleep 1000

I grew up in Ireland about half a kilometre from the border. Apart from a "Welcome to Fermanagh" sign and the road markings changing you wouldn't know you'd entered another country. Used to cross it twice on the way to school.

Ciaran_McCarthy

Posted 2017-04-02T17:33:20.243

Reputation: 689

0

c, gcc 114 bytes

main(s){system("clear");if(s=1553900399-time(0)){printf("%d:%d:%d:%d\n",s/86400,s/3600%24,s/60%60,s%60);main(s);}}

Nothing omitted, full program. The program compiles in gcc on Ubuntu. The countdown will not show a long trail of print statements because of the system call to clear and halts when the countdown reaches 0 seconds.

UnGolfed

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>


//Brexit countdown timer
int main(){
  int sec = 1553900400 - time(0);//seconds remaining until Brexit
  if(sec){
    sleep(1);
    system("clear");
    printf("Brexit Countdown\n");
    printf("days Hours Mins Secs\n");
    printf("%d:  %d:    %d:  %d\n",
            sec/86400, sec/3600%24,
            sec/60%60, sec%60);
    main();
  }
}

Geo

Posted 2017-04-02T17:33:20.243

Reputation: 91