Rabiscos ASCII: Laser em uma caixa


31

Às vezes, quando estou rabiscando, desenho um retângulo, começo com uma diagonal de um dos cantos e, em seguida, trace uma linha "refletindo" toda vez que bato em um lado do retângulo. Eu continuo com isso até atingir outro canto do retângulo (e espero que a proporção do meu retângulo não seja irracional;)). É como traçar o caminho de um laser que brilha dentro de uma caixa. Você deve produzir o resultado disso com a arte ASCII.

Como exemplo, considere uma caixa de largura 5e altura 3. Sempre começaremos no canto superior esquerdo. Os #marca o limite da caixa. Observe que a largura e a altura se referem às dimensões internas.

#######    #######    #######    #######    #######    #######    #######
#\    #    #\    #    #\   \#    #\  /\#    #\  /\#    #\/ /\#    #\/\/\#
# \   #    # \  /#    # \  /#    # \/ /#    # \/ /#    #/\/ /#    #/\/\/#
#  \  #    #  \/ #    #  \/ #    # /\/ #    #\/\/ #    #\/\/ #    #\/\/\#
#######    #######    #######    #######    #######    #######    #######

O desafio

Dada a largura (positiva) e a altura da caixa, você deve produzir o resultado final da localização do laser. Você pode escrever um programa ou função, recebendo entradas via STDIN (ou alternativa mais próxima), argumento de linha de comando, argumento de função e gerar o resultado via STDOUT (ou alternativa mais próxima) ou através de valores ou argumentos de retorno de função.

Você pode usar qualquer formato conveniente de lista, sequência ou número para entrada. A saída deve ser uma única string (a menos que você a imprima em STDOUT, o que você pode fazer gradualmente). Isso também significa que você pode obter a altura primeiro e a largura segundo - basta especificar o formato exato de entrada na sua resposta.

Não deve haver espaços em branco à esquerda nem à direita em nenhuma linha da saída. Opcionalmente, você pode gerar uma única nova linha à direita.

Você deve usar o espaço, /, \e #e reproduzir os casos de teste exatamente como mostrado.

Casos de teste

2 2
####
#\ #
# \#
####

3 2
#####
#\/\#
#/\/#
#####

6 3
########
#\    /#
# \  / #
#  \/  #
########

7 1
#########
#\/\/\/\#
#########

1 3
###
#\#
#/#
#\#
###

7 5
#########
#\/\/\/\#
#/\/\/\/#
#\/\/\/\#
#/\/\/\/#
#\/\/\/\#
#########

22 6
########################
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
# /\  /\  /\  /\  /\  /#
#/  \/  \/  \/  \/  \/ #
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
########################

1
Talvez uma boa pergunta de acompanhamento, uma vez que esta tenha terminado, seja fazer esse desafio com caixas e pontos de partida arbitrariamente moldados.
Sanchises

@sanchises Eu realmente considerei isso (e ainda posso publicá-lo), mas decidi seguir o retângulo na esperança de que alguém pudesse inventar uma fórmula explícita. Eu também estava considerando vários pontos de partida que Xseriam necessários para cruzamentos. Talvez na próxima vez. ;)
Martin Enders


Isso seria perfeito para um ponto de animação. "Animar 1 burst (uma barra) 1 ciclo / sem fim"
Martijn

Respostas:


20

Pitão, 43 41 39 bytes

K*\#+2QKVvzp<*QXX*dyivzQN\\_hN\/Q\#\#)K

Experimente online: Pyth Compiler / Executor . Insira os números na seguinte ordem: altura primeira linha, largura segunda linha.

Obrigado a isaacg, que ajudou a salvar dois bytes.

Explicação:

Minha solução não rastreia o laser, ele usa um padrão simples que inclui o gcd. Se m, nsão as dimensões da caixa, deixe d = gcd(m, n). O tamanho do padrão é exatamente 2*d x 2*d.

Por exemplo, o padrão de repetição para 7 5

#########
#\/\/\/\#
#/\/\/\/#
#\/\/\/\#
#/\/\/\/#
#\/\/\/\#
#########

é

\/
/\

( gcd(7, 5) = 1, tamanho do padrão é 2 x 2)

E o padrão de repetição para 22 6

########################
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
# /\  /\  /\  /\  /\  /#
#/  \/  \/  \/  \/  \/ #
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
########################

é

\  /
 \/ 
 /\
/  \

( gcd(22, 6) = 2, tamanho do padrão é 4 x 4)

Minha solução faz o seguinte para cada uma das linhas: ele simplesmente gera uma linha do padrão, repete-a algumas vezes e corta no final para que caiba na caixa.

K*\#+2QK   implicit: Q is the second input number (=width)
K          K = 
 *\#+2Q        "#" * (2 + Q)
       K   print K (first line)

Vvzp<*QXX*dyivzQN\\_hN\/Q\#\#)K  implicit: vz is the first input number (=height)
VQ                               for N in [0, 1, ..., vz-1]:
           ivzQ                             gcd(vz,Q)
          y                               2*gcd(vz,Q)
        *d                           string with 2*gcd(vz,Q) space chars
       X       N\\                   replace the Nth char with \
      X           _hN\/              replace the -(N+1)th char with /
    *Q                               repeat Q times
   <                   Q           only use the first Q chars
  p                     \#\#       print "#" + ... + "#"
                            )    end for
                             K   print K

Desde Xsuportes "atribuir" para cordas, você pode mudar m\ para *de remover s.
Isaacg

@isaacg Boa chamada. Pensei em usar em *\ vez de em m\ breve, mas descarte-o porque tem o mesmo tamanho. Não pensou na variável de no desnecessário s.
Jakube

11

C, 256 bytes

f(w,h){int i,j,x=1,y=1,v=1,u=1;char b[h+2][w+3];for(i=0;i<w+3;i++)for(j=0;j<h+2;j++)b[j][i]=!i||!j||i>w||j>h?i>w+1?0:35:32;while((x||y)&&(x<=w||y<=h))v=x&&w+1-x?v:(x-=v,-v),u=y&&h+1-y?u:(y-=u,-u),b[y][x]=v/u<0?47:92,x+=v,y+=u;for(i=0;i<h+2;i++)puts(b[i]);}

Provavelmente, posso obter isso abaixo de 200, e adicionarei uma explicação mais tarde, mas talvez eu deva ter um documento dentro de algumas horas.


27
Pontos de internet falsos valem mais do que um diploma educacional, tenho certeza disso.
9788 Adam


5

J, 85 bytes

Let g = gcd(w,h). A função preenche os elementos de uma w/g by h/gmatriz com g by gladrilhos, possuindo /'s \' e 's na diagonal e anti-diagonal. A matriz 4D resultante é dividida em 2D (a parte interna da caixa) e depois é cercada por #'s. (Os números 0 1 2 3são usados ​​em vez de [space] / \ #e os números são alterados para caracteres no final.)

Um cálculo baseado em posição direta da coordenada interna pode gerar uma solução um pouco mais curta.

' \/#'echo@:{~3,.~3,.3,~3,,$[:,[:,"%.0 2 1 3|:((,:2*|.)@=@i.@+.){~[:(2&|@+/&:i.)/,%+.

Uso:

   6 (' \/#'echo@:{~3,.~3,.3,~3,,$[:,[:,"%.0 2 1 3|:((,:2*|.)@=@i.@+.){~[:(2&|@+/&:i.)/,%+.) 22
########################
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
# /\  /\  /\  /\  /\  /#
#/  \/  \/  \/  \/  \/ #
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
########################

Experimente online aqui.


0

Calculadora Desmos - Não competindo para ajudar a conhecer mais

Experimente online!

Entradas:

h as height of box, with 0-indexing
w as width of box, with 0-indexing

Intermediários:

Let b = gcd(h,w),
Let c = |b-h%2b| Or |b-mod(h,2b)|

Formula, abreviada:

(|b-(x+y)%2b|-c)(|b-(x-y)%2b|-c)=0

Saídas:

x as x position, 0-indexed, where the ball will land when released
y as y position, 0-indexed, where the ball will land when released

Como funciona:

(|b-(x+y)%2b|-c)*(|b-(x-y)%2b|-c)=0
                ^ OR operation - |b-(x+y)%2b|-c=0 or |b-(x-y)%2b|-c=0
|b-(x+/-y)%2b|-c = 0
|b-(x+/-y)%2b| = c
|b-(x+/-y)%2b| = c means (b-(x+/-y))%2b = + or -c 
b-(x+/-y)%2b = +/- c -> b +/- c = (x+/-y)%2b -> (x+/-y) = n*2*b + b +/- c 
Where n is integer.  This will force patterns to repeat every 2b steps in x and y.  
Initial pattern n=0: (x +/- y) = b +/- c -> y = +/- x + b +/- c
In the x positive and y positive plane only, these correspond to lines of positive and 
negative slope, set at intercept b, offset by c on either side.

O programa não atende ao critério final - gerando arte ASCII de caixa e linhas, por isso estou enviando informações não competitivas para ajudar outras pessoas a concluir o desafio. Observe que, para que o Desmos funcione quando c = 0 ou c = b, um pequeno fator de deslocamento de 0,01 foi introduzido, pois o Desmos parece ter limites de Mod (A, B) de (0, B) em vez de [0, B )

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.