Sửa cây của bạn!


8

Trong tin học, chúng ta thường sử dụng cây dưới nhiều hình thức và biểu diễn khác nhau. Ba phương thức chính của tuần tự cây nhị phân là ký hiệu tiền tố, ký hiệu và hậu tố. Ví dụ, cây nhị phân sau:

Cây, infix: rbxabde   (nguồn: Olympic Hà Lan về Tin học, chung kết, 2012/13)

có thể được biểu diễn trong ký hiệu tiền tố như abrxdbe, trong infix as rbxabdevà in postfix as rxbbeda.

Trong trường hợp này, bạn phải đối mặt với một cây nhị phân hoàn chỉnh được biểu thị bằng ký hiệu infix . Nhiệm vụ của bạn là chuyển đổi cây này thành ký hiệu tiền tố . Đầu vào của bạn trên stdin sẽ là 2 n -1 ký tự chữ cái viết thường, az và không còn nữa, kết thúc bằng một ký tự dòng mới, với bất kỳ số nguyên n nào sao cho 1 ≤ n 16. Do đó, số lượng ký tự tối đa bạn sẽ nhận được là 65535. Xuất cây thành thiết bị xuất chuẩn theo cách tương tự, nhưng sau đó ở định dạng tiền tố.

Đây là mã golf, vì vậy mã ngắn nhất, được tính bằng byte, sẽ giành chiến thắng. Phiếu bầu sẽ đóng vai trò là người phá vỡ cà vạt, và nếu những người đó cũng trói buộc, hãy nộp ngày và giờ.



@PeterTaylor Cảm ơn bạn đã đề cập, nhưng tôi nghĩ thử thách này thực sự khác biệt vì bạn không cần phải đánh giá toàn bộ biểu thức, chỉ là một cây nhị phân 2 <sup> _n _ </ sup> -1 đơn giản.
tomsmeding

Ok, hạn chế để hoàn thành cây nhị phân không đơn giản hóa mọi thứ khá nhiều.
Peter Taylor

Câu trả lời:


8

GolfScript, 23 ký tự

.,\{;).2base{)!}do}$/n-

Giải pháp này sử dụng một cách tiếp cận khác với Howard: về cơ bản, nó sắp xếp các ký tự đầu vào theo danh sách các nhánh cần thiết để tiếp cận ký tự đó từ gốc của cây.

Lưu ý rằng dòng mới ở cuối đầu vào là bắt buộc (tức là độ dài đầu vào phải là lũy thừa của hai). Phần n-cuối của mã được yêu cầu để chặn một dòng mới bổ sung ở đầu ra; nếu một dòng mới như vậy được chấp nhận, những ký tự đó có thể được bỏ qua cho số điểm 21 ký tự.

Như thường lệ, bạn có thể kiểm tra mã này trực tuyến.

Giải trình:

  • .,\tính toán độ dài của đầu vào và di chuyển nó xuống dưới chuỗi đầu vào trên ngăn xếp. Nó sẽ được sử dụng làm giá trị bắt đầu của bộ đếm vòng lặp được sử dụng để xây dựng các khóa sắp xếp bên dưới. (Mã dựa vào đây là sức mạnh của hai; nếu không, thao tác bit bên dưới sẽ không tạo ra kết quả như mong đợi. Mặc dù vậy, bất kỳ công suất đủ lớn nào của hai sẽ hoạt động.)

  • { }$ sắp xếp các ký tự trong chuỗi đầu vào theo khóa sắp xếp được tính bên trong khối:

    • ;chỉ cần ném đi ký tự được đưa ra làm đầu vào cho khối; chúng tôi không quan tâm đến các giá trị ký tự thực tế ở đây, chỉ về vị trí của chúng trong chuỗi.

    • ). tăng bộ đếm vòng lặp trên ngăn xếp (được khởi tạo theo chiều dài của chuỗi đầu vào) và tạo một bản sao của nó.

    • 2base chuyển đổi bản sao này thành một mảng các bit (bỏ qua các số 0 đứng đầu; đó là lý do tại sao chúng ta cần bắt đầu đếm từ một sức mạnh đủ lớn của hai, thay vì chỉ từ 0).

    • {)!}doliên tục cắt bit thấp nhất từ ​​mảng cho đến khi bit băm nhỏ là a 1.

    Vì các khóa sắp xếp kết quả là các mảng, nên $so sánh chúng theo từ vựng. Vì vậy, ví dụ, mảng [1](tương ứng với nút gốc) sắp xếp trước [1 0](tương ứng với con trái của nút gốc) và [1 1](con phải của nút gốc).

  • Cuối cùng, /loại bỏ bộ đếm vòng lặp bằng cách sử dụng nó làm độ dài của các đoạn để tách chuỗi đầu ra thành (cảm ơn, Peter!) Và n-loại bỏ dòng mới khỏi chuỗi đầu vào được sắp xếp. (Trình thông dịch GolfScript sẽ nối thêm một dòng mới vào đầu ra sau khi in nội dung của ngăn xếp.)


2
Làm tốt lắm! Bạn vẫn có thể lưu thêm một: thay vì \;thoát khỏi bộ đếm vòng lặp, bạn có thể /chia chuỗi thành các phần lớn hơn nó. (Ý n-chí thậm chí sau đó kéo nó ra khỏi mảng đã tạo).
Peter Taylor

7

GolfScript, 28 ký tự

{.,1>{.,)2//([)\c]\~c+}*}:c~

Bạn có thể kiểm tra mã trực tuyến .

Mã chú thích:

# define an operator c acting on the top of stack which does the conversion
{
  # if the input string is more than a single character
  .,1>{
    # split string into two halves (rounded up)
    .,)2//   
    # take first part last character
    ([)
    # take first part rest and call c recursively
    \c]
    # get second part
    \~
    # call c recursively on second part
    c
    # join all three together 
    +
  }*
}:c
# call c
~       

6

GolfScript (29 ký tự)

{.,1>{.,)2//~\[)](f@f++}*}:f~

Bản demo trực tuyến

Hoạt động có hoặc không có dòng mới trong đầu vào.


Tôi đã mất quá nhiều thời gian để viết ra giải pháp của mình ... Như dự đoán các giải pháp trông khá giống nhau.
Howard

3

APL (48)

(Có, bộ ký tự APL không vừa trong một byte .)

{1=⍴⍵:⍵⋄(⊃a),⊃,/∇¨1↓a←1⌽⌽⍵⊂⍨(⍳⍴⍵)∊1,0 1+⌈.5×⍴⍵}⍞

Giải trình:

  • {... }⍞: đọc đầu vào, đưa vào chức năng
  • 1=⍴⍵:⍵: nếu độ dài đầu vào là một, chúng ta đã hoàn thành
  • : nếu không thì:
  • (⍳⍴⍵)∊1,0 1+⌈.5×⍴⍵: tạo một bitfield của các vị trí để phân chia đầu vào (ký tự đầu tiên, ký tự giữa và ký tự qua ký tự giữa)
  • ⍵⊂⍨: phân chia đầu vào tại những nơi này
  • a←1⌽⌽: xoay các mảng con sao cho ký tự ở giữa là đầu tiên, tay trái là thứ hai và tay phải là thứ ba và lưu trữ trong a.
  • ⊃,/∇¨1↓a: chạy lại hàm trên hai phần tử cuối cùng avà nối các kết quả
  • (⊃a),: và nối nó với mục đầu tiên trong a

3

Trăn 3 - 76

def f(x):a=len(x)//2;return x and x[a]+f(x[:a])+f(x[a+1:])
print(f(input()))

1

C, 108 ký tự

Mã của tôi sử dụng hàm đệ quy, luôn in ký tự ở giữa bộ đệm và tự gọi nó bằng một phần của chuỗi trước và một phần của chuỗi sau khi ký tự được in. (Phân chia và chinh phục)

char b[65536];d(s,e){int c=s+(e-s)/2;putchar(b[c]);if(c^s)d(s,c-1),d(c+1,e);}main(){gets(b);d(0,strlen(b));}

vô dụng:

char b[65536];
d(s,e){
    int c=s+(e-s)/2;
    putchar(b[c]);
    if(c^s)d(s,c-1),d(c+1,e);
}
main(){
    gets(b);
    d(0,strlen(b));
}

Đó cũng là cách tiếp cận tôi đã thực hiện trong giải pháp không chơi gôn cá nhân của mình. Dường như không phải là ngắn nhất mặc dù ...
tomsmeding
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.