Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

This challenge is inspired by xkcd:

enter image description here

Challenge:

You'll simulate the copying a large file (1 Gigabyte). The transfer rate will vary between 10 kB/second to 100 MB/second. Your task is to output the time remaining of the file transfer. The output should look like:

Time remaining: 03:12    (meaning it's 3 minutes and 12 seconds left)
Time remaining: 123:12   (meaning it's 2 hours, 3 minutes and 12 seconds left)
Time remaining: 02:03:12 (optional output, meaning the same as above)

Leading zeros need not be displayed for minutes and hours (optional), but must be shown for seconds. Showing the time remaining using only seconds is not OK.

The file transfer:

  • The transfer rate will start at 10 MB/second.
  • Every second, there will be a 30% chance that the transfer rate will change
  • The new transfer rated should be picked randomly (uniform distribution) in the range [10 kB/s, 100 MB/s], in steps of 10 kB/s.

Note: You don't need to actually copy a file.

You may choose to use: 1 GB = 1000 MB, 1 MB = 1000 kB, 1 kB = 1000 B, or 1 GB = 1024 MB, 1 MB = 1024 kB, 1 kB = 1024 B.

Output:

  • You start at 01:40, not 01:39.
  • You display the time after the transfer rate changes, but before anything is transferred at that rate
  • It's optional to round the time remaining up or down to the closest second.
  • You should clear the screen every second, unless that's impossible in your language.
  • The output should be constant: Time remaining: 00:00 when the file transfer is over.

Example:

I have rounded up all decimal seconds. Assume the lines below are shown with 1 second in between, and the screen is cleared between each one:

Time remaining: 01:40  (Transfer rate: 10 MB/s)
Time remaining: 01:39      1 GB - 10 MB
Time remaining: 01:38      1 GB - 2*10 MB
Time remaining: 01:37      1 GB - 3*10 MB
Time remaining: 01:28:54   1 GB - 4*10 MB  (TR: 180 kB/s)
Time remaining: 01:28:53   1 GB - 4*10 MB - 180 kB
Time remaining: 01:28:52   1 GB - 4*10 MB - 2*180 kB  
Time remaining: 00:13      1 GB - 4*10 MB - 3*180 kB  (TR: 75 MB/s)
Time remaining: 00:12      1 GB - 4*10 MB - 3*180 kB - 75 MB
Time remaining: 00:11      1 GB - 4*10 MB - 3*180 kB - 2*75 MB
Time remaining: 00:10      1 GB - 4*10 MB - 3*180 kB - 3*75 MB
Time remaining: 00:09      1 GB - 4*10 MB - 3*180 kB - 4*75 MB
Time remaining: 00:08      1 GB - 4*10 MB - 3*180 kB - 5*75 MB
Time remaining: 14:09:06   1 GB - 4*10 MB - 3*180 kB - 6*75 MB  (TR: 10 kB/s)
Time remaining: 14:09:05   1 GB - 4*10 MB - 3*180 kB - 6*75 MB - 10 kB
Time remaining: 00:06      1 GB - 4*10 MB - 3*180 kB - 6*75 MB - 20 kB  (TR: 88.110 MB/s)
Time remaining: 00:05
Time remaining: 00:04
Time remaining: 00:03
Time remaining: 00:02
Time remaining: 00:01
Time remaining: 00:00     <- Transfer is finished. Display this.
share|improve this question
    
You should put the XKCD tool-tip text below the image. Save people the time of having to look it up themselves. – mbomb007 15 hours ago
    
@mbomb007, hover the image :) – Stewie Griffin 15 hours ago
    
Should that be, "you start at 1:40 (or 1:42) not 1:39 (or 1:41)"? – Jonathan Allan 15 hours ago
    
Also if we are using the 1024 version, what are the step sizes we should be using? – Jonathan Allan 15 hours ago
    
If hours remaining is zero, can we leave output as 00:00:10 for example? – AdmBorkBork 14 hours ago

Pyth - 70 68 bytes

K^T5J^T3W>KZ%." r3úBTê;¥
í".D/KJ60=J?<OT3O^T4J=-KJ.d1.

Try it online without sleeps.

share|improve this answer
    
@DigitalTrauma sorry, was using Luis' answer as a guide ._. – Maltysen 10 hours ago
    
@DigitalTrauma fixed. – Maltysen 10 hours ago
2  
Lol. When porting from (golfing) language A to (golfing) language B is easier than reading the spec ;-) – Digital Trauma 10 hours ago
    
@Maltysen Sorry about that! :-) – Luis Mendo 10 hours ago
    
@DigitalTrauma forgot to take out the sleeps on the updated link. fixed now – Maltysen 9 hours ago

MATL, 78 bytes

Thanks to @Maltysen and @DigitalTrauma for corrections.

1e5 1e3`XK10&XxyXIy/t0>*12L/'MM:SS'XO'Time remaining: 'whD-r.3<?1e4Yr}K]I0>]xx

Try it at MATL Online! (you may need to press "Run" several times if it doesn't initially work). Note that the online interpretet times out after 30 seconds, so the program may not have time to finish. You may want to change 10 (pause time in tenths of second) to something smaller such as 3 in order to increase speed of display

Explanation

1e5                  % Push 1e5: file size in 10-kB units
1e3                  % Push 1e3: initial rate in 10-kB/s units
`                    % Do...while
  XK                 %   Copy current trate into clipboard K
  10&Xx              %   Wait 1 second and clear screen
  y                  %   Duplicate current file size onto the top of the stack
  XI                 %   Copy it to clipboard I
  y                  %   Duplicate current rate onto the top of the stack
  /                  %   Divide. This gives the estimated remaining time in seconds
                     %   It may be negative in the last iteration, because the
                     %   "remaining" file size may have become negative
  t0>*               %   If negative, convert to 0
  12L/               %   Push 86400 and divide, to convert from seconds to days
  'MM:SS'XO          %   Format as a MM:SS string, rounding down
  'Time remaining: ' %   Push this string
  wh                 %   Swap, concatenate
  D                  %   Display
  -                  %   Subtract. This gives the new remaining file size
  r                  %   Push random number uniformly distributed in (0,1)
  .3<                %   Is it less than 0.3?
  ?                  %   If so
    1e4Yr            %     Random integer between 1 and 1e4. This is the new rate 
                     %     in 10-kB/s units
  }                  %   Else
    K                %     Push rate that was copied into clipboard K
  ]                  %   End
  I                  %   Push previous remaining file size from clipboard I
  0>                 %   Is it positive?
]                    % End. If top of the stack is true: next iteration
xx                   % Delete the two numbers that are on the stack
share|improve this answer
    
I don't understand MATL, but it looks to me as if you're always getting a new rate instead of only 30% of the time from your explanation. – Maltysen 10 hours ago
    
@Maltysen Corrected now. Thanks for the heads-up! – Luis Mendo 10 hours ago
    
@DigitalTrauma Corrected now – Luis Mendo 10 hours ago

PowerShell, 190 bytes

$f=1gb;$r=10mb;while($f-gt0){if((1..10|Random)-le3){$r=(Random -mi 1kb -ma (10mb+1))*10}"Time remaining: "+((get-date 2/1/00).addSeconds($f/$r)-(get-date 2/1/00))-f'hh:mm:SS';$f-=$r;sleep 1}

Try it online! (TIO doesn't support clearing screen between lines)

Sets our initial $file size and our initial transfer $rate to 1gb and 10mb/s, respectively. Then, so long as we still have $file remaining, we loop.

Inside the loop, the if selects a number from 1 to 10 inclusive, and if it's 1, 2, or 3 (i.e., 30% of the time), we change the rate. This picks a random integer between 1kb and 10mb then that's multiplied by 10 to get our step count.

We then leverage a quirk of the Get-Date function, in that when given just a date, it returns a datetime object at 00:00:00am. This allows us to add the appropriate amount of seconds (based on the current rate and how much time is left), then subtract that date again, so we have a datetime object of how many seconds remain. That we can feed through the -format function, so it outputs in the desired format. Note we're not doing any rounding of seconds, and this includes leading hours, even if empty (pending decision from OP).

share|improve this answer
1  
00:00:10 is OK, but you must round the seconds as described in the challenge. The output on tio is strange (the same results every time). Does this behave properly in Powershell (not TIO?) – Stewie Griffin 14 hours ago
1  
@StewieGriffin TIO has output caching. Select "disable output cache" in the Settings drawer, and it gives different results. – TheBikingViking 14 hours ago

Ruby, 116 bytes

Try it online, except repl.it can't actually use Unix clear so it prints line by line instead.

f=1e5;r=1e3;(k=f/r=rand<0.3?1+rand(1e4):r;puts`clear`+"Time remaining: %02d:%02d"%[k/60,k%60];f-=r;sleep 1)while f>0

Windows version takes +1 byte by replacing the puts call with puts"\e[H\e[2JTime remaining: %02d:%02d"%[k/60,k%60] instead.

share|improve this answer

Bash + common utils, 117

Straightforward implementation. A few bytes saved by dividing out by 10000:

for((b=10**5,r=1000;b>0;r=RANDOM%10<3?RANDOM%10000+1:r,b-=r));{
clear
date -ud@$[b/r] "+Time remaining: %T"
sleep 1
}

Try it online. Using sleep 0 on the TIO so you don't have to wait. clear doesn't work on TIO.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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