Два лазера між двома дзеркалами


70

Що робити, якщо у нас є коридор, який складається з двох паралельних дзеркал?

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

Тепер ми просвічуємо лазер вниз ...

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

О, дивись. Він відскочив, до кінця, туди.

Що робити, якщо ми намалюємо два лазери, АЛЕ йде в зворотному напрямку?

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

Хм, вони, схоже, не зустрілися там. Це зручно. Що станеться, якщо обидва лазера займають однаковий простір?

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

Я думаю, це було досить очевидно, так?


Малювати ці схеми вручну досить трудомістко (довіряйте мені з цього приводу). Можливо, якийсь код міг би зробити це для нас?

  • Напишіть код, щоб вивести два паралельних дзеркала з двома лазерами, що перетинаються, перетинаючись.
  • Введення (усі цілі числа):
    • Ширина коридору
    • Довжина коридору
    • Вихідне положення правого лазера (нульове значення, має бути менше ширини)
    • Вихідне положення лівого лазера (нульове значення, має бути менше ширини)
  • Процес
    • Якщо лазер рухається правильно, на наступному рядку буде намальовано один пробіл праворуч.
    • Якщо лазер залишився, на наступному рядку буде намальовано пробіл ліворуч.
    • Якщо лазер не може зробити його вбік кроком, він змінить свій напрямок, але не його положення.
    • Якщо обидва лазера мають один і той же індекс, надрукуйте верхній регістр X у цьому індексі.
  • Вихід
    • Рядок з кількома рядками
    • Кожен рядок починається і закінчується символом труби (|)
    • Правий лазер позначається зворотною косою рисою (\)
    • Лівий лазер позначається нахилом вперед (/)
    • Перетин двох лазерів позначається великим регістром X.
  • Будь-яка мова
  • Я хотів би бачити посилання TIO
  • Спроба виправити це в найменшій кількості байтів

Тестові справи

ширина: 6 довжина: 10 праворуч: 1 ліворуч: 4

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

ширина: 6 довжина: 10 праворуч: 0 ліворуч: 1

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

ширина: 4 довжина: 10 праворуч: 2 ліворуч: 0

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

ширина: 20 довжина: 5 праворуч: 5 ліворуч: 15

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

ширина: 5 довжина: 6 праворуч: 2 ліворуч: 2

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

ширина: 1 довжина: 2 праворуч: 0 ліворуч: 0

|X|
|X|

6
Запропонований край корпусу: ширина: 1, довжина: що завгодно, праворуч: 0, ліворуч: 0
Арнольд

2
@Arnauld | X | ;)
AJFaraday

Відповіді:


12

Стакс , 40 байт

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

Запустіть і налагоджуйте його

Спробуйте в Інтернеті!

Досить впевнений, що це може бути додатково гольф.

Введення подається у формі width [right-going left-going] length(за коментарем @EngineerToast).

ASCII еквівалент:

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

1
Ви можете відзначити формат введення якwidth [right-going left-going] length
Engineer Toast

18

JavaScript (ES6), 149 байт

Здійснює введення в синтаксис 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):''

Спробуйте в Інтернеті!

Прокоментував

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 байт

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

Спробуйте в Інтернеті!


Може ви не гольф , \\/щоб \/? Незважаючи на те, що нахил нахилу трактується двічі, він все одно не уникне косої риски.
Джонатан Фрех

@JonathanFrech Ти маєш рацію, я думав, що бути в рядку-струні не вдасться, але це дійсно не вникне жодного разу.
xnor

О, мій рішення, моє рішення було болісно наближене до цієї ідеї - робота модуля 2w має багато сенсу в ретроспективі. Дуже розумний!
Лінн


9

Пітон 2 , 187 181 179 177 174 172 171 байт

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]

Спробуйте в Інтернеті!


Рекурсивна:

Пітон 2 , 172 байти

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)

Спробуйте в Інтернеті!


Рекурсивний, альтернативний друк:

Пітон 2 , 172 байти

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)

Спробуйте в Інтернеті!


Мене знову вражає швидкість отримання перших відповідей на проблеми кодового гольфу. Хороший! :)
AJFaraday

8

C (стук) , 240 236 208 байт

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

Спробуйте в Інтернеті!

f () приймає параметри таким чином:

x= ширина,
y= довжина,
r= Початкове положення початкової лінії правої лінії
l= Початкове початкове положення лівої лінії

-4 байти кредити Кевіна Круїссена. Дякую


1
Ви можете whileграти в 3 байти, змінивши на "a", forщоб видалити {}та одну з напівколонок. І ще 1 байт, змінивши c&&dна c&d. Спробуйте в Інтернеті 236 байт .
Кевін Кройсейсен

Схоже, ви приймаєте два додаткові входи, тобто afaik заборонено.
OOBalance

1
Ви не повинні вирішувати узагальнення виклику, а завдання, як зазначено. Щодо додаткових входів, я трохи розкопав мета і виявив це: codegolf.meta.stackexchange.com/a/12696/79343 Я думаю, що його треба записати ще десь, але я не можу його знайти в атм. Однак це норма.
OOBalance

1
У макросі g ви можете грати у 2 байти, змінюючи a == - 1 на <0.
JohnWells

1
Насправді отримано більше в макро, ++, a і a -, може гольф по 2 байти кожен ++ a і
--a


5

Вугілля , 56 50 байт

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

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Редагувати: збережено 6 байт, зменшивши залежність від перемикання. Пояснення:

↷PIθM⊕η→Iθ

Роздрукуйте сторони.

F²«

Петлю над двома лазерами.

J⊕⎇ιεζ⁰

Перейдіть до початку лазера.

FIθ«

Петля по висоті.

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

Накресліть а \або /у відповідному напрямку, якщо тільки квадрат не порожній, у такому разі намалюйте а X.

¿⁼KK|«

Чи вдарили ми в бік?

¿ι→←≦¬ι

Якщо так, то зробіть один крок вбік і переверніть напрямок руху.


Це виходить за межі, коли вхід "10 2 4 2"
Martijn Vissers

1
@MartijnVissers Ну так, якщо ваша ширина становить 2, то ваші позиції можуть бути лише 0 або 1 ...
Ніл


3

PHP, 177 169 166 байт

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

потрібно PHP 7.1 для негативних рядкових індексів, PHP 5.5 або новіших версій для індексації рядкових літералів.
для PHP <7.1 , видалити ^L, замінити "X\/"з "/X\\", :0з +1:1, [$e]з [$e+1], видалити ."|"і вставити |до кінця рядка. (+3 байти)
для PHP <5,5 , замініть "/X\\"на $pта вставіть $p="/X\\";на початку. (+2 байти)

приймає дані з аргументів командного рядка. Запустіть -nrабо спробуйте їх в Інтернеті .


Прикро, що webphpfunctions.com не зберігає правильну PHP-версію у посиланні для обміну ...
Арнольд

3

Пітон 3 , 162 байти

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

Спробуйте в Інтернеті!


Мені подобається форматування у вашому тестовому наборі, надійно показуючи вхідні дані проти виходу ... Хороший;)
AJFaraday

3

Рубін , 117 байт

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

Спробуйте в Інтернеті!

Анонімна лямбда, приймаючи введення як ширина w, висота hта масив вихідних точок a.


Ви свого роду зробили мій день, зробивши його розширюваним масивом, а не лише 2 вихідними пунктами.
AJFaraday

2

PowerShell , 243 233 222 205 байт

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

Спробуйте в Інтернеті!

Oooof. ці логічні блоки великі та брудні та здебільшого дублюються. Наступним кроком буде їх переписування, щоб вони не потребували іншого твердження.





1

Котлін , 322 311 302 байт

Змінено, як я вводив напрямок лазера в рядок на 11 байт. Переміщене завдання з 9 байт.

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

Спробуйте в Інтернеті!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.