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|
AJFaraday
fonte
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
Weijun Zhou
fonte
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
Arnauld
fonte
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!

xnor
fonte
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!

TFeld
fonte
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

GPS
fonte
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
7

Tela , 66 40 bytes

{²Xø⁶╵[⁷/²2%[↔}∔};x╷?⁷∔⁷+╷}[j}}n⁶[|PJp|p

Experimente aqui!

dzaima
fonte
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.

Neil
fonte
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
5

Java (JDK 10) , 186 bytes

(w,h,r,l)->{var x="";for(int i=0,j,R=1,L=-1;i++<h;l+=L,l+=l<0|l>=w?L=-L:0,r+=R,r+=r<0|r>=w?R=-R:0,x+="|\n")for(j=0,x+="|";j<w;j++)x+="/X\\ ".charAt(j==r?j==l?1:R+1:j==l?L+1:3);return x;}

Experimente online!

Olivier Grégoire
fonte
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 .

Titus
fonte
É 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!

RootTwo
fonte
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.

Kirill L.
fonte
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.

Veskah
fonte
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!

Mnemônico
fonte
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

ngn
fonte
1

C (gcc) , 169 bytes

A,B,c;f(w,l,a,b){for(A=1,B=-1;l--;a+=A,a<0|a==w?A=-A,a+=A:0,b+=B,b<0|b==w?B=-B,b+=B:0,puts("|"))for(c=-1;c<w;c++)putchar(c<0?'|':a^c?b^c?32:B>0?92:47:b^c?A>0?92:47:88);}

Experimente online!

gastropner
fonte
163 bytes
ceilingcat 27/11/18
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!

JohnWells
fonte