两个镜子之间的两个激光器


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
Arnauld

2
@Arnauld | X | ;)
AJFaraday

Answers:


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
Engineer Toast'Bug

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你是对的,我以为串入字符串会失败,但实际上两次都无法逃脱。
xnor18年

哎呀,我的解决方案非常痛苦地接近了这个想法-回想一下,以2w为模进行工作很有意义。非常聪明!
Lynn '18


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=宽度,
y=长度,
r=最初的右行起始位置
l=最初的左行起始位置

-4字节。归功于Kevin Cruijssen。谢谢


1
您可以通过将更while改为for来删除3 {}和1的分号来打高尔夫球3个字节。并通过更改c&&d为1个字节c&d在线尝试236字节
凯文·克鲁伊森

看来您正在接受两个额外的输入,这是afaik所不允许的。
OOBalance

1
您不应该解决挑战的一般性,而是解决指定的挑战。关于额外的输入,我对meta进行了一些挖掘,发现了这一点:codegolf.meta.stackexchange.com/a/12696/79343我认为它也必须写在其他地方,但我找不到atm。但是这是常态。
OOBalance

1
在您的g宏中,您可以通过将a ==-1更改为a <0来高尔夫2个字节。
JohnWells

1
实际上在宏中有更多内容,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 18-4-12

1
@MartijnVissers好吧,如果您的宽度是2,那么您的位置只能是0或1 ...
Neil


3

PHP,177169166字节

[,$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))

在线尝试!


我喜欢您的测试套件中的格式,可以可靠地显示输入与输出...好一个;)
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和起点数组的匿名lambda 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)|"}

在线尝试!

哎呀 这些逻辑块又大又脏,并且大多是重复的。下一步将是重写它们,以便它们不需要else语句。


1

Python 2中,165个 164字节

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

感谢乔纳森·弗雷希(Jonathan Frech),节省了一个字节。
在线尝试!


1
\\/等价于\/
Jonathan Frech '18

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

科特林322个 311 302字节

更改了如何将激光方向放在字符串中11个字节。将分配从when中移出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}()}

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.