Bolas ASCII caindo

16

Entrada

Você recebe um mapa 2D com bolas e chão nele. Se parece com isso:

  1         5          2
                 3
     4


__________________________

Cada número é uma bola e o _nível do solo. O _caractere sublinhado não é permitido em nenhuma outra linha que não seja a linha do nível do solo. Só são 0-9permitidos espaços, novas linhas e dígitos acima do nível do solo. Você não pode assumir que a última linha é o nível do solo - linhas vazias abaixo do nível do solo são permitidas. Você também pode adicionar espaços, para preencher linhas vazias, se isso ajudar.

As bolas podem ter números de 0até 9, podem ser colocadas uma acima da outra, mas não embaixo da terra. Os números da bola serão únicos.

Suponha que cada personagem tenha um metro .

Obter mapa da pastebin!
O caso de teste 1 - deve produzir algo como este
Caso de teste 2 - deve produzir os mesmos resultados que o primeiro mapa

Desafio

Seu desafio é ler um mapa como esse de um arquivo ou de stdin- você tem permissão para usar cat balls.txt | ./yourexecutable- e a velocidade de saída de cada bola quando ela atingir o chão.

Aqui está a fórmula para a velocidade:

insira a descrição da imagem aqui

Suponha que hseja a diferença do número da linha entre o número da linha do solo e o número da linha da bola e que gseja igual 10m/s^2.

Resultado

Você deve imprimir cada número e velocidade de bolas m/sno nível do solo. Por exemplo N - Vm/s, onde Né o número da bola e Vsua velocidade. Você também pode gerar uma matriz, se desejar.

Feliz codificação! :)

Jacajack
fonte
Os casos de teste sem resultado esperado não são casos de teste
edc65
@ edc65 eu adicionei resultados esperados para a pergunta
Jacajack
Tudo bem se eu pegar o diretório como entrada do usuário como parte do programa?
Daniel
@Dopapp O que você quer dizer exatamente?
Jacajack
Veja meu resposta .
21416 Daniel

Respostas:

8

MATL , 31 30 27 25 bytes

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

Input é uma matriz de caracteres 2D com ;como separador de linhas:

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

Experimente online! Ou inclua uma inicial tno código para exibir o mapa para maior clareza.

Aqui estão os outros casos de teste: primeiro , segundo .

Explicação

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
Luis Mendo
fonte
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));}

Compile e execute com gcc -w golf.c -lm && cat balls.txt | ./a.out.

orlp
fonte
Isso é realmente ótimo, senhor! Eu não disse isso na minha pergunta, mas gostaria que você soubesse que seu exemplo não produz nada, quando um caractere diferente do 0 ... 9ocorre no arquivo de texto. De qualquer forma, +1, porque não apontar isto é minha culpa
Jacajack
@Jacajack Não, qualquer caractere é válido, desde que não contenha um caractere com código ASCII maior que _. No entanto, isso pode ser corrigido com um byte extra (em !=vez de <).
orlp
Bem, eu usei 'x' para testar. Deixa pra lá. Great :) do seu código
Jacajack
@Jacajack Na nova versão não é uma correção de um caráter mais, mas eu salvo mais 3 bytes :)
orlp
Agradável! :) Vou dar uma olhada no que posso fazer com o meu código quando voltar para casa. Eu sei que pode ser encurtado muito, mas eu não quero que seja uma cópia de sua: p
Jacajack
6

C - 194 (-5) 150 137 bytes

Com um pouco mais de tempo e pensamento, consegui 44 bytes.
Graças ao orlp por me ajudar a economizar 13 bytes

Vou começar com o meu 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));}

E versão legível 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    
}

Compile e execute assim: gcc -o balls ballsgolf.c -lm && cat 1.txt | ./balls

Resultado

1 10.000000
2 10.000000
3 8.944272
4 7.745967
5 10.000000
Jacajack
fonte
Salve 4 bytes: em ~(c=getchar())vez de (c=getchar())!=EOF.
marinus
Marinus @ Isso é o que eu tinha.
orlp
1
if (x != -1)é o mesmo que if (~x)(nas máquinas de complemento de dois) porque ~-1é (exclusivamente) 0. Em C, o golfe nunca é usado while(cond), pois for(;cond;)é tão longo e oferece mais oportunidades para o golfe. No seu exemplo, isso pode se tornar for(;~(c=getchar());n=c==95?l:n)b[c]=(l+=c==10);.
orlp
@orlp eu entendo, obrigado por conselho :)
Jacajack
1
l=1pode ser contornado criando lo primeiro argumento para main, pois o tempo de execução C passa o número de argumentos para main como seu primeiro argumento ( argc) e, quando você chama um programa sem nenhum argumento de linha de comando ( ./a.out), então argc = l = 1. n=0;é desnecessário, pois números inteiros globais são inicializados automaticamente como 0. Então, isso 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

Experimente online!

Freira Furada
fonte
@ orlp Oh, eu pensei que o nível do solo só pode estar na última linha.
Freira vazada
@orlp Não, isso não acontece
Leaky Nun
1
@orlp Foi nas regras que "Você pode adicionar espaços, para preencher linhas vazias, se isso o ajudar".
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

Muitos bytes salvos graças a Luis Mendo

Formato de entrada:

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

Explicação:

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
pajonk
fonte
3

Python 3, 84 bytes

Versão 6, 84 bytes: (Obrigado à Leaky Nun!)

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

Versão 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()]

Versão 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()]

Versão 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()])

Versão 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

As versões acima usam uma matriz de seqüências de caracteres como entrada.

Versão 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

Isso leva o diretório do arquivo como entrada do usuário.

Daniel
fonte
1 for l in i->1for l in i
Freira vazada
@LeakyNun, esse truque funciona com todas as palavras-chave e números?
Daniel
1
Eu acredito que sim. Também, (n-1)*20->~-n*20
Leaky Nun
1
Aguente. O Python3 não requer parênteses com a printchamada?
Yytsi
1
@LeakyNun Não, ele não funciona para todas as palavras-chave e números no Python 2. Ele não funciona especificamente para palavras-chave iniciadas com um e, porque o tokenizador Python tentará analisá-lo como notação científica de ponto flutuante (por exemplo 1e5). Exemplo que não: f = lambda n:-1if n<0else 1. Um exemplo que falha na versão do Python é 0or 1porque o tokenizer pensa que 0oinicia um 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()]

Uma função anônima que aceita entrada por argumento como uma sequência de linhas múltiplas com todas as linhas vazias preenchidas com espaços e retorna uma matriz em que cada elemento está no formato [número da bola, velocidade].

Como 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]

Experimente no Ideone

TheBikingViking
fonte
Nesse caso, eu acho, é um trecho de código em vez de um script Python autônomo completo, não é?
Jacajack
@Jacajack Na verdade, é uma função, não um trecho, que é permitido por padrão . No Python, funções lambda são funções sem um nome que pode ser atribuído a uma variável e, em seguida, chamado quando necessário; você poderia escrever f = MyAnswere ligar usando f(x). Existe um consenso de que não há necessidade de nomear lambdas . Bom desafio, a propósito!
TheBikingViking
Claro, eu apenas pensei que lambdas eram considerados fragmentos de código aqui ( meta.codegolf.stackexchange.com/a/1146/55729 ). Acho que está tudo bem, então. Obrigado por sua opinião :)
Jacajack
2

JavaScript (ES6) 93

Editar 2 bytes salvos thx @Jacajack

Uma função com uma sequência multilinha como parâmetro de entrada. A saída não é classificada (pois isso não é solicitado)

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

Teste

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>

edc65
fonte
Não sqrt(x)seria mais curto do que pow(x,.5)?
Jacajack
@Jacajack sim graças Eu não sei como que escorregou da minha mente
edc65