Kopieren Sie eine Datei - Windows-Stil


40

Diese Herausforderung ist inspiriert von xkcd :

Bildbeschreibung hier eingeben

Herausforderung:

Sie simulieren das Kopieren einer großen Datei (1 Gigabyte). Die Übertragungsrate variiert zwischen 10 kB / s und 100 MB / s. Ihre Aufgabe ist es, die verbleibende Zeit der Dateiübertragung auszugeben. Die Ausgabe sollte folgendermaßen aussehen:

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)

Führende Nullen müssen nicht für Minuten und Stunden angezeigt werden (optional), sondern müssen für Sekunden angezeigt werden. Es ist nicht OK, die verbleibende Zeit in Sekunden anzugeben.

Die Dateiübertragung:

  • Die Übertragungsrate beginnt bei 10 MB / Sekunde.
  • Jede Sekunde besteht eine Wahrscheinlichkeit von 30%, dass sich die Übertragungsrate ändert
  • Die neue Übertragungsrate sollte zufällig (gleichmäßige Verteilung) [10 kB/s, 100 MB/s]in Schritten von 10 kB / s ausgewählt werden.

Hinweis: Sie müssen eine Datei nicht wirklich kopieren.

Sie können wählen:, 1 GB = 1000 MB, 1 MB = 1000 kB, 1 kB = 1000 Boder 1 GB = 1024 MB, 1 MB = 1024 kB, 1 kB = 1024 B.

Ausgabe:

  • Du fängst bei an 01:40, nicht 01:39.
  • Sie zeigen die Zeit an, nachdem sich die Übertragungsrate geändert hat, aber bevor etwas mit dieser Rate übertragen wird
  • Die Sekunden sollten als ganze Zahlen und nicht als Dezimalzahlen angezeigt werden. Es ist optional, auf / ab / am nächsten zu runden.
  • Sie sollten den Bildschirm jede Sekunde löschen, es sei denn, dies ist in Ihrer Sprache nicht möglich.
  • Die Ausgabe sollte konstant sein: Time remaining: 00:00wenn die Dateiübertragung beendet ist.

Beispiel:

Ich habe alle Dezimalsekunden aufgerundet. Angenommen, die folgenden Zeilen werden mit einem Abstand von 1 Sekunde angezeigt und der Bildschirm wird zwischen den einzelnen Zeilen gelöscht:

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
Sie sollten den XKCD-QuickInfo-Text unter dem Bild platzieren. Sparen Sie den Leuten die Zeit, selbst nachzuschlagen.
mbomb007

6
@ mbomb007, schweben Sie das Bild :)
Stewie Griffin

Sollte das heißen "Du beginnst bei 1:40(oder 1:42) nicht 1:39(oder 1:41)"?
Jonathan Allan

Auch wenn wir die 1024Version verwenden, welche Schrittgrößen sollten wir verwenden?
Jonathan Allan

Wenn die verbleibenden Stunden Null sind, können wir die Ausgabe wie 00:00:10zum Beispiel belassen ?
AdmBorkBork

Antworten:


9

Pyth - 70 68 Bytes

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

Probieren Sie es online aus, ohne zu schlafen .


@DigitalTrauma Entschuldigung, ich habe die Antwort von Luis als Richtlinie verwendet ._.
Maltysen

@DigitalTrauma behoben.
Maltysen

6
Lol. Beim Portieren von (Golf-) Sprache A nach (Golf-) Sprache B ist das Lesen der Spezifikation einfacher ;-)
Digital Trauma

@Maltysen Entschuldigung! :-)
Luis Mendo

2
Können Sie erklären, was zum Teufel hier los ist?
Setzen Sie Monica

8

PowerShell , 190 215 187 Byte

($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"

Probieren Sie es online! (TIO unterstützt das Löschen des Bildschirms zwischen Zeilen nicht.)

Legt unsere anfängliche $fIle-Größe und unser anfängliches Transfer- $rAte auf 1gbund 10mb/ s fest. Dann, solange wir noch $file haben , schleifen wir.

Innerhalb der Schleife ifwählt der eine Zahl von 0bis 9einschließlich, und wenn es 0, 1 oder 2 ist (dh 30% der Zeit), ändern wir die Rate. Dies wählt eine zufällige Ganzzahl zwischen 1kbund diese wird 10mbdann multipliziert 10, um unsere Schrittzahl zu erhalten.

Wir nutzen dann die FromSeconds statische Methode aus der TimeSpan.NET-Bibliothek, um die verbleibende Zeit zu konstruieren. Das Ausgabeformat dieses Aufrufs entspricht genau den Herausforderungsanforderungen, sodass keine zusätzliche Formatierung erforderlich ist.

(Ein Haufen dank @ConnorLSW gerettet)


1
@StewieGriffin TIO hat die Ausgabe zwischengespeichert. Wählen Sie "Ausgabecache deaktivieren" in der Schublade "Einstellungen" und es werden unterschiedliche Ergebnisse angezeigt.
TheBikingViking

Vielleicht fehlt mir etwas, aber der -fOperator scheint nichts zu tun. Indem ich das entfernte und die forSchleife anstelle von " to" verwendete whileund dann beide Instanzen von " get-dateto" änderte date, war ich in der Lage, 22 Bytes zu entfernen. Probieren Sie es online!
Briantist

@briantist TIO erfordert, Get-Dateweil es ansonsten den Linux- dateBefehl verwendet, der anders ist. Sie können es unter Windows ablegen, da PowerShell den Windows- dateBefehl umschließt . Aber danke für die forLoop-Konstruktion!
AdmBorkBork

@AdmBorkBork Ja, das habe ich bemerkt, aber in einer Standard-Windows-Umgebung würde es funktionieren. Ich frage mich, ob es akzeptabel ist, nur nal date get-dateden Header in TIO einzufügen.
Briantist

@AdmBorkBork und unter Windows wird der Windows-Datumsbefehl nicht umbrochen, sondern nur ignoriert, da es sich bei Windows nicht um eine EXE-Datei handelt. Daher wird auf dasselbe Verhalten zurückgegriffen wie bei random(führen Sie den Befehl mit get-vorangestellt aus, wenn alles andere fehlschlägt).
Briantist

5

MATL , 78 Bytes

Vielen Dank an @Maltysen und @DigitalTrauma für die Korrekturen.

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

Probieren Sie es bei MATL Online! (Möglicherweise müssen Sie mehrmals auf "Ausführen" klicken, wenn dies anfangs nicht funktioniert.)

Der Online-Dolmetscher läuft nach 30 Sekunden ab. Sie können geändert werden soll 10(in Zehntel Sekunden Pausenzeit) etwas kleiner wie3 um die Geschwindigkeit der Anzeige zu erhöhen

Erläuterung

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

Ich verstehe MATL nicht, aber für mich sieht es so aus, als würden Sie immer einen neuen Tarif erhalten, anstatt nur 30% der Zeit nach Ihrer Erklärung.
Maltysen

@Maltysen Jetzt korrigiert. Danke für die Warnung!
Luis Mendo

@DigitalTrauma Jetzt korrigiert
Luis Mendo


4

Bash + gemeinsame Utensilien, 117

Einfache Implementierung. Ein paar Bytes gespart durch Teilen durch 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
}

Probieren Sie es online aus . Mit sleep 0dem TIO müssen Sie nicht warten. clearfunktioniert nicht mit TIO.


3

JavaScript (ES6), 162 Byte

Zeigt die Minuten wie sie sind mit aufgefüllten Sekunden (Floored)

Z.B, 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)


Ich glaube , Sie zu verkürzen vergessen console.clearzu c.clearDas ist eine großartige Idee ;-), BTW
ETHproductions

@ETHproductions Hoppla! Danke :)
George Reith

Sie können dies auf 154 Bytes reduzieren, indem Sie HTML hinzufügen <input id=o>und einige andere Anpassungen vornehmen: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 Bytes)

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

Ziemlich einfach, denke ich. Löscht die Zeile mit der ANSI-Escape-Sequenz und dem KBefehl.


1
Überspringen Sie ein Leerzeichen in Ihrer ersten Zeile mit from random import*. d//rist kürzer als int(d/r). Auch könnte genauso gut r=1e7;d=1e9von Anfang an mitgehen .
Value Ink

@ValueInk Richtig, ich habe nicht an 1eX für r und d gedacht, weil ich wollte, dass sie ganze Zahlen sind. als ich die randint line verkürzt habe, habe ich das vergessen ... :)
Jonas Schäfer

1

Batch, 193 Bytes

@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

Hinweis: Geringfügige Abweichung von 27,68 MB / s oder weniger.


1

C 184 171 155 Bytes

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;}}

Ich hoffe das qualifiziert sich.

Ungolfed-Version:

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;          



   }

}

Erklärung: In der Golfversion ientspricht dies der sizeungolften Version und rist ratein der ungolften Version. jspeichert die verbleibende Zeit in Sekunden.

  • Ich muss 10 ^ 9 Bytes kopieren. Ich beginne mit einer Kopierrate von 10 Megabyte / Sekunde,
  • Wenn die Wahrscheinlichkeit weniger als 30% beträgt, ändern Sie die Rate (von 10 Kilobyte auf 100 Megabyte pro Sekunde).

@ValueInk Vielen Dank für das Speichern von 13 Bytes.

@ nmjcman101 Danke, dass du 16 Bytes gespart hast.


Das sieht nicht so aus, als würde es genau das tun, was die Herausforderung verspricht. Kannst du erklären, wie es funktioniert?
Value Ink

Es simuliert nur die Zeitausgabe, ich habe nicht herausgefunden, wie der Datentransfer Teil zu tun ist. Ich schätze, ich werde das bis dahin auf Eis legen.
Abel Tom

Sie ändern die Rate nach 3 Iterationen nicht. Es hat eine 30% ige Chance, sich zu ändern. Daher möchten Sie wahrscheinlich etwas Ähnliches wie das Folgende tun: if(rand()%10<3)r=(rand()%10000+1)*1e4;(Zumal die Mindestrate 10 kB / s beträgt und nicht 1 MB / s, wie in Ihrer Lösung angegeben, und die Ratenchance eine etwas gleichmäßige Verteilung sein sollte.)
Value Ink

@ ValueInk Vielen Dank. :) Aktualisiert. Lässt die Arbeit erledigen! Ich wusste nicht genau, wie ich den 30% -Wahrscheinlichkeitsteil simulieren sollte. So viel klarer jetzt.
Abel Tom

Sie können Golf j/3600,(j/60)%60,j%60(21) mit s=60;und j/s/s,j/s%s,j%s(20)
Davide
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.