> <> ออกจากน้ำ


20

ปลาที่รักที่แหวกว่ายในรหัส> <> (ภาษาโปรแกรมลึกลับ)ได้ถูกนำออกมาจากสภาพแวดล้อมตามธรรมชาติ การเปลี่ยนแปลงนี้ทำให้ไม่สามารถเคลื่อนที่ไปมาได้ในแบบที่มันเคยเป็น: สิ่งที่เคยเป็นการเคลื่อนไหวแบบ toroidal นั้นถูก จำกัด การเคลื่อนไหวแบบซ้ายไปขวาอย่างง่าย แต่>> โปรแกรมยังคงเขียนราวกับว่าปลาสามารถเคลื่อนที่ผ่านมันได้ มันเป็นหน้าที่ของคุณโปรแกรมเมอร์ที่รักการเขียนโปรแกรมให้เป็น Linearize โปรแกรม> <> และทำได้เพียงไม่กี่ไบต์เท่าที่จะทำได้ ปลาไม่มีความทรงจำที่ใหญ่มาก

การเคลื่อนไหวใน> <>

ใน> <> การเคลื่อนไหวนั้นจะเป็นวงแหวนและหนึ่งตัวอักษรในแต่ละครั้ง ซึ่งหมายความว่าปลา (ตัวชี้) สามารถ "พันรอบ" จากจุดสิ้นสุดของบรรทัดกลับไปที่จุดเริ่มต้น ใน> <> ปลายังสามารถเคลื่อนที่จากบนลงล่างล่างขึ้นบนและจากขวาไปซ้ายได้ตรงกันข้ามกับวิธีที่พอยน์เตอร์เคลื่อนที่ส่วนใหญ่ ดังนั้นรูปแบบการเคลื่อนไหวนี้จะถูกต้อง:

>>>^  >>>v
   >>>^  v

และมันจะสิ้นสุดในลูปที่ไม่มีที่สิ้นสุด

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

คุณจะรู้ได้อย่างไรว่าปลาเคลื่อนไหวอย่างไร คำสั่งเหล่านี้เปลี่ยนเวกเตอร์ทิศทางการเคลื่อนที่ (เช่น(-1,0)หมายถึงจากขวาไปซ้าย):

Command | Direction Change
---------------------------
   >    | (1,0) (default)
   <    | (-1,0)
   ^    | (0,1)
   v    | (0,-1)
   /    | (x,y) -> (y,x)
   \    | (x,y) -> (-y,-x)
   |    | (x,y) -> (-x,y)
   _    | (x,y) -> (x,-y)
   #    | (x,y) -> (-x,-y)
   ;    | (0,0)

(1,0)เท่าที่สังเกตปลาเริ่มเคลื่อนไหวจากซ้ายไปขวาคือมีทิศทางเวกเตอร์ ปลาเริ่มแยกคำสั่งที่เริ่มต้นด้วยคำสั่งแรกที่เห็นและเปลี่ยนทิศทางของมันหากคำสั่งตรงกับหนึ่งในตัวเปลี่ยนทิศทางดังกล่าวข้างต้น

ปลาหยุดเคลื่อนไหวเมื่อเห็น;และยุติโปรแกรม

อินพุต

อินพุตจะเป็นโปรแกรมที่ถูกต้อง (เช่นไม่วนซ้ำไม่ จำกัด ) ที่กำหนดผ่าน STDIN คุณสามารถอ่านไฟล์ได้หากต้องการ บรรทัดของแต่ละโปรแกรมไม่จำเป็นต้องมีความยาวเท่ากัน

อินพุตถูกกำหนดเป็นสตริงโดยมีบรรทัดใหม่คั่นแต่ละบรรทัดในโปรแกรม

;โปรแกรมจะไม่ห่วงซึ่งหมายความว่าพวกเขามักจะบอกเลิกกับ

เอาท์พุต

เอาต์พุตจะเป็นโปรแกรมเชิงเส้น นั่นคือคุณควรคืนอักขระทั้งหมด (รวมถึงตัวเปลี่ยนทิศทาง) ที่ปลาจะดูว่ามันรันโปรแกรม "ปกติ" หรือไม่ ;นี่คือทั้งหมดของตัวละครในเส้นทางของมันไป

หากอินพุตมีเส้นที่มีความยาวไม่เท่ากันและปลาเคลื่อนที่ไปตามเส้นที่สั้นกว่าความยาวของเส้นที่ยาวที่สุดคุณควรปฏิบัติต่อราวกับว่าปลากำลังเคลื่อนที่ข้ามอวกาศ (ดูกรณีทดสอบ)

ผู้ที่คุ้นเคยกับ> <> จะรู้ว่าตัวเปลี่ยนทิศทางไม่ใช่วิธีเดียวที่จะทำการเคลื่อนไหว แต่สำหรับความเรียบง่ายนั้นจะถือว่าอินพุตเป็นเสมือนว่าเป็นวิธีเดียวที่จะส่งผลกระทบต่อการเคลื่อนไหว

กฎระเบียบ

  1. ช่องโหว่มาตรฐานใช้
  2. คุณสามารถเขียนโปรแกรมหรือฟังก์ชั่นเต็มรูปแบบได้
  3. อินพุตถูกส่งผ่าน STDIN หรือไฟล์เป็นสตริงที่มีบรรทัดโปรแกรมคั่นด้วยบรรทัดใหม่ ( \n)
    • คุณอาจรับอินพุตที่แตกต่างกันด้วยเหตุผล (อย่าลังเลที่จะถามฉันว่าคุณมีประเภทของข้อมูลเฉพาะในใจ) คุณไม่สามารถใส่อินพุตด้วยช่องว่างเพื่อให้ความยาวบรรทัดตรงกัน
    • อ้างถึงโพสต์เมตานี้เกี่ยวกับการป้อนข้อมูลที่มีความยืดหยุ่น ตามที่โพสต์หมายถึงฉันทามติทั่วไปจะมีความยืดหยุ่นมากที่สุดเท่าที่จะทำได้ภายในเหตุผล
  4. เอาต์พุตเป็นสตริงเดี่ยวผ่าน STDOUT หรือส่งคืนโดยฟังก์ชัน (ขึ้นอยู่กับสิ่งที่คุณเลือกที่จะทำดูกฎ 2)

กรณีทดสอบ

v     >v
>abcv//;
gfed<^ih

v>abcv<defghi^//>v;



v     >v
>abcv//;
gfed<^

v>abcv<defg  ^//>v;


abcdef;

abcdef;


abcd|;

abcd|dcba;


abcd#;

abcd#dcba;


abcd\;
    _

abcd\_\dcba;


^;
>abcde/
 ^jihg<

^ >abcde/ <ghij^a;


;

;

2
เราสามารถรับอินพุตเป็นอาร์เรย์ของสตริงได้หรือไม่?
ลุค

2
เราคิดได้ไหมว่าตัวอักษรตัวแรก (ตัวซ้ายสุด) จะไม่ใช่เซมิโคลอน?
Kritixi Lithos

1
@KritixiLithos คำถามที่ดีฉันจะบอกว่าคุณไม่สามารถสรุปได้ ฉันจะเพิ่มกรณีทดสอบ
โคล

1
@ ลุคคุณสามารถรับอินพุตเป็นอาร์เรย์ของสตริงได้หากมันยากหรือเป็นไปไม่ได้ที่จะทำงานกับรูปแบบอินพุต (สตริงที่มีบรรทัดคั่นด้วยบรรทัดใหม่) ดูกฎข้อที่ 3 ที่เพิ่มเข้ามาในตอนนี้
โคล

3
ภาระหน้าที่ที่เพิ่มขึ้นอย่างมากสำหรับเหตุผลที่ไร้เหตุผล
Patrick Roberts

คำตอบ:


13

Röda , 405 393 392 391 371 366 361 236 234 232 230 223 200 ไบต์

F f{L=f()|[#_]|sort|tail
c=""x=0
y=0
X=1
Y=0{l=f[y]l.=[" "]*(L-#l)c=l[x]a=X
[c]
C=indexOf(c,`><v^/\|_#`)X=[1,-1,0,0,-Y,Y,-X,X,-X,X][C]Y=[0,0,1,-1,-a,a,Y,-Y,-Y,Y][C]x+=X
x=x%L
y+=Y
y=y%#f}until[c=";"]}

ลองออนไลน์!

ตรวจสอบผลลัพธ์!

คำอธิบาย (ล้าสมัย)

F f{                          /* Declares a function F with parameter f */
                              /* Takes a 2D array of single-char Strings as f */
L =                           /* L contains the value of the length of the longest line*/
    f()                       /* Push the contents each element of f to the stream; this pushes each line*/
        | [#_]                /* Pull a line and push its length to the stream*/
               |sort|tail     /* Sort it and get the last value (the largest one) */
c=""                          /* c contains the value of the current char that is being processed */
x=0; y=0                      /* x and y contain the position of the fish */
X=1; Y=0                      /* X and Y contain the direction of the fish */
{ ... }while [c != ";"]       /* While c is not `;` do: */
l=f[y]                        /*  l is the line (row) the fish is at */
c=" " if [x >= #l]            /*  If x is more than or equal to the line's length, set c to a space (so that we don't need to pad spaces to the array at the beginning)*/
else c = l[x]                 /*  Else set c to the character a position x of l*/
[c]                           /*  Push c to the output stream; ie prints c without a trailing newline*/
a = X                         /*  a preserves the value of X before analysing c */
C = indexOf(c,`><v^/\|_#`)    /*  Simple enough */
X=[1,-1,0,0,-Y,Y,-X,X,-X,X][C]/*  Map each value of C to their respective X-direction in the array */
                              /*  If c cannot be found in `><v^/\|_#` then it will be given the value of -1, or in other words, the -1th element of an array its last element */
Y=[0,0,1,-1,-a,a,Y,-Y,-Y,Y][C]/*  Do the same thing for Y */
x += X                        /*  Change the x-pos by the X-direction */
x = x%L                       /*  Wrap around the right edge */
y += Y                        /*  Do the same for y */
y=y%#f                        /*  But wrap around the bottom instead */
x+=L if[x<0]                  /*  Wrap around the left */
y+=#f if[y<0]                 /*  Wrap around the top */
}

การแก้ไข

  • บันทึก 10 ไบต์ด้วย @fergusq โดยใช้%แทนการตรวจสอบว่า x หรือ y อยู่เหนือขอบเขตหรือไม่ซึ่งปูทางไปอีก 2!
  • ใช้`\`แทน"\\"
  • ย้ายc=""ไปที่บรรทัดที่สองจากนั้นลบ newline ที่ตามมา
  • ย้ายการแปลงบรรทัดไปเป็นอาเรย์แบบอักขระเดียวเข้าไปในลูปแทนที่จะเป็นตอนต้น (ได้รับแรงบันดาลใจจากคำตอบของ Python)
  • ใช้ไวยากรณ์ของวงเล็บปีกกาwhile(ขอบคุณ @fergusq สำหรับการตรวจจับ)
  • ย้ายa=Xออกจากคำสั่ง if
  • ขอบคุณ @fergusq สำหรับการค้นหาวิธีที่สั้นกว่าเพื่อค้นหาความยาวของบรรทัดที่ยาวที่สุด
  • ใช้ไวยากรณ์อาร์เรย์แทนคำสั่ง if (เช่นคำตอบของ Python) เพื่อบันทึกจำนวนไบต์
  • ลบรหัสที่มีช่องว่างเบาะแทนที่จะเพิ่มช่องว่างในขณะที่> <> ย้ายตาม
  • แก้ไขข้อผิดพลาดและขอบคุณตัวละครหนึ่งตัวที่ต้องขอบคุณ @fergusq
  • ลบรหัส+1ท้ายindexOfและปรับโครงสร้างใหม่เพื่อบันทึก 2 ไบต์
  • บันทึก 2 ไบต์ด้วยการย้ายสิ่งต่าง ๆ รอบ ๆ (ขอบคุณ @fergusq อีกครั้ง)
  • บันทึก 1 ไบต์ขอบคุณ @fergusq โดยใช้วิธีการเว้นวรรคแบบอื่น
  • บันทึก 1 ไบต์โดยใช้until[c=";"]แทนwhile[c!=";"]
  • ขอบคุณคำแนะนำจาก @fergusq ฉันได้ลบลูปที่วางช่องว่างและแทนที่ด้วย l.=[" "]*L
  • บันทึกมากกว่า 20 ไบต์โดยการลบคำสั่ง if-end ที่ล้อมโปรแกรมรอบขอบด้านซ้ายและด้านบน

ฉันคิดว่าคุณสามารถบันทึกไม่กี่ไบต์โดยใช้แทนx=((x+X)%#l) x+=Xแต่น่าเสียดายที่ยังคงส่งกลับ(-1)%#l -1
fergusq

@fergusq Golfed ข้อเสนอแนะของคุณ :)
Kritixi Lithos

คุณสามารถใช้มันมีมากเกินไป:y y=y%#f
fergusq

@fergusq เป็นเพียงเกี่ยวกับการเพิ่มที่ :)
Kritixi Lithos

ผมคิดเกี่ยวกับเรื่องนี้มากขึ้นนี่สองเคล็ดลับการเล่นกอล์ฟอื่น ๆ ใช้งาน: ใช้keyแทนcmpและใช้แทน{...}while[...] while[...]do ... done
fergusq

10

Python 2, 262 243 237 235 234 233 231 221 219 218 217 ไบต์

ใช้อินพุตเป็น ['<line_1>', '<line_2>', ...]

i=input()
q=max(map(len,i))
i=[k+' '*q for k in i]
x=y=k=0
j=1
o=''
while';'not in o:r=[1,-1,-j,-k,0,0];o+=i[y][x];l='><#\\v^/|_'.find(o[-1]);a=(r+[k,-j,j])[l];k=([k,-k,k,j]+r)[~l];j=a;x=(x+j)%q;y=(y-k)%len(i)
print o

ลองออนไลน์!

-19 ไบต์ขอบคุณ @math_junkie
-6 ไบต์ขอบคุณ @ThisGuy
-2 ไบต์โดยการแยกmax(map(L,i))ตัวแปร (เพราะใช้ในเชิงทฤษฎีสองครั้ง)
-1 ไบต์โดยการลดจำนวนครั้งที่i[y][x]แสดง
-1 ไบต์โดยใช้'\x00'ดังนั้นฉันไม่ต้องทำ[1:]ส่วนของo[1:]เอาต์พุต
-2 ไบต์โดยใช้\0แทน\x00
-10 ไบต์ขอบคุณ @KritixiLithos สำหรับการตระหนักว่าฉันสามารถวางได้มากเท่าที่ต้องการเพราะด้านขวา ส่วนเกินจะถูกละเว้น
(ไม่มีการเปลี่ยนแปลงไบต์) แก้ไขข้อผิดพลาดเนื่องจากตัวแปรที่แยกออกมาอยู่ด้านนอกของลูป
-2 ไบต์เพราะตอนนี้ฉันใช้เพียงlen2 ครั้งดังนั้นการกำหนดใหม่จะใช้เวลา 2 ไบต์เพิ่มเติม
-2 ไบต์โดยใช้while';'not in oแทนwhile o[-1]!=';'และใช้แทนo='' o='\0'สิ่งนี้ไม่เพียง แต่ช่วยประหยัด 2 ไบต์ แต่ยังกำจัด null null ชั้นนำซึ่งในทางเทคนิคไม่ถูกต้องจริงๆ

คำอธิบาย

i = input()                       # Takes input as an array of strings
q = max(map(len,i))               # Finds the width of the longest line
i = [k + ' ' * q for k in i]      # Makes sure everything is at least that width
x = y = k = 0                     # Set the point to (0, 0). Set the vertical motion to 0
j = 1                             # Set the horizontal motion to 1
o = '\0'                          # Initialize the output to a null byte (this is output as nothing, so it doesn't actually affect output)
while o[-1] != ';':               # While the last character in the output is not ';' (this is why the output needs to be initialized with something, otherwise o[-1] gives an index error)
    r = [1,-1,-j,-k,0,0]          # Some of the vertical and horizontal coordinates correspond in opposite order
    o += i[y][x]                  # Add the current character to the output
    l = '><#\\v^/|_'.find(o[-1])  # Find the index of the current character here (or -1 if it's just a regular character)
    a = (r + [k, -j, j])[l]       # The fancy array contains the horizontal movement for each control character
    k = ([k, -k, k, j] + r)[~l]   # The fancy array contains the vertical movement for each control character. Using ~l to get the right index, because r has the values backwards
    j = a                         # a was a placeholder because otherwise k would not be correct
    x = (x + j) % q               # Adjust the pointer position
    y = (y - k) % len(i)          # Adjust the pointer position
print o                           # Print the output after the loop is finished

คุณสามารถตีกลับtryนับตั้งแต่ถ้าไม่พบ: TIOfind-1
คณิตศาสตร์ junkie

@math_junkie โอเคขอบคุณ!
HyperNeutrino

คุณสามารถกำหนดlenให้เป็นเช่นตัวแปรLที่จะบันทึก 3 ไบต์และอีก 4 โดยการเปลี่ยนการกำหนดหลายที่จะเข้าสู่สาย0 1 x=y=k=0
caird coinheringaahing

@ ThisGuy ขอบคุณ!
HyperNeutrino

2
@ เสาในสนามกอล์ฟที่มีความสุขของฉันฉันเพิ่ม j และ k ที่ส่วนท้ายของแต่ละแถว นี่คือทิศทางที่จะรักษา
คณิตศาสตร์ junkie

5

ทับทิม, 274 200 187 183

สลัดตัวละครออกไปเพียงไม่กี่ตัวโดยการปล่อยอาร์เรย์โมเมนตัม, d.

ฉันค่อนข้างภูมิใจกับสิ่งนี้ สนุกมาก! มันใช้เวลาในอาร์เรย์ของสตริงและส่งกลับสตริงที่เหมาะสม

->a{o,x,y='',-1,0
b,m=1,0
(o+=n=a[y=(y+m)%a.size][x=(x+b)%(a.map &:size).max]||' '
b,m=([1]+[0,-1,0]*2+[1,-m]+[-b,m,b]*2+[-m,-b,-m,b,m])[2*('><^v/\\|_#'.index(n)||9),2])until o[?;]
o}

แสดงความคิดเห็นด้านล่าง

->a{
    o,x,y='',-1,0  # o is the output string, x and y are the positions in the array
    b,m=1,0          # b and m are the direction of momentum
    until o[?;] # until o contains a semicolon
        w=(a.map &:size).max # w is the max width of the arrays
        h=a.size    # h is the height of arrays
        x=x+b % w   # increment cursor position
        y=y+m % h
        o+=n=a[y][x]||' ' # add the new char (or " ") to o
        ix=2*('><^v/\\|_#'.index(n)||9) # find the index new char in the string
        b,m=([1]+[0,-1,0]*2+[1,-m]+[-b,m,b]*2+[-m,-b,-m,b,m])[ix,2] # set momentum to its new value
    end
    o # return output string
}

1

PHP 7, 291 260 ไบต์

for($m=max(array_map(strlen,$z=explode("
",$argv[1]))),$y=0,$r=count($z)-$v=1;';'!=$c;[$v,$w]=[[$v,1,-1,0,0,-$w,$w,-$v,$v,-$v][$o=strpos(' ><^v/\|_#',$c)],[$w,0,0,-1,1,-$v,$v,$w,-$w,-$w][$o]],$x+=$m+$v,$x%=$m,$y=0<=($y+=$w)?$r<$y?:$y:$r)echo$c=$z[$y][$x]??' ';

ฉันนับ 291 ไบต์ / ตัวอักษร
HyperNeutrino

คุณถูกต้องฉันไม่สามารถนับได้อย่างชัดเจน = P
chocochaos

ไม่ต้องห่วงฉันก็ทำอย่างนั้นเหมือนกัน
HyperNeutrino

ฉันพบบางสิ่งที่จะตีกอล์ฟลดลง 25% เหลือ 218 ไบต์ ไม่ได้ทดสอบ แต่แน่นอนดูคุ้มค่า
ติตัส

2
ข้อบกพร่องในหนึ่งใน golfings ของฉันและอีกหกไบต์แข็งแรงเล่นกอล์ฟ: การปรับปรุงรายการการเล่นกอล์ฟ
ติตัส

1

JavaScript, 242 236 235 231 220 ไบต์

a=>{n=a.length;m=x=y=p=0;a.map(g=>m=(w=g.length)<m?m:w);q=1,o="";while((t=a[y][x]||" ")!=";")o+=t,h=q,q=[q,1,0,p,-q][(s=">v\\| <^/_#".indexOf(t)+1)%5]*(r=s>5?-1:1),p=[p,0,1,h,p][s%5]*r,x=(x+q+m)%m,y=(y+p+n)%n;return o+t}

ลองออนไลน์!


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