Risolvi una trasformazione Diagonal Burrows-Wheeler


11

introduzione

In questa sfida risolverai le trasformazioni diagonali di Burrows-Wheeler. Ecco una panoramica generale di cosa sia una trasformazione diagonale di Burrows-Wheeler. Per codificare un messaggio, devi prima assicurarti che sia di lunghezza dispari (cioè 5, 7, 9, ecc.). Poi fate una griglia, nda ndove nè la lunghezza del messaggio. La prima riga è il messaggio originale. Ogni riga successiva è la riga sopra di essa, ma spostava 1 carattere a sinistra con il primo personaggio che si spostava indietro. Per esempio:

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

Quindi prendi ogni lettera sulla diagonale da NO a SE e la inserisci in una nuova stringa:

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

Il tuo messaggio codificato è HloWrdel ol. Per decodificare, prendere innanzitutto la lunghezza del messaggio codificato, aggiungere 1 e dividere per 2. Consente di chiamare questo numero x. Ora che sappiamo x, a partire dalla prima lettera, ogni lettera è xdopo l'ultima, in loop. Per esempio:

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

Ora riorganizza le lettere nell'ordine corretto per ottenere Hello World!

Sfida

La tua sfida è scrivere due programmi, funzioni o uno di ciascuno. Tuttavia, entrambi devono usare la stessa lingua. Il primo programma accetterà una stringa come input tramite STDIN, argomenti del programma o parametri di funzione e la codificherà utilizzando questo metodo. Il secondo programma accetterà una stringa come input tramite STDIN, argomenti del programma o parametri di funzione e la decodificherà utilizzando questo metodo.

Requisiti

Primo programma / funzione

  • Una singola stringa di input che utilizza qualsiasi metodo sopra elencato.
  • È necessario codificare la stringa utilizzando uno stile di trasformazione diagonale di Burrows-Wheeler.

Secondo programma / funzione

  • Una singola stringa di input che utilizza qualsiasi metodo sopra elencato.
  • Deve decodificare la stringa usando uno stile di trasformazione diagonale Burrows-Wheeler.

vincoli

  • Non è possibile utilizzare alcuna funzione incorporata o esterna che compia questo compito.
  • Non sono ammesse scappatoie standard.
  • Entrambi i programmi / funzioni devono essere nella stessa lingua.

punteggio

Questo è il golf del codice, quindi vince il programma più breve in byte .

Se devo aggiungere ulteriori informazioni, lascia un commento!


2
Dobbiamo convertire una stringa di input di lunghezza pari in una lunghezza dispari?
Ottimizzatore,

5
Questa non è una transoformazione di Burrows-Wheeler.
FUZxxl,

3
Una trasformazione Burrows-Wheeler è diversa in quanto la matrice di tutte le rotazioni viene ordinata lessicograficamente prima di prendere gli ultimi oggetti.
FUZxxl,

@Optimizer non è necessario.
GamrCorps,

Risposte:


12

CJam, (4 + 8 =) 12 byte

Programma di codifica:

q2/z

Provalo online qui

Programma di decodifica:

q_,2/)/z

Provalo online qui

Come (o meglio, perché) funzionano :

La trasformazione Diagonal Burrows-Wheeler è fondamentalmente ogni altro carattere della stringa, con avvolgimento dalla fine. Se trattiamo la stringa come una matrice 2D di 2 colonne, si riduce semplicemente a prendere la trasformazione della matrice. Esempio:

Hello World

È rappresentato come matrice 2D come

He
ll
o 
Wo
rl
d

Ora, semplicemente leggendolo nella colonna saggia, dai:

HloWrdel ol

Qual è la trasformazione di Burrows-Wheeler.

La decodifica è semplicemente inversa al processo, scrivi la stringa come una matrice 2D a 2 righe e leggi la colonna saggia.

Espansione del codice :

Codificatore:

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

decoder:

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]

Ecrittografa e Ddecodifica. Non conto il E=e D=per il punteggio.

La decrittazione prende ogni ncarattere avvolgente, dove nè arrotondata per metà della lunghezza della stringa. La ragione per cui questo si inverte è che 2e nsono inverse nel modulo della lunghezza della stringa, quindi prendendo ogni ncarattere invertito prendendone ogni 2.

Se fosse consentito l'uso di una singola funzione, potrei fare 44 byte

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

Crittografa quando bè Falsee decodifica quando bè True. L'espressione 1+len(x)**b>>bè uguale a [2,len(x)/2+1][b].


4

J, 10 + 10 = 20

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

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

(Le parentesi graffe circostanti non vengono conteggiate nella partitura in quanto non fanno parte della definizione della funzione.)

Grazie per FUZxxl per un miglioramento di 3 byte.

Ora è ben dimostrato che le due funzioni sono inverse poiché la prima prende i caratteri dalle posizioni definite dalla lista #|2*i.@#e la seconda funzione riordina i caratteri usando la stessa lista dell'ordinamento.

Provalo online qui.


Il primo può essere fatto in 10 caratteri pure: {~#|2*i.@#.
FUZxxl,

@FUZxxl Grazie, aggiornato. Ora la relazione tra le due funzioni è mostrata davvero bene.
randomra,

3

Pyth - 5 + 11 = 16 byte

Ho notato uno schema! ~ Fa danza felice ~ La trasformazione è solo in loop attraverso la stringa che seleziona tutti gli altri elementi. Funziona solo su dispari poiché altrimenti non otterrebbe mai la metà degli elementi. Ciò equivale a ruotare una matrice larga 2.

Codificatore:

%2*2z

Lo step-slicing di Python non gira intorno quindi ho ripetuto la stringa.

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

decoder:

K/hlz2%K*Kz

Ancora una volta non avvolgente per lo step-slicing.

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

@FryAmTheEggman Sono abbastanza sicuro che si supponga di prendere solo una stringa di lunghezza dispari. Era all'inizio della descrizione.
Maltysen,

Oops scusa. : S
FryAmTheEggman,

2

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

Il +1 extra nel punteggio è per l'opzione -r a sed. Si presuppongono stringhe di input di lunghezza dispari.

Codificatore:

s/.*/&&/
s/(.)./\1/g
  • Raddoppia la stringa di input
  • Rilascia ogni carattere dispari (contando da 1)

decoder:

Il decodificatore usa :come carattere marcatore temporaneo, quindi se appare nella stringa di input, otterrai un comportamento indefinito. Se la stringa di input è limitata ai 95 caratteri ASCII, questi marker possono essere sostituiti con qualcosa al di fuori dell'intervallo ASCII (ad es. BEL 0x7) per risolvere il problema.

s/.*/:&:/
:l;s/:(.)(.+)(.):/\1:\2:\3/;tl
s/:(.*)/\1:/
:m;s/(.)(.*):(.?)(.*):(.*)/\2:\4:\5\1\3/;tm
s/://g
  • Inserisci i :marcatori all'inizio e alla fine della stringa di input
  • Mescola il primo carattere in :avanti e il secondo :indietro di un personaggio alla volta fino a quando i :segnalini sono su entrambi i lati del personaggio centrale
  • Rimuovi il primo :e aggiungine un altro :alla fine lasciando "A: B:", dove A è la stringa composta da caratteri dispari dall'input di testo e B è la stringa composta da caratteri pari
  • Riffleggia i caratteri di A e B insieme dopo l'ultimo :per riassemblare il testo in chiaro
  • Rimuovere i :marcatori rimanenti

2

JavaScript ES6, 41 + 49 = 90 byte

Codificatore

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

decoder

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

Queste sono funzioni anonime, quindi conto solo il codice tra parentesi perché è l'intera definizione della funzione. Provalo con il frammento di seguito: (modificato per utilizzare ES5)


Che ne dici di questo [t=>t.replace(/./g,(_,o)=>t[o*2%t.length]),t=>t.replace(/./g,(_,o)=>t[(1+(l=t.length))/2*o%l])]:? Lo usi come [...][0]('encode string')e [...][1]('decode string'). Non c'è niente da dire che questo non può essere fatto! E risparmi 1 byte.
Ismael Miguel,

Grazie, ma si dice che scriva 2 funzioni, e non penso che questo conterebbe.
NinjaBearMonkey il

Sono ancora 2 funzioni. Le regole non specificano nomi o modi per accedere alle funzioni. Dice solo che è necessario utilizzare 2 funzioni.
Ismael Miguel,

1
@IsmaelMiguel Ora che ci penso, penso che le funzioni anonime siano consentite da sole, quindi l'uso che mi fa risparmiare ancora più byte.
NinjaBearMonkey il

Sono contento che abbassi il conteggio dei byte.
Ismael Miguel,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.