Giải quyết một biến đổi Burrows-Wheeler


11

Giới thiệu

Trong thử thách này, bạn sẽ giải được các phép biến đổi Burrows-Wheeler chéo. Dưới đây là tổng quan chung về biến đổi Burrows-Wheeler chéo là gì. Để mã hóa tin nhắn, trước tiên bạn phải đảm bảo rằng nó có độ dài lẻ (tức là 5, 7, 9, v.v.). Sau đó, bạn tạo một lưới, nbởi n, nđộ dài của tin nhắn. Hàng đầu tiên là thông điệp ban đầu. Mỗi hàng sau đó là hàng phía trên nó, nhưng dịch chuyển 1 ký tự còn lại với ký tự đầu tiên di chuyển về phía sau. Ví dụ:

Hello World
ello WorldH
llo WorldHe
lo WorldHel
o WorldHell
 WorldHello
WorldHello 
orldHello W
rldHello Wo
ldHello Wor
dHello Worl

Sau đó, bạn lấy từng chữ cái trên đường chéo NW đến SE và đặt nó vào một chuỗi mới:

Hello World  H
ello WorldH  l
llo WorldHe  o
lo WorldHel  W
o WorldHell  r
 WorldHello  d
WorldHello   e
orldHello W  l
rldHello Wo  (space)
ldHello Wor  o
dHello Worl  l

Tin nhắn được mã hóa của bạn là HloWrdel ol. Để giải mã, trước tiên hãy lấy độ dài của tin nhắn được mã hóa, thêm 1 và chia cho 2. Hãy gọi số này x. Bây giờ chúng ta đã biết x, bắt đầu từ chữ cái đầu tiên, mỗi chữ cái là xsau chữ cái cuối cùng, lặp đi lặp lại. Ví dụ:

H   l   o   W   r   d   e   l     o   l
1   

Then...

H   l   o   W   r   d   e   l     o   l
1                       2

And again...

H   l   o   W   r   d   e   l     o   l
1   3                   2

Until you get...

H   l   o   W   r   d   e   l       o   l
1   3   5   7   9  11   2   4   6   8  10

Bây giờ chỉ cần sắp xếp lại các chữ cái theo đúng thứ tự để có được Hello World!

Thử thách

Thách thức của bạn là viết hai chương trình, chức năng hoặc một trong hai chương trình. Tuy nhiên, cả hai phải sử dụng cùng một ngôn ngữ. Chương trình đầu tiên sẽ chấp nhận một chuỗi làm đầu vào thông qua STDIN, đối số chương trình hoặc tham số hàm và mã hóa nó bằng phương thức này. Chương trình thứ hai sẽ chấp nhận một chuỗi làm đầu vào thông qua STDIN, đối số chương trình hoặc tham số hàm và giải mã nó bằng phương thức này.

Yêu cầu

Chương trình / Chức năng đầu tiên

  • Một đầu vào chuỗi đơn sử dụng bất kỳ phương pháp được liệt kê ở trên.
  • Phải mã hóa chuỗi bằng cách sử dụng kiểu biến đổi Burrows-Wheeler chéo.

Chương trình / Chức năng thứ hai

  • Một đầu vào chuỗi đơn sử dụng bất kỳ phương pháp được liệt kê ở trên.
  • Phải giải mã chuỗi bằng cách sử dụng kiểu biến đổi Burrows-Wheeler chéo.

Những ràng buộc

  • Bạn không thể sử dụng bất kỳ chức năng tích hợp hoặc bên ngoài nào để thực hiện nhiệm vụ này.
  • Sơ hở tiêu chuẩn không được phép.
  • Cả hai chương trình / chức năng phải ở cùng một ngôn ngữ.

Chấm điểm

Đây là mã golf, vì vậy chương trình ngắn nhất trong byte thắng.

Nếu tôi cần thêm thông tin, hãy để lại nhận xét!


2
Chúng ta có phải chuyển đổi chuỗi đầu vào có độ dài chẵn thành chiều dài lẻ không?
Trình tối ưu hóa

5
Đây không phải là một transoformation Burrows-Wheeler.
FUZxxl

3
Một phép biến đổi Burrows-Wheeler khác ở chỗ mảng tất cả các phép quay được sắp xếp theo từ vựng trước khi bạn lấy các mục cuối cùng.
FUZxxl

@Optimizer không cần thiết.
GamrCorps 27/2/2015

Câu trả lời:


12

CJam, (4 + 8 =) 12 byte

Chương trình mã hóa:

q2/z

Dùng thử trực tuyến tại đây

Chương trình giải mã:

q_,2/)/z

Dùng thử trực tuyến tại đây

Làm thế nào (hoặc đúng hơn, tại sao) họ làm việc :

Biến đổi Dia chéo Burrows-Wheeler về cơ bản là mọi ký tự khác của chuỗi, với sự bao bọc từ cuối. Nếu chúng ta coi Chuỗi là một ma trận 2D gồm 2 cột, thì đơn giản chỉ cần thực hiện chuyển đổi ma trận. Thí dụ:

Hello World

Được biểu diễn dưới dạng ma trận 2D như

He
ll
o 
Wo
rl
d

Bây giờ, chỉ cần đọc nó cột khôn ngoan, đưa ra:

HloWrdel ol

Đó là biến đổi Burrows-Wheeler.

Giải mã đơn giản là đảo ngược quá trình, viết chuỗi dưới dạng ma trận 2D 2 hàng và đọc cột khôn ngoan.

Mở rộng mã :

Mã hoá:

q          "Read the input";
 2/        "divide it into sub arrays of 2 characters";
   z       "Take transform";

Bộ giải mã:

q_,        "Read the input, take copy and get length of copy";
   2/      "Divide the length by 2";
     )/    "Increment and split the input into two rows";
       z   "Take transform";

7

Python 2, 61 byte

E=lambda x:x[::2]+x[1::2]
D=lambda y:(-~len(y)/2*y)[::len(y)/2+1]

Emã hóa và Dgiải mã. Tôi không tính E=D=cho điểm.

Việc giải mã lấy mọi nký tự bao quanh, trong đó nmột nửa chiều dài chuỗi được làm tròn. Lý do điều này đảo ngược là 2nđảo ngược modulo độ dài của chuỗi, do đó, mỗi nký tự đảo ngược lấy mỗi 2thứ một.

Nếu sử dụng một hàm duy nhất được cho phép, tôi có thể thực hiện 44 byte

def F(x,b):n=1+len(x)**b>>b;return(n*x)[::n]

Mã hóa khi bFalsevà giải mã khi bTrue. Biểu thức 1+len(x)**b>>bbằng [2,len(x)/2+1][b].


4

J, 10 + 10 = 20

   ({~#|2*i.@#) 'Hello World'
HloWrdel ol

   (/:#|2*i.@#) 'HloWrdel ol'
Hello World

(Niềng răng xung quanh không được tính vào điểm số vì chúng không phải là một phần của định nghĩa hàm.)

Cảm ơn FUZxxl vì đã cải thiện 3 byte.

Bây giờ nó được hiển thị độc đáo rằng hai hàm là nghịch đảo khi hàm thứ nhất lấy các ký tự từ các vị trí được xác định bởi danh sách #|2*i.@#và hàm thứ hai sắp xếp lại các ký tự bằng cách sử dụng cùng một danh sách.

Hãy thử trực tuyến tại đây.


Cái đầu tiên cũng có thể được thực hiện trong 10 ký tự : {~#|2*i.@#.
FUZxxl

@FUZxxl Cảm ơn, đã cập nhật. Bây giờ mối quan hệ giữa hai chức năng được hiển thị thực sự độc đáo.
Randomra

3

Pyth - 5 + 11 = 16 byte

Tôi nhận thấy một mô hình! ~ Nhảy có vui không ~ Biến đổi chỉ thực sự lặp lại qua chuỗi chọn mọi yếu tố khác. Nó chỉ hoạt động trên lẻ vì nếu không nó sẽ không bao giờ có được một nửa các yếu tố. Điều này tương đương với việc xoay một ma trận rộng 2.

Mã hoá:

%2*2z

Bước cắt của Python không lặp xung quanh nên tôi lặp lại chuỗi.

%2      Take every other elements
 *2z    Double input string

Bộ giải mã:

K/hlz2%K*Kz

Một lần nữa không có bọc xung quanh cho bước cắt.

K/hlz2       K=length of (input+1)/2
%K           Every kth element
 *Kz         From K*the input

@FryAmTheEggman Tôi khá chắc chắn rằng nó chỉ được coi là có chuỗi độ dài lẻ. Đó là vào đầu mô tả.
Maltysen 27/2/2015

Ối xin lỗi. : S
FryAmTheEggman

2

GNU sed -r, (20 + 104 + 1) = 125

Thêm +1 trong điểm số là cho tùy chọn -r để sed. Các chuỗi đầu vào có độ dài lẻ được giả sử.

Mã hoá:

s/.*/&&/
s/(.)./\1/g
  • Nhân đôi chuỗi đầu vào
  • Thả mọi ký tự lẻ (tính từ 1)

Bộ giải mã:

Bộ giải mã sử dụng :như một ký tự đánh dấu tạm thời, vì vậy nếu nó xuất hiện trong chuỗi đầu vào, bạn sẽ nhận được hành vi không xác định. Nếu chuỗi đầu vào bị giới hạn ở 95 ký tự ASCII, thì các điểm đánh dấu này có thể được thay thế bằng một cái gì đó nằm ngoài phạm vi ASCII (ví dụ: BEL 0x7) để sửa lỗi này.

s/.*/:&:/
:l;s/:(.)(.+)(.):/\1:\2:\3/;tl
s/:(.*)/\1:/
:m;s/(.)(.*):(.?)(.*):(.*)/\2:\4:\5\1\3/;tm
s/://g
  • Đặt :điểm đánh dấu ở đầu và cuối chuỗi đầu vào
  • Xáo trộn lần đầu tiên :về phía trước và lần thứ hai :lùi một ký tự cho đến khi các :điểm đánh dấu là một trong hai nhân vật ở giữa
  • Xóa cái đầu tiên :và thêm cái khác :vào cuối để lại "A: B:", trong đó A là chuỗi bao gồm các ký tự lẻ từ đầu vào văn bản gốc và B là chuỗi bao gồm các ký tự chẵn
  • Sắp xếp lại các ký tự của A và B sau cùng :để ghép lại đầu vào văn bản gốc
  • Xóa các :điểm đánh dấu còn lại

2

JavaScript ES6, 41 + 49 = 90 byte

Mã hoá

(t=>t.replace(/./g,(_,o)=>t[o*2%t.length]))('Hello World')

Bộ giải mã

(t=>t.replace(/./g,(_,o)=>t[-~(l=t.length)/2*o%l]))('HloWrdel ol')

Đây là các hàm ẩn danh, vì vậy tôi chỉ đếm mã bên trong dấu ngoặc đơn vì đó là toàn bộ định nghĩa hàm. Dùng thử với đoạn trích dưới đây: (đã sửa đổi để sử dụng ES5)


Làm thế nào về điều này : [t=>t.replace(/./g,(_,o)=>t[o*2%t.length]),t=>t.replace(/./g,(_,o)=>t[(1+(l=t.length))/2*o%l])]? Bạn sử dụng nó như thế nào [...][0]('encode string')[...][1]('decode string'). Không có gì nói rằng điều này không thể được thực hiện! Và bạn tiết kiệm được 1 byte.
Ismael Miguel

Cảm ơn, vì nó nói viết 2 hàm và tôi không nghĩ nó sẽ được tính.
NinjaBearMonkey 27/2/2015

Đó vẫn là 2 chức năng. Các quy tắc không chỉ định tên hoặc cách để truy cập các chức năng. Nó chỉ nói rằng bạn phải sử dụng 2 chức năng.
Ismael Miguel

1
@IsmaelMiguel Bây giờ tôi nghĩ về nó, tôi nghĩ rằng các hàm ẩn danh được chính họ cho phép, vì vậy sử dụng nó giúp tôi tiết kiệm nhiều byte hơn.
NinjaBearMonkey

Tôi rất vui vì bạn đã cắt giảm số lượng byte.
Ismael Miguel
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.