คัดลอกไฟล์ - สไตล์ Windows


40

ความท้าทายนี้ได้รับแรงบันดาลใจจากxkcd :

ป้อนคำอธิบายรูปภาพที่นี่

ท้าทาย:

คุณจะจำลองการคัดลอกไฟล์ขนาดใหญ่ (1 กิกะไบต์) อัตราการถ่ายโอนจะแตกต่างกันระหว่าง 10 kB / วินาทีถึง 100 MB / วินาที งานของคุณคือการส่งออกเวลาที่เหลือของการถ่ายโอนไฟล์ ผลลัพธ์ควรมีลักษณะดังนี้:

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 MB / วินาที
  • ทุกวินาทีจะมีโอกาส 30% ที่อัตราการถ่ายโอนจะเปลี่ยนแปลง
  • อัตราการถ่ายโอนใหม่ควรเลือกแบบสุ่ม (การกระจายแบบสม่ำเสมอ) ในช่วงเป็น[10 kB/s, 100 MB/s]ขั้นตอน 10 kB / s

หมายเหตุ: คุณไม่จำเป็นต้องคัดลอกไฟล์จริง

คุณอาจเลือกที่จะใช้: หรือ1 GB = 1000 MB, 1 MB = 1000 kB, 1 kB = 1000 B1 GB = 1024 MB, 1 MB = 1024 kB, 1 kB = 1024 B

เอาท์พุท:

  • คุณเริ่มต้นที่ไม่01:4001: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)"?
Jonathan Allan

นอกจากนี้หากเรากำลังใช้1024เวอร์ชันขนาดขั้นตอนที่เราควรใช้คืออะไร
Jonathan Allan

หากจำนวนชั่วโมงที่เหลืออยู่เป็นศูนย์เราสามารถปล่อยเอาท์พุทเป็น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
ฮ่า ๆ. เมื่อทำการย้ายจากภาษา (กอล์ฟ) ภาษา A ถึง (กอล์ฟ) ภาษา B นั้นง่ายกว่าการอ่านข้อมูลจำเพาะ ;-)
Digital Trauma

@Maltysen ขออภัยเกี่ยวกับสิ่งนั้น! :-)
Luis Mendo

2
คุณช่วยอธิบายได้ไหมว่าเกิดอะไรขึ้นที่นี่?
Reinstate Monica

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/ s ตามลำดับ จากนั้นตราบใดที่เรายังมีอิล$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เพราะไม่เช่นนั้นจะใช้dateคำสั่งLinux ซึ่งแตกต่างกัน คุณสามารถวางลงบน Windows เพราะ PowerShell ล้อมdateคำสั่งของWindows แต่ขอบคุณสำหรับการ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! (คุณอาจต้องกด "Run" หลายครั้งหากไม่ได้ผลในตอนแรก)

ล่ามออนไลน์หมดเวลาหลังจาก 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 แก้ไขแล้ว ขอบคุณสำหรับหัวขึ้น!
Luis Mendo

@DigitalTrauma แก้ไขแล้วตอนนี้
Luis Mendo

5

Ruby, 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 + utils ทั่วไป, 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 Ooooops! ขอบคุณ :)
George Reith

คุณสามารถลดขนาดนี้ได้ถึง 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

ฉันคิดว่าตรงไปตรงมา ลบบรรทัดโดยใช้ ANSI escape sequence และKคำสั่ง

  • บันทึกแล้ว 9 ไบต์ขอบคุณ@ValueInk

1
from random import*ข้ามพื้นที่ในบรรทัดแรกของคุณด้วย จะสั้นกว่าd//r int(d/r)นอกจากนี้ยังอาจไปด้วยr=1e7;d=1e9ตั้งแต่เริ่มต้น
หมึกมูลค่า

@ValueInk ใช่ไม่คิด 1eX สำหรับ r และ d เพราะฉันต้องการให้พวกเขาเป็นจำนวนเต็ม; เมื่อฉันย่อ randint บรรทัดฉันลืมเกี่ยวกับเรื่องนั้น ... :)
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 MB / s หรือน้อยกว่า


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 ไบต์


สิ่งนี้ไม่ได้ดูเหมือนว่ามันจะเป็นสิ่งที่ท้าทาย คุณอธิบายได้ไหมว่ามันทำงานอย่างไร
หมึกมูลค่า

เป็นเพียงการจำลองเวลาที่ส่งออกฉันยังไม่ได้คิดวิธีการทำส่วนการถ่ายโอนข้อมูล คิดว่าฉันจะหยุดเรื่องนี้ไว้จนกว่าจะถึงวันนั้น
Abel Tom

คุณไม่ได้เปลี่ยนอัตราหลังจากทำซ้ำ 3 ครั้ง มีโอกาส 30% ในการเปลี่ยนแปลง ดังนั้นคุณอาจต้องการทำสิ่งที่คล้ายกับต่อไปนี้: if(rand()%10<3)r=(rand()%10000+1)*1e4;(โดยเฉพาะอย่างยิ่งเนื่องจากอัตราขั้นต่ำคือ 10 kB / s ไม่ใช่ 1MB / s เหมือนที่โซลูชันของคุณกำลังพูดและโอกาสอัตราควรมีการกระจายค่อนข้างสม่ำเสมอ)
Value Ink

@ มูลค่าขอบคุณมาก อัพเดตแล้ว :) ทำงานให้เสร็จ! ฉันไม่รู้ว่าจะจำลองส่วนความน่าจะเป็น 30% ได้อย่างไร ชัดเจนยิ่งขึ้นในตอนนี้
Abel Tom

คุณสามารถเล่นกอล์ฟj/3600,(j/60)%60,j%60(21) ด้วยs=60;และ j/s/s,j/s%s,j%s(20)
Davide
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.