Bolas ASCII que caen


16

Entrada

Te dan un mapa 2D con bolas y tierra en él. Se parece a esto:

  1         5          2
                 3
     4


__________________________

Cada número es una bola y el _nivel del suelo. El _carácter de subrayado no está permitido en ninguna otra línea que no sea la línea a nivel del suelo. Solo se permiten espacios, líneas nuevas y dígitos 0-9sobre el nivel del suelo. No puede asumir que la última línea es el nivel del suelo: se permiten líneas vacías debajo del nivel del suelo. También puede agregar espacios, para llenar líneas vacías, si eso le ayuda.

Las bolas pueden tener números del 0al 9, pueden colocarse una encima de la otra, pero no debajo del suelo. Los números de la pelota serán únicos.

Suponga que cada personaje es un metro .

Obtener mapa de pastebin!
Caso de prueba 1 - debería mostrar algo como esto
Caso de prueba 2 - debería producir los mismos resultados que el primer mapa

Desafío

Su desafío es leer un mapa como ese de un archivo o de stdin - se le permite usar cat balls.txt | ./yourexecutable- y la velocidad de salida de cada bola cuando toca el suelo.

Aquí está la fórmula para la velocidad:

ingrese la descripción de la imagen aquí

Suponga que esa hes la diferencia del número de línea entre el número de línea del suelo y el número de línea de la pelota, y eso ges igual10m/s^2 .

Salida

Debes sacar el número y la velocidad de cada bola m/sal nivel del suelo. Por ejemplo N - Vm/s, donde Nes el número de bola y Ves su velocidad. También puede generar una matriz si lo desea.

¡Feliz codificación! :)


Los casos de prueba sin resultado esperado no son casos de prueba
edc65

@ edc65 Agregué los resultados esperados a la pregunta
Jacajack el

¿Está bien si tomo el directorio como entrada del usuario como parte del programa?
Daniel

@Dopapp ¿Qué quieres decir exactamente?
Jacajack

Mira mi respuesta .
Daniel

Respuestas:


8

MATL , 31 30 27 25 bytes

95\16\5B#fG&X>1)b- 20*X^h

La entrada es una matriz de caracteres 2D con un ;separador de filas:

['  1         5          2  ';'                 3        ';'     4                    ';'                          ';'                          ';'__________________________']

Pruébalo en línea! O incluya una inicial ten el código para mostrar el mapa para mayor claridad.

Aquí están los otros casos de prueba: primero , segundo .

Explicación

95\      % Take input implicitly. Modulo 95: convert to numbers and map '_' into 0
16\      % Modulo 16: map space into 0 and digit chars into corresponding numbers
5B#f     % Find row indices and values of nonzero entries
G        % Push input again
&X>      % Index of maximum of each column. This finds character '_'
1)       % Get first value (they are all equal)
b        % Bubble row indices of numbers up in the stack
-        % Subtract to get distance from each number to the ground
20*X^    % Multiply by 20, take sqrt. This gives the velocity values
h        % Horizontally concat numbers and velocities. Display implicitly

7

C, 125 122 121 bytes

b[99]={};main(l,c){for(;(c=getchar())<95u;)b[c]=(l+=c==10);for(c=47;++c<58;)b[c]&&printf("%c,%f\n",c,sqrt((l-b[c])*20));}

Compilar y ejecutar con gcc -w golf.c -lm && cat balls.txt | ./a.out.


Eso es realmente genial, señor! No dije eso en mi pregunta, pero me gustaría que supiera que su ejemplo no 0 ... 9genera nada, cuando el carácter no aparece en el archivo de texto. De todos modos, +1, porque no señalar esto es mi culpa
Jacajack

@Jacajack No, cualquier carácter está bien siempre que no contenga un carácter con un código ASCII mayor que _. Sin embargo, esto podría solucionarse con un byte adicional (en !=lugar de <).
orlp

Bueno, usé 'x' para probar. No importa. Your code's great :)
Jacajack

@Jacajack En la nueva versión ya no es una solución de un carácter, pero
guardé

¡Agradable! :) Cuando regrese a casa, echaré un vistazo a lo que puedo hacer con mi código. Sé que se puede acortar mucho, pero no quiero que sea una copia tuya: p
Jacajack

6

C - 194 (-5) 150 137 bytes

Con un poco más de tiempo y pensando, jugué 44 bytes.
Gracias a orlp por ayudarme a ahorrar 13 bytes.

Comenzaré con mi código C:

b[256]={},n,i=47;main(l,c){for(;~(c=getchar());n=c==95?l:n)b[c]=(l+=c==10);for(;++i<58;)b[i]&&printf("%d %f\n",i-48,sqrt((n-b[i])*20));}

Y versión legible por humanos:

//Throws many warnings, but lack of libraries is tolerated

/*
    c - current character
    l - line number (starts at 1)
    n - ground level
    i - iterator
    b - balls array
*/

b[256] = {}, n, i = 47; //That actually works, as long as you are using ASCII

main( l, c )
{
    for ( ;~( c = getchar( ) ); n = c == 95 ? l : n ) //Read stdin and search for ground
        b[c] = ( l += c == 10 ); //Increment lines counter on newlines, and save line numbers

    for ( ; ++i < 58; ) //Iterate through balls
        b[i] && printf( "%d %f\n", i - 48, sqrt( ( n - b[i] ) * 20 ) ); //Print out data    
}

Compila y ejecuta así: gcc -o balls ballsgolf.c -lm && cat 1.txt | ./balls

Salida

1 10.000000
2 10.000000
3 8.944272
4 7.745967
5 10.000000

Ahorre 4 bytes: en ~(c=getchar())lugar de (c=getchar())!=EOF.
marinus

@marinus Eso es lo que tenía.
orlp

1
if (x != -1)es lo mismo que if (~x)(en las máquinas complementarias de dos) porque ~-1es (únicamente) 0. En C el golf nunca se usa while(cond), ya que for(;cond;)es igual de largo y ofrece más oportunidades para jugar al golf. En tu ejemplo esto puede convertirse for(;~(c=getchar());n=c==95?l:n)b[c]=(l+=c==10);.
orlp

@orlp Entiendo, gracias por el consejo :)
Jacajack

1
l=1se puede eludir haciendo lel primer argumento para main, ya que el tiempo de ejecución de C pasa el número de argumentos a main como su primer argumento ( argc), y cuando llama a un programa sin ningún argumento de línea de comandos ( ./a.out), entonces argc = l = 1. n=0;es innecesario, ya que los enteros globales se inicializan automáticamente a 0. Por lo tanto, n;será suficiente.
orlp

4

Pyth, 27 26 25 24 bytes

smf-hT "_". e, b @ * 20-xd \ _k2dC 
smf @ hT`M; .e, b @ * 20-xd \ _k2dC 
smf @ T`M; .e, b @ * 20-xd \ _k2dC
sm @ # `M; .e, b @ * 20-xd \ _k2dC

Pruébalo en línea!



@orlp Oh, pensé que el nivel del suelo solo puede estar en la última línea.
Leaky Nun



1
@orlp Estaba en las reglas que "Puedes agregar espacios, para llenar líneas vacías, si eso te ayuda".
Leaky Nun

3

Matlab, 100 96 89 90 bytes

s=input('');X=find(s==95);for i=0:9
[x y]=find(s==48+i);if(x)[i sqrt(20*(X(1)-x))]
end
end

Muchos bytes guardados gracias a Luis Mendo

Formato de entrada:

['  1         9          2  ';'                 3        ';'     4                    ';'                          ';'                          ';'__________________________']

Explicación:

X=find(s==95)         -- finds '_', we'll need X(1) to determine max height
for i=0:9             -- loops through balls' numbers
[x y]=find(s==48+i)   -- finds the ball
if(x)                 -- if it is present
[i sqrt(20*(X(1)-x))] -- output its number and velocity

3

Python 3, 84 bytes

Versión 6, 84 bytes: (¡Gracias a Leaky Nun!)

lambda a:[(c,(~-(len(a)-i)*20)**.5)for i,s in enumerate(a)for c in s if c.isdigit()]

Versión 5, 91 bytes:

lambda a:[c+":"+str((~-(len(a)-i)*20)**.5)for i,s in enumerate(a)for c in s if c.isdigit()]

Versión 4, 92 bytes:

lambda i:[c+":"+str((~-(len(i)-n)*20)**.5)for n in range(len(i))for c in i[n]if c.isdigit()]

Versión 3, 99 bytes:

def r(i):x=len(i);print([c+":"+str((~-(x-n)*20)**.5)for n in range(x)for c in i[n] if c.isdigit()])

Versión 2, 102 bytes:

def r(i):
 n=len(i)
 for l in i:
  for c in l:
   if c.isdigit():print(c+":"+str((~-n*20)**.5))
  n-=1

Las versiones anteriores toman una serie de cadenas como entrada.

Versión 1, 140 bytes:

with open(input(),"r")as i:
 n=sum(1for l in i);i.seek(0)
 for l in i:
  for c in l:
   if c.isdigit():print(c+":"+str((~-n*20)**.5))
  n-=1

Esto toma el directorio del archivo como entrada del usuario.


1 for l in i->1for l in i
Leaky Nun

@LeakyNun, ¿funciona ese truco con todas las palabras clave y números?
Daniel

1
Eso creo. Además, (n-1)*20->~-n*20
Leaky Nun

1
Espere. ¿Python3 no requiere paréntesis con la printllamada?
Yytsi

1
@LeakyNun No, no funciona para todas las palabras clave y números en Python 2. No funciona específicamente para palabras clave que comienzan con un e, porque entonces el tokenizer de Python intentará analizarlo como notación científica de coma flotante (por ejemplo 1e5). Ejemplo que falla: f = lambda n:-1if n<0else 1. Un ejemplo que falla en ambas versiones de Python es 0or 1, porque el tokenizer piensa que 0ocomienza un número octal.
orlp

2

Python 3, 84 bytes

lambda x:[[i,(20*x[x.find(i):x.find('_')].count('\n'))**.5]for i in x if i.isdigit()]

Una función anónima que acepta la entrada por argumento como una cadena de varias líneas con todas las líneas vacías llenas de espacios, y devuelve una matriz donde cada elemento tiene la forma [número de bola, velocidad].

Cómo funciona

lambda x                      Function with input x
...for i in x if i.isdigit()  Loop through all characters i in x for which i is a digit,
                              and hence one of the balls
x[x.find(i):x.find('_')]      Slice x to give the substring between the ball and the ground
....count('\n')               Count the number of newlines in the substring to give the
                              height of the ball
(20*...)**.5                  Calculate the speed of the ball as it hits the ground
[i,...]                       Package the ball number and speed into a list
:[...]                        Return all ball-speed pairs as a list with elements [ball
                              number, speed]

Pruébalo en Ideone


En este caso, creo, es un fragmento de código en lugar de un script Python completo e independiente, ¿no?
Jacajack

@Jacajack De hecho, esta es una función, no un fragmento, que está permitido de forma predeterminada . En Python, las funciones lambda son funciones sin un nombre que pueden asignarse a una variable y luego llamarse cuando sea necesario; podrías escribir f = MyAnswery luego llamar usando f(x). Existe un consenso de que no hay necesidad de nombrar lambdas . Buen desafío, por cierto!
TheBikingViking

Claro, pensé que se suponía que las lambdas eran fragmentos de código aquí ( meta.codegolf.stackexchange.com/a/1146/55729 ). Supongo que todo está bien, entonces. Gracias por tu opinión :)
Jacajack

2

JavaScript (ES6) 93

Editar 2 bytes guardados gracias a @Jacajack

Una función con una cadena multilínea como parámetro de entrada. La salida no está ordenada (ya que esto no se solicita)

a=>[...a].reverse().map(c=>c>'Z'?b=i:c<' '?++i:c>' '&&console.log(c,Math.sqrt((i-b)*20)),i=0)

Prueba

F=
a=>[...a].reverse().map(c=>c>'Z'?b=i:c<' '?++i:c>' '&&console.log(c,Math.sqrt((i-b)*20)),i=0)

function test()
{
  F(I.value);
}

test()
#I { height: 12em; width: 30em}
<textarea id=I>
    
 
  1         5          2
                 3
     4


__________________________




</textarea>
<button onclick="test()"></button>


No sqrt(x)sería más corto que pow(x,.5)?
Jacajack

@Jacajack sí, gracias, no sé cómo se me pasó eso por la cabeza
edc65
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.