Dwa lasery między dwoma lustrami

70

Co jeśli mamy korytarz złożony z dwóch równoległych lusterek?

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

Teraz świecimy laserem ...

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

O popatrz. Tam odbiło się pod koniec.

Co jeśli narysujemy dwa lasery, ALE idąc w przeciwnym kierunku?

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

Hmm, tam chyba się nie spotkali. To wygodne. Co się stanie, jeśli oba lasery zajmą tę samą przestrzeń?

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

Myślę, że to było dość oczywiste, co?


Ręczne rysowanie tych diagramów jest dość pracochłonne (zaufaj mi w tym). Być może jakiś kod mógłby to dla nas zrobić?

  • Napisz kod, aby wyprowadzić dwa równoległe zwierciadła z dwoma odbijającymi się, przecinającymi się laserami.
  • Dane wejściowe (wszystkie liczby całkowite):
    • Szerokość korytarza
    • Długość korytarza
    • Pozycja początkowa prostopadłego lasera (indeksowana od zera, musi być mniejsza niż szerokość)
    • Pozycja początkowa lasera lewostronnego (indeksowany od zera, musi być mniejsza niż szerokość)
  • Proces
    • Jeśli laser leci prawidłowo, zostanie narysowany o jedno pole w prawo na następnej linii.
    • Jeśli laser pozostanie w ruchu, zostanie narysowany o jedno miejsce w lewo w poniższej linii.
    • Jeśli laser nie może wykonać kroku w bok, zmieni kierunek, ale nie pozycję.
    • Jeśli oba lasery mają ten sam indeks, wydrukuj wielką literę X przy tym indeksie.
  • Wynik
    • Ciąg z wieloma liniami
    • Każda linia zaczyna się i kończy znakiem kreski (|)
    • Prawy laser jest oznaczony odwrotnym ukośnikiem (\)
    • Lewy laser jest oznaczony ukośnikiem (/)
    • Przecięcie dwóch laserów jest oznaczone wielką literą X.
  • Dowolny język
  • Chciałbym zobaczyć linki do TIO
  • Spróbuj naprawić go w jak najmniejszej liczbie bajtów

Przypadki testowe

szerokość: 6 długość: 10 w prawo: 1 w lewo: 4

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

szerokość: 6 długość: 10 w prawo: 0 w lewo: 1

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

szerokość: 4 długość: 10 w prawo: 2 w lewo: 0

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

szerokość: 20 długość: 5 w prawo: 5 w lewo: 15

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

szerokość: 5 długość: 6 w prawo: 2 w lewo: 2

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

szerokość: 1 długość: 2 w prawo: 0 w lewo: 0

|X|
|X|
AJFaraday
źródło
6
Sugerowany przypadek krawędzi: szerokość: 1, długość: cokolwiek, prawa: 0, lewa: 0
Arnauld
2
@Arnauld | X | ;)
AJFaraday

Odpowiedzi:

12

Stax , 40 bajtów

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

Uruchom i debuguj

Wypróbuj online!

Jestem całkiem pewien, że można to pograć w golfa.

Dane wejściowe są podawane w formie width [right-going left-going] length(na komentarz @EngineerToast).

Odpowiednik ASCII:

xHXdmzx);hi+x%Y92&;Hi-x%cy=41*47+&2ME:R\{|+m'||S
Weijun Zhou
źródło
1
Może chcesz zapisać format wejściowy jakowidth [right-going left-going] length
Inżynier Toast
18

JavaScript (ES6), 149 bajtów

Pobiera dane wejściowe w składni 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):''

Wypróbuj online!

Skomentował

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
źródło
11

Python 2 , 119 bajtów

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

Wypróbuj online!

xnor
źródło
Nie umiesz grać \\/w golfa \/? Mimo że odwrotny ukośnik jest interpretowany dwukrotnie, nadal nie uniknie ukośnika.
Jonathan Frech,
@JathanathanFrech Masz rację, myślałem, że bycie w sznurku w sznurku nie powiedzie się, ale tak naprawdę nie ucieknie ani razu.
xnor
O rany, moje rozwiązanie boleśnie zbliżyło się do tego pomysłu - działający moduł 2w ma sens z perspektywy czasu. Bardzo mądry!
Lynn,
9

Python 2 , 187 181 179 177 174 172 171 bajtów

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]

Wypróbuj online!


Rekurencyjne:

Python 2 , 172 bajty

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)

Wypróbuj online!


Rekurencyjny, alternatywny druk:

Python 2 , 172 bajty

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)

Wypróbuj online!

TFeld
źródło
Po raz kolejny zadziwia mnie szybkość pierwszych odpowiedzi na wyzwania związane z golfem. Niezłe! :)
AJFaraday
8

C (clang) , 240 236 208 bajtów

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

Wypróbuj online!

f () przyjmuje parametry w następujący sposób:

x= szerokość,
y= długość,
r= początkowo pozycja początkowa linii początkowej
l= początkowo pozycja początkowa linii lewej

-4 bajty. kredyty Kevin Cruijssen. Dzięki

GPS
źródło
1
Możesz zagrać w golfa 3 bajty, zmieniając na whilea, foraby usunąć {}jeden i jeden z średników. I jeszcze 1 bajt, zmieniając c&&dna c&d. Wypróbuj online 236 bajtów .
Kevin Cruijssen
Wygląda na to, że bierzesz dwa dodatkowe dane wejściowe, co jest niedozwolone.
OOBalance,
1
Nie powinieneś rozwiązać uogólnienia wyzwania, ale wyzwanie określone. Jeśli chodzi o dodatkowe dane wejściowe, trochę przekopałem metę i znalazłem to: codegolf.meta.stackexchange.com/a/12696/79343 Myślę, że to musi być napisane także gdzie indziej, ale nie mogę znaleźć bankomatu. Jest to jednak normą.
OOBalance,
1
W swoim makrze g możesz golfować 2 bajty, zmieniając a == - 1 na <0.
JohnWells,
1
Właściwie dostałem więcej w makro, a ++, a i a, a can golf 2 bajty każdy na ++ a i - a
JohnWells
5

Węgiel drzewny , 56 50 bajtów

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

Wypróbuj online! Link jest do pełnej wersji kodu. Edycja: Zapisano 6 bajtów, zmniejszając zależność od obrotu. Wyjaśnienie:

↷PIθM⊕η→Iθ

Wydrukuj boki.

F²«

Pętla nad dwoma laserami.

J⊕⎇ιεζ⁰

Przejdź na początek lasera.

FIθ«

Pętla na wysokości.

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

Narysuj \lub /w odpowiednim kierunku, chyba że kwadrat nie jest pusty, w takim przypadku narysuj X.

¿⁼KK|«

Czy uderzyliśmy w bok?

¿ι→←≦¬ι

Jeśli tak, zrób krok w bok i odwróć kierunek jazdy.

Neil
źródło
To wychodzi poza granice, gdy dane wejściowe to „10 2 4 2”
Martijn Vissers,
1
@MartijnVissers Cóż, jeśli twoja szerokość wynosi 2, to twoje pozycje mogą wynosić tylko 0 lub 1 ...
Neil
5

Java (JDK 10) , 186 bajtów

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

Wypróbuj online!

Olivier Grégoire
źródło
3

PHP, 177 169 166 bajtów

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

wymaga PHP 7.1 do indeksowania łańcuchów ujemnych, PHP 5.5 lub nowszego do indeksowania literałów łańcuchowych.
dla PHP <7,1 , usunąć ^L, zastąpić "X\/"z "/X\\", :0z +1:1, [$e]z [$e+1], wyjąć ."|"i włożyć |przed linią. (Bajtów), +3
do PHP <5,5 , wymienić "/X\\"z $pi wstawić $p="/X\\";na początku. (+2 bajty)

pobiera dane wejściowe z argumentów wiersza poleceń. Uruchom je -nrlub wypróbuj online .

Tytus
źródło
Szkoda, że ​​onlinephpfunctions.com nie zapisuje poprawnej wersji PHP w linku udostępniania ...
Arnauld
3

Python 3 , 162 bajty

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

Wypróbuj online!

RootTwo
źródło
Podoba mi się formatowanie w twoim zestawie testowym, niezawodnie pokazujące dane wejściowe w stosunku do wyniku ... Ładne;)
AJFaraday
3

Rubin , 117 bajtów

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

Wypróbuj online!

Anonimowa lambda przyjmuje dane wejściowe jako szerokość w, wysokość hi tablicę punktów początkowych a.

Kirill L.
źródło
W pewnym sensie uczyniłeś mój dzień, robiąc z niego rozszerzalną tablicę, a nie tylko 2 punkty początkowe.
AJFaraday
2

PowerShell , 243 233 222 205 bajtów

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

Wypróbuj online!

Oooof. te bloki logiczne są duże, brudne i w większości powielone. Następnym krokiem byłoby przepisanie ich, aby nie potrzebowały instrukcji else.

Veskah
źródło
1

Python 2, 165 164 bajtów

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

Oszczędność bajtu dzięki Jonathanowi Frechowi.
Wypróbuj online!

Mnemoniczny
źródło
1
\\/jest równoważne z \/.
Jonathan Frech,
1

K (ngn / k) , 58 bajtów

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

Wypróbuj online!

anonimowa funkcja, która akceptuje trzy argumenty: xszerokość, ydługość, zparę pozycji początkowych dla laserów

ngn
źródło
1

C (gcc) , 169 bajtów

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

Wypróbuj online!

gastropner
źródło
163 bajty
ceilingcat
1

Kotlin , 322 311 302 bajtów

Zmieniono sposób umieszczania kierunku lasera w ciągu 11 bajtów. Przeniesiono przypisanie poza kiedy na 9 bajtów.

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

Wypróbuj online!

JohnWells
źródło