Nửa đảo ngược một chuỗi nhị phân


12

Đây là một câu hỏi tiếp theo để tôi câu hỏi Puzzling.SE : Tôi hỏi nếu có một hàm f lập bản đồ chuỗi Boolean để chuỗi Boolean, do đó f (f (b)) = đảo ngược (b) cho tất cả các đầu vào chuỗi b . ( Ngược lại , ý tôi là hàm đảo ngược thứ tự các bit.)

Liên kết trên có chứa một câu trả lời tích cực, với bằng chứng, bởi f '' tuyệt vời , nhưng bạn có thể muốn tự suy ngẫm câu hỏi trước khi tìm kiếm.

Thực hiện một hàm f như vậy trong càng ít byte càng tốt.

  • Bạn có thể đọc đầu vào từ STDIN hoặc lấy tham số hàm; và viết chuỗi kết quả vào STDOUT hoặc trả về nó.

  • Dù bằng cách nào, bạn có thể làm việc với chuỗi thực tế của hai byte riêng biệt hoặc các ký tự bạn đã chọn (nói 01hay \x00\x01), hoặc với các mảng / danh sách truthy và giá trị falsy . Chọn hai giá trị và gắn bó với những giá trị, mặc dù.

  • Kết quả của một ứng dụng duy nhất của f phải là một chuỗi nhị phân: không có câu trả lời ngớ ngẩn nào như b -> if b starts with 'x' then reverse(b[1:]) else 'x' + b...

  • Chức năng của bạn nên là tổng số ; cụ thể, đầu vào có thể là chuỗi rỗng hoặc dài một bit, v.v. Không có giới hạn trên cho độ dài của chuỗi.

  • Nó cũng phải thuần túy : không giữ bất kỳ trạng thái toàn cầu nào giữa các lệnh gọi hàm; chuỗi đầu vào phải xác định hoàn toàn chuỗi đầu ra.


Đầu ra có thể có chiều dài khác với đầu vào?
Luis Mendo

Chắc chắn rồi! (Trên thực tế, nếu không, thách thức là không thể chứng minh được.)
Lynn

Nó có phải làm việc cho các chuỗi có độ dài một hoặc không?
Máy

Đúng; chức năng phải là tổng số. Tôi đã làm rõ điều này trong câu hỏi!
Lynn

Câu trả lời:



7

Python 2, 64 69 byte

def f(s):p=(s+s).find(s,1);return[s[~p::-1],s+s[:p]][len(s)/p%2]

Ung dung:

def f(s):
    p = (s+s).find(s,1)
    n = len(s)/p
    return s[:p][::1|n%-2] * -~(n-1^1)

Điều này tìm thấy chu kỳ của chuỗi, tức là tối thiểu pnhư vậy slà một chuỗi thời gian plặp lại nhiều nlần (tôi đã tìm thấy một phương pháp đánh gôn trên SO). Sau đó, nếu nlà số lẻ, nó thêm một lần lặp lại của thời kỳ. Nếu nlà chẵn, nó sẽ loại bỏ một lần lặp lại của giai đoạn và đảo ngược nó.

Cảm ơn @ Sp3000 đã giúp triển khai ánh xạ chức năng giữa 1 <-> 2, 3 <-> 4, v.v.


... Khi nào mã không mã hóa sẽ được cập nhật?
Máy

@CatsAreFluffy Tôi không có kế hoạch sửa đổi mã không được mã hóa vì nó sử dụng cùng một ý tưởng chỉ với một sự khác biệt nhỏ. Mặt khác, tiếng Anh là cập nhật.
frageum

2

Perl, 49 47 byte

Bao gồm +2 cho -lp

Dựa trên thuật toán rất hay của @ frageum

Chạy với đầu vào trên STDIN, ví dụ:

perl -lp halfreverse.pl <<< "101001"

halfreverse.pl:

/^(.+?)((\1\1?)*)$/;$_=$3eq$1?reverse$2:$_.$1

Giải trình

/^               $/         Match the complete input string
  (.+?)                     Non-greedy match. Try only one digit at the start,
                            if that doesn't work try 2, then 3 etc. The string
                            being tried is remembered in backreference \1
       ((\1\1?)*)           Try to repeat \1 as many times as possible but
                            prefer in groups of 2. Fall back to only 1 at the
                            end of the string if the trailing part has an odd
                            number of \1 (so the total count is even)

   $3eq$1                   So the last match $3 equals the first match $1
         ?                  if and only if the total count is even
          reverse$2         If total count is even drop the first instance of
                   :        \1 and reverse
                    $_.$1   If total count is odd extend $_ by one instance
$_=                         Assign result

Làm thế nào nó hoạt động??
Máy
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.