Hủy bỏ chuỗi Pythlike


13

Pyth có lẽ là ngôn ngữ chơi gôn đa năng thành công nhất. Mặc dù nó có phần suy giảm do các ngôn ngữ mới hơn, từ cú pháp ngắn gọn từ 2014 đến 2016 của Pyth, cập nhật liên tục, quá tải và (trong thời đại của nó), nhiều nội dung đã khiến nó trở thành yêu thích của phần lớn các câu hỏi.

Mã Pyth thường khó đọc. Ngay cả đầu ra của chế độ gỡ lỗi (Python được phiên mã) thường bao gồm một dòng dài, đôi khi có dấu ngoặc đơn được lồng sâu mười. Tuy nhiên, Pyth được định dạng chính xác là rất dễ đọc.

Đây là một đoạn mã Pyth, được viết bởi @isaacg trong Play the Word Chain .

.MlZfqhMtTeMPT+Lzs.pMyQ

Nó dễ đọc hơn nhiều như thế này.

.M                     Filter by gives-maximal-value of
   l Z                   lambda Z:length(Z) over
   f                     filter by (lambda T:
     q                     equal
       hM t T                head-map tail T
       eM P T                end-map Pop T)
     +L                    Append z to each element in
        z                        
        s .pM y Q            flattened permutations of each subset of Q

Đối với thử thách này, chúng tôi loại bỏ khía cạnh kolmogorov trong việc phân loại các ký tự Pyth và tập trung vào định dạng. Thay vì là mã Pyth, đầu vào sẽ bao gồm các ký tự 0123456789M. Chữ số nđại diện cho một chức năng của arity nMđại diện cho một toán tử. Ví dụ, đoạn mã trên được biểu diễn dưới dạng 210221M101M102M011M10. Dưới đây là các bước để hủy bỏ:

Phân tách chuỗi thành mã thông báo.

Một mã thông báo phù hợp [0-9]M*. 0Msẽ không xảy ra trong đầu vào.

Thêm dấu 0s.

Khi không có đủ đối số, Pyth sẽ thêm nhiều biến ẩn (biến lambda hoặc Qs) vào mã khi cần thiết để điền vào các đối số của chương trình; chúng nên được đại diện bởi 0s.

Nhóm mã thông báo thành dòng.

Giá trị của mã thông báo là giá trị của chữ số của nó.

  • Mã thông báo arity-0 (tức là 0) kết thúc một dòng.

  • Đối với mã thông báo arity-1, mã thông báo tiếp theo sẽ nằm trên cùng một dòng, cách nhau bởi khoảng trắng.

  • Đối với mã thông báo arity> = 2, các đối số của nó đi trên các dòng riêng biệt, theo thứ tự chúng xuất hiện trong mã, mỗi mã được theo sau bởi các biểu tượng con của riêng chúng, v.v. Các đối số cho mã thông báo được thụt vào cuối mã thông báo đó cộng với một khoảng trắng.

Đầu vào

Một chuỗi không trống (hoặc mảng char, mảng chuỗi có độ dài-1, v.v. được cho phép bởi Phương thức I / O tiêu chuẩn) bao gồm 0123456789M, sẽ không chứa chuỗi con 0M.

Đầu ra

Chuỗi được định dạng theo các quy tắc trên.

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

210221M101M102M011M10

2
  1 0
  2
    2
      1M 1 0
      1M 1 0
    2M
       0
       1 1M 1 0


123M4M

1 2
    3M
       4M
          0
          0
          0
          0
       0
       0
    0


2MM

2MM
    0
    0


11011100

1 1 0
1 1 1 0
0


9000000

9
  0
  0
  0
  0
  0
  0
  0
  0
  0


Tôi có thể lấy đầu vào là một mảng các chữ số / chuỗi không? Ví dụ 210221M101M102M011M10sẽ là[2,1,0,2,2,1,'M',1,0,1,'M',1,0,2,'M',0,1,1,'M',1,0]
Luis felipe De jesus Munoz

@LuisfelipeDejesusMunoz Không, trừ khi các quy tắc I / O tiêu chuẩn yêu cầu bạn được phép (mà tôi không nghĩ là họ làm.) IMO sẽ thay đổi một chút thách thức nếu các Ms được phép là một kiểu dữ liệu khác với các số nguyên.
lirtosiast

@lirtosiast Vì vậy, một mảng các ký tự / chuỗi ký tự đơn là ổn, chỉ cần không sử dụng các kiểu dữ liệu khác nhau giữa các chữ số và M?
Kamil Drakari

1
@LeakyNun Chuỗi rỗng hiện không được xác định hành vi.
lirtosiast

Câu trả lời:


1

JavaScript (ES8), 160 159 byte

f=(s,a=[d=0,p=[1]])=>s.replace(/(.)M*/g,(s,c)=>(g=_=>a[d]?s+(P=p[d]-=c--&&~s.length,c?`
`.padEnd(P):' '):g(d--))(a[d]--,a[++d]=+c,p[d]=p[d-1]))+(d?f('0',a):'')

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

Đã bình luận

f = (                          // f = recursive function taking:
  s,                           //   s   = input string
  a = [                        //   a[] = array holding the number of expected arguments
    d = 0,                     //   d   = current depth, initialized to 0
    p = [1]                    //   p[] = array holding the padding values
  ]                            //
) =>                           //
  s.replace(                   // search in s all substrings
    RegExp('(.)M*', 'g'),      // consisting of a digit followed by 0 to N 'M' characters
    (s, c) =>                  // for each substring s beginning with the digit c:
      ( g = _ =>               //   g = recursive function
          a[d] ?               //     if we're still expecting at least one argument at
                               //     this depth:
            s + (              //       append s
              P = p[d] -=      //       update the padding value P = p[d] for this depth:
                c-- &&         //         decrement c; unless c was equal to 0,
                ~s.length,     //         add the length of s + 1 to p[d]
              c ?              //       if c is not equal to 0 (i.e. was not equal to 1):
                `\n`.padEnd(P) //         append a linefeed followed by P - 1 spaces
              :                //       else:
                ' '            //         append a single space
            )                  //
          :                    //     else (all arguments have been processed):
            g(d--)             //       decrement the depth and call g again
      )(                       //   before the initial call to g:
        a[d]--,                //     decrement the number of arguments at depth d
        a[++d] = +c,           //     set the number of arguments for the next depth
        p[d] = p[d - 1]        //     set the padding value for the next depth,
      )                        //     using a copy of the previous depth
  ) + (                        // end of replace()
    d ?                        // if we're not back at depth 0:
      f('0', a)                //   do a recursive call to f with an extra '0'
    :                          // else:
      ''                       //   stop recursion
  )                            //

1

Haskell , 192 190 187 byte

unlines.snd.f
f(n:r)|(m,t)<-span(>'9')r,(s,l)<-n#t=(s,n?((n:m):map((' '<$(n:n:m))++)l))
f e=(e,["0"])
'1'?(a:b:r)=(a++drop(length a)b):r
_?s=s
'0'#s=(s,[])
n#s|(r,l)<-f s=(l++)<$>pred n#r

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

Phải có một cách tốt hơn để xử lý trường hợp arity-1, hiện tại nó chiếm tới 45 byte.

Chỉnh sửa:

  • -2 byte bằng cách chuyển sang một phương thức xử lý 1 khác, mặc dù phương thức trước đó có thể có tiềm năng tối ưu hóa nhiều hơn.
  • -3 byte bằng cách không chuyển đổi các chữ số ký tự thành số và sử dụng predthay vì n-1.
unlines.snd.f
f(n:r)|(m,t)<-span(>'9')r,(s,l)<-read[n]#t,w<-map((' '<$(n:n:m))++)=(s,last$((n:m):w l):[(n:m++' ':h):w t|n<'2',h:t<-[l]])
f e=(e,["0"])
0#s=(s,[])
n#s|(r,l)<-f s=(l++)<$>(n-1)#r

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


1

Than , 75 byte

FS⊞υ⎇⁼ιM⁺⊟υιι≔⮌υυ≔⟦⟧θ≔⟦⟧ηW∨υη«≔⎇υ⊟υ0ιι¿⊖Σι↘→⊞θι⊞ηΣιW∧η¬§η±¹«⊟ηM⊕L⊟θ←¿η⊞η⊖⊟η

Hãy thử trực tuyến!Liên kết là phiên bản dài dòng của mã. Giải trình:

FS⊞υ⎇⁼ιM⁺⊟υιι

Lặp lại các ký tự đầu vào và biến chúng thành một danh sách các chữ số với tùy chọn M các hậu tố .

≔⮌υυ

Đảo ngược danh sách này để chúng ta có thể sử dụng Pop để tiêu thụ nó.

≔⟦⟧θ

Biến này là một chồng các mã thông báo mà mức độ chưa được hoàn thành.

≔⟦⟧η

Biến này là một chồng của arity còn lại của các mã thông báo chưa hoàn thành.

W∨υη«

Lặp lại cho đến khi chúng tôi đã tiêu thụ tất cả các mã thông báo và làm trống ngăn xếp.

     ≔⎇υ⊟υ0ι

Nhận mã thông báo tiếp theo hoặc 0 nếu không có.

     ι¿⊖Σι↘→

In mã thông báo và sau đó di chuyển con trỏ theo chiều ngang nếu bắt đầu bằng 1 đường chéo.

     ⊞θι⊞ηΣι

Thêm mã thông báo và độ thơm của nó vào các biến thích hợp.

     W∧η¬§η±¹«

Lặp lại trong khi ngăn xếp arity là không trống rỗng nhưng arity top là zero.

              ⊟η

Hủy bỏ không có arity.

              M⊕L⊟θ←

Xóa mã thông báo của nó và di chuyển mà nhiều ký tự còn lại.

              ¿η⊞η⊖⊟η

Nếu có bất kỳ hương liệu nào còn lại thì làm giảm độ cao hàng đầu.

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.