เลเซอร์สองอันระหว่างกระจกสองอัน


70

จะเป็นอย่างไรถ้าเรามีทางเดินที่ประกอบด้วยกระจกสองบานขนานกัน

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

ตอนนี้เราส่องเลเซอร์ลงไป ...

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

โอ้ดูสิ มันเด้งไปยังจุดสิ้นสุดมี

ถ้าเราวาดเลเซอร์สองตัว แต่ไปในทิศทางตรงกันข้าม

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

อืมดูเหมือนว่าพวกเขาจะไม่พบกันที่นั่น สะดวกมาก จะเกิดอะไรขึ้นถ้าเลเซอร์ทั้งสองกินพื้นที่เดียวกัน?

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

ฉันเดาว่ามันค่อนข้างชัดเจนใช่มั้ย


การวาดไดอะแกรมเหล่านี้ด้วยมือนั้นค่อนข้างลำบาก (วางใจในสิ่งนี้) บางทีรหัสบางอย่างสามารถทำได้สำหรับเรา

  • เขียนโค้ดบางส่วนเพื่อส่งออกมิเรอร์แบบขนานสองชุดพร้อมด้วยการตีกลับสองครั้ง
  • อินพุต (จำนวนเต็มทั้งหมด):
    • ความกว้างของทางเดิน
    • ความยาวของทางเดิน
    • ตำแหน่งเริ่มต้นของเลเซอร์ไปทางขวา (zero-indexed ต้องน้อยกว่าความกว้าง)
    • ตำแหน่งเริ่มต้นของเลเซอร์ที่หมุนซ้าย (ศูนย์ที่จัดทำดัชนีจะต้องน้อยกว่าความกว้าง)
  • กระบวนการ
    • หากเลเซอร์ไปทางขวามันจะถูกดึงหนึ่งช่องว่างไปทางขวาในบรรทัดต่อไปนี้
    • หากเลเซอร์ถูกปล่อยออกไปมันจะถูกดึงหนึ่งช่องว่างไปทางซ้ายในบรรทัดต่อไปนี้
    • หากเลเซอร์ไม่สามารถก้าวไปข้างหน้าได้มันจะเปลี่ยนทิศทาง แต่ไม่ใช่ตำแหน่ง
    • หากเลเซอร์ทั้งสองอยู่ที่ดัชนีเดียวกันให้พิมพ์ตัวพิมพ์ใหญ่ 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
Arnauld

2
@Arnauld | X | ;)
AJFaraday

คำตอบ:


12

Stax , 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
Toast วิศวกร

18

JavaScript (ES6), 149 ไบต์

(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

ลองออนไลน์!


คุณไม่สามารถกอล์ฟ\\/เพื่อ\/? แม้ว่าแบ็กสแลชจะถูกตีความสองครั้ง แต่มันจะไม่รอดจากเครื่องหมายทับ
Jonathan Frech

@JonathanFrech คุณพูดถูกฉันคิดว่าการอยู่ในสตริงจะล้มเหลว แต่แน่นอนว่ามันจะไม่สามารถหนีได้ในเวลาใดเวลาหนึ่ง
xnor

อ๋อ jeez วิธีแก้ปัญหาของฉันใกล้เคียงกับความคิดนี้มาก - modulo 2w ที่ใช้งานได้ทำให้รู้สึกย้อนหลังได้มาก ฉลาดมาก!
ลินน์

9

9

Python 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]

ลองออนไลน์!


ซ้ำ:

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

ลองออนไลน์!


เรียกซ้ำ, การพิมพ์ทางเลือก:

Python 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= width,
y= length,
r= ตำแหน่งเริ่มต้นของบรรทัดไปทางขวาเริ่ม
lแรก = ตำแหน่งเริ่มต้นของบรรทัดไปทางซ้ายเริ่มต้น

-4 ไบต์ หน่วยกิต Kevin Cruijssen ขอบคุณ


1
คุณสามารถเล่นกอล์ฟ 3 ไบต์โดยเปลี่ยนwhilea เป็น a forเพื่อลบ{}และหนึ่งในเซมิโคลอน ไบต์และอีก 1 โดยการเปลี่ยนไปc&&d ลองมันออนไลน์236 ไบต์ c&d
Kevin Cruijssen

ดูเหมือนว่าคุณกำลังรับอินพุตพิเศษสองรายการซึ่งไม่ได้รับอนุญาตให้ใช้ Afaik
OOBalance

1
คุณไม่ควรที่จะแก้ปัญหาทั่วไปของความท้าทาย แต่ความท้าทายตามที่ระบุไว้ เกี่ยวกับอินพุตพิเศษฉันขุดเมตาบิตแล้วพบสิ่งนี้: codegolf.meta.stackexchange.com/a/12696/79343ฉันคิดว่ามันต้องถูกเขียนขึ้นที่อื่นด้วย แต่ฉันหามันไม่เจอ อย่างไรก็ตามมันเป็นบรรทัดฐาน
OOBalance

1
ในมาโคร g ของคุณคุณสามารถเล่นกอล์ฟได้ 2 ไบต์โดยเปลี่ยน == - 1 เป็น <0
JohnWells

1
จริงๆแล้วมีมากขึ้นในมาโคร a ++ a และ a - a can golf 2 bytes ต่อ a ++ 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 เท่านั้น ...
Neil


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หรือลองพวกเขาออนไลน์


มันโชคร้ายที่ onlinephpfunctions.com ไม่ได้บันทึก PHP รุ่นที่ถูกต้องในการเชื่อมโยงร่วมกัน ...
Arnauld

3

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

ลองออนไลน์!


ฉันชอบการจัดรูปแบบในชุดทดสอบของคุณแสดงผลอินพุตที่น่าเชื่อถือกับเอาท์พุต ... Nice one;)
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ความสูงและอาเรย์ของจุดเริ่มต้นha


คุณทำให้วันของฉันเป็นแบบขยายได้ไม่ใช่เพียงแค่จุดเริ่มต้น 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

K (ngn / k) , 58 ไบต์

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

ลองออนไลน์!

ฟังก์ชั่นไม่ระบุชื่อที่ยอมรับสามข้อโต้แย้ง: xความกว้างความyยาวzคู่ของตำแหน่งเริ่มต้นสำหรับเลเซอร์



1

Kotlin , 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}()}

ลองออนไลน์!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.