Скопіюйте файл - стиль 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, наведіть на нього зображення :)
Стюі Гріффін

Чи повинно це бути "ви починаєте з 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 вибачте, використовував відповідь Луїса як керівництво ._.
Мальтісен

@DigitalTrauma виправлено.
Мальтісен

6
Лол. Коли переносити з (гольф) мови A на (гольф) мову 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розмір ile та наш початковий перенос $rїли відповідно до 1gbта 10mb/ с. Тоді, поки у нас ще $fзалишилось ile, ми робимо петлю.

Всередині циклу, то 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, він просто ігнорує його, тому що це не .exe для Windows, тому він повертається до тієї ж поведінки, що і random(спробуйте команду з попередньою, get-якщо все інше не вдасться).
британіст

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 Виправлено зараз. Дякую за голову!
Луїс Мендо

@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 0TIO, тому вам не доведеться чекати. 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 Ooooops! Дякую :)
Джордж Рейт

Ви можете зменшити це до 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

Думаю, прямо, я думаю. Стирає рядок, використовуючи послідовність та Kкоманду відбору ANSI .

  • Збережено 9 байт завдяки @ValueInk

1
Пропустіть пробіл у першому рядку с from random import*. d//rкоротше, ніж int(d/r). Крім того, може також піти з r=1e7;d=1e9самого початку.
Значення чорнила

@ValueInk Правильно, не думав про 1eX для r і d, тому що я хотів, щоб вони були цілими числами; коли я скоротив лінію рандінта, я забув про це ... :)
Jonas Schäfer

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;          



   }

}

Пояснення: У версії iдля гольфу відповідає версії, що не використовується для sizeгольфу, та rє rateу версії, що не використовується для гольфу. jзберігає час, що залишився в секундах.

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

@ValueInk Дякуємо за збереження 13 байт.

@ nmjcman101 Дякуємо за збереження 16 байт.


Це не схоже, що насправді робить те, що говорить виклик. Чи можете ви пояснити, як це працює?
Значення чорнила

Він просто імітує вихідний час, я не зрозумів, як зробити частину передачі даних. Здогадуюсь, я до цього часу затримаю.
Абель Том

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

@ValueInk Дякую :) Оновлено. Здійснює виконану роботу! Я не знав, як саме змоделювати 30% частку ймовірності. Настільки зрозуміліше зараз.
Абель Том

можна пограти в гольф j/3600,(j/60)%60,j%60(21) з s=60;і j/s/s,j/s%s,j%s(20)
Девіде
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.