Écrire un encodeur de chiffrement VIC


18

Le chiffrement VIC est l'un des chiffrements pour crayons et papiers les plus compliqués jamais conçus. Utilisé dans les années 1950 par l'espion soviétique Reino Häyhänen, surnommé "VICTOR", son principe principal est la sécurité grâce à l'obscurcissement; un grand nombre de faux - fuyants.

Votre tâche consiste à écrire un programme ou une fonction qui prendra un message et le codera à l'aide du chiffrement VIC. J'ai également posté un défi de décodeur de chiffrement VIC ici . Si l'une des instructions suivantes n'est pas claire, n'hésitez pas à vous renseigner à leur sujet dans les commentaires. Les instructions sont adaptées de ce site .

Encodage du chiffrement VIC

Préparation

Vous aurez besoin de cinq entrées:

  • le message en clair
  • un mot-clé court ou une phrase contenant les lettres les plus courantes dans votre langue
  • une phrase clé, comme une citation ou une ligne d'une chanson (au moins 20 caractères)
  • une date (ou un autre nombre composé de six chiffres ou plus)
  • un numéro d'agent personnel

En pratique, ces quatre derniers doivent être convenus au préalable par l'expéditeur et le destinataire, y compris si le numéro d'agent de l'expéditeur ou du destinataire est utilisé pour le codage.

Mon exemple de message sera: We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.

Nous encoderons en anglais (bien que vous puissiez utiliser la langue et l'alphabet que vous préférez) et les lettres les plus courantes de l'alphabet anglais sont A, E, I, N, O, R, S, T. Je vais utiliser le mot-clé SENATORI.

Ma phrase clé est une citation de Richard Feynman: "Le premier principe est que vous ne devez pas vous tromper - et vous êtes la personne la plus facile à tromper."

Comme date, je vais utiliser le 31 juillet 2016 (dans le format 3172016), qui est le jour où j'ai écrit cette description.

Le numéro personnel que j'ai choisi est 9.

Résumé des étapes

  1. Dérivez les clés intermédiaires à utiliser dans les étapes suivantes.
  2. Construisez et appliquez le damier chevauchant.
  3. Construisez et appliquez la première table de transposition.
  4. Construisez et appliquez la deuxième table de transposition (interrompue).
  5. Finalisez le message en insérant le groupe d'indicateurs de message.

Sous-mécanismes

Deux autres choses à expliquer avant d'entrer dans le vif du sujet: les processus d'addition de chaîne et de séquentialisation.

L'addition de chaîne, également connue sous le nom de générateur de Fibonacci décalé, fonctionne en prenant une séquence de chiffres de départ, en ajoutant les deux premiers chiffres sans les transporter (les additionner ensuite mod 10) et en ajoutant le résultat à la fin. Par exemple:

79081
7 + 9 = 6

790816
9 + 0 = 9

7908169
0 + 8 = 8

79081698
8 + 1 = 9

790816989
1 + 6 = 7

7908169897
... and so on

La séquentialisation consiste essentiellement à prendre une séquence de lettres ou de chiffres et à les étiqueter par ordre alphabétique / numérique. Les doublons sont étiquetés de gauche à droite. Par exemple:

E X A M P L E
    0           # A
1   0       2   # Es
1   0     3 2   # L
1   0 4   3 2   # M
1   0 4 5 3 2   # P
1 6 0 4 5 3 2   # X

3  3  0  5  8  4  2  0  4  7  5  4  8  1
      0              1                     # 0s
      0              1                 2   # 1
      0           3  1                 2   # 2
4  5  0           3  1                 2   # 3s
4  5  0        6  3  1  7        8     2   # 4s
4  5  0  9     6  3  1  7    10  8     2   # 5s
4  5  0  9     6  3  1  7 11 10  8     2   # 7
4  5  0  9 12  6  3  1  7 11 10  8 13  2   # 8s

J'utilise l'indexation zéro ici, mais indexez comme vous le souhaitez.

1. Clés intermédiaires

Divisez les 20 premières lettres de la phrase clé en deux groupes de 10 et séquentiellement chacune individuellement, que nous appellerons S1et S2.

    THEFIRSTPR
S1: 8201357946

    INCIPLEIST
S2: 2603751489

Choisissez un identifiant de message aléatoire à 5 chiffres M(cela peut être l'une des entrées si vous préférez):

M = 47921

Soustraire, sans emprunter (soustraire mod 10), les cinq premiers chiffres de la date clé 3172016de M:

M      47921
date - 31720
     = 16201

Ajoutez le résultat jusqu'à ce que vous ayez dix chiffres:

1620178218

Ajoutez ces chiffres à S1, sans porter ou mod 10, pour obtenir G:

     1620178218
S1 + 8201357946
G  = 9821425154

Ci S2- dessus , écrivez la séquence 0123456789. Localisez chaque chiffre de Gdans la séquence 0123456789 et remplacez-le par le chiffre directement en dessous S2. Le résultat est T.

   0123456789
S2 2603751489

G  9821425154
T  9806705657

Utilisez l'ajout de chaîne pour passer Tà 60 chiffres.

9806705657

becomes

980670565778637511245490262369939288595822106344304316978734

Ces 50 derniers chiffres, en cinq rangées de dix chiffres chacune, forment le Ubloc.

T  9806705657
U  7863751124
   5490262369
   9392885958
   2210634430
   4316978734

Les deux derniers chiffres non égaux du Ubloc sont ajoutés individuellement au numéro personnel de l'agent pour donner les largeurs des deux transpositions, pet q.

9 + 3 = 12 (p, première largeur de transposition) 9 + 4 = 13 (q, deuxième largeur de transposition)

Séquentialiser Tet utiliser cette séquence pour copier au large des colonnes du Ubloc, de haut en bas, dans une nouvelle rangée de caractères, V.

T     9806705657
seqT  9804612537

U     7863751124
      5490262369
      9392885958
      2210634430
      4316978734

V     69911 56837 12548 26533 30206 13947 72869 49804 84323 75924

Séquentialisez les premiers pchiffres pour obtenir la clé de la première transposition K1et les qchiffres suivants pour la clé de la seconde K2.

First 12  6  9  9  1  1  5  6  8  3  7  1  2
K1        6 10 11  0  1  5  7  9  4  8  2  3

Next 13   5  4  8  2  6  5  3  3  3  0  2  0  6
K2        8  7 12  2 10  9  4  5  6  0  3  1 11

Enfin, séquentialisez la dernière ligne du Ubloc à obtenir C, les en-têtes de colonne pour le damier chevauchant:

U5  4316978734
C   3105968724

2. Damier chevauchant

Tout d'abord, je vais donner mon exemple de damier, puis expliquer les principes de sa création de cette manière:

  3 1 0 5 9 6 8 7 2 4
  S E N A T O R I
2 B D G J L P U W Y .
4 C F H K M Q V X Z #

La première ligne de lettres est notre court mot - clé SENATORI. Votre mot-clé peut être n'importe quelle chaîne sans doublons, mais comme il définit la ligne supérieure de votre damier, choisissez judicieusement. Au-dessus du mot-clé se trouve C, et les autres lignes sont le reste de votre alphabet dans l'ordre que vous choisissez. Dans mon cas, j'ai rempli le damier avec le reste de l'alphabet latin, un signe de ponctuation .et un signe de démarcation des nombres #. Essentiellement, le damier est un chiffrement de substitution sophistiqué. Par exemple, "E" sera remplacé par 1et "W" sera remplacé par 27.

Une fois que nous avons encodé notre message en clair avec ce damier, mais d'abord, nous devons rendre le début de notre message moins évident en le divisant à une position aléatoire et en le rendant tout en majuscules. Pour désigner l'autre début d'origine, nous utilisons deux arrêts complets..

We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.

devient

HING ELSE. MOVE TO SAFEHOUSE FOXTROT#3#.. WE ARE
DISCOVERED. TAKE WHAT YOU CAN. BURN EVERYT

Nous encodons avec le damier, nous donnant:

407020 1293124 496481 96 354114062831 416479869443442424 271 581 
2173436481812124 95451 274059 22628 435024 232880 14818229

Si la longueur du message n'est pas divisible par 5, nous ajoutons quelques caractères nuls pour compléter le message. Notre message comporte 109 chiffres, je vais donc ajouter un null: "4".

40702 01293 12449 64819 63541 14062 83141 64798 69443 44242 42715
81217 34364 81812 12495 45127 40592 26284 35024 23288 01481 82294

Remarque: Étant donné que mon exemple de message ne contient pas de chiffres, je dirai ici que vous pouvez désigner, disons, as #3#, qui est codé comme 44344ici.

3. Première transposition

Créez la table de transposition en écrivant K1(à partir de la section Clés intermédiaires) suivi du message codé de l'étape précédente, en lignes de même longueur, sous la clé:

K1   6 10 11  0  1  5  7  9  4  8  2  3

     4  0  7  0  2  0  1  2  9  3  1  2
     4  4  9  6  4  8  1  9  6  3  5  4
     1  1  4  0  6  2  8  3  1  4  1  6
     4  7  9  8  6  9  4  4  3  4  4  2
     4  2  4  2  7  1  5  8  1  2  1  7
     3  4  3  6  4  8  1  8  1  2  1  2
     4  9  5  4  5  1  2  7  4  0  5  9
     2  2  6  2  8  4  3  5  0  2  4  2
     3  2  8  8  0  1  4  8  1  8  2  2
     9  4

En prenant les colonnes numérotées dans l'ordre de leur nombre, nous obtenons:

060826428  246674580  151411542  246272922  961311401  082918141
4414434239 118451234  334422028  293488758  0417249224 794943568

4. Deuxième transposition

La première transposition a été relativement simple. Celui-ci, cependant, est une transposition perturbée. Le motif de perturbation est déterminé par la largeur de la table et de la clé. Dans notre exemple, nous avons 110 chiffres et 13 colonnes, ce qui signifie que nous aurons 8 lignes complètes et 6 restes. Nous commençons à remplir la première ligne, mais nous nous arrêtons à la colonne 0 et continuons comme suit:

K2   8  7 12  2 10  9  4  5  6  0  3  1 11

     0  6  0  8  2  6  4  2  8              stop at 0
     2  4  6  6  7  4  5  8  0  1           continue in a triangle pattern
     5  1  4  1  1  5  4  2  2  4  6
     2  7  2  9  2  2  9  6  1  3  1  1
     4  0  1  0  8  2  9  1  8  1  4  1  4  until the end
     4  1  4  4  3  4  2  3  9  1  1        restart and stop at 1
     8  4  5  1  2  3  4  3  3  4  4  2
     2  0  2  8  2  9  3  4  8  8  7  5  8
     0  4  1                                restart and stop at 2

Ensuite, nous remplissons les derniers espaces avec les chiffres restants.

K2   8  7 12  2 10  9  4  5  6  0  3  1 11

     0  6  0  8  2  6  4  2  8  7  2  4  9
     2  4  6  6  7  4  5  8  0  1  2  2  4
     5  1  4  1  1  5  4  2  2  4  6  7  9
     2  7  2  9  2  2  9  6  1  3  1  1  4
     4  0  1  0  8  2  9  1  8  1  4  1  4
     4  1  4  4  3  4  2  3  9  1  1  9  4
     8  4  5  1  2  3  4  3  3  4  4  2  3
     2  0  2  8  2  9  3  4  8  8  7  5  8
     0  4  1  5  6  8

Maintenant, nous lisons les colonnes exactement de la même manière que pour la première transposition.

71431148  42711925  861904185 22614147  45499243  28261334  80218938
641701404 025244820 645224398 271283226 94944438  064214521

Et divisez tout en groupes à 5 chiffres:

71431 14842 71192 58619 04185 22614 14745 49924 32826 13348 02189
38641 70140 40252 44820 64522 43982 71283 22694 94443 80642 14521

5. Finalisez le message

La dernière étape consiste à insérer notre identifiant de message aléatoire,, 47921dans le message lui-même. Le dernier chiffre de la date clé 6indique la distance que le groupe doit être de la fin.

71431 14842 71192 58619 04185 22614 14745 49924 32826 13348 02189 38641
70140 40252 44820 64522 43982 47921 71283 22694 94443 80642 14521

Notes pour ce défi

  • Vous disposez d'au moins cinq entrées: le message, le mot clé de la lettre, la phrase clé, la date et un numéro personnel. Vous pouvez inclure deux entrées supplémentaires: l'identificateur de message aléatoire et les valeurs nulles nécessaires pour remplir le message, ou votre fonction peut générer des nombres aléatoires d'elle-même.
  • Vous pouvez supposer que toutes les entrées sont valides, avec le nombre correct de chiffres et de lettres (identifiant de message à 5 chiffres, au moins 20 chiffres pour la phrase clé, etc.). Vous pouvez supposer que toutes les ponctuations et tous les espaces ont déjà été supprimés, à l'exception de ceux que vous autorisez dans votre version, et que les nombres sont déjà délimités par des signes numériques.
  • Le premier mot clé ne doit pas contenir de lettres en double, et dans votre code, vous pouvez supposer qu'il n'a jamais de lettres en double.
  • La langue que vous utilisez pour encoder n'a pas d'importance, tant que la langue est préexistante, l'alphabet est préexistant et que vous spécifiez la langue que vous utilisez dans votre réponse.
  • Quel que soit l'alphabet que vous employez pour votre damier chevauchant, vous pouvez ajouter ou supprimer des symboles pour remplir le damier. Spécifiez la raison pour laquelle vous utilisez ces symboles (par exemple, la ponctuation, un symbole distinct de «début de message», des symboles de mots courants). Vous pouvez renoncer entièrement au signe numérique et épeler les chiffres ou inclure chaque chiffre dans le damier, en utilisant la fente où le signe numérique était pour autre chose. Veuillez préciser quel damier vous avez utilisé dans votre réponse.
  • La sortie doit être soit une chaîne de groupes à cinq chiffres séparés par des espaces, une liste d'entiers à cinq chiffres, ou quelque chose de similaire.
  • J'ai utilisé l'indexation zéro et 0123456789dans mon exemple. Vous pouvez utiliser l'indexation 1 et 1234567890, ou un autre système dans votre réponse, tant que vous spécifiez ce que vous avez utilisé.

Voici un exemple d'implémentation sur Ideone .

Ceci est un long post et j'ai écrit la plupart à la main, donc s'il y a des parties confuses dans ce post ou des erreurs dans mon comptage et ma transposition, veuillez me le faire savoir. Bonne chance et bon golf!


1
adding the first two digits without addingVoulez-vous dire porter?
isaacg

@isaacg Oui, je l'ai fait. Édité.
Sherlock9

Pourriez-vous préciser ce que vous entendez par without borrowinget without carrying? Voulez-vous dire ajouter et soustraire le mod 10, c'est (6+7) mod 10 = 3-à- dire et (6-8) mod 10 = 8?
R. Kap

@ R.Kap Ouais, permettez-moi d'aller clarifier cela.
Sherlock9

Est - ce que nous avons à des numéros DeMarco?
R. Kap

Réponses:


10

Python 3 , 1423 1348 1324 1316 1300 1286 1250 1249 1209 1206 1204 octets

C'est certainement le plus long golf que j'ai jamais fait, et le seul golf où je craignais sérieusement de manquer de noms de variable à un caractère. Suggestions de golf bienvenues. Essayez-le en ligne!

J'encode avec l'alphabet latin majuscule avec des caractères supplémentaires .et #, en utilisant l'indexation 0 et 0123456789lors de la conversion gen t. Mon damier est dans un format similaire à l'exemple suivant:

  2 9 7 4 5 8 3 1 0 6    # C
  S E N A T O R I        # keyword
0 B D G J L P U W Y .    # remaining alphabet arranged in columns
6 C F H K M Q V X Z #    # . and # at the end

Edit: -63 octets grâce à la suggestion de TuukkaX de raccourcir certaines des fonctions fréquemment utilisées avec des variables à une lettre. -12 octets de rendre a, g, tplus compact.

Modifier: -24 octets de création en supprimant les noms de variables pour les clés intermédiaires qui ne sont utilisées qu'une seule fois, à savoir a, g, s, S, k, K.

Edit: -74 octets de consolidation H(), T() and C().

Edit: -1 octet merci à Nick A pour sa suggestion de changer ord(s[i])+ord(s[i+1])en sum(map(ord,s[i:i+2])). -2 octets de la modification de 2 +=[a]appels à +=a,. -13 octets de changer la façon dont a G()trouvé l'indice du minimum de s. -2 octets de passer y=(y+1)%và y=-~y%v. -15 octets d'affectation k.index()à K. -4 octets d'attribution 10à W. -5 octets d'affectation 1-I(d[-1])à l' Xintérieur V. -3 octets de C()la boucle principale de réécriture . -2 octets de réorganisation T().

I=int;L=list;E=len;R=range;B=str;J=''.join;W=10
def H(s,e):
 for i in R(e-E(s)):s+=chr(48+sum(map(ord,s[i:i+2]))%32%W)
 return s
def Q(s):
 r=[0]*E(s);s=L(s)
 for z in R(E(s)):b=s.index(min(s));r[b]=z;s[b]="~"
 return r
def T(x,k,d=0):
 u=E(x);v=E(k);g=R(v);K=k.index;n=u//v+1;w=[];e=r=y=0;i=K(y);c=[]
 if d:
  while r<n:
   if r>n-1:i=min(i,(u%v or v))
   w+=L(x[e:e+i]),;e+=i;i+=1;r+=1
   if i>v:y=-~y%v;i=K(y)
  r=y=0;i=v-K(y)
  while r<n:
   w[r]+=L(x[e:e+i]);e+=i;i-=1;r+=1
   if i<1:y+=1;i+=v-K(y);r+=1
  w[-1]+=['']*(v-E(w[-1]))
  for j in g:c+=J(z[j]for z in w),
 else:c=[x[i::v]for i in g]
 s=[0]*v
 for f in g:s[k[f]]=c[f]
 return J(s)
def C(m,s,w,n):
 t={".":s[-2:],"#":s[-1]*2};j=z=0
 for x in R(26):
  v=chr(x+65)
  if v in w:t[v]=s[w.index(v)]
  else:t[v]=s[z-2]+s[j];j+=z;z=-~z%2
 r=J(i.isdigit()and i or t[i]for i in m)
 return r+n[:-E(r)%5]
def V(m,w,P,d,A,M,n):X=1-I(d[-1]);t=J(B(Q(P[W:20])[I(J(B((I(H(J(B((I(M[i])-I(d[i]))%W)for i in R(5)),W)[i])+I(Q(P[:W])[i]))%W)for i in R(W))[i])])for i in R(W));u=H(t,60)[W:];p=A+I(u[-2]);v=T(u,Q(t));z=T(T(C(m,J(B(i)for i in Q(u[40:])),w,n),Q(v[:p])),Q(v[p:p+A+I(u[-1])]),1);e=[z[5*i:5*-~i]for i in R(-(-E(z)//5))];return' '.join(e[:X]+[M]+e[X:])

Ungolfing:

def chain_add(seq, end):
    for i in range(end - len(seq)):
        seq += chr(48+sum(map(ord,seq[i:i+2]))%32%10)
    return seq

def sequent(seq):
    res = [0]*len(seq)
    seq = list(seq)
    for z in range(len(seq)):
        b = seq.index(min(seq))
        res[b] = z
        seq[b] = "~"
    return res

def transpose(text, keys, disrupt=False):
    if disrupt:
        num_rows = len(text) // len(keys) + 1
        len_last = len(text) % len(keys)
        if len_last == 0:
            len_last = len(keys)
        d_rows = []
        text_index = 0
        current_row = 0
        stop_key = 0
        stop_index = keys.index(stop_key)
        while current_row < num_rows:
            if current_row > num_rows-1:
                stop_index = min(stop_index, len_last)
            d_rows += [list(text[text_index:text_index+stop_index])]
            text_index += stop_index
            stop_index += 1
            if stop_index>len(keys):
                stop_key = (stop_key+1) % len(keys)
                stop_index = keys.index(stop_key)
            current_row += 1
        current_row = 0
        stop_key = 0
        stop_len = len(keys) - keys.index(stop_key)
        while current_row < num_rows:
            d_rows[current_row] += list(text[text_index:text_index+stop_len])
            text_index += stop_len
            stop_len -= 1
            if stop_len < 1:
                stop_key += 1
                stop_len = len(keys) - keys.index(stop_key)
                current_row += 1
            current_row += 1
        d_rows[-1] += ['']*(len(keys)-len(d_rows[-1]))
        columns = []
        for j in range(len(keys)):
            columns += [''.join(i[j]for i in d_rows)]
    else:
        columns = ['']*len(keys)
        for t in range(len(text)):
            columns[t%len(keys)] += text[t]
    res = [0]*len(keys)
    for index in range(len(keys)):
        res[keys[index]] = columns[index]
    return''.join(res)

def checkerboard(message, seq, word, null):
    trans = {".":seq[-2:], "#":seq[-1]*2};res='';j=z=0
    for x in range(26):
        v = chr(x + 65)
        if v in word:
            trans[v] = seq[word.index(v)]
        else:
            trans[v] = seq[z-2] + seq[j]
            j += z
            z = (z+1) % 2
    for i in message:
        if i.isdigit():
            res += i
        else:
            res += trans[i]
    return res + null[:-len(res)%5]

def vic_cipher(message, keyword, phrase, date, agent, m_id, null):
    s1 = sequent(phrase[:10])
    s2 = sequent(phrase[10:20])
    a = ''.join(str((int(m_id[i])-int(date[i]))%10) for i in range(5))
    g = ''.join(str((int(a[i])+int(s1[i]))%10) for i in range(10))
    t = ''.join(str(s2[int(g[i])]) for i in range(10))
    u = chain_add(t,60)[10:]
    p = agent+int(u[-2])
    q = agent+int(u[-1])
    seqT = sequent(t)
    v = transpose(u,seqT)
    k1 = sequent(v[:p])
    k2 = sequent(v[p:p+q])
    c = ''.join(str(i)for i in sequent(u[40:]))
    x = checkerboard(message,c,keyword,null)
    y = transpose(x,k1)
    z = transpose(y,k2,1)
    e = [z[5*i:5*(i+1)] for i in range(-(-len(z)//5))]
    X = 1-int(date[-1])
    return ' '.join(e[:X] + [m_id] + e[X:])

2
Python 3 autorise les caractères Unicode comme variables, FYI.
Paul

Changer ord(seq[i])+ord(seq[i+1])pour sum(map(ord,seq[i:i+2]))sauver 1 personnage je crois.

3

C, 2880 2769 2766 2762 2743 2741 2739 2699 2458 octets

#include<stdio.h>
#define m(x)malloc(x)
#define Y(x)strlen(x)
typedef int i;typedef char*c;c _(c A,i B,i D){if(D>=B){return A;}c C=m(Y(A)+2);sprintf(C,"%s%c",A,48+(A[D]+A[D+1]-96)%10);return _(C,B,D+1);}c l(c A){i J=Y(A);c P=m(J+2);for(i m=0;m<J;m++){P[m]=32;}for(i v=0;v<J;v++){char G;i R;for(i u=0;u<J;u++){R=u<1|A[u]<G?u:R;G=u<1|A[u]<G?A[u]:G;}P[R]=48+v;c V=m(J);for(i t=0;t<J;t++){V[t]=t!=R?A[t]:97;}A=V;}return P;}c S(c C,c N,c I,char U){srand(time(NULL));i M=Y(I);i O=Y(N);i R=rand()%M;c Q=m(M+1);for(i u=R;u<M;u++){Q[u-R]=I[u];}Q[M-R]=46;for(i H=0;H<R;H++){Q[H+M-R+1]=I[H];}c g=m(28);c V=m(28);strcat(V,C);sprintf(g,"%s%s",N,"BCDFGHJKLMPQUVWXYZ.#");i B=Y(N);for(i q=B;q<10;q++){for(i x=0;x<10;x++){char J[2]={C[q],C[x]};V[B]=48+atoi(J);B++;}}c w=m(M*2+4);for(i J=0;J<=M;J++){i K=0;for(i X=0;X<28;X++){if(Q[J]==g[X]){char F[3];sprintf(F,"%d",V[X]-48);strcat(w,F);K=1;}}if(K<1){w[Y(w)]=Q[J];}}i f=Y(w);if(f%5>0){c P=m(5-f%5);for(i E=0;E<5-f%5;E++){P[E]=U;}strcat(w,P);}return w;}c a(c I,c U){i M=Y(I),K=Y(U);c T=m(M);i F=0;for(i b=0;b<K;b++){for(i y=0;y<K;y++){if(U[y]==48+b){for(i u=y;u<M;u+=K){T[F]=I[u];F++;}}}}return T;}c da(c I,c K){i e=Y(I),k=Y(K);c T=m(e);for(i y=0;y<e;y++){T[y]=32;}i F,P;F=P=0;for(i u=0;u<k;u++){for(i v=0;v<k;v++){T[F]=I[P];P++;F++;if(K[v+1]-48==u){for(i C=1;C<k-v;C++){F+=k-v-C;for(i E=0;E<=v+C;E++){if(F<e&P<e){T[F]=I[P];}F++;P++;}}break;}}if(F>e){break;}}i U=0;for(i g=0;g<e;g++){U=T[g]-48<10&-1<T[g]-48?U+1:U;}for(i j=U;j<e;j++){for(i x=0;x<e;x++){if(T[x]==32){T[x]=I[j];break;}}}return a(T,K);}En(c n,c m,c k,i d,c v,c s,char u){c S1,S2;S1=m(10);S2=m(10);for(i i=0;i<20;i++){if(i<10){S1[i]=k[i];}else{S2[i-10]=k[i];}}S1=l(S1);S2=l(S2);c M=m(5);for(i i=4;i>-1;i--){M[i]=48+(s[i]-v[i])%10;}c G=_(M,5,0);for(i y=0;y<10;y++){G[y]=48+(S1[y]+G[y]-96)%10;}c N="0123456789";c T=m(10);for(i q=0;q<10;q++){for(i t=0;t<10;t++){if(N[t]==G[q]){T[q]=S2[t];}}}c Z=_(T,50,0);c U=m(50);for(i h=0;h<50;h++){U[h]=Z[h+10];}i p,q;for(i b=49;b>10;b++){if(U[b]!=U[b-1]){q=d+U[b]-48;p=d+U[b-1]-48;break;}}c V=m(50);i Ct=0;for(i j=0;j<10;j++){for(i o=0;o<10;o++){if(l(T)[o]==48+j){for(i x=o;x<o+41;x+=10){V[Ct]=U[x];Ct+=1;}}}}c K1=m(p);c K2=m(q);for(i D=0;D<p+q;D++){if(D<p){K1[D]=V[D];}else{K2[D-p]=V[D];}}K1=l(K1);K2=l(K2);c C=m(10);for(i b=40;b<50;b++){C[b-40]=U[b];}C=l(C);c t=da(a(S(C,m,n,u),K1),K2);i O=0;for(i B=0;B<Y(t)/5+1;B++){if(B==Y(t)/5-v[Y(v)-1]+49){printf("%s ",s);}else{for(i J=O;J<O+5;J++){printf("%c",t[J]);}printf(" ");O+=5;}}}

Mon Dieu. C'est le programme le plus long que j'ai jamais eu au golf. C'est également le premier sur lequel j'ai en fait manqué de noms de variables à un seul caractère pour la portée globale et j'ai donc dû passer à l'utilisation de quelques caractères à 2 caractères (le fait que je ne peux apparemment pas redéclarer les variables n'aide pas). Les conseils de golf sont donc très appréciés.

Non golfé

Compile sans aucun avertissement, contrairement à la version golfée. Les modifications mineures apportées à la version golfée ne seront pas reflétées dans cette version non golfée.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

char*Chain_Add(char*String,int End,int Start){
  if(Start>=End){return String;}
  char*C=malloc(strlen(String)+2);
  sprintf(C,"%s%c",String,'0'+(((String[Start]-'0')+(String[Start+1]-'0'))%10));
  return Chain_Add(C,End,Start+1);
}

char*Sequent(char*String){
  int J=strlen(String);
  char*P=malloc(J+2);
  for(int m=0;m<J;m++){
    P[m]=' ';
  }
  for(int v=0;v<J;v++){
    char G;
    int R;
    for(int u=0;u<J;u++){
      R=(u<1||String[u]<G)?u:R;
      G=(u<1||String[u]<G)?String[u]:G;
    }
    P[R]='0'+v;
    char*V=malloc(J);
    for(int t=0;t<J;t++){
      if(t!=R){
    V[t]=String[t];
      }
      else{
    V[t]='a';
      }
    }
    String=V;
  }
  return P;
}

char*Straddling_Checkerboard(char*C,char*Key,char*Message,char null){
  srand(time(NULL));
  int Msg_Len=strlen(Message);
  int Key_Len=strlen(Key);
  int R=rand()%Msg_Len;
  char*Q=malloc(Msg_Len+1);
  for(int u=R;u<Msg_Len;u++){
    Q[u-R]=Message[u];
  }
  Q[Msg_Len-R]='.';
  for(int H=0;H<R;H++){
    Q[H+Msg_Len-R+1]=Message[H];
  }
  char*Alphabet=malloc(26);
  for(int W=0;W<26;W++){
    Alphabet[W]='A'+W;
  }
  int q=0;
  char*e=malloc(Key_Len);
  for(int z=0;z<Key_Len;z++){
    if(strchr(e,Key[z])!=NULL){
      q++;
    }
    else{
      e[z-q]=Key[z];
    }
  }
  int r=0;
  for(int h=0;h<26;h++){
    if(strchr(e,Alphabet[h-r])!=NULL){
      for(int X=h-r;X<26;X++){
    Alphabet[X]=Alphabet[X+1];
      }
      r++;
    }
  }
  char*Checkerboard=malloc(28);
  for(int i=0;i<26;i++){
    if(i<strlen(e)){
      Checkerboard[i]=e[i];
    }
    else{
      Checkerboard[i]=Alphabet[i-strlen(e)];
    }
  }
  Checkerboard[26]='.';
  Checkerboard[27]='#';
  char*Values=malloc(28);
  strcat(Values,C);
  int B=strlen(e);
  for(int q=B;q<10;q++){
    for(int x=0;x<10;x++){
      char J[2]={C[q],C[x]};
      Values[B]='0'+atoi(J);
      B++;
    }
  }
  char*Encoded=malloc(Msg_Len*2+4);
  for(int J=0;J<=Msg_Len;J++){
    int K=0;
    for(int X=0;X<28;X++){
      if(Q[J]==Checkerboard[X]){
    char F[3];
    sprintf(F,"%d",Values[X]-'0');
    strcat(Encoded,F);
    //printf("F = %s while Q[J] = %c and Checkerboard[X] = %c and Encoded = %s\n",F,Q[J],Checkerboard[X],Encoded);
    K=1;
      } 
    }
    if(K<1){
      Encoded[strlen(Encoded)]=Q[J];
    }
  }
  int Encded_Len=strlen(Encoded);
  if(Encded_Len%5>0){
    char*P=malloc(5-Encded_Len%5);
    for(int E=0;E<5-Encded_Len%5;E++){
      P[E]=null;
    }
  strcat(Encoded,P);
  }
  return Encoded;
}

char*Transpose(char*Message,char*K1){
  int Msg_Len=strlen(Message),K1_Len=strlen(K1);
  char*T=malloc(Msg_Len);
  int F=0;
  for(int i=0;i<K1_Len;i++){
    for(int y=0;y<K1_Len;y++){
      if(K1[y]=='0'+i){
    for(int u=y;u<Msg_Len;u+=K1_Len){
      T[F]=Message[u];
      F++;
    }
      }
    }
  }
  return T;
}

char*Disrupted_Transpose(char*Message,char*K2){
  int Msg_Len=strlen(Message),K2_Len=strlen(K2);
  char*T=malloc(Msg_Len);
  for(int y=0;y<Msg_Len;y++){
    T[y]=' ';
  }
  int F=0;
  int P=0;
  for(int u=0;u<K2_Len;u++){
    for(int v=0;v<K2_Len;v++){
      T[F]=Message[P];
      P++;F++;
      if(K2[v+1]-'0'==u){
        for(int C=1;C<K2_Len-v;C++){
      F+=K2_Len-v-C;
      for(int E=0;E<=v+C;E++){
        if(F<Msg_Len&P<Msg_Len){
          T[F]=Message[P];
        }
        F++;P++;
      }
    }
    break;
      }
    }
    if(F>Msg_Len){
      break;
    }
  }
  int U=0;
  for(int g=0;g<Msg_Len;g++){
    U=(T[g]-'0'<10&-1<T[g]-'0')?U+1:U;
  }
  for(int j=U;j<Msg_Len;j++){
    for(int x=0;x<Msg_Len;x++){
      if(T[x]==' '){
    T[x]=Message[j];
    break;
      }
    }
  }
  return Transpose(T,K2);
}

void VIC_Encoder(char*Message,char*Phrase,char*Key,int a_id,char*date,char*m_id,char null){
  char*S1=malloc(10);
  char*S2=malloc(10);
  for(int i=0;i<20;i++){
    if(i<10){
      S1[i]=Key[i];
    }
    else{
      S2[i-10]=Key[i];
    }
  }
  S1=Sequent(S1);
  S2=Sequent(S2);
  char*M=malloc(5);
  for(int i=4;i>-1;i--){
    M[i]='0'+(((m_id[i]-'0')-(date[i]-'0'))%10);
  }
  char*G=Chain_Add(M,5,0);
  for(int y=0;y<10;y++){
    G[y]='0'+(((S1[y]-'0')+(G[y]-'0'))%10);
  }
  char*N="0123456789";
  char*T=malloc(10);
  for(int q=0;q<10;q++){
    for(int t=0;t<10;t++){
      if(N[t]==G[q]){
    T[q]=S2[t];
      }
    }
  }
  char*Z=Chain_Add(T,50,0);
  char*U=malloc(50);
  for(int h=0;h<50;h++){
    U[h]=Z[h+10];
  }
  int p,q;
  for(int b=49;b>10;b++){
    if(U[b]!=U[b-1]){
      q=a_id+(U[b]-'0');
      p=a_id+(U[b-1]-'0');
      break;
    }
  }
  char*seqT=Sequent(T);
  char*V=malloc(50);
  int Count=0;
  for(int j=0;j<10;j++){
    for(int o=0;o<10;o++){
      if(seqT[o]=='0'+j){
    for(int x=o;x<o+41;x+=10){
      V[Count]=U[x];
      Count+=1;
    }
      }
    }
  }
  char*K1=malloc(p);
  char*K2=malloc(q);
  for(int D=0;D<p+q;D++){
    if(D<p){
      K1[D]=V[D];
    }
    else{
      K2[D-p]=V[D];
    }
  }
  K1=Sequent(K1);
  K2=Sequent(K2);
  char*C=malloc(10);
  for(int b=40;b<50;b++){
    C[b-40]=U[b];
  }
  C=Sequent(C);
  char*Transposed_2=Disrupted_Transpose(Transpose(Straddling_Checkerboard(C,Phrase,Message,null),K1),K2);
  int O=0;
  for(int B=0;B<strlen(Transposed_2)/5+1;B++){
    if(B==strlen(Transposed_2)/5-date[strlen(date)-1]+'1'){
      printf("%s ",m_id);
    }
    else{
      for(int J=O;J<O+5;J++){
    printf("%c",Transposed_2[J]);
      }
      printf(" ");
      O+=5;
    }
  }
}

Remarques

  • Cela utilise un damier semblable au suivant pour coder le message:

      3 4 5 6 2 3 4 5 6 7
      S E N A T O R I     
    6 B C D F G H J K L M 
    7 P Q U V W X Y Z . #
    
  • Cela suppose que toutes les chaînes applicables sont données en majuscules. Le message doit également avoir toute la ponctuation sauf les périodes supprimées et tous les nombres délimités par# s, tandis que la phrase clé doit avoir supprimé toute la ponctuation.

  • Le message codé résultant est envoyé à STDOUT sous la forme d'une chaîne de groupes à cinq chiffres séparés par des espaces.

  • Le message d'entrée doit être en anglais.

  • J'aurais combiné quelques-unes des fonctions que j'ai utilisées, mais je devrais alors recourir à plus de noms de variables à deux lettres, ce qui rend le programme final plus long qu'il ne le serait avec quelques fonctions supplémentaires.

  • Actuellement, cela ne suppose pas que le mot-clé (au moins en anglais) contiendra toujours le même ensemble de lettres, et compense donc cela en supprimant les doublons, en manipulant le damier, etc. Cette capacité n'est apparemment pas requise par OP, donc je joue actuellement sur les octets supplémentaires inutiles qui prennent. Mis à jour pour la version golfée.


2

JavaScript (ES6), 946 938 953 octets

V=(c,d,f,g,j,k,m)=>{S=a=>a.split``,J=a=>a.join``,A=(a,b)=>{for(i=0;a[L="length"]<b;a+=(a[i++]- -a[i])%h);return a},Q=b=>(a=S(b).sort(),S(b).map(b=>a[i=a[X="indexOf"](b)]=i)),u=A(t=J(S(A(J(S(k).map((a,b)=>Math.abs(a-g[b]))),h=10)).map((a,b)=>Q(f[C="slice"](h,20))[(Q(f[C](0,h))[b]- -a)%h])),60)[C](h),T=((a,b,c)=>{if(r=Array(l=b[L]).fill(""),c){for(e=a[L]/l,i=0,w=[],u=R=b[X](x=0);i<e;)w[i++]=a[P](0,R++),u?u=0:R>l||(R=b[X](u=++x));for(i=0;i<e;)w[i]=J(w[i].concat(a[P](0,l-w[i++][L])));a=J(w)}for(i in a)r[+b[i%l]]+=a[i];return r}),v=J(T(u,Q(t))),q=J(Q(u[C](-h))),t="ABCDEFGHIJKLMNOPQRSTUVWXYZ#".match(new RegExp("[^"+d+"]","g")),t[P="splice"](9,0,"."),M=[];for(i in t)M[t[i]]=q[8^i/h]+(M[d[i]]=q[i%h]);for(n=c[L],b=J((c[C](n-=new Date%n)+"."+c[C](0,n)).split(/ |/).map(a=>M[a]||a)),b+=m.repeat(5-b[L]%5),i=f=q=49;f==q;)f=+u[i-1]+j,q=+u[i++]+j;return t=J(T(S(J(T(b,Q(v[C](0,f))))),Q(v.substr(f,q)),1)).match(/.{5}/g),g=-g[C](-1),g++&&t[P](g||t[L],0,k),t}

J'ai vu au cours du week-end qu'il n'y avait pas encore d'entrée JS pour cela, alors voici ma tentative (de dernière minute). Mettre en œuvre et jouer au golf était aussi fou que amusant!

Extrait de démonstration

Modifier: -8 octets

Réalisé qu'il y avait des parenthèses supplémentaires autour de la fonction S,J,A,Q

Modifier: +15 octets

Mise à jour de la logique de la façon dont le message idest placé dans le message final (désormais indexé 1 et 0 ne l'inclut pas dans la sortie).

Non golfé

chainAdd = (s,l)=>{for(i=0;s.length<l;s+=(s[i++]- -s[i])%10);return s;}

sequentialize = (s)=> {
    a=s.split('').sort();
    return s.split('').map(c=>(i=a.indexOf(c),a[i]='',i));  
}

transpose = (s,k,disruptive)=>{
    var result=Array(k.length).fill('')
    if(disruptive){
        rows=[]
        k_index=0;
        rowLength=k.indexOf(k_index);
        triangling=!rowLength;

        expectedRows = s.length/k.length
        for(row=0;row<expectedRows;row++){
            rows[row]=s.splice(0,rowLength++)
            if(triangling){     
                if(rowLength>k.length){
                    triangling=false;
                    rowLength=k.indexOf(++k_index)              
                }
            }
            else{               
                triangling=true;
            }
        }

        for(row=0;row<expectedRows;row++){
            rows[row]= rows[row].concat(s.splice(0,k.length-rows[row].length)).join('')
        }
        s=rows.join('')
    }
    for(i in s)
        result[+k[i%k.length]]+=s[i];   
    return result;
}

checkerboard =(message,seq, keyword, nulls)=>{  
    t='ABCDEFGHIJKLMNOPQRSTUVWXYZ#'.match(new RegExp('[^'+keyword+']','g'));
    t.splice(9,0,'.')

    map=[]
    for(i in t)
        map[t[i]]=(seq[8^(i/10)])+(map[keyword[i]]=seq[i%10])

    r = new Date%message.length;
    rotateMessage=message.substr(message.length-r)+'.'+message.substr(0,message.length-r)

    result =rotateMessage.split(/ |/).map(x=>map[x]||x).join('');
    result+=nulls.repeat(5-result.length%5)

    return result;
}

vic = (message, keyword, phrase, date, agent, m_id, nulls)=>{
    s1=sequentialize(phrase.substr(0,10))//.join('')
    s2=sequentialize(phrase.substr(10,10))//.join('')

    r = m_id.split('').map((x,i)=>Math.abs(x-date[i])).join('')
    g = chainAdd(r,10).split('').map((x,i)=>(s1[i]- -x)%10);

    t = g.map(i=>s2[+i]).join('');
    u=chainAdd(t,60).substr(10)

    var p,q;
    for(i=49;p==q;i++){
        p=agent + +u[i-1];
        q=agent + +u[i];
    }
    seqT = sequentialize(t);
    v=transpose(u,seqT).join('');

    k1 = sequentialize(v.substr(0,p));
    k2 = sequentialize(v.substr(p,q));
    c  = sequentialize(u.substr(-10)).join('')

    CB =checkerboard(message,c, keyword, nulls);
    t1=transpose(CB,k1).join('')
    t2=transpose(t1.split(''),k2,1).join('').match(/.{5}/g);
    (d=-date.substr(-1))&&t2.splice((d+1)||t2.length,0,m_id);
    return t2;
}

Remarques

  • Cela utilise un damier semblable au suivant pour coder le message:

      3 1 0 5 9 6 8 7 2 4
      S E N A T O R I
    2 B C D F G H J K L .
    4 M P Q U V W X Y Z #
    
  • Toutes les chaînes sont données en majuscules. Le message est en latin alphanumérique (plus .et #) et doit avoir supprimé toute ponctuation (sauf les points). Tous les numéros doivent déjà être marqués de l' #art. La phrase clé doit avoir supprimé tous les signes de ponctuation / espaces.

  • Le message résultant est renvoyé sous la forme d'un tableau de chaînes à 5 chiffres.

Améliorations

  • J'ai l'impression qu'il existe un moyen d'abuser des "Toutes les langues" pour économiser quelques octets. Si j'avais plus de temps, je refigurerais cela pour supposer que la langue était quelque chose comme le hawaïen qui n'a que 12 lettres.

  • Toutes les suggestions de golf sont toujours les bienvenues.


Pourriez-vous s'il vous plaît ajouter un extrait afin que je puisse vérifier que cela fonctionne? Si c'est le cas, je peux vous accorder la prime.
R. Kap

@ R.Kap Bien sûr, j'ai ajouté un extrait de démo
SLuck49

Hmm ... dans la démo, le message identifiersemble être 7loin de la fin au lieu de 6. De plus, dans votre version non golfée, la même chose Idsemble être 6loin du début plutôt que de la fin.
R. Kap

@ R.Kap Ouais il y avait un bug quand je l'ai posté pour la première fois (ne doit pas l'avoir corrigé dans le non-golfé). En ce qui concerne le golf, j'ai supposé qu'il était indexé 0 car sinon, si cela 1signifie la toute fin, où diriez-vous que le message identifierdevrait aller sur un 0? Je peux le changer, j'ai juste besoin de le savoir.
SLuck49

Je dirais que sur 0la message identifierdevrait être exclue de la sortie.
R. Kap du

1

Clojure, 1197 1212 octets

Ough, je suis épuisé.

Mise à jour: ajout de l'emplacement de fractionnement aléatoire requis du message, la version non golfée utilise le même emplacement que l'exemple donné afin que l'algorithme puisse être facilement vérifié.

(defn enc[I K E D Y M](let[P split-at A concat Z zipmap R partition W mapcat % count X repeat O vector / map x(fn[C](apply / O C))G range t 10 r(G t)m(fn[i](mod i t))F(fn[[n & N]](/ last(iterate(fn[[[b & N]a]][(A N[(m(+ a b))])b])[N n])))Q(fn[S](for[i(G(% S))a[(nth S i)]](apply +(%(filter #{a}(take i S)))(for[b S :when(pos?(compare a b))]1))))[S J](/ Q(P t(take 20 E)))T(/(Z r J)(/ m(/ + S(F(/ - M D)))))U(take 50(drop t(F T)))l(last U)p(+ Y(last(remove #{l}U)))V(W(Z(Q T)(x(R t U)))r)[k j](/ Q(P p(take(+ p Y l)V)))B(into(Z(/ char(G 48 58))(G))(/(fn[i c][c(+(*(quot i 10)20)(nth(Q(reverse(take t(reverse U))))(m i)))])(G)(A(str K",,")(remove(set K)(/ char(A(G 65 91)".#"))))))?(% k)T(vec(filter some?(W(Z k(x(R ?(A(flatten(R 5(A(W str(/ B(let[[b e](P(rand-int(count I))I)](apply str(A e".. "b)))))(X 4(B\,)))))(X(dec ?)nil)))))(G ?))))w (% j)NR(+(quot(% T)w)1)L(flatten(for[k r](for[i(G(.indexOf j k)(inc w))](G i))))C(for[[r c](/ O(rest(reductions + -1(/(fn[i](get{0 1}i 0))L)))L):when(< r NR)][r c])H(R 5(filter some?(W(Z j(x(R w (A(vals(into(sorted-map)(/ O(A C(for[i(G NR)j(G w)c[[i j]]:when(not((set C)c))]c))T)))(X(dec w)nil)))))(G w))))](/(fn[p](apply str p))(let[[b e](P(-(% H)(D 6)-1)H)](A b[M]e)))))

Exemples d'entrées et scénario de test:

(def mymsg (clojure.string/upper-case "We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot#3#"))
(def mykey "SENATORI")
(def mypharase (clojure.string/upper-case (apply str (remove #{\space} "The first principle is that you must not fool yourself — and you are the easiest person to fool."))))
(def mydate [3 1 7 2 0 1 6])
(def mynum 9)
(def M [4 7 9 2 1])

;("61231" "12824" "71192" "58609" "92185" "48612" "14927" "22944" "34046" "13348" "04159" "38645" "70546" "20254" "22026" "64584" "21904" "47921" "90253" "42694" "42221" "56644" "14541")
(enc mymsg mykey mypharase mydate mynum M)

Non golfé:

(defn enc[mymsg mykey mypharase mydate mynum M]
  (let[t       10
       r       (range t)
       m       (fn[i](mod i t))
       lagfib  (fn[[n & N]](map last(iterate(fn[[[b & N]a]][(concat N[(m(+ a b))])b])[N n])))
       toseq   (fn[S](for[i(range(count S))a[(nth S i)]](apply +(count(filter #{a}(take i S)))(for[b S :when(pos?(compare a b))]1))))
       [S1 S2] (map toseq(split-at t(take 20 mypharase)))
       M2      (take t(lagfib(map - M mydate)))
       G       (map m(map + S1 M2))
       Gmap    (zipmap r S2)
       T       (map Gmap G)
       U       (take 50(drop t(lagfib T)))
       L2      (last U)
       L1      (last(remove #{L2}U))
       p       (+ mynum L1)
       q       (+ mynum L2)
       seqT    (toseq T)
       V       (mapcat(zipmap seqT(apply map vector(partition t U)))r)
       [K1 K2] (map toseq(split-at p(take(+ p q)V)))
       C       (toseq(reverse(take t(reverse U))))
       B       (into(zipmap(map char(range 48 58))(range))(map(fn[i c][c(+(*(quot i 10)20)(nth C(m i)))])(range)(concat(str mykey",,")(remove(set mykey)(map char(concat(range 65 91)".#"))))))
      ;B       (into(zipmap(map char(range 48 58))(range))(map(fn[i c][c(+(nth C(quot i 3))(*(mod i 3)20))])(range)(flatten(apply map vector(partition 10(apply concat mykey",,"(apply map vector (partition 2(remove(set mykey)(map char(concat(range 65 91)".#")))))))))))
       N1      (count K1)
       mymsg   (flatten(partition 5(concat(mapcat str(map B(let[[b e](split-at 49 mymsg)](apply str(concat e".. "b)))))(repeat 4(B\,)))))
       T1      (vec(filter some?(mapcat(zipmap K1(apply map vector(partition N1(concat mymsg(repeat(dec N1)nil)))))(range N1))))
       N2      (count K2)
       NR      (+(quot(count T1)N2)1)
       cols    (flatten(for[k r](for[i(range(.indexOf K2 k)(+(count K2)1))](range i))))
       rows    (rest(reductions + -1(map(fn[i](get{0 1}i 0))cols)))
       coords  (for[[r c](map vector rows cols):when(< r NR)][r c])
       coords  (concat coords(for[i(range NR)j(range N2)c[[i j]]:when(not((set coords)c))]c))
       T2      (partition 5(filter some?(mapcat(zipmap K2(apply map vector(partition N2(concat(vals(into(sorted-map)(map vector coords T1)))(repeat(dec N2)nil)))))(range N2))))]
    (map(fn[p](apply str p))(let[[b e](split-at(-(count T2)(mydate 6)-1)T2)](concat b[M]e)))))

Il a une implémentation alternative sur le damier Bqui est la même que sur la définition de la tâche. Mais la soumission en utilise une autre dans laquelle les alphabets inutilisés remplissent d'abord la 2e ligne, puis la 3e au lieu de remplir colonne par colonne.


Envisagé d'écrire une solution Clojure, mais ma tête a explosé pendant que je lisais la question. Combien de temps cela a-t-il pris pour écrire?
Carcigenicate

Peut-être 3 heures en regardant Youtube sur le côté. Cela a commencé assez facilement mais j'étais sur le point d'abandonner quand j'ai dû mettre en œuvre la deuxième "transposition interrompue". Maintenant, cela coordsest généré deux fois, générant d'abord la forme triangulaire, puis remplissant toutes les coordonnées manquantes. «Remplissage à la longueur de la multiplication de N» pourrait également avoir une solution plus élégante que la concaténation des éléments N-1 et le partitionnement aux longueurs de N.
NikoNyrh

Oh putain, j'ai oublié de changer le point de partage codé en dur (split-at 49 mymsg), 49 devrait être quelque chose comme (rand-int(count mymsg))si la bonne réponse serait un peu plus de 1200 octets. zzz
NikoNyrh

Zut. Probablement encore moins que la réponse c.
Carcigenicate
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.