Onde a bola vai pousar?


17

Dada uma sequência em que a primeira linha contém espaços e um ponto ( ., a "bola"), seguida por linhas que contêm espaços, barras ( /) e barras invertidas ( \), determine em qual coluna a bola aterrará após cair da posição inicial . Cada um o /move para a esquerda por 1 coluna e cada \um para a direita por 1 coluna.

Entrada de amostra

    .
  /   \  \
    /   /
 \   \/  \
   \   /\
    \ /\  \
     \    /

Saída de amostra

A bola começa na coluna 5, bate /na linha 3, depois os três \nas linhas 5 a 7 para uma posição final de:

7

Observe que as colunas são indexadas em 1, principalmente para consistência com as convenções do editor de texto.

Casos de borda

Se a bola atingir um /na primeira coluna, ficará eternamente presa na coluna 0. inexistente. Seu programa deve lidar com isso corretamente imprimindo 0.

Se a bola atingir um dos lados de um \/padrão, o resultado será indefinido. É permitido ao seu programa terminar sem saída, executar um loop infinito ou imprimir uma mensagem de erro (minha solução é impressa -1), mas não deve imprimir nada que possa ser visto como uma saída válida.

Se a bola acertar a barra esquerda em um \\padrão, ela deve terminar diretamente abaixo da barra direita, não à direita dela. A solução que eu originalmente imaginava era propensa a errar, então não siga esse caminho!

Pode ou não haver espaços após a .ou a última /ou \em cada linha. Seu programa não deve contar com esse preenchimento disponível. Em uma nota semelhante, pode ou não haver linhas após a primeira linha.

Você pode assumir que a primeira linha terá zero ou mais espaços e exatamente um .. Linhas subsequentes, se houver, terão zero ou mais espaços e zero ou mais barras.

Detalhes da implementação

Seu programa pode ler de um arquivo (especificado como argumento da linha de comando) ou ler da entrada padrão, conforme sua conveniência.

Seu programa deve gerar um único número na saída padrão. (Sim, uma nova linha à direita está correta. Sim, o número pode ter mais de um dígito.)

Casos de teste

Entrada:

.

Resultado:

1

Observe que a entrada aqui é exatamente um byte. Este é o menor caso que você deve conseguir lidar.

 

Entrada:

 .
 \
  \
   \
    \

Resultado:

 6

Observe que não há espaços após essas barras.

 

Entrada:

  .
  /
 /\\  /  \
//\ \/// //
\\/ \/\ /\/

Resultado:

0

 

Entrada:

  .
/ / /
 \\\
  /\\
 /   \

Resultado:

1

 

Entrada:

   .


 \
       /
/

      \

Resultado:

4

 

Entrada:

 .
 \

\/\/\/

Resultado:

(anything but a nonnegative number)

Considerações finais

Essa pergunta é semelhante à simulação de um computador do tipo bola de bilhar (com base na gravidade) , mas significativamente mais simples, portanto, esperamos que ganhe mais interesse.

Eu tenho uma solução de 169 caracteres em Python. Tenho certeza de que os talentosos jogadores de golfe daqui podem rasgar esse recorde em pedaços. : ^)

Como o é , a resposta mais curta em caracteres será aceita no final do mês!


Também é muito parecido com o A Mere Bagatelle, com um formato de importação ligeiramente diferente e apenas um lançamento. Você pode emprestar e modificar meus scripts de teste, se desejar.
Gareth

Bem, dispara, o título dessa pergunta não era suspeito o suficiente para eu verificar. Me desculpe por isso.
Fraxtil

Tudo bem, essa pergunta foi há dois anos e meio atrás.
amigos estão

Sugiro que no último exemplo, a saída deva ser "A bola está presa".
Mukul Kumar 24/04

Ainda conta como final do mês>. <
alexander-brett

Respostas:


5

Python, 143B

import sys
for l in sys.stdin:
 a=l.find('.')
 if a>-1:F=a
 elif F>-1: 
    if'\\/'in l[F-1:F+2]:z
    F+={'\\':1,'/':-1}.get((l+' '*F)[F],0)
print F+1

Usando o truque de recuo de espaço / tabulação. Eu não fiz nada particularmente inteligente aqui. Fé o índice atual, lé a linha atual; zé indefinido e gera uma exceção, que definitivamente não é um número inteiro positivo, lidando com a \/situação.


2

05AB1E , 37 bytes

¶¡ð«ć'.ksvU…/ \yXD>‚èJD„\/Qiõqëнk<X+]>

Entrada como uma sequência de linhas múltiplas. Saídas \/se a bola estiver presa.

Experimente online ou verifique todos os casos de teste .

Explicação:

¶¡                       # Split the (implicit) input-string on newlines
                         # (work-around instead of `|`, because it will stop at empty lines)
  ð«                     # Add a trailing space to each line (work-around because indexing
                         # -1 in 05AB1E will wrap around to the other side)
    ć                    # Extract head; pop and push the remainder-lines and first line
                         # separated to the stack
     '.k                '# Get the 0-based index of "." in this first line
s                        # Swap to get the remainder-list of lines
v                        # Loop over each line `y`:
 U                       #  Pop and store the top value (the index) in variable `X`
       X                 #  Push the current index `X`
        D>               #  Duplicate it, and increase the copy by 1
                        #  Pair to [X, X+1]
      y    è             #  Index both of those into the current line `y`
            JD           #  Join the two characters together, and duplicate it
              \/Qi      #  If it's equal to "\/":
                   q     #   Stop the program
                         #   (after which the string is output implicitly as result)
                  ë      #  Else:
                   н     #   Only leave the first character (at index `X`)
  …/ \              k    #   Get its 0-based index in string "/ \"
                     <   #   Decrease it by 1
                      X+ #   And add it to `X`
]                        # After the loop:
 >                       # Increase the top of the stack (`X`) by 1
                         # (after which it's output implicitly as result)

1

CJam, 61 bytes

qN/('.#)\_:,0+:e>f{' e]" /"f#0\+}{1$1$=\@2$-_@=@[\]$[W1]#/z}/

Se a regra referente \/for levantada (e não somos obrigados a lidar com isso), isso pode ser reduzido para 41 bytes:

qN/('.#)\_:,:e>f{' e]" /"f#0\+0+}{1$=-}/

1

Java 10, 213 208 190 bytes

s->{int r=s.indexOf('.'),c;for(var x:s.split("\n")){for(;r>x.length()-2;x+=" ");c=x.charAt(r);if(c==46)continue;r/=c>47&x.charAt(r+1)==47?0:1;r+=c<33?0:c<48?-1:1;if(r<0)return 0;}return-~r;}

Lança uma divisão com erro zero quando estamos presos dentro de a \/.

-5 bytes graças a @EdgyNerd .

Explicação:

Experimente aqui.

s->{                             // Method with String parameter and integer return-type
  int r=s.indexOf('.'),          //  Get the index of the dot on the first line
      c;                         //  Temp integer
  for(var x:s.split("\n")){      //  Split the input by newlines, and loop over the lines:
    for(;r>x.length()-2;x+=" "); //   Append trailing spaces if necessary
    c=x.charAt(r);               //   Get the character at the current index of this line
    if(c==46)                    //   If this is the first line (the char is the dot)
      continue;                  //    Continue to the next iteration of the loop
    r/=c>47&x.charAt(r+1)==47?   //   If we're stuck in a `\/`
        0                        //    Divide by 0 to exit the function with an error
       :1;                       //   Else: divide by 1 as no-op
    r+=c<33?                     //   If the current character is a space:
        0                        //    `r` remains at the same index
       :c<48?                    //   Else if it's a `/`:
        -1                       //    Index `r` is decreased by 1
       :                         //   Else (if it's a `\`):
        1;                       //    Index `r` is increased by 1
    if(r<0)                      //   If `r` is now -1:
      return 0;}                 //    Return 0
  return-~r;}                    //  After the loop: return the index `r` + 1

2
Não conheço Java, mas o erro não seria menor que retornar -1?
EdgyNerd 8/08/19

@ EdgyNerd Obrigado, isso economiza 5 bytes. :)
Kevin Cruijssen

1

Python 3 , 124 bytes

import sys
for l in sys.stdin:i=('.'in l)*l.find('.')or(i<0)*i-2*('\\/'in l[i-1:i+2])or' \\'.find((l+i*' ')[i])+i
print(i+1)

Experimente online!

Também funciona em Python 2.

Explicação

for l in sys.stdin:i=          # Change value i for each line in the input
('.'in l)*l.find('.')          # Set i to (0-indexed) dot position if present
or(i<0)*i                      # Keep i fixed if it is below zero
-2*('\\/'in l[i-1:i+2])        # Set i to -2 if \/ trap is encountered
or' \\'.find((l+i*' ')[i])+i   # Else: move position based on character
print(i+1)                     # Print final 1-indexed position

0

J , 95 bytes

[:>[:(<"1@|.@}.([:(1&{+_*0>[:*/2-/\])(]+{~ ::])^:(<3))&.>/@,2<@i.~{.)[:(0,'/ \'<:@i.]);._1 LF,]

Experimente online!

Retorna o infinito _quando a bola fica presa. Perdeu muitos bytes lidando com esse caso especial. Caso contrário, é mais ou menos uma simples redução de linhas. Certamente poderia ser jogado ainda mais.

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.