Ký hiệu tiền tố để ký hiệu tiền tố


19

Tuyên bố miễn trừ trách nhiệm: Không, đây không phải là một thử thách đùa để đảo ngược chuỗi.

Bài tập

Chỉ có một thao tác để hỗ trợ: phép trừ ( -).

Bạn cũng chỉ có hai nguyên tử để hỗ trợ: zero ( 0) và one ( 1).

Ở đây, ký hiệu tiền tố -ABtương đương với ký hiệu hậu tố AB-, ở đâu ABlà biểu thức.

Nhiệm vụ của bạn là (đệ quy) chuyển đổi một biểu thức trong ký hiệu tiền tố thành tương đương với ký hiệu hậu tố.

Định nghĩa

Một biểu thức trong ký hiệu tiền tố được tạo bởi ngữ pháp sau:

S > -SS
S > 0
S > 1

Một biểu thức trong ký hiệu postfix được tạo bởi ngữ pháp sau:

S > SS-
S > 0
S > 1

Thí dụ

Prefix notation:  --01-0-01
Parentheses:      -(-01)(-0(-01))
Convert:          (01-)(0(01-)-)-
Postfix notation: 01-001---

Quy tắc và tự do

  • Bạn có thể đổi tên hoạt động và các nguyên tử thành ký tự nào, miễn là phù hợp.
  • Định dạng đầu vào phải phù hợp với định dạng đầu ra (ngoài thực tế là đầu vào có ký hiệu tiền tố và đầu ra là ký hiệu hậu tố).

Testcase

Input       Output
1           1
0           0
-01         01-
-10         10-
--01-0-01   01-001---

Kiểm tra tín dụng cho Dada .


1
Bạn có thể thêm một vài trường hợp thử nghiệm không?
Xù xì

@Shaggy bạn muốn loại thử nghiệm nào?
Nữ tu rò rỉ

@LeakyNun Có tốt không khi lấy đầu vào và đầu ra làm các vòng lặp, như tôi đã làm trong phiên bản mới nhất của câu trả lời của mình?
L3viathan

@ L3viathan Tôi cho là vậy ...
Leaky Nun

Câu trả lời:


12

Brainfuck , 32 byte

,[[->++++<<+>]>[[-]<<[.[-]<]]>,]

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

Tôi đã sử dụng @như là hoạt động, bởi vì điểm mã của nó (64) là thuận tiện. Ucũng có thể có cùng số byte, sử dụng 3 * 85 + 1 = 256 = 0.

Giải trình

Các băng được sử dụng như một chồng. Trong mỗi lần lặp của vòng lặp chính, con trỏ dữ liệu bắt đầu hai ô bên phải của đỉnh ngăn xếp.

,[                Take input and start main loop
  [->++++<<+>]    Push input, and compute 4*input
  >[              If 4*input is nonzero (and thus input is not @):
    [-]<<           Zero out this cell and move to top of stack
    [.[-]<]         Pop from stack and output until \0 is reached
  ]
  >,              Move pointer into the correct position.  If input was @, the earlier > pushed \0 onto the stack.
]

6

Võng mạc , 37 30 29 byte

M!`-*.
+m`^-(.*)¶(\d.*)
$1$2-

Hãy thử trực tuyến! Đã lưu 7 byte bằng cách nhận ra rằng các thuật ngữ luôn bắt đầu bằng một chữ số, vì vậy tôi không phải giới hạn kết quả khớp cuối cùng -nữa (trước đây nó là thuật ngữ duy nhất được đảm bảo tuân theo hai thuật ngữ). Đã lưu 1 byte bằng cách không đặt -s trên dòng riêng của họ. Ví dụ, -01trở thành -0¶1cái mà sau đó được thay thế bằng 01-. Bây giờ, nếu tôi có --010nghĩa là --0¶1¶0sau đó tôi muốn thay đổi bên trong -0¶1để 01-tôi có thể thay thế -01-¶0bằng 01-0-, nhưng thực sự không có vấn đề gì trong hai cái -tôi loại bỏ, vì vậy tôi loại bỏ cái ở đầu dòng, như đó là dễ dàng hơn để kiểm tra.


Tôi nghĩ đây là thứ gì đó của bạn :)
Leo

@Leo Không hoạt động nói chung, ví dụ như -0-0-00sẽ trở thành 0000---.
Neil

Bạn nói đúng, xin lỗi. Tôi có một ý tưởng khác, nhưng về cơ bản thì khác, vì vậy tôi sẽ đăng nó dưới dạng câu trả lời mới
Leo

1
@Leo Bây giờ tôi đã tìm thấy thứ gì đó của mình ...
Neil

1
@Leo Với môn đánh gôn mới nhất của chúng tôi, chúng tôi bị trói!
Neil

6

Haskell , 62 59 byte

f(x:r)|x>'-'=([x],r)|(a,(b,c))<-f<$>f r=(a++b++"-",c)
fst.f

Hãy thử trực tuyến! Cách sử dụng : fst.f $ "--01-0-01". 01có thể là các ký tự tùy ý lớn hơn ký tự -.

Chỉnh sửa: -3 byte nhờ Zgarb!

Hàm fđệ quy phân tích một biểu thức và trả về một tuple của biểu thức này trong ký hiệu hậu tố và chuỗi còn lại, theo ngữ pháp đơn giản mà từ đó các biểu thức tiền tố hợp lệ có thể được xây dựng:

<exp> ::= - <exp> <exp> | 0 | 1

Nếu ký tự đầu tiên acủa chuỗi đầu vào lớn hơn -, chúng ta đang ở một biểu thức nguyên tử và trả về một chuỗi của chuỗi có ký tự avà phần còn lại của chuỗi đầu vào.

Nếu chúng ta tìm thấy một -, hai biểu thức cần được phân tích cú pháp. Điều này có thể đạt được bằng cách (a,x)<-f rlấy biểu thức đầu tiên avà sau đó phân tích lại chuỗi còn xlại (b,c)<-f xđể có được biểu thức thứ hai bvà chuỗi còn lại cuối cùng c. (a,(b,c))<-f<$>f rthực hiện chính xác điều này bởi vì <$>trên tuples ánh xạ một hàm hai phần tử thứ hai của một tuple trong khi ngắn hơn ba byte (a,x)<-f r,(b,c)<-f x. Sau khi có được cả biểu thức và chuỗi còn lại, các biểu thức được nối và một dấu "-" được nối thêm : (a++b++"-",c).


1
Bạn có thể lưu 3 byte bằng cách kết hợp các trường hợp:f(x:r)|x>'-'=([x],r)|(a,(b,c))<-f<$>f r=(a++b++"-",c)
Zgarb

@Zgarb Cảm ơn! Vì một số lý do, tôi chỉ xem xét f(x:r)|x<'0',(a,(b,c))<-f<$>f r=(a++b++"-",c)|1<3=([x],r)khi tôi tìm một phiên bản có cả hai trường hợp kết hợp, đó là byte dài hơn.
Laikoni

5

Haskell, 54 byte

v f""=""
v f(a:s)=last(v.v:[id|a>'-'])((a:).f)s
h=v h

Hàm vlấy một chuỗi và một hàm, sắp xếp lại biểu thức con ban đầu, sau đó áp dụng hàm cho phần còn lại của chuỗi cho đến khi mọi thứ được sắp xếp lại. Ngăn xếp cuộc gọi và đối số chức năng cùng nhau theo dõi biểu thức nào đang được phân tích cú pháp. Hàm này htrả lời cho thử thách và chỉ vđược gọi với chính nó như là một đối số đầu tiên giả.


1
Ồ (1) Đó chỉ là 53, bạn không cần phải tính dòng mới cuối cùng. (2) Dòng đầu tiên có thể được rút ngắn thành v f l=lnếu bạn di chuyển nó thứ hai.
Ørjan Johansen

1
Tôi không nghĩ rằng bạn cần phân tích nhiều hơn một biểu thức, vì vậy bạn có thể lưu một byte bằng cách sử dụng hàm ẩn danh v id.
Ørjan Johansen

1
Trên thực tế, dòng đầu tiên không bao giờ được gọi trên đầu vào hợp lệ, vì vậy bạn chỉ cần xóa nó.
Ørjan Johansen

1
Chia thành các vệ sĩ dường như đánh bại lastthủ thuật bằng một byte.
Ørjan Johansen

4

Perl 5 , 57 byte

sub f{"@_"=~s/x((?0)|.)((?0)|.)/my$n=$2;f($1).f($n).x/re}

Tôi sử dụng xnhư là toán tử thay vì -(xem liên kết TryItOnline dưới đây).

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

Giải thích:
/x((?0)|.)((?0)|.)/ khớp đệ quy một biểu thức đầy đủ: a xlúc bắt đầu, sau đó là một biểu thức (?0)(đó là một cuộc gọi đệ quy) hoặc một nguyên tử ( .), theo sau là một biểu thức hoặc nguyên tử khác.
Sau đó, tôi cần lưu biểu thức / nguyên tử thứ hai ( my$n=$2;) bởi vì nếu không các cuộc gọi đệ quy sẽ ghi đè lên nó.
Hàm sau đó được gọi đệ quy trên biểu thức đầu tiên ( f($1)), sau đó vào biểu thức thứ hai f($n)xđược thêm vào cuối ( .x).


4

Python 3, 117 112 105 100 98 76 62 61 59 byte

def p(s):x=next(s);yield from[x]*(x>"-")or[*p(s),*p(s),"-"]

Thay đổi:

  • loại bỏ ngắt dòng nếu có thể (-5 byte)
  • lambda thay vì một chức năng đầy đủ (-7 byte, cảm ơn @Dada)
  • không có gì khác (-5 byte, cảm ơn @Leaky Nun)
  • hoàn tác việc chơi golf quá nhiệt tình (-2 byte, cảm ơn @Leaky Nun)
  • thay vào đó, làm việc trên một danh sách toàn cầu (-22 byte)
  • thực tế, hãy làm việc trên các trình vòng lặp thay thế (-14 byte)
  • thay đổi !=thành >(-1 byte, được sao chép từ đề xuất của @ovs)
  • thủ thuật đánh giá lười biếng (-2 byte, cảm ơn @ovs)

Sử dụng nó như thế này:

>>> list(p(iter("--01-0-01")))
['0', '1', '-', '0', '0', '1', '-', '-', '-']


2
lambda x:p(x)[0]có thể có thể thay thế fchức năng của bạn .
Dada

1
Bạn không cần else, methinks.
Nữ tu bị rò rỉ

1
d="-"thực sự tiết kiệm byte?
Leaky Nun

1
def p(s):x=next(s);yield from[x]*(x>"-")or[*p(s),*p(s),"-"]cho 59 byte
ovs

3

Bình thường, 20 byte

L+&-hbTsyM.-Btbytbhb

Điều này tạo ra một hàm ydự kiến ​​một chuỗi là tham số.

Dùng thử trực tuyến: Trình diễn hoặc Test Suite

Giải trình:

Hàm ysẽ phân tích cú pháp và chuyển đổi biểu thức tiền tố đầu tiên thành biểu thức hậu tố. Vì vậy, nếu nó được gọi như y"10"nó sẽ chỉ trở lại 1.

L+&-hbTsyM.-Btbytbhb
L                      define a function y(b), that returns:
   -hbT                   remove the chars "10" from the first char b
                          (T=10, and - will convert a number to a string)
  &                       if this gives the empty string (a falsy value)
 +                hb         then append b[0] to it and return it
                             (so this will parse a digit 0 or 1 from the string)
  &                       otherwise (the first char is a -)
               ytb           parse the first prefix expression from b[1:]
                             (recursive call)
          .-Btb              remove this parsed expression bifurcated from b[1:]
                             this gives a tuple [b[1:], b[1:] without first expr]
        yM                   parse and convert an expression from each one
       s                     join the results
 +                hb         and append the b[0] (the minus) to it and return

2

Võng mạc , 34 31 29 byte


;
-;
¶
+`¶(.+);(.+)
$1$2-
;

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

;được sử dụng để chỉ ra các nút, ban đầu được tạo bởi một số duy nhất và sau đó phát triển thành bất kỳ thứ gì đã được phân tích cú pháp. -được chuyển thành dòng mới để cùng với .+chúng tôi có thể lấy bất cứ thứ gì không phải là không có bản quyền -.


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.