Tulis encoder cipher VIC

18

The VIC cipher adalah salah satu pensil dan kertas cipher yang paling rumit yang pernah disusun. Digunakan pada 1950-an oleh mata-mata Soviet Reino Häyhänen, dengan nama sandi "VICTOR", prinsip utamanya adalah keamanan melalui kebingungan; a banyak kebingungan.

Tugas Anda adalah menulis program atau fungsi yang akan mengambil pesan dan menyandikannya menggunakan sandi VIC. Saya juga telah memposting tantangan decoder cipher VIC di sini . Jika salah satu dari petunjuk berikut tidak jelas, jangan ragu untuk menanyakannya di komentar. Instruksi diadaptasi dari situs ini .

Menyandikan sandi VIC

Persiapan

Anda akan membutuhkan lima input:

  • pesan teks biasa
  • kata kunci atau frasa pendek yang berisi huruf paling umum dalam bahasa Anda
  • frasa kunci, seperti kutipan atau garis dari sebuah lagu (setidaknya 20 karakter)
  • tanggal (atau nomor lain yang enam digit atau lebih)
  • nomor agen pribadi

Dalam praktiknya, keempat terakhir ini harus disepakati sebelumnya oleh pengirim dan penerima, termasuk apakah nomor agen pengirim atau penerima digunakan dalam penyandian.

Contoh pesan saya adalah: We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.

Kami akan menyandikannya dalam bahasa Inggris (meskipun Anda dapat menggunakan bahasa dan alfabet apa pun yang Anda suka) dan huruf paling umum dalam alfabet bahasa Inggris adalah A, E, I, N, O, R, S, T. Saya akan menggunakan kata kunci SENATORI.

Ungkapan kunci saya adalah kutipan oleh Richard Feynman: "Prinsip pertama adalah bahwa Anda tidak boleh membodohi diri sendiri - dan Anda adalah orang yang paling mudah untuk dibodohi."

Sebagai tanggal, saya akan menggunakan 31 Juli 2016 (dalam format 3172016), yang merupakan hari ketika saya menulis deskripsi ini.

Nomor pribadi yang saya pilih untuk diri saya adalah 9.

Ringkasan langkah-langkah

  1. Turunkan kunci perantara untuk digunakan dalam langkah-langkah berikut.
  2. Bangun dan terapkan kotak-kotak straddling.
  3. Bangun dan terapkan tabel transposisi pertama.
  4. Bangun dan terapkan tabel transposisi kedua (terganggu).
  5. Akhiri pesan dengan memasukkan grup indikator pesan.

Submekanisme

Dua hal lagi untuk dijelaskan sebelum kita masuk ke inti permasalahan: proses penambahan rantai dan pengurutan.

Selain rantai, juga dikenal sebagai generator Fibonacci yang lambat, bekerja dengan mengambil urutan digit awal, menambahkan dua digit pertama tanpa membawa (menambahkannya bersama-sama lalu mod 10) dan menambahkan hasilnya ke akhir. Sebagai contoh:

79081
7 + 9 = 6

790816
9 + 0 = 9

7908169
0 + 8 = 8

79081698
8 + 1 = 9

790816989
1 + 6 = 7

7908169897
... and so on

Sequentializing pada dasarnya mengambil urutan huruf atau digit dan memberi label berdasarkan urutan abjad / numerik. Duplikat berlabel kiri ke kanan. Sebagai contoh:

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

Saya menggunakan pengindeksan nol di sini, tetapi indeks sesuka Anda.

1. Tombol Menengah

Membagi 20 huruf pertama dari frasa kunci menjadi dua kelompok 10 dan mengurutkan masing-masing secara individual, yang akan kita panggil S1dan S2.

    THEFIRSTPR
S1: 8201357946

    INCIPLEIST
S2: 2603751489

Pilih pengidentifikasi pesan 5 digit acak, M(ini bisa menjadi salah satu input jika Anda mau):

M = 47921

Kurangi, tanpa meminjam (kurangi mod 10), lima digit pertama dari tanggal utama 3172016dari M:

M      47921
date - 31720
     = 16201

Chain menambahkan hasilnya hingga Anda memiliki sepuluh digit:

1620178218

Tambahkan digit ini ke S1, tanpa membawa atau mod 10, untuk mendapatkan G:

     1620178218
S1 + 8201357946
G  = 9821425154

Di atas S2, tulis urutan 0123456789. Temukan setiap digit Gdalam urutan 0123456789 dan ganti dengan angka tepat di bawahnya S2. Hasilnya adalah T.

   0123456789
S2 2603751489

G  9821425154
T  9806705657

Gunakan penambahan rantai untuk memperluas Tke 60 digit.

9806705657

becomes

980670565778637511245490262369939288595822106344304316978734

50 digit terakhir ini, dalam lima baris masing-masing sepuluh digit, membentuk Ublok.

T  9806705657
U  7863751124
   5490262369
   9392885958
   2210634430
   4316978734

Dua digit terakhir yang tidak sama dari Ublok secara individual ditambahkan ke nomor pribadi agen untuk memberikan lebar dari dua transposisi, pdan q.

9 + 3 = 12 (p, lebar transposisi pertama) 9 + 4 = 13 (q, lebar transposisi kedua)

Urutkan Tdan gunakan urutan ini untuk menyalin kolom Ublok, dari atas ke bawah, ke baris digit baru V,.

T     9806705657
seqT  9804612537

U     7863751124
      5490262369
      9392885958
      2210634430
      4316978734

V     69911 56837 12548 26533 30206 13947 72869 49804 84323 75924

Urutkan pdigit pertama untuk mendapatkan kunci untuk transposisi pertama K1, dan qdigit berikut untuk kunci untuk yang kedua 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

Akhirnya, sekuensial baris terakhir dari Ublok yang akan Anda dapatkan C, tajuk kolom untuk kotak-kotak yang mengangkang:

U5  4316978734
C   3105968724

2. Kotak-kotak Straddling

Pertama, saya akan memberikan contoh pada kotak-kotak saya kemudian menjelaskan prinsip-prinsip dalam membuatnya dengan cara itu:

  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 #

Baris pertama huruf adalah kata kunci singkat kami SENATORI. Kata kunci Anda dapat berupa string apa pun tanpa duplikat, tetapi karena itu menentukan baris teratas kotak-kotak Anda, pilihlah dengan bijak. Di atas kata kunci C, dan baris lainnya adalah sisa dari alfabet Anda dalam urutan apa pun yang Anda pilih. Dalam kasus saya, saya mengisi kotak-kotak dengan alfabet Latin lainnya, tanda baca .dan tanda untuk demarkasi angka #. Pada dasarnya, kotak-kotak adalah sandi pengganti yang bagus. Misalnya, "E" akan diganti dengan 1, dan "W" akan diganti dengan 27.

Setelah kami menyandikan pesan plaintext kami dengan kotak-kotak ini, tetapi pertama-tama, kita perlu membuat awal pesan kami menjadi kurang jelas dengan memecahnya pada posisi acak, dan membuatnya menjadi huruf besar semua. Untuk menunjukkan awal asli lainnya, kami menggunakan dua pemberhentian penuh..

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

menjadi

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

Kami menyandikan dengan kotak-kotak, memberi kami:

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

Jika panjang pesan tidak habis dibagi 5, kami menambahkan beberapa karakter nol untuk mengisi pesan. Pesan kami adalah 109 digit, jadi saya akan menambahkan satu nol: "4".

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

Catatan: Karena pesan contoh saya tidak mengandung angka, saya akan mengatakan di sini bahwa Anda dapat menunjuk, katakanlah, sebagai #3#, yang disandikan seperti di 44344sini.

3. Transposisi Pertama

Buat tabel transposisi dengan menulis K1(dari bagian Tombol Menengah) diikuti dengan pesan yang disandikan dari langkah sebelumnya, dalam baris dengan panjang yang sama, di bawah tombol:

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

Mengambil kolom bernomor sesuai nomornya, kita dapat:

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

4. Transposisi Kedua

Transposisi pertama relatif sederhana. Yang ini, bagaimanapun, adalah transposisi yang terganggu. Pola gangguan ditentukan oleh lebar tabel dan kunci. Dalam contoh kita, kita memiliki 110 digit dan 13 kolom, artinya kita akan memiliki 8 baris penuh dan 6 sisanya. Kami mulai mengisi baris pertama, tetapi berhenti di kolom 0, dan melanjutkan sebagai berikut:

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

Kemudian kita mengisi beberapa ruang terakhir dengan digit yang tersisa.

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

Sekarang, kita membaca kolom dengan cara yang persis sama dengan yang kita lakukan pada transposisi pertama.

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

Dan bagi semuanya menjadi 5 kelompok:

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

5. Finalisasi Pesan

Langkah terakhir adalah menyisipkan pengidentifikasi pesan acak kami 47921,, ke dalam pesan itu sendiri. Digit terakhir dari tanggal kunci 6menunjukkan jarak grup dari akhir.

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

Catatan untuk tantangan ini

  • Anda diberi minimal lima input: pesan, kata kunci huruf, frasa kunci, tanggal, dan nomor pribadi. Anda dapat memasukkan dua input tambahan: pengidentifikasi pesan acak dan null yang diperlukan untuk mengganti pesan, atau fungsi Anda dapat menghasilkan beberapa angka acak sendiri.
  • Anda dapat mengasumsikan semua input valid, dengan jumlah digit dan huruf yang benar (pengidentifikasi pesan 5 digit, setidaknya 20 digit untuk frasa kunci, dan sebagainya). Anda dapat mengasumsikan bahwa string Anda (pesan dan kata kunci) telah menghapus semua tanda baca dan spasi kecuali untuk yang Anda izinkan dalam versi Anda, dan bahwa angka-angka tersebut sudah ditandai dengan tanda-tanda angka.
  • Kata kunci pertama tidak boleh memiliki surat duplikat di dalamnya, dan dalam kode Anda, Anda dapat mengasumsikan bahwa tidak pernah ada surat duplikat.
  • Bahasa yang Anda gunakan untuk menyandikan tidak menjadi masalah, selama bahasa tersebut sudah ada sebelumnya, alfabetnya sudah ada sebelumnya, dan Anda menentukan bahasa yang Anda gunakan dalam jawaban Anda.
  • Alfabet mana pun yang Anda gunakan untuk kotak-kotak yang mengangkang, Anda dapat menambah atau menghapus simbol untuk menutup kotak-kotak itu. Tetapkan untuk apa Anda menggunakan simbol-simbol itu (misalnya, tanda baca, simbol "pesan awal" yang terpisah, simbol untuk kata-kata umum). Anda dapat meninggalkan tanda angka sepenuhnya dan mengeja angka-angka atau memasukkan setiap digit di kotak-kotak, menggunakan slot di mana tanda angka adalah untuk sesuatu yang lain. Silakan tentukan kotak-kotak mana yang Anda gunakan dalam jawaban Anda.
  • Outputnya harus berupa string kelompok lima digit yang dipisahkan ruang, daftar bilangan bulat lima digit, atau yang serupa.
  • Saya menggunakan pengindeksan nol dan 0123456789dalam contoh saya. Anda dapat menggunakan pengindeksan 1 dan 1234567890, atau beberapa sistem lain dalam jawaban Anda, selama Anda menentukan apa yang Anda gunakan.

Berikut ini contoh implementasi pada Ideone .

Ini adalah posting yang panjang dan saya menulis sebagian besar dengan tangan, jadi jika ada bagian yang membingungkan dalam posting ini atau kesalahan dalam penghitungan dan transpos saya, beri tahu saya. Semoga berhasil dan bermain golf dengan baik!

Sherlock9
sumber
1
adding the first two digits without addingApakah maksud Anda membawa?
isaacg
@isaacg Ya, saya lakukan. Diedit.
Sherlock9
Bisakah Anda mengklarifikasi apa yang Anda maksud dengan without borrowingdan without carrying? Apakah yang Anda maksud menambah dan mengurangi mod 10, yaitu (6+7) mod 10 = 3dan (6-8) mod 10 = 8?
R. Kap
@ R.Kap Ya, izinkan saya menjelaskannya.
Sherlock9
Apakah kita harus membatasi angka?
R. Kap

Jawaban:

10

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

Ini jelas merupakan golf terpanjang yang pernah saya lakukan, dan satu-satunya golf di mana saya sangat khawatir kehabisan nama variabel satu karakter. Saran bermain golf diterima. Cobalah online!

Saya menyandikan dengan huruf latin huruf besar dengan karakter tambahan .dan #, menggunakan pengindeksan 0 dan 0123456789ketika mengkonversi gke t. Kotak-kotak saya dalam format yang mirip dengan contoh berikut:

  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

Sunting: -63 bytes berkat saran TuukkaX untuk mempersingkat beberapa fungsi yang sering digunakan dengan variabel satu huruf. -12 byte dari membuat a, g, tlebih ringkas.

Edit: -24 byte dari pembuatan dengan menghapus nama variabel untuk kunci perantara yang hanya digunakan sekali, yaitu a, g, s, S, k, K.

Edit: -74 byte dari konsolidasi H(), T() and C().

Edit: -1 byte terima kasih kepada Nick A untuk saran mereka berubah ord(s[i])+ord(s[i+1])ke sum(map(ord,s[i:i+2])). -2 byte dari mengubah 2 +=[a]panggilan menjadi +=a,. -13 byte dari mengubah cara G()menemukan indeks minimum s. -2 byte dari berubah y=(y+1)%vmenjadi y=-~y%v. -15 byte dari menugaskan k.index()ke K. -4 byte dari menugaskan 10ke W. -5 byte dari penetapan 1-I(d[-1])ke Xdalam V. -3 byte dari C()loop utama penulisan ulang . -2 byte dari pengorganisasian kembali 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:])

Tidak melakukan pelanggaran:

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
sumber
2
Python 3 memungkinkan karakter unicode sebagai variabel, FYI.
Paul
Mengubah ord(seq[i])+ord(seq[i+1])untuk sum(map(ord,seq[i:i+2]))menyimpan 1 karakter, saya percaya.
3

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

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

Astaga. Ini adalah program terpanjang yang pernah saya miliki untuk bermain golf. Ini juga yang pertama di mana saya benar-benar kehabisan nama-nama variabel karakter tunggal untuk lingkup global dan karenanya harus beralih menggunakan beberapa karakter 2 (fakta bahwa saya tampaknya tidak dapat redecare variabel tidak membantu). Tips golf sangat dihargai.

Tidak disatukan

Kompilasi tanpa peringatan, tidak seperti versi golf. Perubahan kecil yang dilakukan pada versi golf tidak akan tercermin dalam versi yang tidak diklik ini.

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

Catatan

  • Ini menggunakan kotak-kotak yang mirip dengan yang berikut ini untuk menyandikan pesan:

      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 . #
    
  • Ini mengasumsikan bahwa semua string yang berlaku diberikan dalam huruf besar. Pesan juga harus memiliki semua tanda baca kecuali periode dihapus dan semua angka ditandai dengan #s, sedangkan frasa kunci harus menghapus semua tanda baca.

  • Pesan yang dikodekan yang dihasilkan adalah output ke STDOUT sebagai string kelompok lima digit yang dipisahkan oleh ruang.

  • Pesan input harus dalam bahasa Inggris.

  • Saya akan menggabungkan beberapa fungsi yang saya gunakan, tetapi kemudian saya harus menggunakan lebih banyak nama variabel dua huruf, membuat program akhir lebih lama daripada dengan beberapa fungsi lainnya.

  • Ini saat ini tidak mengasumsikan bahwa kata kunci (setidaknya dalam bahasa Inggris) selalu akan berisi set huruf yang sama, dan dengan demikian menggantikannya dengan menghapus duplikat, memanipulasi kotak-kotak, dll. Kemampuan ini tampaknya tidak diperlukan oleh OP, jadi saya saat ini bermain golf dari byte ekstra yang tidak perlu yang mengambil. Diperbarui untuk versi golf.

R. Kap
sumber
2

JavaScript (ES6), 946 938 953 byte

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}

Saya melihat selama akhir pekan belum ada entri JS untuk ini, jadi inilah upaya saya (menit terakhir). Menerapkan dan bermain golf ini gila seperti menyenangkan!

Cuplikan Demo

Edit: -8 byte

Menyadari ada tanda kurung tambahan di sekitar fungsi S,J,A,Q

Edit: +15 byte

Memperbarui logika untuk bagaimana message idditempatkan dalam pesan akhir (sekarang 1-diindeks dan 0 tidak termasuk dalam output).

Tidak disatukan

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

Catatan

  • Ini menggunakan kotak-kotak yang mirip dengan yang berikut ini untuk menyandikan pesan:

      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 #
    
  • Semua string diberikan dalam huruf besar. Pesannya adalah alfanumerik Latin (plus .dan #) dan seharusnya semua tanda baca (kecuali periode) dihapus. Semua angka harus sudah ditandai dengan #s. Frasa kunci harus menghapus semua tanda baca / spasi.

  • Pesan yang dihasilkan dikembalikan sebagai array string 5 digit.

Perangkat tambahan

  • Saya merasa ada cara untuk menyalahgunakan "Semua bahasa" untuk menghemat beberapa byte. Jika saya punya lebih banyak waktu, saya akan mengonfigurasi ulang ini untuk menganggap bahasa itu seperti bahasa Hawaii yang hanya memiliki 12 huruf.

  • Saran bermain golf selalu diterima.

Sluck49
sumber
Bisakah Anda menambahkan potongan sehingga saya dapat memverifikasi bahwa ini berfungsi? Jika ya, maka saya bisa memberi Anda hadiah.
R. Kap
@ R.Kap Tentu, saya telah menambahkan cuplikan demo
SLuck49
Hmm ... dalam demo, message identifiersepertinya 7jauh dari akhir, bukan 6. Juga, dalam versi Anda yang tidak disatukan, hal yang sama Idtampaknya 6jauh dari awal alih-alih akhir.
R. Kap
@ R.Kap Ya ada bug ketika saya pertama kali mempostingnya (tidak harus memperbaikinya di ungolfed). Adapun golf, saya berasumsi itu 0-diindeks karena kalau tidak 1berarti akhir di mana Anda mengatakan message identifierharus pergi pada 0? Saya bisa mengubahnya, saya hanya perlu tahu.
SLuck49
Saya akan mengatakan bahwa pada 0yang message identifierharus dihilangkan dari output.
R. Kap
1

Clojure, 1197 1212 byte

Wah, saya lelah.

Pembaruan: Menambahkan lokasi pemisahan pesan yang diperlukan secara acak, versi ungolfed menggunakan lokasi yang sama dengan contoh yang diberikan sehingga algoritme dapat dengan mudah diverifikasi.

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

Input sampel dan uji kasus:

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

Tidak Disatukan:

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

Ini memiliki implementasi alternatif pada kotak-kotak Byang sama dengan definisi tugas. Tetapi pengiriman menggunakan yang lain di mana huruf yang tidak terpakai pertama mengisi baris ke-2 dan kemudian ke-3 alih-alih mengisi kolom demi kolom.

NikoNyrh
sumber
Dianggap menulis solusi Clojure, tetapi kepala saya meledak ketika saya membaca pertanyaan itu. Berapa lama waktu yang dibutuhkan untuk menulis?
Carcigenicate
Mungkin 3 jam sambil menonton Youtube di samping. Ini dimulai dengan cukup mudah tetapi saya akan menyerah ketika saya harus menerapkan "transposisi terganggu" yang kedua. Sekarang yang coordsdihasilkan dua kali, pertama menghasilkan bentuk segitiga dan kemudian mengisi koordinat yang hilang. "Padding to length of multiply of N" mungkin memiliki solusi yang lebih elegan daripada menggabungkan elemen N - 1 dan mempartisi ke panjang N.
NikoNyrh
Sial, saya lupa mengubah titik perpecahan hard-coded di (split-at 49 mymsg), 49 harus seperti (rand-int(count mymsg))jawaban yang benar akan sedikit lebih dari 1200 byte. zzz
NikoNyrh
Sial. Mungkin masih kurang dari jawaban c.
Carcigenicate