Copiar um arquivo - estilo Windows


40

Este desafio é inspirado no xkcd :

insira a descrição da imagem aqui

Desafio:

Você simulará a cópia de um arquivo grande (1 Gigabyte). A taxa de transferência varia entre 10 kB / segundo e 100 MB / segundo. Sua tarefa é gerar o tempo restante da transferência de arquivos. A saída deve se parecer com:

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)

Os zeros à esquerda não precisam ser exibidos por minutos e horas (opcional), mas devem ser mostrados por segundos. Mostrar o tempo restante usando apenas alguns segundos não está OK.

A transferência de arquivos:

  • A taxa de transferência começará em 10 MB / segundo.
  • A cada segundo, haverá uma chance de 30% de que a taxa de transferência mude
  • A nova taxa de transferência deve ser escolhida aleatoriamente (distribuição uniforme) na faixa [10 kB/s, 100 MB/s], em passos de 10 kB / s.

Nota: Você não precisa copiar um arquivo.

Você pode optar por usar:, 1 GB = 1000 MB, 1 MB = 1000 kB, 1 kB = 1000 Bou 1 GB = 1024 MB, 1 MB = 1024 kB, 1 kB = 1024 B.

Saída:

  • Você começa às 01:40, não 01:39.
  • Você exibe o tempo após a alteração da taxa de transferência, mas antes de qualquer coisa ser transferida nessa taxa
  • Os segundos devem ser exibidos como números inteiros, não decimais. É opcional arredondar para cima / baixo / mais próximo.
  • Você deve limpar a tela a cada segundo, a menos que seja impossível no seu idioma.
  • A saída deve ser constante: Time remaining: 00:00quando a transferência do arquivo terminar.

Exemplo:

Arredondei todos os segundos decimais. Suponha que as linhas abaixo sejam mostradas com 1 segundo no meio e a tela seja limpa entre cada uma:

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.

11
Você deve colocar o texto da dica da ferramenta XKCD abaixo da imagem. Economize nas pessoas o tempo de procurar por elas mesmas.
Mbomb007

6
@ mbomb007, pairar a imagem :)
Stewie Griffin

Deveria ser ", você começa em 1:40(ou 1:42) não 1:39(ou 1:41)"?
Jonathan Allan

Além disso, se estamos usando a 1024versão, quais são os tamanhos das etapas que devemos usar?
Jonathan Allan

Se as horas restantes forem zero, podemos deixar a saída como 00:00:10por exemplo?
AdmBorkBork 02/02

Respostas:


9

Pitão - 70 68 bytes

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

Experimente online sem dormir .


@DigitalTrauma desculpe, estava usando a resposta de Luis como guia ._.
Maltysen

@DigitalTrauma fixed.
Maltysen

6
Ri muito. Ao transportar do idioma A (golfe) para o idioma B (golfe) é mais fácil do que ler as especificações ;-)
Digital Trauma

@ Maltysen Desculpe por isso! :-)
Luis Mendo

2
Você pode dar uma explicação do que diabos está acontecendo aqui?
Reinstale Monica

8

PowerShell , 190 215 187 bytes

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

Experimente online! (O TIO não suporta a limpeza de tela entre linhas)

Define nosso $ftamanho de arquivo inicial e nossa transferência inicial $rpara 1gbe 10mb/ s, respectivamente. Então, enquanto ainda $frestarmos íleo, fazemos um loop.

Dentro do loop, as ifselecciona um número de 0até 9, inclusive, e se é 0, 1, ou 2 (ou seja, 30% do tempo), que alteram a taxa. Isso seleciona um número inteiro aleatório entre 1kbe 10mbdepois é multiplicado por 10para obter nossa contagem de etapas.

Em seguida, aproveitamos o FromSeconds método estático da TimeSpanbiblioteca .NET para construir o tempo restante. O formato de saída dessa chamada corresponde exatamente aos requisitos de desafio, portanto, não há necessidade de formatação adicional.

(Salvo um monte graças a @ConnorLSW)


11
O @StewieGriffin TIO possui cache de saída. Selecione "desativar o cache de saída" na gaveta Configurações e ele fornece resultados diferentes.
TheBikingViking 2/02

Talvez esteja faltando alguma coisa, mas o -foperador não parece fazer nada. Retirando isso e usando forloop em vez de while, e depois alterando as duas instâncias de get-datepara date, consegui remover 22 bytes. Experimente online!
Briantist

O @briantist TIO exige Get-Dateporque, caso contrário, ele usa o datecomando Linux , que é diferente. Você pode soltá-lo no Windows porque o PowerShell agrupa o datecomando do Windows . Mas, obrigado pela forconstrução do loop!
AdmBorkBork 3/17/17

@AdmBorkBork sim, eu notei isso, mas em um ambiente Windows padrão funcionaria. Gostaria de saber se é aceitável apenas colocar nal date get-dateno cabeçalho no TIO?
Briantist

O @AdmBorkBork e no Windows não envolve o comando date do Windows, apenas o ignora porque não é um .exe no Windows; portanto, ele volta ao mesmo comportamento que random(tente o comando com get-prefpended se tudo mais falhar).
Briantist

5

MATL , 78 bytes

Obrigado a @Maltysen e @DigitalTrauma pelas correções.

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

Experimente no MATL Online! (pode ser necessário pressionar "Executar" várias vezes se não funcionar inicialmente).

O intérprete online atinge o tempo limite após 30 segundos. Você pode alterar 10(tempo de pausa em décimos de segundo) para algo menor , como3 para aumentar a velocidade da exibição

Explicação

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

Eu não entendo MATL, mas parece-me que você está sempre recebendo uma nova taxa em vez de apenas 30% do tempo de sua explicação.
Maltysen 03/02/19

@ Maltysen Corrected now. Obrigado pelo alerta!
Luis Mendo

@DigitalTrauma Corrected now
Luis Mendo


4

Bash + utils comuns, 117

Implementação direta. Poucos bytes salvos dividindo por 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
}

Experimente online . Usando sleep 0no TIO para que você não precise esperar. clearnão funciona no TIO.


3

JavaScript (ES6), 162 bytes

Mostra os minutos como estão com os segundos acolchoados (no chão)

Por exemplo, 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)


Acho que você esqueceu de encurtar console.clearpara c.clear;-) Essa é uma ótima idéia, BTW
ETHproductions

@ETHproductions Ooooops! Obrigado :)
George Reith

Você pode obter isso para 154 bytes adicionando HTML - <input id=o>- e fazendo alguns outros ajustes: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

Bem simples, eu acho. Apaga a linha usando a seqüência e Kcomando de escape ANSI .


11
Pule um espaço na sua primeira linha com from random import*. d//ré mais curto que int(d/r). Além disso, pode muito bem continuar r=1e7;d=1e9desde o início.
Value Ink

@ValueInk Certo, não pensei em 1eX para re porque eu queria que eles fossem números inteiros; quando reduzi a linha aleatória, esqueci-me disso ... :)
Jonas Schäfer

1

Lote, 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

Nota: Pequeno desvio para taxas de 27,68 MB / s ou menos.


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

Espero que isso se qualifique.

Versão não destruída:

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;          



   }

}

Explicação: Na versão golfed icorresponde à sizeversão ungolfed e restá ratena versão ungolfed. jarmazena o tempo restante em segundos.

  • Eu tenho 10 ^ 9 bytes para copiar. Começo a copiar na taxa de 10 megabytes / segundo,
  • Se a probabilidade for menor que 30%, altere a taxa (de 10 kilobytes para 100 megabytes por segundo)

Obrigado por salvar 13 bytes.

@ nmjcman101 Obrigado por salvar 16 bytes.


Isso não parece realmente fazer o que o desafio diz. Você pode explicar como isso funciona?
Value Ink

Ele apenas simula a saída do tempo, ainda não descobri como fazer a parte da transferência de dados. Acho que vou colocar isso em espera até então.
Abel Tom

Você não altera a taxa após três iterações. Tem 30% de chance de mudar. Portanto, você provavelmente deseja fazer algo semelhante ao seguinte: if(rand()%10<3)r=(rand()%10000+1)*1e4;(Especialmente porque a taxa mínima é de 10 kB / s, não 1 MB / s como a sua solução está dizendo, e a chance de taxa deve ser uma distribuição um tanto uniforme.)
Value Ink

@ ValueInk Muito obrigado. :) Atualizada. Faz o trabalho! Eu não sabia exatamente como simular a parte de probabilidade de 30%. Muito mais claro agora.
Abel Tom

você pode golfe j/3600,(j/60)%60,j%60(21) com s=60;e j/s/s,j/s%s,j%s(20)
Davide
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.