Escreva um codificador de codificação VIC

18

A cifra VIC é uma das mais complicadas cifras de lápis e papel já criadas. Utilizado na década de 1950 pelo espião soviético Reino Häyhänen, codinome "VICTOR", seu principal princípio é a segurança através da ofuscação; um monte de confusão.

Sua tarefa é escrever um programa ou função que receba uma mensagem e a codifique usando a cifra VIC. Também publiquei um desafio do decodificador de codificação VIC aqui . Se alguma das seguintes instruções não for clara, não hesite em perguntar sobre elas nos comentários. As instruções são adaptadas deste site .

Codificando a codificação VIC

Preparação

Você precisará de cinco entradas:

  • a mensagem de texto sem formatação
  • uma palavra-chave ou frase curta que contém as letras mais comuns no seu idioma
  • uma frase-chave, como uma citação ou uma linha de uma música (pelo menos 20 caracteres)
  • uma data (ou outro número com seis dígitos ou mais)
  • um número de agente pessoal

Na prática, esses quatro últimos devem ser previamente acordados entre o remetente e o destinatário, incluindo se o número de agente do remetente ou do destinatário é usado na codificação.

Meu exemplo de mensagem será: We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.

Codificaremos em inglês (embora você possa usar o idioma e o alfabeto de sua preferência) e as letras mais comuns do alfabeto em inglês A, E, I, N, O, R, S, T. Vou usar a palavra-chave SENATORI.

Minha frase-chave é uma citação de Richard Feynman: "O primeiro princípio é que você não deve se enganar - e você é a pessoa mais fácil de se enganar".

Como data, usarei 31 de julho de 2016 (no formato 3172016), que é o dia em que escrevi essa descrição.

O número pessoal que eu escolhi para mim é 9.

Resumo das etapas

  1. Derive as chaves intermediárias para usar nas etapas a seguir.
  2. Construa e aplique o tabuleiro de damas abrangido.
  3. Construa e aplique a primeira tabela de transposição.
  4. Construa e aplique a segunda tabela de transposição (interrompida).
  5. Finalize a mensagem inserindo o grupo de indicadores de mensagens.

Submecanismos

Mais duas coisas a explicar antes de entrarmos na questão: os processos de adição e seqüencialização de cadeias.

A adição de cadeia, também conhecida como gerador de Fibonacci defasado, funciona tomando uma sequência de dígitos inicial, adicionando os dois primeiros dígitos sem carregar (adicione-os juntos mod 10) e anexando o resultado ao final. Por exemplo:

79081
7 + 9 = 6

790816
9 + 0 = 9

7908169
0 + 8 = 8

79081698
8 + 1 = 9

790816989
1 + 6 = 7

7908169897
... and so on

Seqüencializar é essencialmente pegar uma sequência de letras ou dígitos e rotulá-los por ordem alfabética / numérica. As duplicatas são rotuladas da esquerda para a direita. Por exemplo:

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

Eu uso a indexação zero aqui, mas indexe como quiser.

1. Teclas intermediárias

Divida as primeiras 20 letras da frase-chave em dois grupos de 10 e sequencie cada uma individualmente, que chamaremos de S1e S2.

    THEFIRSTPR
S1: 8201357946

    INCIPLEIST
S2: 2603751489

Escolha um identificador de mensagem aleatório de 5 dígitos M(pode ser uma das entradas, se você preferir):

M = 47921

Subtraia, sem emprestar (subtraia mod 10), os cinco primeiros dígitos da data fixada 3172016de M:

M      47921
date - 31720
     = 16201

Cadeia adicione o resultado até você ter dez dígitos:

1620178218

Adicione esses dígitos a S1, sem carregar ou mod 10, para obter G:

     1620178218
S1 + 8201357946
G  = 9821425154

Acima S2, escreva a sequência 0123456789. Localize cada dígito Gna sequência 0123456789 e substitua-o pelo dígito diretamente abaixo dele em S2. O resultado é T.

   0123456789
S2 2603751489

G  9821425154
T  9806705657

Use a adição de cadeia para expandir Tpara 60 dígitos.

9806705657

becomes

980670565778637511245490262369939288595822106344304316978734

Esses últimos 50 dígitos, em cinco linhas de dez dígitos cada, formam o Ubloco.

T  9806705657
U  7863751124
   5490262369
   9392885958
   2210634430
   4316978734

Os dois últimos dígitos não iguais do Ubloco são adicionados individualmente ao número pessoal do agente para fornecer as larguras das duas transposições, pe q.

9 + 3 = 12 (p, primeira largura de transposição) 9 + 4 = 13 (q, segunda largura de transposição)

Seqüencialize Te use essa sequência para copiar as colunas do Ubloco, de cima para baixo, em uma nova linha de dígitos V,.

T     9806705657
seqT  9804612537

U     7863751124
      5490262369
      9392885958
      2210634430
      4316978734

V     69911 56837 12548 26533 30206 13947 72869 49804 84323 75924

Seqüencialize os primeiros pdígitos para obter a tecla para a primeira transposição K1e os qdígitos seguintes para a tecla para o segundo 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

Por fim, sequencialmente, a linha final do Ubloco a ser obtida C, os cabeçalhos das colunas do tabuleiro de damas abrangido:

U5  4316978734
C   3105968724

2. Quadriculado

Primeiro, darei meu exemplo de tabuleiro de xadrez e depois explicarei os princípios para criá-lo dessa maneira:

  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 #

A primeira linha de letras é a nossa palavra-chave curta SENATORI. Sua palavra-chave pode ser qualquer sequência sem duplicatas, mas como define a linha superior do tabuleiro de damas, escolha sabiamente. Acima da palavra-chave está C, e as outras linhas estão no restante do alfabeto, na ordem que você escolher. No meu caso, preenchi o tabuleiro de damas com o restante do alfabeto latino, um sinal de pontuação .e um sinal de demarcação de números #. Essencialmente, o tabuleiro de damas é uma cifra de substituição sofisticada. Por exemplo, "E" será substituído por 1e "W" será substituído por 27.

Depois de codificarmos nossa mensagem em texto sem formatação com esse tabuleiro de damas, mas primeiro, precisamos tornar o início de nossa mensagem menos óbvio dividindo-o em uma posição aleatória e deixando tudo em maiúsculas. Para indicar o outro começo original, usamos dois pontos completos..

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

torna-se

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

Codificamos com o tabuleiro de damas, dando-nos:

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

Se o comprimento da mensagem não for divisível por 5, adicionamos alguns caracteres nulos para preencher a mensagem. Nossa mensagem tem 109 dígitos, então adicionarei um nulo: "4".

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

Nota: Como meu exemplo de mensagem não contém números, direi aqui que você pode designar, digamos, como #3#, que é codificado como 44344aqui.

3. Primeira transposição

Crie a tabela de transposição escrevendo K1(na seção Chaves Intermediárias), seguido pela mensagem codificada da etapa anterior, em linhas do mesmo comprimento, abaixo da chave:

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

Tomando as colunas numeradas na ordem de seus números, obtemos:

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

4. Segunda transposição

A primeira transposição foi relativamente simples. Este, no entanto, é uma transposição interrompida. O padrão de interrupção é determinado pela largura da tabela e da chave. No nosso exemplo, temos 110 dígitos e 13 colunas, o que significa que teremos 8 linhas completas e 6 sobras. Começamos a preencher a primeira linha, mas paramos na coluna 0 e continuamos da seguinte forma:

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

Em seguida, preenchemos os últimos espaços com os dígitos restantes.

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

Agora, lemos as colunas exatamente da mesma maneira que fizemos na primeira transposição.

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

E divida tudo em grupos de 5 dígitos:

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

5. Finalize a mensagem

A etapa final é inserir nosso identificador de mensagem aleatória,, 47921na própria mensagem. O dígito final da data fixada 6indica a distância que o grupo deve estar do final.

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

Notas para este desafio

  • Você recebe um mínimo de cinco entradas: a mensagem, a palavra-chave da letra, a frase-chave, a data e um número pessoal. Você pode incluir duas entradas adicionais: o identificador de mensagem aleatória e os nulos necessários para preencher a mensagem ou sua função pode gerar alguns números aleatórios por si só.
  • Você pode assumir que todas as entradas são válidas, com o número correto de dígitos e letras (identificador de mensagem de 5 dígitos, pelo menos 20 dígitos para a frase-chave e assim por diante). Você pode presumir que suas strings (a mensagem e as palavras-chave) já tiveram toda a pontuação e os espaços removidos, exceto aqueles que você permite na sua versão e que os números já estão demarcados com sinais numéricos.
  • A primeira palavra-chave não deve conter letras duplicadas e, no seu código, você pode supor que nunca tenha letras duplicadas.
  • O idioma que você usa para codificar não importa, desde que o idioma esteja preexistente, o alfabeto esteja preexistente e você especifique o idioma que usará na sua resposta.
  • Qualquer que seja o alfabeto que você emprega para o seu tabuleiro de damas, você pode adicionar ou remover símbolos para preencher o tabuleiro de damas. Especifique para que você usa esses símbolos (por exemplo, pontuação, um símbolo "início da mensagem" separado, símbolos para palavras comuns). Você pode renunciar inteiramente ao sinal numérico e soletrar os números ou incluir cada dígito no tabuleiro de damas, usando o slot onde o sinal numérico era para outra coisa. Especifique qual tabuleiro de damas você usou em sua resposta.
  • A saída deve ser uma sequência de grupos de cinco dígitos separados por espaço, uma lista de números inteiros de cinco dígitos ou algo semelhante.
  • Eu usei a indexação zero e 0123456789no meu exemplo. Você pode usar a indexação 1 e 1234567890, ou algum outro sistema em sua resposta, desde que especifique o que usou.

Aqui está um exemplo de implementação no Ideone .

Este é um post longo e eu escrevi a maioria manualmente, portanto, se houver partes confusas neste post ou erros na minha contagem e transposição, informe-me. Boa sorte e bom golfe!

Sherlock9
fonte
1
adding the first two digits without addingVocê quer dizer carregar?
Isaacg
@isaacg Sim, eu fiz. Editado.
Sherlock9
Você poderia esclarecer o que você quer dizer com without borrowinge without carrying? Você quer dizer adicionar e subtrair mod 10, ie (6+7) mod 10 = 3e (6-8) mod 10 = 8?
R. Kap
@ R.Kap Sim, deixe-me esclarecer isso.
Sherlock9
Temos que demarcar números?
R. Kap

Respostas:

10

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

Esse é definitivamente o golfe mais longo que já fiz e o único golfe em que fiquei seriamente preocupado com a falta de nomes de variáveis ​​de um caractere. Sugestões de golfe são bem-vindas. Experimente online!

Estou codificando com o alfabeto latino maiúsculo com caracteres adicionais .e #, usando a indexação 0 e 0123456789ao converter gpara t. Meu tabuleiro de damas está em um formato semelhante ao seguinte exemplo:

  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 bytes, graças à sugestão do TuukkaX de reduzir algumas das funções usadas com freqüência com variáveis ​​de uma letra. -12 bytes de tornar a, g, tmais compacto.

Edit: -24 bytes de criação removendo nomes de variáveis ​​para chaves intermediárias que são usadas apenas uma vez, a saber a, g, s, S, k, K.

Editar: -74 bytes da consolidação H(), T() and C().

Edit: -1 byte, graças a Nick A pela sugestão de mudar ord(s[i])+ord(s[i+1])para sum(map(ord,s[i:i+2])). -2 bytes da alteração de 2 +=[a]chamadas para +=a,. -13 bytes de alterar como G()encontrou o índice do mínimo de s. -2 bytes da mudança y=(y+1)%vpara y=-~y%v. -15 bytes da atribuição k.index()a K. -4 bytes da atribuição 10a W. -5 bytes da atribuição 1-I(d[-1])ao Xinterior V. -3 bytes do C()loop principal da reescrita . -2 bytes de reorganização 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:])
Sherlock9
fonte
2
Python 3 permite caracteres unicode como variáveis, FYI.
Paul
Mudar ord(seq[i])+ord(seq[i+1])para sum(map(ord,seq[i:i+2]))salva 1 caractere, acredito.
3

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

#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;}}}

Meu Deus. Este é o programa mais longo que tive para jogar golfe. Este também é o primeiro no qual, na verdade, fiquei sem nomes de variáveis ​​de um caractere para o escopo global e, portanto, tive que passar a usar alguns de dois caracteres (o fato de aparentemente não poder redefinir variáveis ​​não ajuda). Dicas de golfe são, portanto, muito apreciadas.

Ungolfed

Compila sem nenhum aviso, ao contrário da versão em golfe. Pequenas alterações feitas na versão golfed não serão refletidas nesta versão ungolfed.

#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;
    }
  }
}

Notas

  • Isso usa um tabuleiro de damas semelhante ao seguinte para codificar a mensagem:

      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 . #
    
  • Isso pressupõe que todas as strings aplicáveis ​​são fornecidas em maiúsculas. A mensagem também deve ter toda a pontuação, exceto os períodos removidos e todos os números demarcados por# s, enquanto a frase-chave deve ter toda a pontuação removida.

  • A mensagem codificada resultante é enviada para STDOUT como uma sequência de grupos de cinco dígitos separados por espaço.

  • A mensagem de entrada deve estar em inglês.

  • Eu teria combinado algumas das funções que usei, mas teria que recorrer ao uso de mais nomes de variáveis ​​de duas letras, tornando o programa final mais longo do que seria com mais algumas funções.

  • Atualmente, isso não pressupõe que a palavra-chave (pelo menos em inglês) sempre contenha o mesmo conjunto de letras e, portanto, compensa isso removendo duplicatas, manipulando o tabuleiro de damas etc. Esse recurso aparentemente não é exigido pelo OP, então, atualmente, estou jogando fora os bytes extras desnecessários que estão ocupando. Atualizado para a versão golfada.

R. Kap
fonte
2

JavaScript (ES6), 946 938 953 bytes

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}

Vi no final de semana que ainda não havia uma entrada de JS para isso, então aqui está a minha (última hora) tentativa. Implementar e jogar golfe era tão louco quanto divertido!

Snippet de demonstração

Editar: -8 bytes

Percebeu que havia parênteses extras em torno da função S,J,A,Q

Editar: +15 bytes

Atualizada a lógica de como a message idmensagem é colocada na mensagem final (agora 1 indexada e 0 não a inclui na saída).

Ungolfed

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;
}

Notas

  • Isso usa um tabuleiro de damas semelhante ao seguinte para codificar a mensagem:

      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 #
    
  • Todas as strings são fornecidas em maiúsculas. A mensagem é latina alfanumérica (mais .e #) e deve ter toda a pontuação (exceto pontos) removida. Todos os números já devem estar marcados com #s. A frase-chave deve ter todos os espaços / pontuação removidos.

  • A mensagem resultante é retornada como uma matriz de sequências de 5 dígitos.

Aprimoramentos

  • Sinto que há uma maneira de abusar do "Todos os idiomas" para salvar alguns bytes. Se eu tivesse mais tempo, refiguraria isso para assumir que o idioma era algo como o havaiano, com apenas 12 letras.

  • Todas as sugestões de golfe são sempre bem-vindas.

SLuck49
fonte
Você poderia adicionar um trecho para que eu possa verificar se isso funciona? Se assim for, então eu posso lhe conceder a recompensa.
R. Kap 12/01
@ R.Kap Claro, eu adicionei um trecho de demonstração
SLuck49
Hmm ... na demo, o message identifierparece estar 7longe do final, em vez de 6. Além disso, na sua versão não-gasta, o mesmo Idparece estar 6longe do começo, e não do fim.
R. Kap
@ R.Kap Sim, houve um erro quando o publiquei pela primeira vez (não deve ter sido corrigido no Ungolfed). Quanto aos jogadores de golfe, presumi que o índice fosse 0 porque, caso contrário, se 1significa o final, onde você diria que o jogo message identifierdeveria continuar 0? Eu posso mudar isso, só preciso saber.
precisa saber é o seguinte
Eu diria que em um 0o message identifierdeve ser omitido da saída.
R. Kap
1

Clojure, 1197 1212 bytes

Estou exausta.

Atualização: adicionada a localização de divisão aleatória necessária da mensagem, a versão não-gasta usa a mesma localização do exemplo fornecido, para que o algoritmo possa ser facilmente verificado.

(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)))))

Entradas de amostra e caso de teste:

(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)

Ungolfed:

(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)))))

Possui uma implementação alternativa no tabuleiro de damas Bque é igual à definição da tarefa. Mas o envio usa outro em que os alfabetos não utilizados preenchem primeiro a 2ª linha e depois a 3ª vez, em vez de preencher coluna por coluna.

NikoNyrh
fonte
Considerei escrever uma solução Clojure, mas minha cabeça explodiu enquanto eu estava lendo a pergunta. Quanto tempo levou para escrever?
precisa saber é o seguinte
Talvez 3 horas enquanto assiste o Youtube ao lado. Isso começou muito fácil, mas eu estava prestes a desistir quando tive que implementar a segunda "transposição interrompida". Agora isso coordsé gerado duas vezes, primeiro gerando a forma triangular e depois preenchendo as coordenadas que estavam faltando. Também "preenchimento de comprimento de multiplicação de N" pode ter solução mais elegante que concatenando N - 1 e elementos de separação para comprimentos de N.
NikoNyrh
Oh caramba, eu esqueci de mudar o ponto de divisão codificado em (split-at 49 mymsg)49, deve ser algo como (rand-int(count mymsg))resposta correta seria um pouco mais de 1200 bytes. zzz
NikoNyrh
Droga. Provavelmente ainda menos do que a resposta c.
Carcigenicate