Định dạng thứ tự của Alice


9

Giới thiệu

Alice là ngôn ngữ 2 chiều của Martin Ender , có hai chế độ thực thi khác nhau, hồng ythứ tự . Khi con trỏ lệnh đi qua một gương (hoặc /hoặc \), nó sẽ chuyển từ chế độ này sang chế độ khác.

Trong thử thách này, chúng tôi sẽ tập trung vào chế độ thứ tự , trong đó các lệnh hoạt động trên các chuỗi và con trỏ lệnh di chuyển theo đường chéo, nảy lên các cạnh của mã.

Các chương trình đơn giản chỉ hoạt động ở chế độ thứ tự có thể được viết theo kiểu khá nhỏ gọn, như trong ví dụ sau:

/fbd/
@aec\

Ở đây chỉ IP bắt đầu trong chế độ hồng y từ ô đầu tiên đi hướng đông, đi qua gương đầu tiên và bắt đầu di chuyển theo đường chéo và nảy, thực hiện lệnh a, bc. Sau đó nó gặp gương phía đông bắc mà làm cho nó đi về phía nam đến gương khác và sau đó bắt đầu tăng trở lại về phía tây, gặp lệnh d, e, f, và cuối cùng @, mà chấm dứt chương trình.

Kiểu cấu trúc này khá nhỏ gọn, nhưng không dễ để viết và bảo trì (thêm một lệnh có thể buộc chúng ta phải sắp xếp lại hầu hết mã!), Vì vậy tôi muốn bạn giúp tôi định dạng.

Nhiệm vụ

Đưa ra một chuỗi các lệnh, trong đó mỗi lệnh là một ký tự ASCII có thể in được, sắp xếp lại chúng trên hai dòng để nửa đầu của chuỗi có thể được đọc bắt đầu từ ký tự đầu tiên của dòng thứ hai và sau đó di chuyển luôn theo đường chéo về bên phải, trong khi nửa sau có thể được đọc lấy các ký tự còn lại từ phải sang trái. Đừng lo lắng về gương và biểu tượng chấm dứt, tôi sẽ tự thêm chúng vào.

Vì vậy, ví dụ, đầu vào đã cho, abcdefbạn nên xuất

fbd
aec

Trong trường hợp đầu vào có độ dài lẻ, bạn nên thêm một khoảng trắng (là noop trong Alice) ở bất cứ đâu, miễn là chuỗi lệnh gặp phải vẫn giữ nguyên. Bạn cũng có thể chọn xuất hai dòng có độ dài khác nhau theo một ký tự, trong trường hợp đó, dòng ngắn hơn được coi là có một khoảng trắng ở cuối.

Quy tắc

Đây là , câu trả lời ngắn nhất, tính bằng byte, thắng!

  • Bạn có thể nhập / xuất thông qua bất kỳ phương thức nhập / xuất mặc định nào
  • Đầu vào bao gồm một dòng ký tự ASCII có thể in
  • Một dòng mới duy nhất được phép trong đầu ra
  • Một số đầu ra của chương trình của bạn có thể không có hành vi hoàn toàn chính xác khi chạy dưới dạng chương trình Alice (ví dụ: nếu không gian đệm được chèn bên trong một chuỗi ký tự). Bạn không phải lo lắng về những tình huống này
  • Sơ hở tiêu chuẩn bị cấm

Các trường hợp thử nghiệm

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

Câu trả lời:


1

Thạch , 15 byte

œs2U2¦ṚZUJḤ$¦ZY

Hãy thử trực tuyến!

Đưa đầu vào trích dẫn.

Giải trình:

œ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

Alice , 28 byte

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

Hãy thử trực tuyến!

Nếu độ dài đầu vào là số lẻ, điều này sẽ đặt không gian đệm ở cuối chương trình tuyến tính hóa, kết thúc là ký tự đầu tiên của đầu ra.

Leo đã viết một định dạng thông thường trong Alice vài ngày trước. Sau khi thêm hỗ trợ cho các đầu vào có độ dài lẻ và sau đó loại bỏ một số nội dung không cần thiết cho thử thách này, chúng tôi đã kết thúc ở mức 28 byte . Tôi muốn thử một cách tiếp cận hơi khác, đó là câu trả lời này. Thật không may, nó chỉ kết thúc việc buộc 28 byte, nhưng ít nhất bằng cách này tôi có thể đăng giải pháp của riêng mình và để Leo đăng thuật toán gốc của mình.

Điều này sử dụng ý tưởng thực sự thông minh của Leo để chia một nửa chuỗi ..Y;m;.!z?~.

Giải trình

Giả sử rằng đầu vào có độ dài bằng nhau (vì chúng ta sẽ chỉ thêm nó vào một khoảng trắng nếu không có). Mẫu dễ hơn một chút để xem nếu chúng ta sử dụng 0123456789làm mã. Đầu ra cần thiết sẽ là:

91735
08264

Vì vậy, dòng đầu tiên chứa tất cả các vị trí lẻ của đầu vào và dòng thứ hai tất cả các đầu vào chẵn. Hơn nữa, nếu chúng ta đảo ngược các vị trí lẻ, thì các dòng chính là cả nửa đầu (có thể dài hơn) xen kẽ với đảo ngược của nửa thứ hai.

Vì vậy, ý tưởng cơ bản là:

  • Phân tách đầu vào thành các vị trí lẻ và chẵn.
  • Pad các vị trí lẻ với một không gian nếu cần thiết.
  • Đảo ngược các vị trí lẻ.
  • Sau đó hai lần: giảm một nửa chuỗi hiện tại, đảo ngược nửa thứ hai, xen kẽ cả hai nửa, in với dòng cấp dữ liệu.

Đối với mã, nó trông rất giống kiểu bố trí mà chúng ta tạo ra trong thử thách này, nhưng nó khác biệt một cách tinh tế: khi IP chạm /vào cuối mã, nó được phản xạ về phía đông , không phải phía nam. Sau đó, trong khi ở chế độ Cardinal, IP sẽ quấn quanh cột đầu tiên. Ở \đó nhập lại chế độ Thông thường, để nửa sau của mã không đi từ phải sang trái ở đây, mà từ trái sang phải cũng vậy. Điều này có lợi khi làm việc với ngăn xếp địa chỉ trả về, vì nó không lưu trữ thông tin về hướng của IP. Điều này cho phép chúng tôi lưu một vài byte vì IP sẽ di chuyển theo cùng một hướng (ngang) trên cả hai wk.

Mã tuyến tính là đây:

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

Chúng ta hãy đi qua nó:

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
Tôi sẽ phải đăng một thử thách khác cho bố cục mới này mà bạn đã nghĩ ra! : D Rất hay, tôi nghĩ rằng tôi sẽ bắt đầu sử dụng nó ngay cả khi tôi không sử dụng ngăn xếp trả về, việc đọc cả hai nửa mã từ trái sang phải dễ dàng hơn
Leo

4

Thạch , 23 22 byte

-1 byte nhờ Leo (phía dưới bên trái có thể là phần đệm)

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

Một chương trình đầy đủ in kết quả (liên kết đơn âm trả về danh sách danh sách các danh sách các ký tự).

Hãy thử trực tuyến! hoặc xem một bộ thử nghiệm .

Làm sao?

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 byte

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>

Hoạt động bằng cách mô phỏng đường dẫn thực thi và điền vào các lệnh khi nó đi.


Có vẻ là một ý tưởng hay, nhưng tôi không biết đủ về javascript để hiểu thuật toán bạn đã sử dụng ... Bạn có thể thêm một số lời giải thích?
Leo

@Leo Tôi không chắc mình có thể giải thích thêm bao nhiêu nữa. Như bạn đã biết, các lệnh theo một đường zig-zag từ trái sang phải và ngược lại một lần nữa. Những người 1&~iđạt được zig-zag dọc, trong khi i+i>l?l-i:iđạt được gương nửa chừng. Khi tất cả các lệnh đã được nhập vào các vị trí thực hiện mong muốn, mảng sẽ được thu thập lại với nhau để tạo ra kết quả mong muốn.
Neil
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.