Dos láseres entre dos espejos.


70

¿Qué pasa si tenemos un corredor compuesto por dos espejos paralelos?

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

Ahora, le damos brillo a un láser ...

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

Oh mira. Rebotó, hacia el final, allí.

¿Qué pasa si dibujamos dos láseres PERO yendo en la dirección opuesta?

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

Hmm, no parecían encontrarse allí. Eso es conveniente ¿Qué sucede si ambos láseres ocupan el mismo espacio?

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

Supongo que fue bastante obvio, ¿eh?


Dibujar estos diagramas a mano es bastante laborioso (confía en mí en esto). ¿Quizás algún código podría hacerlo por nosotros?

  • Escriba un código para generar dos espejos paralelos, con dos láseres que se cruzan y se cruzan.
  • Entrada (todos los enteros):
    • El ancho del corredor
    • La longitud del corredor
    • Posición inicial del láser que se dirige hacia la derecha (indexado a cero, debe ser inferior al ancho)
    • Posición inicial del láser izquierdo (indexado a cero, debe ser inferior al ancho)
  • Proceso
    • Si un láser funciona correctamente, se dibujará un espacio a la derecha en la siguiente línea.
    • Si se deja en funcionamiento un láser, se dibujará un espacio a la izquierda en la siguiente línea.
    • Si un láser no puede dar el paso lateral, cambiará su dirección, pero no su posición.
    • Si ambos láser están en el mismo índice, imprima una X mayúscula en ese índice.
  • Salida
    • Una cadena con varias líneas.
    • Cada línea comienza y termina con un carácter de tubería (|)
    • El láser a la derecha se denota con una barra diagonal inversa (\)
    • El láser izquierdo se denota con una barra diagonal (/)
    • La intersección de dos láseres se denota con una X mayúscula.
  • Cualquier idioma
  • Me gustaría ver enlaces TIO
  • Intenta arreglarlo en el menor número de bytes

Casos de prueba

ancho: 6 longitud: 10 a la derecha: 1 a la izquierda: 4

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

ancho: 6 longitud: 10 derecha: 0 izquierda: 1

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

ancho: 4 largo: 10 a la derecha: 2 a la izquierda: 0

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

ancho: 20 longitud: 5 a la derecha: 5 a la izquierda: 15

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

ancho: 5 longitud: 6 derecha: 2 izquierda: 2

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

ancho: 1 longitud: 2 derecha: 0 izquierda: 0

|X|
|X|

66
Caso de borde sugerido: ancho: 1, longitud: lo que sea, derecha: 0, izquierda: 0
Arnauld

2
@Arnauld | X | ;)
AJFaraday

Respuestas:


12

Stax , 40 bytes

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

Ejecutar y depurarlo

Pruébalo en línea!

Estoy bastante seguro de que esto puede ser más golfizado.

La entrada se proporciona en forma de width [right-going left-going] length(por comentario de @EngineerToast).

ASCII equivalente:

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

1
Es posible que desee tener en cuenta el formato de entrada comowidth [right-going left-going] length
Engineer Toast

18

JavaScript (ES6), 149 bytes

Toma entrada en la sintaxis de curry (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):''

Pruébalo en línea!

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

Pruébalo en línea!


¿No puedes jugar \\/al golf \/? Aunque la barra diagonal inversa se interpreta dos veces, aún no escapará de la barra diagonal.
Jonathan Frech

@JonathanFrech Tienes razón, pensé que estar en una cadena en cadena fallaría, pero de hecho no escapa en ningún momento.
xnor

Oh, Dios mío, mi solución se acercó dolorosamente a esta idea: trabajar en módulo 2w tiene mucho sentido en retrospectiva. ¡Muy inteligente!
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]

Pruébalo en línea!


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)

Pruébalo en línea!


Impresión 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)

Pruébalo en línea!


Una vez más, estoy sorprendido por la velocidad de las primeras respuestas en los desafíos de código de golf. ¡Buena esa! :)
AJFaraday

8

C (sonido metálico) , 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));}

Pruébalo en línea!

f () toma los parámetros de la siguiente manera:

x= ancho,
y= longitud,
r= posición inicial de línea inicial derecha
l= posición inicial de línea inicial izquierda

-4 bytes. créditos Kevin Cruijssen. Gracias


1
Puede jugar al golf 3 bytes cambiando el whilea a forpara eliminar el {}y uno de los punto y coma. Y 1 byte más cambiando c&&da c&d. Pruébelo en línea 236 bytes .
Kevin Cruijssen

Parece que está tomando dos entradas adicionales, eso no está permitido afaik.
OOBalance

1
No se supone que resuelva una generalización del desafío, sino el desafío como se especifica. Con respecto a las entradas adicionales, busqué meta un poco y encontré esto: codegolf.meta.stackexchange.com/a/12696/79343 Estoy pensando que también debe escribirse en otro lugar, pero no puedo encontrarlo en el cajero automático . Sin embargo, es la norma.
OOBalance

1
En su macro g, puede jugar al golf 2 bytes cambiando a == - 1 a <0.
JohnWells

1
En realidad, obtuve más en la macro, a ++, a y a -, una lata de golf de 2 bytes cada una para ++ a y --a
JohnWells


5

Carbón , 56 50 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Editar: guardado 6 bytes al reducir la dependencia de pivotar. Explicación:

↷PIθM⊕η→Iθ

Imprime los lados.

F²«

Pase sobre los dos láseres.

J⊕⎇ιεζ⁰

Muévase al inicio del láser.

FIθ«

Bucle sobre la altura.

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

Dibuje a \o /en la dirección apropiada, a menos que el cuadrado no esté vacío, en cuyo caso dibuje un X.

¿⁼KK|«

¿Hemos golpeado un lado?

¿ι→←≦¬ι

Si es así, dé un paso de lado e invierta la dirección de desplazamiento.


Esto queda fuera de límites cuando la entrada es "10 2 4 2"
Martijn Vissers

1
@MartijnVissers Bueno, sí, si tu ancho es 2, entonces tus posiciones solo pueden ser 0 o 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
";}

requiere PHP 7.1 para índices de cadena negativos, PHP 5.5 o posterior para indexar literales de cadena.
para PHP <7.1 , eliminar ^L, reemplazar "X\/"con "/X\\", :0con +1:1, [$e]con [$e+1], eliminar ."|"e insertar |antes de la nueva línea. (+3 bytes)
para PHP <5.5 , reemplace "/X\\"con $pe inserte $p="/X\\";al principio. (+2 bytes)

toma datos de los argumentos de la línea de comandos. Corre con ellos-nr o pruébalos en línea .


Es lamentable que onlinephpfunctions.com no guarde la versión correcta de PHP en el enlace para compartir ...
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))

Pruébalo en línea!


Me gusta el formato en su conjunto de pruebas, que muestra de manera confiable las entradas contra la salida ... Nice one;)
AJFaraday

3

Rubí , 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+?|}}

Pruébalo en línea!

Lambda anónima tomando datos como ancho w, alto hy una variedad de puntos de partida a.


Me alegraron el día al convertirlo en una matriz expandible, no solo en 2 puntos de partida.
AJFaraday

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)|"}

Pruébalo en línea!

Oooof esos bloques lógicos son grandes y sucios y en su mayoría duplicados. El siguiente paso sería reescribirlos para que no necesiten la declaración 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

Salvó un byte gracias a Jonathan Frech.
Pruébalo en línea!


1
\\/es 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}

Pruébalo en línea!

función anónima que acepta tres argumentos: xel ancho, yla longitud, zun par de posiciones iniciales para los láseres



1

Kotlin , 322 311 302 bytes

Cambió la forma en que pongo la dirección del láser en la cadena de 11 bytes. Se eliminó la asignación de cuándo para 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}()}

Pruébalo en línea!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.