introduction
Dans ce défi, vous allez résoudre des transformations diagonales Burrows-Wheeler. Voici un aperçu général de ce qu'est une transformation diagonale de Burrows-Wheeler. Pour encoder un message, vous devez d'abord garantir qu'il est de longueur impaire (c'est-à-dire 5, 7, 9, etc.). Ensuite, vous créez une grille, n
par n
, où n
est la longueur du message. La première ligne est le message d'origine. Chaque ligne après cela est la ligne au-dessus, mais décalée d'un caractère vers la gauche avec le premier caractère se déplaçant vers l'arrière. Par exemple:
Hello World
ello WorldH
llo WorldHe
lo WorldHel
o WorldHell
WorldHello
WorldHello
orldHello W
rldHello Wo
ldHello Wor
dHello Worl
Ensuite, vous prenez chaque lettre sur la diagonale NW à SE et la mettez dans une nouvelle chaîne:
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
Votre message encodé est HloWrdel ol
. Pour décoder, prenez d'abord la longueur du message codé, ajoutez 1 et divisez par 2. Appelons ce numéro x
. Maintenant que nous savons x
, en commençant par la première lettre, chaque lettre est x
après la dernière, en boucle. Par exemple:
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
Maintenant, réorganisez simplement les lettres dans le bon ordre pour les obtenir Hello World
!
Défi
Votre défi consiste à écrire soit deux programmes, des fonctions, soit un de chacun. Cependant, les deux doivent utiliser la même langue. Le premier programme acceptera une chaîne en entrée via STDIN, des arguments de programme ou des paramètres de fonction et la codera en utilisant cette méthode. Le deuxième programme acceptera une chaîne en entrée via STDIN, des arguments de programme ou des paramètres de fonction et la décodera en utilisant cette méthode.
Exigences
Premier programme / fonction
- Une entrée de chaîne unique à l'aide de l'une des méthodes répertoriées ci-dessus.
- Doit coder la chaîne en utilisant un style de transformation diagonale Burrows-Wheeler.
Deuxième programme / fonction
- Une entrée de chaîne unique à l'aide de l'une des méthodes répertoriées ci-dessus.
- Doit décoder la chaîne en utilisant un style de transformation diagonale Burrows-Wheeler.
Contraintes
- Vous ne pouvez pas utiliser de fonctions intégrées ou externes pour accomplir cette tâche.
- Les échappatoires standard ne sont pas autorisées.
- Les deux programmes / fonctions doivent être dans la même langue.
Notation
C'est le golf de code, donc le programme le plus court en octets gagne.
Si j'ai besoin d'ajouter plus d'informations, laissez un commentaire!
la source
Réponses:
CJam, (4 + 8 =) 12 octets
Programme d'encodage:
Essayez-le en ligne ici
Programme de décodage:
Essayez-le en ligne ici
Comment (ou plutôt pourquoi) ils fonctionnent :
La transformation Diagonal Burrows-Wheeler est essentiellement tous les autres caractères de la chaîne, avec un enroulement à la fin. Si nous traitons la chaîne comme une matrice 2D de 2 colonnes, cela revient simplement à prendre la transformation de la matrice. Exemple:
Est représenté comme matrice 2D comme
Maintenant, en le lisant simplement colonne par colonne, donnez:
Quelle est la transformation Burrows-Wheeler.
Le décodage est simplement inverse du processus, écrivez la chaîne comme une matrice 2D à 2 lignes et lisez les colonnes.
Expansion du code :
Encodeur:
Décodeur:
la source
Python 2, 61 octets
E
chiffre etD
déchiffre. Je ne compte pas leE=
etD=
pour le score.Le déchiffrement prend chaque
n
caractère autour, oùn
est la moitié de la longueur de la chaîne arrondie. La raison pour laquelle cette inversion est que2
etn
sont inverses modulo la longueur de la chaîne, donc prendre chaquen
th caractère inverse en prenant chaque2
nd.Si l'utilisation d'une seule fonction était autorisée, je pourrais faire 44 octets
Le chiffre quand
b
estFalse
et déchiffre quandb
estTrue
. L'expression1+len(x)**b>>b
est égale à[2,len(x)/2+1][b]
.la source
J, 10 + 10 = 20
(Les accolades environnantes ne sont pas prises en compte dans la partition car elles ne font pas partie de la définition de la fonction.)
Merci pour FUZxxl pour une amélioration de 3 octets.
Maintenant, il est bien montré que les deux fonctions sont inverses car la première prend des caractères aux positions définies par la liste
#|2*i.@#
et la deuxième fonction réorganise les caractères en utilisant la même liste que la commande.Essayez-le en ligne ici.
la source
{~#|2*i.@#
.Pyth - 5 + 11 = 16 octets
J'ai remarqué un motif! ~ Est-ce que la danse est heureuse ~ La transformation est juste vraiment en boucle à travers la corde en choisissant tous les autres éléments. Cela ne fonctionne que sur les impairs car sinon il n'obtiendrait jamais la moitié des éléments. Cela équivaut à faire tourner une matrice à 2 larges.
Encodeur:
Le découpage par étapes de Python ne fait pas de boucle, j'ai donc répété la chaîne.
Décodeur:
Encore une fois, pas d'enveloppement pour le découpage en tranches.
la source
GNU sed -r, (20 + 104 + 1) = 125
Le +1 supplémentaire dans le score correspond à l'option -r de sed. Des chaînes d'entrée de longueur impaire sont supposées.
Encodeur:
Décodeur:
Le décodeur utilise
:
un caractère marqueur temporaire, donc s'il apparaît dans la chaîne d'entrée, vous obtiendrez un comportement indéfini. Si la chaîne d'entrée est limitée aux 95 caractères ASCII, ces marqueurs peuvent être remplacés par quelque chose en dehors de la plage ASCII (par exemple BEL 0x7) pour résoudre ce problème.:
marqueurs au début et à la fin de la chaîne d'entrée:
vers l'avant et le deuxième:
vers l'arrière un caractère à la fois jusqu'à ce que les:
marqueurs soient de chaque côté du caractère du milieu:
et ajoutez un autre:
à la fin en laissant "A: B:", où A est la chaîne composée de caractères impairs de l'entrée en texte brut et B est la chaîne composée des caractères pairs:
pour réassembler l'entrée en texte brut:
marqueurs restantsla source
JavaScript ES6, 41 + 49 = 90 octets
Encodeur
Décodeur
Ce sont des fonctions anonymes, donc je ne compte que le code entre parenthèses car c'est la définition de la fonction entière. Essayez-le avec l'extrait ci-dessous: (modifié pour utiliser ES5)
Afficher l'extrait de code
la source
[t=>t.replace(/./g,(_,o)=>t[o*2%t.length]),t=>t.replace(/./g,(_,o)=>t[(1+(l=t.length))/2*o%l])]
:? Vous l'utilisez comme[...][0]('encode string')
et[...][1]('decode string')
. Rien ne dit que cela ne peut pas être fait! Et vous économisez 1 octet.