Deux lasers entre deux miroirs

70

Et si nous avions un couloir composé de deux miroirs parallèles?

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

Maintenant, nous lançons un laser

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

Oh regarde. Il a rebondi, vers la fin, là-bas.

Et si on dessinait deux lasers MAIS dans la direction opposée?

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

Hmm, ils ne semblaient pas se rencontrer, là-bas. C'est pratique. Que se passe-t-il si les deux lasers occupent le même espace?

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

Je suppose que c'était assez évident, hein?


Dessiner ces diagrammes à la main est assez laborieux (croyez-moi là-dessus). Peut-être que du code pourrait le faire pour nous?

  • Ecrivez du code pour produire deux miroirs parallèles, avec deux lasers qui se croisent et qui rebondissent.
  • Entrée (tous les entiers):
    • La largeur du couloir
    • La longueur du couloir
    • Position de départ du laser de droite (index zéro, doit être inférieur à la largeur)
    • Position de départ du laser de gauche (index zéro, doit être inférieur à la largeur)
  • Processus
    • Si un laser fonctionne correctement, il sera tracé d’un espace vers la droite sur la ligne suivante.
    • Si un laser est laissé en cours, il sera dessiné d'un espace à gauche sur la ligne suivante.
    • Si un laser ne peut pas faire son pas de côté, il changera de direction, mais pas sa position.
    • Si les deux lasers se trouvent au même index, imprimez un X majuscule à cet index.
  • Sortie
    • Une ficelle à plusieurs lignes
    • Chaque ligne commence et finit par un caractère de pipe (|)
    • Les lasers à droite sont signalés par une barre oblique inversée (\)
    • Les lasers de gauche sont signalés par une barre oblique (/)
    • L'intersection de deux lasers est désignée par un X majuscule.
  • N'importe quel langage
  • J'aimerais voir des liens TIO
  • Essayez de le réparer dans le plus petit nombre d'octets

Cas de test

largeur: 6 longueur: 10 à droite: 1 à gauche: 4

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

largeur: 6 longueur: 10 à droite: 0 à gauche: 1

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

largeur: 4 longueur: 10 à droite: 2 à gauche: 0

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

largeur: 20 longueur: 5 à droite: 5 à gauche: 15

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

largeur: 5 longueur: 6 à droite: 2 à gauche: 2

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

largeur: 1 longueur: 2 à droite: 0 à gauche: 0

|X|
|X|
AJFaraday
la source
6
Bande de chant suggérée: largeur: 1, longueur: peu importe, droite: 0, gauche: 0
Arnauld
2
@Arnauld | X | ;)
AJFaraday

Réponses:

12

Stax , 40 octets

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

Exécuter et déboguer

Essayez-le en ligne!

Je suis sûr que cela peut encore être joué au golf.

La saisie est donnée sous la forme de width [right-going left-going] length(par commentaire par @EngineerToast).

Équivalent ASCII:

xHXdmzx);hi+x%Y92&;Hi-x%cy=41*47+&2ME:R\{|+m'||S
Weijun Zhou
la source
1
Peut-être voudrez-vous noter le format d'entrée en tant quewidth [right-going left-going] length
Engineer Toast
18

JavaScript (ES6), 149 octets

Prend des entrées dans la syntaxe 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):''

Essayez-le en ligne!

Commenté

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
la source
11

Python 2 , 119 octets

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

Essayez-le en ligne!

Xnor
la source
Ne pouvez-vous pas jouer \\/au golf \/? Même si la barre oblique inverse est interprétée deux fois, elle n'échappera toujours pas à la barre oblique.
Jonathan Frech
@ JonathanFrech Vous avez raison, je pensais qu'être dans une chaîne dans une chaîne échouerait, mais cela n'échappe en fait à aucun moment.
xnor
Oh ma foi, ma solution a été douloureusement proche de cette idée - travailler avec modulo 2w a beaucoup de sens rétrospectivement. Très intelligent!
Lynn
9

Python 2 , 187 181 179 177 174 172 172 171 octets

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]

Essayez-le en ligne!


Récursif:

Python 2 , 172 octets

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)

Essayez-le en ligne!


Impression récursive, alternative:

Python 2 , 172 octets

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)

Essayez-le en ligne!

TFeld
la source
Je suis encore une fois surpris par la rapidité des premières réponses aux défis du code golf. Joli! :)
AJFaraday
8

C (clang) , 240 236 208 octets

#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));}

Essayez-le en ligne!

f () prend les paramètres comme suit:

x= largeur,
y= longueur,
r= position de départ de la ligne initiale droite
l= position de départ de la ligne initiale gauche

-4 octets. crédits Kevin Cruijssen. Merci

GPS
la source
1
Vous pouvez jouer au golf 3 octets en changeant le whileen forpour supprimer le {}et un des points-virgules. Et 1 octet supplémentaire en changeant c&&dpour c&d. Essayez-le en ligne 236 octets .
Kevin Cruijssen
On dirait que vous prenez deux entrées supplémentaires, ce n'est pas permis.
OOBalance
1
Vous n'êtes pas censé résoudre une généralisation du défi, mais le défi spécifié. En ce qui concerne les entrées supplémentaires, j'ai un peu creusé autour de la méta et trouvé ceci: codegolf.meta.stackexchange.com/a/12696/79343 Je pense que cela doit être écrit ailleurs, mais je ne le trouve pas. C'est cependant la norme.
OOBalance
1
Dans votre macro g, vous pouvez jouer au golf sur 2 octets en remplaçant un == - 1 par un <0.
JohnWells
1
En fait plus dans la macro, un ++, un et un -, un peut golf 2 octets chacun pour ++ un et --a
JohnWells
5

Charbon de bois , 56 à 50 octets

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

Essayez-le en ligne! Le lien est vers la version verbeuse du code. Éditer: sauvegardé 6 octets en réduisant le recours au pivotement. Explication:

↷PIθM⊕η→Iθ

Imprimer les côtés.

F²«

Boucle sur les deux lasers.

J⊕⎇ιεζ⁰

Déplacer au début du laser.

FIθ«

Boucle sur la hauteur.

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

Dessinez a \ou /dans la direction appropriée, à moins que le carré ne soit pas vide, auquel cas dessinez un X.

¿⁼KK|«

Avons-nous frappé un côté?

¿ι→←≦¬ι

Si c'est le cas, faites un pas de côté et inversez le sens de la marche.

Neil
la source
Cela sort des limites quand l'entrée est "10 2 4 2"
Martijn Vissers
1
@MartijnVissers Eh bien oui, si votre largeur est égale à 2, vos positions ne peuvent être que 0 ou 1 ...
Neil
5

Java (JDK 10) , 186 octets

(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;}

Essayez-le en ligne!

Olivier Grégoire
la source
3

PHP, 177 169 166 octets

[,$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
";}

requiert PHP 7.1 pour les index de chaîne négatifs, PHP 5.5 ou supérieur pour l'indexation des littéraux de chaîne.
pour PHP <7.1 , supprimez ^L, remplacez "X\/"par "/X\\", :0avec +1:1, [$e]avec [$e+1], supprimez ."|"et insérez |avant la nouvelle ligne. (+3 octets)
pour PHP <5.5 , remplacez "/X\\"par $pet insérez $p="/X\\";au début. (+2 octets)

accepte les arguments de la ligne de commande. Courez avec -nrou essayez-les en ligne .

Titus
la source
Il est regrettable que onlinephpfunctions.com n'enregistre pas la version PHP correcte dans le lien de partage ...
Arnauld
3

Python 3 , 162 octets

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

Essayez-le en ligne!

RootTwo
la source
J'aime la mise en forme dans votre suite de tests, montrant de manière fiable les entrées par rapport à la sortie ...
Très jolie
3

Ruby , 117 octets

->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+?|}}

Essayez-le en ligne!

Anonyme lambda prenant en entrée largeur w, hauteur het un tableau de points de départ a.

Kirill L.
la source
Vous avez en quelque sorte fait ma journée en faisant un tableau extensible, pas seulement 2 points de départ.
AJFaraday
2

PowerShell , 243 233 222 205 octets

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

Essayez-le en ligne!

Oooof. ces blocs logiques sont gros et sales et la plupart du temps dupliqués. La prochaine étape consisterait à les réécrire afin qu'ils n'aient pas besoin de la déclaration else.

Veska
la source
1

Python 2, 165 164 octets

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

Enregistrement d'un octet grâce à Jonathan Frech.
Essayez-le en ligne!

Mnémonique
la source
1
\\/est équivalent à \/.
Jonathan Frech
1

K (ngn / k) , 58 octets

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

Essayez-le en ligne!

fonction anonyme qui accepte trois arguments: xla largeur, yla longueur, zune paire de positions de départ pour les lasers

ngn
la source
1

C (gcc) , 169 octets

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

Essayez-le en ligne!

gastropner
la source
163 octets
ceilingcat
1

Kotlin , 322 311 302 octets

Changement de la façon dont j'ai mis la direction du laser dans une chaîne de 11 octets. Affectation déplacée de quand pour 9 octets.

{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}()}

Essayez-le en ligne!

JohnWells
la source