Скопируйте файл - стиль Windows


40

Эта проблема вдохновлена xkcd :

введите описание изображения здесь

Вызов:

Вы будете имитировать копирование большого файла (1 гигабайт). Скорость передачи данных будет варьироваться от 10 кБ / с до 100 МБ / с. Ваша задача - вывести оставшееся время передачи файла. Вывод должен выглядеть так:

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)

Лидирующие нули не обязательно должны отображаться в течение нескольких минут и часов (необязательно), а должны отображаться в течение нескольких секунд. Показывать оставшееся время, используя только секунды, не в порядке.

Передача файлов:

  • Скорость передачи начнется с 10 МБ / с.
  • Каждую секунду будет 30% вероятность того, что скорость передачи будет меняться
  • Новая скорость передачи должна выбираться случайным образом (равномерное распределение) в диапазоне [10 kB/s, 100 MB/s]с шагом 10 кБ / с.

Примечание. Вам не нужно копировать файл.

Вы можете использовать:, 1 GB = 1000 MB, 1 MB = 1000 kB, 1 kB = 1000 Bили 1 GB = 1024 MB, 1 MB = 1024 kB, 1 kB = 1024 B.

Выход:

  • Вы начинаете 01:40, а не 01:39.
  • Вы отображаете время после изменения скорости передачи, но до того, как что-либо передается по этой скорости
  • Секунды должны отображаться как целые числа, а не как десятичные дроби. Необязательно округлять вверх / вниз / ближе всего.
  • Вы должны очищать экран каждую секунду, если это невозможно на вашем языке.
  • Вывод должен быть постоянным: Time remaining: 00:00когда передача файла закончена.

Пример:

Я собрал все десятичные секунды. Предположим, что строки ниже показаны с интервалом в 1 секунду, и экран очищается между каждым:

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.

1
Вы должны поместить текст подсказки XKCD ниже изображения. Сэкономьте людям время, чтобы самим искать это.
mbomb007

6
@ mbomb007, наведите курсор на изображение :)
Stewie Griffin

Должно ли это быть, «вы начинаете с 1:40(или 1:42) не 1:39(или 1:41)»?
Джонатан Аллан

Также, если мы используем 1024версию, какие размеры шагов мы должны использовать?
Джонатан Аллан

Если оставшиеся часы равны нулю, можем ли мы оставить вывод как, 00:00:10например?
AdmBorkBork

Ответы:


9

Pyth - 70 68 байт

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

Попробуйте онлайн без снов .


@DigitalTrauma извините, я использовал ответ Луиса в качестве руководства ._.
Maltysen

@DigitalTrauma исправлено.
Maltysen

6
Смешно. При переносе с языка (игры в гольф) на язык B (игры в гольф) легче, чем читать спецификацию ;-)
Digital Trauma

@Maltysen Извините за это! :-)
Луис Мендо

2
Можете ли вы дать объяснение того, что, черт возьми, происходит здесь?
Дэвид говорит восстановить Монику

8

PowerShell , 190 215 187 байт

($t="Time remaining: ")+"00:01:42";for($f,$r=1gb,10mb;$f-gt0;$f-=$r){if((Random 10)-lt3){$r=(Random -mi 1kb -ma (10mb+1))*10}$t+[Timespan]::FromSeconds([int]($f/$r));sleep 1}$t+"00:00:00"

Попробуйте онлайн! (TIO не поддерживает очистку экрана между строк)

Устанавливает наш начальный $fразмер файла и нашу начальную передачу $rв 1gbи 10mb/ с, соответственно. Затем, до тех пор, пока у нас еще остался $fфайл, мы зациклимся.

Внутри цикла ifвыбирается число от 0до 9включительно, и если оно равно 0, 1 или 2 (т. Е. 30% времени), мы меняем скорость. Это выбирает случайное целое число между, 1kbа 10mbзатем умножается на, 10чтобы получить наш счетчик шагов.

Затем мы используем FromSeconds статический метод из TimeSpanбиблиотеки .NET, чтобы построить оставшееся время. Выходной формат этого вызова точно соответствует требованиям вызова, поэтому нет необходимости в дополнительном форматировании.

(Спас кучу благодаря @ConnorLSW)


1
@StewieGriffin TIO имеет кэширование вывода. Выберите «отключить кэш вывода» в окне «Настройки», и это даст разные результаты.
TheBikingViking

Может быть, я что-то упускаю, но -fоператор, похоже, ничего не делает. Вынеся это и использовав forцикл вместо while, а затем изменив оба экземпляра get-dateна date, я смог сэкономить 22 байта.Попробуйте онлайн!
Бриантист

@briantist TIO требует, Get-Dateпотому что в противном случае он использует команду Linux date, которая отличается. Вы можете удалить его в Windows, потому что PowerShell переносит команду Windows date. Но спасибо заfor конструкцию петли!
AdmBorkBork

@AdmBorkBork да, я заметил это, но в стандартной среде Windows это будет работать. Интересно, допустимо ли просто поставитьnal date get-date в шапку в TIO?
бриантист

@AdmBorkBork и в Windows он не переносит команду windows date, он просто игнорирует ее, потому что это не .exe для Windows, поэтому он возвращается к тому же поведению, что и random(попробуйте команду с get-prepended, если все остальное не удалось ).
бриантист

5

MATL , 78 байт

Спасибо @Maltysen и @DigitalTrauma за исправления.

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

Попробуйте это в MATL Online! (вам может понадобиться нажать «Выполнить» несколько раз, если он изначально не работает).

Онлайн переводчик истекает через 30 секунд. Вы можете изменить 10(время паузы в десятых долях секунды) на что-то меньшее, например3 , чтобы увеличить скорость отображения

объяснение

1e5                  % Push 1e5: file size in 10-kB units
1e3                  % Push 1e3: initial rate in 10-kB/s units
`                    % Do...while
  XK                 %   Copy current rate into clipboard K (doesn't consume it)
  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 (doesn't consume it)
  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

Я не понимаю, MATL, но мне кажется, что вы всегда получаете новую ставку, а не только 30% времени от вашего объяснения.
Maltysen

@ Maltysen Исправлено сейчас. Спасибо за хедз-ап!
Луис Мендо

@DigitalTrauma Исправлено сейчас
Луис Мендо

5

Рубин, 116 110 байт

Попробуйте онлайн, за исключением того, что repl.it читает \rкак новую строку и также не может использовать $><<его, поэтому он заменен 5-байтовым эквивалентом print.

Привет JonasWielicki за первоначальную идею использования \rдля сброса линии.

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

Эта версия не протестирована в Windows, но работает в Unix.


4

Bash + общие утилиты, 117

Простая реализация. Несколько байтов сохраняются путем деления на 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
}

Попробуйте онлайн . Использование sleep 0на TIO, чтобы вам не пришлось ждать. clearне работает на TIO.


3

JavaScript (ES6), 162 байта

Показывает минуты как есть с добавленными секундами (с полами)

Например, 123:45

t=1e5
s=1e3
setInterval(c=>c.log(`Time remaining: ${c.clear(d=t/s),d/60|0}:`+`0${t-=s>t?t:s,r=Math.random,s=r()<0.3?1+r()*1e4|0:s,d%60|0}`.slice(-2)),1e3,console)


Я думаю , что вы забыли , чтобы сократить console.clearдо c.clear;-) Это отличная идея, BTW
ETHproductions

@ETHproductions Спасибо :)
Джордж Райт

Вы можете уменьшить это до 154 байтов, добавив HTML - <input id=o>и сделав пару других корректировок:t=1e5;i=s=1e3;setInterval(_=>o.value=`Time remaining: ${(d=t/s)/60|0}:`+`0${t-=s>t?t:s,r=Math.random(),s=r<.3?1+r*1e4|0:s,d%60|0}`.slice(-2),i)
Shaggy

2

Python 3,6 ( 212 203 байта)

from random import*
import time,datetime
r=1e7
d=1e9
while 1:
 print(f"\x1b[KTime remaining: {datetime.timedelta(seconds=d//r)}",end="\r");d=max(0,d-r);time.sleep(1)
 if random()>.7:r=randint(1,1e4)*1e4

Я думаю, довольно просто. Стирает строку, используя escape-последовательность ANSI и Kкоманду.

  • Сохранено 9 байт благодаря @ValueInk

1
Пропустить пробел в первой строке с from random import*. d//rкороче int(d/r). Кроме того, может также пойти с r=1e7;d=1e9самого начала.
Value Ink

@ValueInk Правильно, я не думал о 1eX для r и d, потому что я хотел, чтобы они были целыми числами; когда я сократил строку ранда, я забыл об этом ... :)
Йонас Шефер

1

Пакет, 193 байта

@set/ap=10000,s=p*10,r=p/10
:l
@set/at=s/r,m=t/60,n=t%%60+100,s-=r
@cls
@echo Time remaining: %m%:%n:~1%
@timeout/t>nul 1
@if %random:~-1% lss 3 set/ar=%random%%%p+1
@if %t% gtr 0 goto l

Примечание. Небольшое смещение в сторону скоростей 27,68 МБ / с или менее.


1

C 184 171 155 байтов

f(){i,j=0,r=1e7;for(i=1e9;i>0;i-=r){j=i/r;printf("Time remaining: %02d:%02d:%02d\r",j/3600,(j/60)%60,j%60);sleep(1);if(rand()%10<3)r=(rand()%10000)*1e4;}}

Я надеюсь, что это подходит.

Безголовая версия:

void f()
{
    int j=0;
    float rate=1e7; 
    for(int size=1e9;i>0; size-=rate)
    {     
       j=size/rate;      
       printf("Time remaining: %02d:%02d:%02d\r",j/3600,(j/60)%60,j%60);
       sleep(1);

       if(rand()%10<3)
          rate=(rand()%10000)*1e4;          



   }

}

Объяснение: В golfed версия iсоответствует sizeв ungolfed версии и rнаходится rateв ungolfed версии. jсохраняет оставшееся время в секундах.

  • У меня есть 10 ^ 9 байт для копирования. Я начинаю копирование со скоростью 10 Мегабайт в секунду,
  • Если вероятность составляет менее 30%, измените скорость (с 10 килобайт до 100 мегабайт в секунду)

@ValueInk Спасибо за сохранение 13 байтов.

@ nmjcman101 Спасибо за сохранение 16 байтов.


Это не похоже на то, что на самом деле делает то, что говорит задача. Можете ли вы объяснить, как это работает?
Чернила стоимости

Это просто имитирует вывод времени, я не понял, как сделать часть передачи данных. Думаю, я отложу это до тех пор.
Авель Том

Вы не меняете скорость после 3 итераций. С вероятностью 30% он может измениться. Таким образом, вы, вероятно, захотите сделать что-то похожее на следующее: if(rand()%10<3)r=(rand()%10000+1)*1e4;(Тем более, что минимальная скорость составляет 10 КБ / с, а не 1 МБ / с, как говорит ваше решение, и вероятность скорости должна быть несколько равномерным.)
Value Ink

@ValueInk Большое спасибо. :) Обновлено. Получает проделанную работу! Я не знал, как именно имитировать 30% вероятности. Теперь все намного понятнее.
Абель Том

Вы можете j/3600,(j/60)%60,j%60s=60;j/s/s,j/s%s,j%s
Davide
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.