การจัดรูปแบบตามลำดับของ Alice


9

บทนำ

อลิซเป็น 2-D ภาษาโดยมาร์ตินเอนเดอร์ซึ่งมีสองโหมดการดำเนินการที่แตกต่างกัน, พระคาร์ดินัลและลำดับ เมื่อตัวชี้คำแนะนำส่งผ่านมิรเรอร์ (อย่างใดอย่างหนึ่ง/หรือ\) มันจะสลับจากโหมดหนึ่งไปอีกโหมดหนึ่ง

ในการท้าทายนี้เราจะมุ่งเน้นไปที่โหมดเลขลำดับซึ่งคำสั่งทำงานกับสตริงและตัวชี้คำสั่งเคลื่อนที่ในแนวทแยงมุมกระดอนกับขอบของรหัส

โปรแกรมอย่างง่ายที่ใช้งานได้เฉพาะในโหมดเลขลำดับสามารถเขียนในสไตล์ที่ค่อนข้างกะทัดรัดได้ดังตัวอย่างต่อไปนี้:

/fbd/
@aec\

ที่นี่ IP เริ่มต้นในโหมดที่สำคัญจากเซลล์แรกไปทางทิศตะวันออกผ่านมิรเรอร์แรกและเริ่มเคลื่อนที่ในแนวทแยงมุมและกระดอนโดยเรียกใช้คำสั่ง a , และb cจากนั้นก็พบกระจกภาคตะวันออกเฉียงเหนือซึ่งจะทำให้มันไปทางทิศใต้กระจกอื่น ๆ และจากนั้นเริ่มใหญ่กลับไปทางทิศตะวันตกคำสั่งเผชิญหน้าd, e, fและในที่สุด@ซึ่งสิ้นสุดโปรแกรม

โครงสร้างแบบนี้ค่อนข้างเล็ก แต่ไม่ง่ายในการเขียนและบำรุงรักษา (การเพิ่มคำสั่งเดียวอาจบังคับให้เราเรียงลำดับโค้ดส่วนใหญ่!) ดังนั้นฉันต้องการให้คุณช่วยฉันจัดรูปแบบ

งาน

กำหนดลำดับของคำสั่งโดยที่แต่ละคำสั่งเป็นอักขระ ASCII เดียวที่พิมพ์ได้ให้เรียงลำดับใหม่ในสองบรรทัดเพื่อให้ครึ่งแรกของลำดับสามารถอ่านได้โดยเริ่มจากอักขระตัวแรกของบรรทัดที่สองจากนั้นเลื่อนแนวทแยงมุมไปทางขวาเสมอ ในขณะที่ครึ่งหลังสามารถอ่านตัวอักษรที่เหลือจากขวาไปซ้าย ไม่ต้องกังวลกับกระจกเงาและสัญลักษณ์บอกเลิกฉันจะเพิ่มมันเอง

ตัวอย่างเช่นอินพุตที่กำหนด abcdefคุณควรส่งออก

fbd
aec

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

กฎระเบียบ

นี่คือ คำตอบที่สั้นที่สุดเป็นไบต์ชนะ!

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

กรณีทดสอบ

--Input
abcdef
--Output
fbd
aec

--Input
123
--Output
 2
13
OR
31
 2
OR
3
12
OR
32
1

--Input
O
--Output
O

OR

O

--Input
"Hello, World!"o
--Output
oH!lloo 
""edlr,W

--Input
i.szR.szno
--Output
o.zz.
inssR

--Input
"  ^^} .~[}.~~[}{~~{}[^^^^.""!}"r.h~;a*y'~i.*So
--Output
o *^i}'.*[;.h~r}}~"{.[^
"S .^~ y~a}~~.["{!~"}^^^
(Odd length, your solution may be different)

คำตอบ:


1

เยลลี่ 15 ไบต์

œs2U2¦ṚZUJḤ$¦ZY

ลองออนไลน์!

รับอินพุตที่ยกมา

คำอธิบาย:

œs2U2¦ṚZUJḤ$¦ZY Main link, monadic
œs2             Split into 2 chunks of similar lengths, last might be shorter
   U2¦          Reverse the 2nd chunk
      Ṛ         Swap the chunks
       Z        Transpose into chunks of length 2
        UJḤ$¦   Reverse the chunks at even indices (1-indexed)
             Z  Transpose into 2 chunks again
              Y Join by a newline

12

อลิซ 28 ไบต์

/mY. zm~wZ.k;
\I;'!*?RR.OY@/

ลองออนไลน์!

หากความยาวของอินพุตเป็นเลขคี่สิ่งนี้จะทำให้ช่องว่างภายในช่องว่างท้ายโปรแกรมเชิงเส้นซึ่งกลายเป็นอักขระตัวแรกของเอาต์พุต

เลโอเขียนฟอร์แมตฟอร์แมตในอลิซเมื่อสองสามวันก่อน หลังจากเพิ่มการสนับสนุนปัจจัยการผลิตที่แปลกยาวแล้วเอาสิ่งบางอย่างที่ไม่จำเป็นสำหรับความท้าทายนี้เราสิ้นสุด ณ วันที่ 28 ไบต์ ฉันต้องการลองวิธีที่แตกต่างกันเล็กน้อยซึ่งเป็นคำตอบนี้ น่าเสียดายที่มันจบลงด้วยการผูก 28 ไบต์ แต่อย่างน้อยฉันก็สามารถโพสต์วิธีแก้ปัญหาของตัวเองแล้วปล่อยให้ Leo โพสต์อัลกอริทึมดั้งเดิมของเขา

..Y;m;.!z?~นี้ไม่ใช้ความคิดที่ฉลาดจริงๆของลีโอที่จะแยกสตริงในช่วงครึ่งปีกับ

คำอธิบาย

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

91735
08264

ดังนั้นบรรทัดแรกจึงมีตำแหน่งคี่ทั้งหมดของอินพุตและบรรทัดที่สองอินพุตทั้งหมด ยิ่งกว่านั้นถ้าเราสลับตำแหน่งคี่แล้วเส้นนั้นจะเป็นครึ่งแรก (อาจยาวกว่า) สลับกับครึ่งหลังของครึ่งหลัง

ดังนั้นแนวคิดพื้นฐานคือ:

  • แยกอินพุตออกเป็นตำแหน่งคี่และคู่
  • วางตำแหน่งแปลก ๆ ด้วยช่องว่างหากจำเป็น
  • สลับตำแหน่งคี่
  • จากนั้นสองครั้ง: แบ่งสตริงปัจจุบันครึ่งหนึ่งย้อนกลับครึ่งหลังแทรกทั้งสองส่วนให้พิมพ์ด้วยการป้อนบรรทัดต่อท้าย

สำหรับรหัสนี้ดูเหมือนกับรูปแบบที่เรากำลังสร้างในการท้าทายนี้ แต่มันก็แตกต่างกันอย่างละเอียด: เมื่อ IP ชน/กับรหัสท้ายสุดมันจะสะท้อนไปทางตะวันออกไม่ใช่ทางใต้ จากนั้นในขณะที่อยู่ในโหมด Cardinal IP จะล้อมรอบไปยังคอลัมน์แรก \มีอีกครั้งจะเข้าสู่โหมดลำดับเพื่อที่ว่าในช่วงครึ่งหลังของรหัสที่ไม่ได้ไปจากขวาไปซ้ายที่นี่ แต่จากซ้ายไปขวาเช่นกัน สิ่งนี้มีประโยชน์เมื่อทำงานกับที่อยู่ผู้ส่งคืนเนื่องจากจะไม่เก็บข้อมูลเกี่ยวกับทิศทางของ IP นี้จะช่วยให้เราประหยัดไม่กี่ไบต์เพราะ IP จะย้ายในตัวเดียวกัน (แนวนอน) ทิศทางทั้งในและwk

รหัส linearised คือ:

IY' *mRw..Y;m;.!z?~RZOk@

ไปดูกัน:

I       Read one line of input.
Y       Unzip. Separates the string into even and odd positions.
' *     Append a space to the odd half.
m       Truncate: discards characters from the longer of the two
        strings until they're the same length. So if the input
        length was even, appending a space will make the odd half
        longer and this discards the space again. Otherwise, the
        space just padded the odd half to the same length as the
        even half and this does nothing.
R       Reverse the odd half.
w       Push the current IP address to the return address stack.
        The purpose of this is to run the following section
        exactly twice.

          This first part splits the current line in half, based
          on an idea of Leo's:
  ..        Make two copies of the current half.
  Y         Unzip one of the copies. The actual strings are irrelevant
            but the important part is that the first string's length
            will be exactly half the original string's length (rounded up).
  ;         Discard the potentially shorter half.
  m         Truncate on the original string and its even half. This shortens
            the original string to the first half of its characters.
  ;         Discard the even half, because we only needed its length.
  .!        Store a copy of the first half on the tape.
  z         Drop. Use the first half to discard it from the original string.
            This gives us the the second (potentially shorter half).
  ?         Retrieve the first half from the tape.
  ~         Swap it so that the second half is on top.
          The string has now been split in half.
  R       Reverse the second half.
  Z       Zip. Interleave the two halves.
  O       Print the result with a trailing linefeed.

k       Pop an address from the return address stack and jump back there.
        The second time we reach this, the return address stack is empty,
        and this does nothing.
@       Terminate the program.

1
ฉันจะต้องโพสต์ความท้าทายใหม่สำหรับเลย์เอาต์ใหม่ที่คุณคิดขึ้น : D ดีมากฉันคิดว่าฉันจะเริ่มใช้มันแม้ว่าฉันจะไม่ได้ใช้ stack return มันง่ายต่อการอ่านโค้ดทั้งสองครึ่งจากซ้ายไปขวา
Leo

4

เยลลี่ , 23 22 ไบต์

-1 ไบต์ขอบคุณ Leo (ซ้ายล่างอาจเป็นช่องว่างภายใน)

LḂ⁶ẋ;µṚ,µm2œs2U0¦ż/µ€Y

โปรแกรมเต็มรูปแบบการพิมพ์ผลลัพธ์ (ลิงก์ monadic ส่งคืนรายการของรายการของอักขระ)

ลองออนไลน์! หรือดูชุดทดสอบ

อย่างไร?

LḂ⁶ẋ;µṚ,µm2œs2U0¦ż/µ€Y - Main link: list of characters
L                      - length
 Ḃ                     - modulo 2
  ⁶                    - literal space character
   ẋ                   - repeat
    ;@                 - concatenate (swap @rguments) (appends a space if the input's length is odd)
      µ                - monadic chain separation, call that s
       Ṛ               - reverse s
        ,              - pair with s
         µ         µ€  - for €ach:
          m2           -   modulo 2 slice (take every other character)
            œs2        -   split into two "equal" chunks (first half longer if odd)
               U0¦     -   upend index 0 (reverse the second chunk)
                   /   -   reduce by:
                  ż    -     zip
                     Y - join with newlines (well just the one in this case)
                       - implicit print (mushes the sublists together)

1

JavaScript (ES6), 104 ไบต์

f=
s=>s.replace(/./g,(c,i)=>a[1&~i][i+i>l?l-i:i]=c,a=[[` `],[]],l=s.length-1|1)&&a.map(a=>a.join``).join`
`
<input oninput=o.textContent=f(this.value)><pre id=o>

ทำงานโดยเลียนแบบพา ธ การประมวลผลและเติมคำสั่งในขณะที่ไป


ดูเหมือนว่าเป็นความคิดที่ดี แต่ฉันไม่รู้จัก javascript เพียงพอที่จะเข้าใจอัลกอริทึมที่คุณใช้ ... คุณสามารถเพิ่มคำอธิบายได้ไหม
Leo

@Leo ฉันไม่แน่ใจว่าสามารถอธิบายได้มากกว่านี้ อย่างที่คุณทราบคำสั่งจะตามด้วยเส้นซิกแซกจากซ้ายไปขวาและกลับซ้ายอีกครั้ง 1&~iประสบความสำเร็จในแนวซิกแซกในขณะที่i+i>l?l-i:iประสบความสำเร็จในกระจกลงครึ่งหนึ่ง เมื่อคำสั่งทั้งหมดถูกป้อนเข้าไปในตำแหน่งการดำเนินการที่ต้องการแล้วอาร์เรย์จะถูกรวบรวมเข้าด้วยกันเพื่อสร้างผลลัพธ์ที่ต้องการ
Neil
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.