Simule un ping de Cisco

8

Premisa:

Para aquellos en redes, lo más probable es que haya enviado un ping ao desde algún dispositivo para asegurarse de que todo esté conectado correctamente. Cisco, una compañía popular en redes [cita requerida] , tiene un comando para ello en su IOS que se ve así:

Capturar

( Fuente de la imagen )

Su desafío es recrear gráficamente una parte de esto. Las partes que estamos omitiendo son la primera línea ( Type escape sequence to abort.) por completo, junto con la dirección IP y los tiempos de ida y vuelta.

Comenzará generando lo siguiente:

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

Luego simulará las solicitudes de eco que salen. Cada solicitud comenzará esperando 2 segundos y luego generará la respuesta. Una respuesta de eco exitosa está representada por a !, una fallida por .. En realidad no enviaremos paquetes, pero para representar la pérdida de paquetes, su programa debe elegir aleatoriamente entre las dos opciones con una probabilidad distinta de cero para cada una. Esta línea comenzará vacía y cada marca agregará otro carácter.

Después del quinto eco, se emitirá la línea de porcentaje y el programa debería terminar. La línea de porcentaje tendrá el formato de

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

donde $pestá en regex 0|20|40|60|80|100y $ses el número de ecos exitosos. La pantalla debe actualizarse después de cada período de espera redibujando el nuevo estado o agregando a la línea de eco existente. Esto incluye la Sendinglínea.

Ejemplo de ejecución: (El recuento de ticks no debe mostrarse y está ahí para aclarar cómo debería verse la salida en cada paso de tiempo)

#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:

No se proporcionan datos utilizables.

Salida:

Cualquier formato razonable. Un resultado final de ejemplo se ve así:

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

Reglas:

  • Debe agregar a la línea de eco o volver a dibujar la pantalla después de cada marca.
  • !y .no tiene que ser igualmente probable, solo ambas posibles.
  • Las ejecuciones sucesivas deben ser capaces de generar resultados diferentes.
  • Los gifs o webms de tu salida serían geniales. Sin embargo, no hay bonificación ni nada por ello.
  • Lagunas estándar prohibidas
  • Esto es
Veskah
fuente
¿Se nos permite imprimir las cadenas con espacios finales si la salida es visualmente la misma?
J. Sallé
¿Debería terminar la última línea con un salto de línea?
@Rogem Es opcional.
Veskah

Respuestas:

5

C (gcc) , 172 bytes

Entonces, eliminé 6 bytes de esta cosa con un truco bastante ridículo. Compilar con -DK=!sleep(2)-putchar(rand()%2?33:46)/46. Depende de la sleep()función que se defina en las bibliotecas estándar del sistema. No se repite ni se repite.

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

Pruébalo en línea!

Explicación

Esta solución depende de tres detalles críticos de implementación / tiempo de ejecución. Primero, sleep() no se debe interrumpir , por ejemplo, mediante una señal. En segundo lugar, las sumas y restas se resuelven en orden de izquierda a derecha. Tercero, los argumentos printf()deben resolverse de derecha a izquierda.

Con eso fuera del camino, analicemos esto.

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

El argumento del compilador

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

Entonces, comenzando desde la izquierda (es decir, como debería resolverse), tenemos sleep(). sleep()devuelve el número de segundos restantes cuando regresa, por lo que esperamos que el usuario (y otros procesos) sean amables y no interrumpan nuestro sueño. Tomamos el complemento lógico, y porque en nuestro caso sleep()siempre regresará 0, el resultado es 1. Más sobre el significado más adelante.

A continuación, entramos putchar(). putchar()imprime un solo carácter de 1 byte y devuelve el valor del byte. Entonces, obtenemos un valor aleatorio en el interior, calculamos el módulo-2 para una buena división 50-50 (aunque con una entropía horrible), y luego lo condicionamos ternariamente en nuestros caracteres deseados - ! (33) y . (46). Luego dividimos el valor de retorno de putchar()con 46.

Ahora, esa división regresará 0por !y 1para .- entonces tomamos 1 (de !sleep()) y restamos el resultado de la división de eso. ¡Presto!

De acuerdo, hay un pequeño problema. Cuando escribe cosas en un búfer en C (es decir stdout), no necesariamente escribe en el extremo receptor inmediatamente. De hecho, cuando estaba ejecutando esto en mi distribución de elección, descubrí que solo imprimiría los pings después de que finalizara el programa. Sin embargo, dado que todas las otras soluciones en C están dejando que eso se deslice, y que probablemente exista al menos una máquina en algún lugar que lo haga y cumpla con todos los demás requisitos previos (y uno siempre podría "arreglarlo" en el núcleo ... .), No voy a meterme con mi puntaje fflush()ing stdout.


fuente
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

Pruébalo en línea!

Esta es una gran función directa. Al igual que con otras respuestas, el enlace TIO solo se generará una vez completada la ejecución. Dicho esto, @ Adám ha creado una útil función auxiliar para poder visualizar las marcas de tiempo. Esa versión del código se puede encontrar aquí .

Esta respuesta usos ⎕IO←0, que establece el I ndice O rigin de todo lo que de 1 a 0.

Gracias a @ngn por los 9 bytes guardados (¡y por arruinar mi explicación! Ahora tengo que volver a hacerlo (ლಠ益ಠ)ლ)

Cómo:

La función recibe 1 argumento fijo, que está a la derecha.

Como , tenemos ¨1↓¨,\?6⍴2. Esta expresión elige aleatoriamente ( ?) entre 0 y 1 6 veces ( 6⍴2crea un vector de 6 elementos de 2). Los resultados se concatenan ( ,\) para formar un vector de 6 elementos de 1 a 6 vectores de elementos (por ejemplo:) 1 0 1 0 1 1 0 1 1 0 0 1 1 0 1 0 1 1 0 1 0. El primer elemento de cada uno se descarta ( 1↓¨), y luego cada vector resultante se pasa como ( ¨), ejecutando la función 6 veces.

{5=≢⍵⊣...:...}Es una declaración condicional. Si tiene 5 elementos (es decir, si es la última iteración), ejecutará el código después de la protección ( :). Esto asegura que la condición será la última cosa evaluada, por lo que el programa siempre imprimirá la cadena antes de la protección.

{...⎕DL≢⎕←↑⌽'.!'[⍵]'Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:'...}crea un vector de dos elementos formado por el vector indexado '.!'[⍵], que generará los éxitos y fracasos, y la propia cadena de ping. Ese vector se invierte (monádico ) en el orden correcto, luego se mezcla (monádico ) en una matriz. Esa matriz se envía a stdout ( ⎕←), y se agrega un D e L ay ( ⎕DL). El argumento para ⎕DLes el número de elementos en la matriz ( ), a saber, 2, creando un retraso de 2 segundos entre las llamadas a funciones.

{...:⎕←('Success rate is',×∘20,'percent (','/5)',⍨⍕)+/⍵}crea la última cadena que se generará. Sumará los elementos del argumento ( +/⍵) y pasará el resultado como argumento a la función tácita dentro del paréntesis. Esa función antecede primero (diádico ,, seguido de ) el argumento stringified ( ) con la cadena '/5)', luego lo agrega a la cadena 'percent ('. A continuación, agregará la cadena resultante a 20 veces el argumento ( ×∘20), y luego la agregará al resto de la salida, que se envía a stdout a través de ⎕←.

J. Sallé
fuente
La nueva línea final está bien. Comentando aquí porque estoy en el móvil
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);}

Pruébalo en línea!


El ping en acción

El ping en acción


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
fuente
la impresión es el asesino allí: /
Adam
3

C # (compilador interactivo de 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)");

Pruébalo en línea!

Encarnación de la ignorancia
fuente
2
Bienvenido a PPCG! Me tomé la libertad de generar un ¡Pruébalo en línea! enlace para ti. Le sugiero que edite su respuesta con la plantilla que TIO proporciona para publicar respuestas en PPCG (aunque eso naturalmente no es obligatorio ).
J. Sallé
Puede reducir esto a 299 bytes construyendo Randomen línea en lugar de guardarlo var r. Heres un enlace a mi sugerencia
Robin B
Esto sigue fallando con IndexOutOfBoundsExceptions para mí.
mi pronombre es monicareinstate el
@mypronounismonicareinstate Fixed. ¿Cómo no atrapé esto hace meses?
Encarnación de la ignorancia el
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)

Intentalo

Si new Dateno es lo suficientemente aleatorio, agregue 8 bytes para usar Math.random()en su lugar (se han realizado otras modificaciones para permitir que se ejecute correctamente en un fragmento):

Lanudo
fuente
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)"

Pruébalo en línea!

Realmente similar a la respuesta de Python a TFeld. El tiempo no funciona en TIO (TIO solo sale al finalizar el programa), pero funciona localmente.

La primera línea es solo una cadena colocada en la tubería. La línea media recorre de 0a 4, cada iteración sleeppor 2segundos, luego write-hostcon -nonueva línea. Estamos escribiendo una !o .elegida Randomy almacenada en $x. Luego incrementamos $dsegún $x.

La última línea es otra cadena (multilínea) colocada en la tubería, con un poco de cálculo en el medio para obtener el porcentaje.

-1 byte gracias a Veskah
-3 bytes gracias a Ciaran_McCarthy

AdmBorkBork
fuente
Al convertir la línea de éxito en una cadena de varias líneas en lugar de utilizar la marca de retroceso n (no sé cómo escapar de ella en los comentarios) debería guardar un byte. 161 bytes
Veskah
1
¿Se puede reducir el uso de 3 bytes en *20lugar de /5*100?
Ciaran_McCarthy
@Veskah Sí, gracias.
AdmBorkBork
@Ciaran_McCarthy Santa vaca, gracias por el golf cegadoramente obvio. :)
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)')

Pruébalo en línea!

La sincronización no funciona en TIO, pero funciona en la consola. (TIO sale al final de la ejecución)

-7 bytes, gracias a Erik the Outgolfer

TFeld
fuente
201 bytes .
Erik the Outgolfer
@EriktheOutgolfer ¡Gracias! :)
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(_),'')

Pruébalo en línea!

JavaScript + HTML, 299 bytes

Para cumplir con el requisito de formato de salida

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

invitado271314
fuente
1

Limpio , 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)")

Pruébalo en línea!

Οurous
fuente
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)"}

Pruébalo en línea!

Sean
fuente
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)";

Pruébalo en línea!

$ php fakeping.php

Sending 5, 100-byte ICMP Echos, timeout is 2 seconds:
.!.!.
Success rate is 40 percent (2/5)
640 KB
fuente
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);}

Pruébalo en línea!

Guardado 2 bytes gracias a Rogem

Sin golf:

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
fuente
174 con 33y en 46lugar de '!'y '.', respectivamente.
1

05AB1E , 83 bytes

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

Pruébalo en línea!

Mugriento
fuente
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,

Pruébalo en línea!

Desafortunadamente, solo pude probarlo en TIO, donde devuelve todo después de diez segundos, pero debería funcionar como se esperaba.

david
fuente