Memecahkan transformasi Burrows-Wheeler Diagonal

11

pengantar

Dalam tantangan ini, Anda akan menyelesaikan transformasi Burrows-Wheeler diagonal. Berikut ini adalah gambaran umum tentang apa transformasi Burrows-Wheeler diagonal. Untuk menyandikan pesan, Anda harus memastikan bahwa panjangnya aneh (mis. 5, 7, 9, dll.). Kemudian Anda membuat kotak, ndengan n, di mana npanjang pesan. Baris pertama adalah pesan asli. Setiap baris setelah itu adalah baris di atasnya, tetapi bergeser 1 karakter ke kiri dengan karakter pertama bergerak ke belakang. Sebagai contoh:

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

Kemudian Anda mengambil setiap huruf pada NW ke SE diagonal dan memasukkannya ke dalam string baru:

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

Pesan Anda yang disandikan adalah HloWrdel ol. Untuk memecahkan kode, pertama-tama ambil panjang pesan yang disandikan, tambahkan 1, dan bagi dengan 2. Ayo panggil nomor ini x. Sekarang kita tahu x, mulai dari huruf pertama, setiap huruf adalah xsetelah huruf terakhir, berputar-putar. Sebagai contoh:

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

Sekarang atur ulang surat-surat dengan urutan yang benar untuk mendapatkan Hello World!

Tantangan

Tantangan Anda adalah menulis dua program, fungsi, atau masing-masing. Namun, keduanya harus menggunakan bahasa yang sama. Program pertama akan menerima string sebagai input melalui STDIN, argumen program, atau parameter fungsi dan menyandikannya menggunakan metode ini. Program kedua akan menerima string sebagai input melalui STDIN, argumen program, atau parameter fungsi dan mendekode menggunakan metode ini.

Persyaratan

Program / Fungsi pertama

  • Input string tunggal menggunakan metode apa pun yang tercantum di atas.
  • Harus menyandikan string menggunakan gaya transformasi Burrows-Wheeler diagonal.

Program / Fungsi kedua

  • Input string tunggal menggunakan metode apa pun yang tercantum di atas.
  • Harus mendekode string menggunakan gaya transformasi Burrows-Wheeler diagonal.

Kendala

  • Anda tidak dapat menggunakan fungsi internal atau eksternal yang menyelesaikan tugas ini.
  • Tidak ada celah standar.
  • Kedua program / fungsi harus dalam bahasa yang sama.

Mencetak gol

Ini adalah kode golf, jadi program terpendek dalam byte menang.

Jika saya perlu menambahkan lebih banyak informasi, tinggalkan komentar!

GamrCorps
sumber
2
Apakah kita harus mengubah string input panjang panjang ke panjang aneh?
Pengoptimal
5
Ini bukan transoformasi Burrows-Wheeler.
FUZxxl
3
Transformasi Burrows-Wheeler berbeda karena array semua rotasi diurutkan secara leksikografis sebelum Anda mengambil item terakhir.
FUZxxl
@ Opptizer itu tidak perlu.
GamrCorps

Jawaban:

12

CJam, (4 + 8 =) 12 byte

Program pengodean:

q2/z

Cobalah online di sini

Program decoding:

q_,2/)/z

Cobalah online di sini

Bagaimana (atau lebih tepatnya, mengapa) mereka bekerja :

Transformasi Burrows-Wheeler Diagonal pada dasarnya adalah setiap karakter string yang lain, dengan balutan dari ujungnya. Jika kita memperlakukan String sebagai matriks 2D dari 2 kolom, itu hanya bermuara untuk mengambil transformasi dari matriks. Contoh:

Hello World

Diwakili sebagai matriks 2D sebagai

He
ll
o 
Wo
rl
d

Sekarang, cukup bacalah kolomnya dengan bijaksana, berikan:

HloWrdel ol

Yang merupakan transformasi Burrows-Wheeler.

Decoding hanya kebalikan dari proses, menulis string sebagai matriks 2D 2 baris dan membaca kolom bijaksana.

Perluasan kode :

Encoder:

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

Dekoder:

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";
Pengoptimal
sumber
7

Python 2, 61 byte

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

Emengenkripsi dan Dmendekripsi. Saya tidak menghitung E=dan D=untuk skor.

Dekripsi mengambil setiap nkarakter 'membungkus, di mana nsetengah panjang string dibulatkan. Alasan pembalikan ini adalah karena 2dan ninverses modulo panjang string, jadi ambil setiap nkarakter pembalikan mengambil setiap 2nd satu.

Jika menggunakan fungsi tunggal diizinkan, saya bisa melakukan 44 byte

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

The mengenkripsi saat bini Falsedan mendekripsi saat bini True. Ekspresi 1+len(x)**b>>bsama dengan [2,len(x)/2+1][b].

Tidak
sumber
4

J, 10 + 10 = 20

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

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

(Kawat gigi yang mengelilinginya tidak dihitung dalam skor karena mereka bukan bagian dari definisi fungsi.)

Terima kasih untuk FUZxxl untuk peningkatan 3 byte.

Sekarang ditunjukkan dengan baik bahwa kedua fungsi terbalik karena yang pertama mengambil karakter dari posisi yang ditentukan oleh daftar #|2*i.@#dan fungsi kedua mengatur kembali karakter menggunakan daftar yang sama dengan pemesanan.

Cobalah online di sini.

randomra
sumber
Yang pertama dapat dilakukan dalam 10 karakter juga: {~#|2*i.@#.
FUZxxl
@ FuZxxl Terima kasih, diperbarui. Sekarang hubungan antara kedua fungsi ditampilkan dengan sangat baik.
randomra
3

Pyth - 5 + 11 = 16 byte

Saya perhatikan sebuah pola! ~ Apakah menari bahagia ~ Transformasi hanya benar-benar hanya perulangan melalui string memetik setiap elemen lainnya. Ini hanya bekerja pada aneh karena selain itu tidak akan pernah mendapatkan setengah elemen. Ini sama dengan memutar 2 matriks lebar.

Encoder:

%2*2z

Mengiris langkah Python tidak berputar sehingga saya mengulangi string.

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

Dekoder:

K/hlz2%K*Kz

Sekali lagi tidak ada bungkus untuk step-slicing.

K/hlz2       K=length of (input+1)/2
%K           Every kth element
 *Kz         From K*the input
Maltysen
sumber
@FryAmTheEggman Saya cukup yakin bahwa itu seharusnya hanya mengambil string panjang ganjil. Itu di awal deskripsi.
Maltysen
Ups, maaf. : S
FryAmTheEggman
2

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

+1 ekstra dalam skor adalah untuk opsi -r untuk sed. String input panjang ganjil diasumsikan.

Encoder:

s/.*/&&/
s/(.)./\1/g
  • Gandakan string input
  • Jatuhkan setiap karakter ganjil (dihitung dari 1)

Dekoder:

Decoder digunakan :sebagai karakter marker sementara, jadi jika itu muncul dalam string input, Anda akan mendapatkan perilaku yang tidak terdefinisi. Jika string input dibatasi hingga 95 karakter ASCII, maka marker ini dapat diganti dengan sesuatu di luar rentang ASCII (mis. BEL 0x7) untuk memperbaikinya.

s/.*/:&:/
:l;s/:(.)(.+)(.):/\1:\2:\3/;tl
s/:(.*)/\1:/
:m;s/(.)(.*):(.?)(.*):(.*)/\2:\4:\5\1\3/;tm
s/://g
  • Letakkan :marker di awal dan di akhir string input
  • Kocok :maju pertama dan :mundur satu karakter satu demi satu sampai :penanda adalah kedua sisi karakter tengah
  • Hapus yang pertama :dan tambahkan yang lain :ke ujung meninggalkan "A: B:", di mana A adalah string yang terdiri dari karakter aneh dari input plaintext dan B adalah string yang terdiri dari karakter genap
  • Riffle karakter A dan B bersama setelah yang terakhir :untuk memasang kembali input plaintext
  • Hapus :spidol yang tersisa
Trauma Digital
sumber
2

JavaScript ES6, 41 + 49 = 90 byte

Encoder

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

Dekoder

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

Ini adalah fungsi anonim, jadi saya hanya menghitung kode di dalam tanda kurung karena itu adalah definisi fungsi secara keseluruhan. Cobalah dengan cuplikan di bawah ini: (dimodifikasi untuk menggunakan ES5)

NinjaBearMonkey
sumber
Bagaimana dengan ini [t=>t.replace(/./g,(_,o)=>t[o*2%t.length]),t=>t.replace(/./g,(_,o)=>t[(1+(l=t.length))/2*o%l])]:? Anda menggunakannya suka [...][0]('encode string')dan [...][1]('decode string'). Tidak ada yang mengatakan bahwa ini tidak dapat dilakukan! Dan Anda menghemat 1 byte.
Ismael Miguel
Terima kasih, bu dikatakan menulis 2 fungsi, dan saya tidak berpikir ini akan masuk hitungan.
NinjaBearMonkey
Itu masih 2 fungsi. Aturan tidak menentukan nama atau cara untuk mengakses fungsi. Itu hanya mengatakan bahwa Anda harus menggunakan 2 fungsi.
Ismael Miguel
1
@IsmaelMiguel Sekarang saya memikirkannya, saya pikir fungsi anonim diizinkan oleh mereka sendiri, jadi menggunakan itu menghemat lebih banyak byte.
NinjaBearMonkey
Saya senang Anda mengurangi jumlah byte.
Ismael Miguel