Simule um ping da Cisco

8

Premissa:

Para quem está em rede, provavelmente enviou um ping de ou para algum dispositivo para garantir que tudo esteja conectado corretamente. A Cisco, uma empresa popular em rede [citação necessário] , possui um comando em seu IOS que se parece com isso:

Capturar

( Fonte da imagem )

Seu desafio é recriar graficamente uma parte disso. As partes que estamos pulando são a primeira linha ( Type escape sequence to abort.) inteiramente, junto com o endereço IP e os tempos de ida e volta.

Você começará emitindo o seguinte:

Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:

Você simulará as solicitações de eco que saem. Cada solicitação começará aguardando 2 segundos e, em seguida, gerando a resposta. Uma resposta de eco bem-sucedida é representada por a !, uma falha por .. Na verdade, não enviaremos pacotes, mas para representar a perda de pacotes, seu programa deve escolher aleatoriamente entre as duas opções com uma chance diferente de zero para cada uma. Esta linha começará vazia e cada marca adicionará outro caractere.

Após o quinto eco, a linha de porcentagem será emitida e o programa deverá terminar. A linha de porcentagem estará no formato de

Success rate is $p percent ($s/5)

onde $pestá na regex 0|20|40|60|80|100e $sé o número de ecos bem-sucedidos. A tela deve ser atualizada após cada período de espera, redesenhando o novo estado ou anexando à linha de eco existente. Isso inclui a Sendinglinha.

Exemplo de execução: (a contagem de marcações não deve ser exibida e existe para esclarecer como deve ser a saída a cada etapa)

#Tick 0
Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:

#Tick 1
Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:
.

#Tick 2
Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:
.!

#Tick 3
Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:
.!.

#Tick 4
Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:
.!.!

#Tick 5
Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:
.!.!.
Success rate is 40 percent (2/5)

Entrada:

Nenhuma entrada utilizável fornecida.

Resultado:

Qualquer formato razoável. Um exemplo de saída final é assim:

Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:
...!!
Success rate is 40 percent (2/5)    

Regras:

  • Você deve anexar à linha de eco ou redesenhar a tela após cada marca.
  • !e .não precisa ser igualmente provável, apenas os dois possíveis.
  • Execuções sucessivas devem ser capazes de gerar resultados diferentes
  • Gifs ou webms da sua saída seriam legais. Nenhum bônus ou qualquer coisa para isso embora.
  • Lacunas padrão proibidas
  • Isso é
Veskah
fonte
É permitido imprimir as strings com espaços à direita se a saída for visualmente a mesma?
J. Sallé 23/11
A última linha deve terminar com um avanço de linha?
@Rogem É opcional.
Veskah

Respostas:

5

C (gcc) , 172 bytes

Então, eu retirei 6 bytes dessa coisa com alguns truques bastante ridículos. Compile com -DK=!sleep(2)-putchar(rand()%2?33:46)/46. Depende da sleep()função que está sendo definida nas bibliotecas padrão do sistema. Não faz loop ou recursão.

p(n){puts("Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:");printf("\nSuccess rate is %i percent (%i/5)",n*20,n=K+K+K+K+K);}

Experimente online!

Explicação

Essa solução depende de três detalhes críticos de implementação / tempo de execução. Primeiro, sleep() não deve ser interrompido , por exemplo, por um sinal. Segundo, as adições e subtrações sendo resolvidas da esquerda para a direita. Terceiro, os argumentos a printf()serem resolvidos da direita para a esquerda.

Com isso fora do caminho, vamos resolver isso.

p(n){ // Unfortunately, I need a variable to store the RNG result.
    // This is straight-forward printing of a line.
    puts("Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:");
    // So, resolving right-to-left, we have a) the K preprocessor macros,
    // b) the assigment of their sum to n, c) the percentage equivalent of
    // the fraction n/5 and d) a constant format string.
    // The summation of the K's is where the magic happens.
    printf("\nSuccess rate is %i percent (%i/5)",n*20,n=K+K+K+K+K);
}

O argumento do compilador

-DK=!sleep(2)-putchar(rand()%2?33:46)/46

Então, a partir da esquerda (ou seja, como deveria resolver), temos sleep(). sleep()retorna o número de segundos restantes quando retorna, portanto esperamos que o usuário (e outros processos) seja gentil e não interrompa o sono. Tomamos o complemento lógico e, como no nosso caso sleep()sempre retornará 0, o resultado é 1. Mais sobre o significado mais tarde.

Em seguida, entramos putchar(). putchar()imprime um único caractere de 1 byte e retorna o valor do byte. Portanto, obtemos um valor aleatório interno, calculamos o módulo-2 para uma boa divisão de 50-50 (embora com entropia horrível) e depois o condicionamos para os caracteres desejados - ! (33) e . (46). Depois, dividimos o valor de retorno de putchar()com 46.

Agora, essa divisão retornará 0para !e 1para .- então pegamos 1 (de !sleep()) e subtraímos o resultado da divisão disso. Presto!

Ok, há um pequeno problema. Quando você escreve coisas em um buffer em C (ou seja stdout), ele não necessariamente grava imediatamente no destinatário. De fato, quando eu estava executando isso na minha distribuição preferida, descobri que ele só imprimia os pings após o término do programa. No entanto, considerando que todas as outras soluções em C estão deixando de funcionar, e que provavelmente existe pelo menos uma máquina por aí em algum lugar, faz isso e cumpre todos os outros pré-requisitos (e sempre é possível "consertar" isso no kernel). .), Não vou mexer na minha pontuação ao fflush()ing stdout.


fonte
4

APL (Dyalog Unicode) , 147 138 bytes

{5=≢⍵⊣⎕DL≢⎕←↑⌽'.!'[⍵]'Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:':⎕←('Success rate is',×∘20,'percent (','/5)',⍨⍕)+/⍵}¨1↓¨,\?62

Experimente online!

Esta é uma grande função direta. Como em outras respostas, o link TIO será emitido somente após a conclusão da execução. Dito isto, o @ Adám criou uma função auxiliar útil para que os carimbos de data e hora possam ser visualizados. Essa versão do código pode ser encontrada aqui .

Esta resposta usos ⎕IO←0, que define a I NDEX O Rigin de tudo 1-0.

Obrigado a @ngn pelos 9 bytes salvos (e por estragar minha explicação! Agora eu tenho que fazê-lo novamente (ლಠ益ಠ)ლ)

Quão:

A função recebe 1 argumento fixo, que está à direita.

Como nós temos ¨1↓¨,\?6⍴2. Essa expressão escolhe aleatoriamente ( ?) entre 0 e 1 6 vezes ( 6⍴2cria um vetor de 6 elementos de 2's). Os resultados são concatenados ( ,\) para formar um vetor de 6 elementos de 1 a 6 vetores de elementos (por exemplo 1 0 1 0 1 1 0 1 1 0 0 1 1 0 1 0 1 1 0 1 0:). O primeiro elemento de cada um é descartado ( 1↓¨) e, em seguida, cada vetor resultante é passado como ( ¨), executando a função 6 vezes.

{5=≢⍵⊣...:...}é uma declaração condicional. Se tiver 5 elementos (também conhecido como a última iteração), ele executará o código após o guard ( :). Como garante que a condição será a última coisa avaliada, o programa sempre imprimirá a corda antes da guarda.

{...⎕DL≢⎕←↑⌽'.!'[⍵]'Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:'...}cria um vetor de dois elementos formado pelo vetor indexado '.!'[⍵], que produzirá os sucessos e falhas e a própria sequência de ping. Esse vetor é então revertido (monádico ) para a ordem correta e depois misturado (monádico ) em uma matriz. Essa matriz é então enviada para stdout ( ⎕←) e um D e L ay ( ⎕DL) é adicionado. O argumento para ⎕DLé o número de elementos na matriz ( ), ou seja, 2, criando um atraso de 2 segundos entre as chamadas de função.

{...:⎕←('Success rate is',×∘20,'percent (','/5)',⍨⍕)+/⍵}cria a última string a ser impressa. Ele somará os elementos do argumento ( +/⍵) e passará o resultado como argumento para a função tácita entre parênteses. Essa função primeiro anexa (diádico ,, seguido por ) o argumento stringified ( ) à string e '/5)', em seguida, anexa à string 'percent ('. Em seguida, anexará a string resultante a 20 vezes o argumento ( ×∘20) e, em seguida, anexará ao restante da saída, que será enviada ao stdout via ⎕←.

J. Sallé
fonte
Trailing newline está bom. Comentando aqui porque estou no celular
Veskah
⎕DL 2⊣⎕←... -> ⎕DL≢⎕←...
NGN
3

Java (JDK) , 227 bytes

()->{var o=System.out;int s=0,i=0;for(o.println("Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:");i++<5;Thread.sleep(2000))o.print(Math.random()>.5&&s++<9?"!":".");o.printf("\nSuccess rate is %d percent (%d/5)",s*20,s);}

Experimente online!


O ping em ação

O ping em ação


Explicado

()->{                               // Lambda taking no input
    var o=System.out;               // Assign System.out to a variable
    int s=0,i=0;                    // Initialise successes and loop ints
    for(o.println("Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:");
                                    // ^Print opening line
        i++<5;                      // Loop five times
        Thread.sleep(2000))         // Sleep for 2 seconds at the end of each loop
            o.print(                // Print out..
                Math.random()>.5    // ..if random number is greater than .5 (50%)
                    &&s++<9?        // ..and incremented successes 
                        "!":".");   // ! for success and . for failure
    o.printf("\nSuccess rate is %d percent (%d/5)",s*20,s);
                                    //^Print formatted closing line
}
Luke Stevens
fonte
a impressão é o assassino lá: /
Adam
3

C # (compilador interativo do Visual C #) , 212 bytes

int i,p;for(Write("Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:\n");i++<5;Write(".!"[-p+(p+=new Random().Next(2))]))System.Threading.Thread.Sleep(2000);Write($"\nSuccess Rate is {p*20} percent ({p}/5)");

Experimente online!

Modalidade de ignorância
fonte
2
Bem-vindo ao PPCG! Tomei a liberdade de gerar um Try It Online! link para você. Sugiro que você edite sua resposta com o modelo que o TIO fornece para postar respostas no PPCG (embora isso naturalmente não seja obrigatório ).
J. Sallé
Você pode reduzir isso para 299 bytes construindo Randomem linha, em vez de salvá-lo var r. Heres um link para o meu suggestestion
Robin B
Isso continua travando com IndexOutOfBoundsExceptions para mim.
meu pronome é monicareinstate
@mypronounismonicareinstate Fixed. Como eu não peguei isso meses atrás?
Modalidade de ignorância
2

JavaScript + HTML, 203 + 9 = 212 bytes

<pre id=o
f=(x,y=0,g=z=>setTimeout(f,2e3,-~x,y+z),u=s=>o.innerText+=s)=>x?x<6?u(`.!`[n=new Date%2],g(n)):u(`
Success rate is ${y/20} percent (${y}/5)`):u`Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:`&g(0)

Tente

Se new Datenão for aleatório o suficiente, adicione 8 bytes para usar Math.random()(algumas outras modificações foram feitas para permitir que ele seja executado corretamente em um snippet):

Shaggy
fonte
2

PowerShell , 166 162 158 bytes

'Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:'
0..4|%{sleep 2;write-host -no '.!'[($x=0,1|Random)];$d+=$x}
"
Success rate is $($d*20) percent ($d/5)"

Experimente online!

Muito parecido com a resposta do Python ao TFeld. O tempo não funciona no TIO (o TIO apenas sai na conclusão do programa), mas funciona localmente.

A primeira linha é apenas uma string colocada no pipeline. A linha do meio faz um loop de 0para 4, cada iteração sleeppor 2segundos e depois write-hostcom -nonova linha. Estamos escrevendo um !ou .escolhido Randome armazenado $x. Em seguida, incrementamos com $dbase em$x .

A última linha é outra string (multilinha) colocada no pipeline, com um pouco de cálculo no meio para chegar à porcentagem.

-1 byte graças a Veskah
-3 bytes graças a Ciaran_McCarthy

AdmBorkBork
fonte
Transformar a linha de sucesso em uma sequência de várias linhas em vez de usar back-tick n (não sei como escapar nos comentários) deve salvar um byte. 161 bytes
Veskah 21/11
1
Você pode economizar 3 bytes usando em *20vez de /5*100?
Ciaran_McCarthy
@Veskah Sim, obrigado.
AdmBorkBork
@Ciaran_McCarthy Santa vaca, obrigado pelo golfe óbvio. :)
AdmBorkBork
1

Python 3 , 221 220 216 209 208 201 bytes

import time,random
p=print
p('Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:')
n=0
exec("time.sleep(2);i=random.choice('.!');n+=i<'#';p(end=i);"*5)
p(f'\nSuccess rate is {n*20} percent ({n}/5)')

Experimente online!

O tempo não funciona no TIO, mas funciona no console. (TIO sai no final da execução)

-7 bytes, graças a Erik the Outgolfer

TFeld
fonte
201 bytes .
Erik the Outgolfer
@EriktheOutgolfer Thanks! :)
TFeld
1

JavaScript, 322 268 267 265 bytes

(f=(a,t,s)=>a--?new Promise(r=>setTimeout(r,2e3,s+='!.'[~~(Math.random()<.5)],t(`Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:`))).then(_=>t(s)||f(a,t,s)):t(`Success rate is ${s=s.match(/!/g),s=s?s.length*2:''}0 percent (${s/2}/5)`))(5,_=>console.log(_),'')

Experimente online!

JavaScript + HTML, 299 bytes

Para atender aos requisitos de formatação de saída

(f=(a,t,s)=>a--?new Promise(r=>setTimeout(r,2e3,s+='!.'[~~(Math.random()<.5)])).then(_=>t(...s)&&f(a,t,s)):t(`\nSuccess rate is ${s=s.match(/!/g),s=s?s.length*2:''}0 percent (${s/2}/5)`))(5,t=(..._)=>p.innerHTML+=_.pop(),'',t(`Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:\n`))
<pre id=p></pre>

guest271314
fonte
1

Limpo , 305 bytes

import StdEnv,Math.Random
s::!Int->Int
s _=code {
ccall sleep "I:I"
}
t::!Int->Int
t _=code {
ccall time "I:I"
}
Start#l=take 5(map((bitand)1)(genRandInt(t 0)))
=("Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:\n",[if(e>0)'!''.'\\e<-l|s 2==0],"\nSuccess rate is ",20*sum l," percent (",sum l,"/5)")

Experimente online!

Furioso
fonte
1

Perl 6 , 154 bytes

say "Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:";say
sum(map {sleep 2;.print;?/\!/},roll
5,<. !>).&{"\nSuccess rate is {$_*20} percent ($_/5)"}

Experimente online!

Sean
fonte
1

PHP , 161 bytes

<?="Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:
";for(;$x++<5;print$y?'!':'.')$z+=$y=rand()%2+sleep(2);echo"
Success rate is ",$z*20," percent ($z/5)";

Experimente online!

$ php fakeping.php

Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:
.!.!.
Success rate is 40 percent (2/5)
640KB
fonte
1

C (gcc) , 176 174 bytes

f(i,j){for(puts("Sending 5, 100-byte ICMP Echos, timeout is 2 seconds"),j=i=5;sleep(2),i--;putchar(rand()%2?j--,33:46));printf("\nSuccess rate is %d percent (%d/5)",j*20,j);}

Experimente online!

Economizou 2 bytes graças ao Rogem

Ungolfed:

f(i,j) {
    for (puts("Sending 5, 100-byte ICMP Echos, timeout is 2 seconds"),
            j = i = 5; sleep(0), i--;
            putchar(rand() % 2 ? j--, 33 : 46));
    printf("\nSuccess rate is %d percent (%d/5)",j * 20, j);
}
qookie
fonte
174 com 33e em 46vez de '!'e '.', respectivamente.
1

05AB1E , 83 bytes

т’Sïà 5, ÿ-ÄÁ ICMP ®Ès, €º€Ä is 2 šÀ:’,„.!5ãΩDv.Z.Zy?}õ,'.¢xT*“íÞ„¼€ˆ ÿ‰» (ÿ/5)“.ª?

Experimente online!

Grimmy
fonte
1

Befunge-98 (PyFunge) , 164 bytes

#va":sdnoces 2 si tuoemit ,sohcE PMCI etyb-001 ,5 gnidneS5"k,>0"2 peels"=k
>?1'!>,+\1+:4`!jv\'^'=1p
;>0'.^;")5/",,,@>$" si etar sseccuS"afk,,:2a**.'0+"( tnecrep"9k,

Experimente online!

Infelizmente, só pude testá-lo no TIO, onde ele retorna tudo após dez segundos, mas deve funcionar conforme o esperado.

david
fonte