Dois lasers entre dois espelhos


70

E se tivermos um corredor composto por dois espelhos paralelos?

|          |
|          |
|          |
|          |
|          |
|          |
|          |
|          |
|          |
|          |

Agora, apontamos um laser para baixo ...

|  \       |
|   \      |
|    \     |
|     \    |
|      \   |
|       \  |
|        \ |
|         \|
|         /|
|        / |

Veja. Ele saltou, no final, lá.

E se nós desenharmos dois lasers, mas indo na direção oposta?

|  \    /  |
|   \  /   |
|    \/    |
|    /\    |
|   /  \   |
|  /    \  |
| /      \ |
|/        \|
|\        /|
| \      / |

Hmm, eles não pareciam se encontrar lá. Isso é conveniente. O que acontece se os dois lasers ocuparem o mesmo espaço?

|  \     / |
|   \   /  |
|    \ /   |
|     X    |
|    / \   |
|   /   \  |
|  /     \ |
| /       \|
|/        /|
|\       / |

Eu acho que isso era bastante óbvio, hein?


Desenhar esses diagramas à mão é bastante trabalhoso (confie em mim). Talvez algum código possa fazer isso por nós?

  • Escreva algum código para emitir dois espelhos paralelos, com dois lasers que se cruzam e saltam.
  • Entrada (todos os números inteiros):
    • A largura do corredor
    • O comprimento do corredor
    • A posição inicial do laser correto (indexado a zero, deve ser menor que a largura)
    • Posição inicial do laser esquerdo (indexado a zero, deve ser menor que a largura)
  • Processo
    • Se um laser estiver funcionando corretamente, ele será desenhado um espaço à direita na linha a seguir.
    • Se um laser for deixado em movimento, ele será desenhado um espaço à esquerda na linha a seguir.
    • Se um laser não puder dar um passo lateral, ele mudará de direção, mas não de posição.
    • Se os dois laser estiverem no mesmo índice, imprima um X maiúsculo nesse índice.
  • Resultado
    • Uma sequência com várias linhas
    • Cada linha começa e termina com um caractere de barra vertical (|)
    • O laser à direita é indicado por uma barra invertida (\)
    • O laser esquerdo é indicado por uma barra (/)
    • A interseção de dois lasers é denotada por um X maiúsculo.
  • Qualquer língua
  • Eu gostaria de ver os links do TIO
  • Tentativa de corrigi-lo no menor número de bytes

Casos de teste

largura: 6 comprimento: 10 à direita: 1 à esquerda: 4

| \  / |
|  \/  |
|  /\  |
| /  \ |
|/    \|
|\    /|
| \  / |
|  \/  |
|  /\  |
| /  \ |

largura: 6 comprimento: 10 à direita: 0 à esquerda: 1

|\/    |
|/\    |
|\ \   |
| \ \  |
|  \ \ |
|   \ \|
|    \/|
|    /\|
|   / /|
|  / / |

largura: 4 comprimento: 10 à direita: 2 à esquerda: 0

|/ \ |
|\  \|
| \ /|
|  X |
| / \|
|/  /|
|\ / |
| X  |
|/ \ |
|\  \|

largura: 20 comprimento: 5 à direita: 5 à esquerda: 15

|     \         /    |
|      \       /     |
|       \     /      |
|        \   /       |
|         \ /        |

largura: 5 comprimento: 6 à direita: 2 à esquerda: 2

|  X  |
| / \ |
|/   \|
|\   /|
| \ / |
|  X  |

largura: 1 comprimento: 2 à direita: 0 à esquerda: 0

|X|
|X|

6
Caixa de borda sugerida: largura: 1, comprimento: qualquer que seja, direita: 0, esquerda: 0
— Arnauld

2
@Arnauld | X | ;)
— AJFaraday

Respostas:


12

Stax , 40 bytes

àù@○⌡┼PY¼îαφu^·A☺°É⌠■╟¡Åt^◘v(µ╩Ñ♣t{╓○xß╦

Execute e depure

Experimente online!

Certamente isso pode ser ainda mais jogado.

A entrada é fornecida na forma de width [right-going left-going] length(por comentário de @EngineerToast).

Equivalente ASCII:

xHXdmzx);hi+x%Y92&;Hi-x%cy=41*47+&2ME:R\{|+m'||S

11
Pode-se notar o formato de entrada comowidth [right-going left-going] length
— Engineer Toast

18

JavaScript (ES6), 149 bytes

Recebe entrada na sintaxe de currying (w)(h)([a,b]).

w=>h=>g=(p,d=[1,-1],s=Array(w).fill` `)=>h--?`|${p=p.map((x,i)=>~(k=d[i],s[x]='/X\\'[x-p[i^1]?k+1:1],x+=k)&&x<w?x:x+(d[i]=-k)),s.join``}|
`+g(p,d):''

Experimente online!

Comentado

w => h =>                  // w = width, h = height
  g = (                    // g = recursive function taking:
    p,                     //   p[] = array holding the point coordinates
    d = [1, -1],           //   d[] = directions
    s = Array(w).fill` `   //   s = array of w spaces (we can't use a string because it's
  ) =>                     //       immutable in JS)
    h-- ?                  // if we haven't reached the last row yet:
      `|${                 //   append the left pipe
      p = p.map((x, i) =>  //   for each x at position i in p[]:
        ~(k = d[i],        //     k = direction for this point
          s[x] = '/X\\'[   //     insert either '/', 'X' or '\' at position x in s
            x - p[i ^ 1] ? //     if p[0] != p[1]:
              k + 1        //       use the direction
            :              //     else:
              1            //       force 'X'
          ], x += k        //     add k to x
        ) &&               //     if the result is not equal to -1
        x < w ?            //     and is less than w:
          x                //       use the current value of x
        :                  //     else:
          x + (d[i] = -k)  //       change the direction and restore the initial value of x
      ),                   //   end of map()
      s.join``}|\n` +      //   join and append s; append the right bar and a linefeed
      g(p, d)              //   followed by the result of a recursive call
    :                      // else:
      ''                   //   stop recursion

11

Python 2 , 119 bytes

w,l,a,b=input()
exec"print'|%s|'%''.join(' \/X'[sum(i==k%(2*w)for k in[a,~b]+[~a,b]*2)]for i in range(w));a+=1;b-=1;"*l

Experimente online!


Você pode não golf \\/para \/? Mesmo que a barra invertida seja interpretada duas vezes, ainda não escapará da barra.
— Jonathan Frech

@ JonathanFrech Você está certo, eu pensei que estar em uma string em string falharia, mas na verdade não escapa em nenhum momento.
— Xnor

Oh caramba, minha solução ficou dolorosamente próxima dessa idéia - trabalhar com o módulo 2w faz muito sentido em retrospecto. Muito esperto!
— Lynn


9

Python 2 , 187 181 179 177 174 172 171 bytes

def f(w,l,a,b,A=1,B=-1):
 while l:l-=1;print'|%s|'%''.join(' \X/'[[0,A,B,2][(i==a)+2*(i==b)]]for i in range(w));a,A=[a,a+A,-A,A][-1<a+A<w::2];b,B=[b,b+B,-B,B][-1<b+B<w::2]

Experimente online!


Recursivo:

Python 2 , 172 bytes

def f(w,l,a,b,A=1,B=-1):
 if not-1<a<w:A=-A;a+=A
 if not-1<b<w:B=-B;b+=B
 if l:print'|%s|'%''.join(' \X/'[[0,A,B,2][(i==a)+2*(i==b)]]for i in range(w));f(w,l-1,a+A,b+B,A,B)

Experimente online!


Impressão alternativa recursiva:

Python 2 , 172 bytes

def f(w,l,a,b,A=1,B=-1):
 if not-1<a<w:A=-A;a+=A
 if not-1<b<w:B=-B;b+=B
 if l:L=[' ']*w;L[a]=' \/'[A];L[b]=[' \/'[B],'X'][a==b];print'|%s|'%''.join(L);f(w,l-1,a+A,b+B,A,B)

Experimente online!


Mais uma vez, fico impressionado com a velocidade das primeiras respostas sobre os desafios do código de golfe. Agradável! :)
— AJFaraday

8

C (clang) , 240 236 208 bytes

#define g(a,b) b?a++,a==x&&(a=x-1,b=0):a--,a==-1&&(a=0,b=1)
i,m,n,o,p,t[]={47,92};f(x,y,r,l){for(m=1,n=0;y--;puts("|"),g(r,m),g(l,n))for(printf("|"),i=0;i<x;o=i==r,p=i++==l,putchar(o*p?88:o?t[m]:p?t[n]:32));}

Experimente online!

f () assume os parâmetros da seguinte maneira:

x= largura,
y= comprimento,
r= posição inicial da linha inicial direita
l= posição inicial da linha esquerda inicial

-4 bytes. créditos Kevin Cruijssen. obrigado


11
Você pode obter 3 bytes de golfe alterando o whilepara a forpara remover o {}e um ponto e vírgula. E mais 1 byte, alterando c&&dpara c&d. Experimente online 236 bytes .
— Kevin Cruijssen

Parece que você está recebendo duas entradas extras, o que não é permitido.
— OOBalance

11
Você não deve resolver uma generalização do desafio, mas o desafio conforme especificado. Com relação a entradas extras, procurei um pouco por meta e achei o seguinte: codegolf.meta.stackexchange.com/a/12696/79343 Estou pensando que deve ser escrito em outro lugar também, mas não consigo encontrá-lo. É no entanto a norma.
— OOBalance

11
Na sua macro g, você pode obter 2 bytes de golfe alterando a == - 1 para <0.
— 21419 JohnWells

11
Na verdade tem mais na macro, a ++, um e um -, um Golf Can 2 bytes cada para ++ um e --uma
— JohnWells


5

Carvão , 56 50 bytes

↷PIθM⊕η→IθF²«J⊕⎇ιεζ⁰FIθ«✳§⟦↘↙⟧ι∨⁼KKψX¿⁼KK|«¿ι→←≦¬ι

Experimente online! Link é a versão detalhada do código. Editar: salvou 6 bytes, reduzindo a dependência de rotação. Explicação:

↷PIθM⊕η→Iθ

Imprima os lados.

F²«

Faça um loop sobre os dois lasers.

J⊕⎇ιεζ⁰

Mover para o início do laser.

FIθ«

Laço sobre a altura.

✳§⟦↘↙⟧ι∨⁼KKψX

Desenhe a \ou /na direção apropriada, a menos que o quadrado não esteja vazio; nesse caso, desenhe a X.

¿⁼KK|«

Atingimos um lado?

¿ι→←≦¬ι

Nesse caso, dê um passo para o lado e inverta a direção da viagem.


Isto vai para fora dos limites quando a entrada é "10 2 4 2"
— Martijn Vissers

11
@MartijnVissers Bem, sim, se a sua largura é de 2, então suas posições só pode ser 0 ou 1 ...
— Neil


3

PHP, 177 169 166 bytes

[,$w,$h,$a,$b]=$argv;for($e=-$d=1;$h--;$s[$a+=$d]^L?:$a+=$d=-$d,$s[$b+=$e]^L?:$b+=$e=-$e){$s=str_pad("",$w)."|";$s[$b]="X\/"[$e];$s[$a]="X\/"[$a-$b?$d:0];echo"|$s
";}

requer PHP 7.1 para índices de string negativos, PHP 5.5 ou posterior para indexar literais de string.
para PHP <7.1 , remova ^L, substitua "X\/"por "/X\\", :0com +1:1, [$e]com [$e+1], remova ."|"e insira |antes da nova linha. (+3 bytes)
para PHP <5.5 , substitua "/X\\"por $pe insira $p="/X\\";no início. (+2 bytes)

recebe entrada dos argumentos da linha de comando. Corra com -nrou experimente-os online .


É lamentável que onlinephpfunctions.com não salva a versão PHP correto no link de compartilhamento ...
— Arnauld

3

Python 3 , 162 bytes

from numpy import*
def f(w,h,u,v):
 v=w+w-v-1;T=eye(w);M=vstack([T,2*T[::-1]]*2*h)
 for r in M[u:u+h,:]+M[v:v+h,:]:print('|%s|'%''.join(' \/X'[int(i)]for i in r))

Experimente online!


Eu gosto da formatação do conjunto de testes, mostrando de forma confiável as entradas contra a saída ... Nice one;)
— AJFaraday

3

Ruby , 117 bytes

->w,h,a{a[1]-=w;(1..h).map{s=' '*w;a.map!{|x|d=x<0?-1:1;s[x]='X\\/'[s[x][/ /]?d:0];x+=d;x==w ?-1:x<-w ?0:x};?|+s+?|}}

Experimente online!

Lambda anônima tendo entrada como largura w, altura he uma matriz de pontos de partida a.


Você meio que fez o meu dia, tornando-o uma matriz expansível, não apenas 2 pontos de partida.
— precisa saber é o seguinte

2

PowerShell , 243 233 222 205 bytes

param($w,$h,$a,$b)$l,$r,$s=1,-1,' \/'
1..$h|%{$p,$p[$b],$p[$a]=[char[]](' '*$w),$s[$r],($s[$l],"x")[!($a-$b)]
if($a+$l-in($z=0..($w-1))){$a+=$l}else{$l*=-1}if($b+$r-in$z){$b+=$r}else{$r*=-1}"|$(-join$p)|"}

Experimente online!

Oooof. esses blocos lógicos são grandes e sujos e quase sempre duplicados. O próximo passo seria reescrevê-los para que eles não precisem da declaração else.


1

Python 2, 165 164 bytes

w,h,x,y=input()
a,b,s=1,-1,' \/'
exec"""l=[' ']*w
l[x],l[y]=s[a],s[b]if x-y else'X'
if-1<x+a<w:x+=a
else:a=-a
if-1<y+b<w:y+=b
else:b=-b
print'|%s|'%''.join(l)
"""*h

Guardou um byte graças a Jonathan Frech.
Experimente online!


11
\\/é equivalente a \/.
— Jonathan Frech

1

K (ngn / k) , 58 bytes

{" \\/X|"4,'(+/3!1 2*(x#'e+2*|e:=2*x)(2*x)!z+(!y;-!y)),'4}

Experimente online!

função anônima que aceita três argumentos: xa largura, yo comprimento, zum par de posições iniciais para os lasers



1

Kotlin , 322 311 302 bytes

Mudou como eu coloquei a direção do laser na string por 11 bytes. Atribuição removida de quando por 9 bytes.

{w:Int,h:Int,r:Int,l:Int->{var a=""
var f=r
var d=1>0
var s=l
var t=!d
for(o in 1..h){a+="|"
for(c in 0..w-1)a+=when{c==f&&c==s->"X"
c==f&&d||c==s&&t->"\\"
c==f||c==s->"/"
else->" "}
a+="|\n"
if(d){if(++f==w){--f
d=!d}}else if(--f<0){f=0
d=!d}
if(t){if(++s==w){--s
t=!t}}else if(--s<0){s=0
t=!t}}
a}()}

Experimente online!

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.