Napisz koder VIC


18

VIC szyfr jest jednym z najbardziej skomplikowanych ołówek i papier szyfrów kiedykolwiek wymyślono. Używany w latach 50. XX wieku przez radzieckiego szpiega Reino Häyhäna, o kryptonimie „ZWYCIĘZCA”, jego główną zasadą jest bezpieczeństwo poprzez zaciemnianie; dużo od zaciemniania.

Twoim zadaniem jest napisanie programu lub funkcji, która odbierze komunikat i zakoduje go za pomocą szyfru VIC. Mam również opublikował tutaj VIC szyfr dekodera wyzwanie . Jeśli którakolwiek z poniższych instrukcji jest niejasna, nie wahaj się zapytać o nią w komentarzach. Instrukcje są dostosowane z tej strony .

Kodowanie szyfru VIC

Przygotowanie

Będziesz potrzebował pięciu danych wejściowych:

  • wiadomość w postaci zwykłego tekstu
  • krótkie słowo kluczowe lub wyrażenie zawierające najczęściej używane litery w Twoim języku
  • fraza kluczowa, taka jak cytat lub wiersz utworu (co najmniej 20 znaków)
  • data (lub inny numer składający się z sześciu cyfr lub więcej)
  • osobisty numer agenta

W praktyce te cztery ostatnie powinny zostać wcześniej uzgodnione przez nadawcę i odbiorcę, w tym to, czy do kodowania używany jest numer agenta nadawcy lub odbiorcy.

Moja przykładowa wiadomość będzie: We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.

Będziemy kodować w języku angielskim (chociaż możesz używać dowolnego języka i alfabetu, który preferujesz), a najczęściej używane litery w alfabecie angielskim A, E, I, N, O, R, S, T. Użyję słowa kluczowegoSENATORI .

Moją kluczową frazą jest cytat Richarda Feynmana: „Pierwszą zasadą jest to, że nie możesz oszukiwać siebie - i jesteś najłatwiejszą osobą do oszukania”.

Jako datę użyję 31 lipca 2016 r. (W formacie 3172016 ), czyli w dniu, w którym napisałem ten opis.

Numer osobisty, który wybrałem dla siebie to 9.

Podsumowanie kroków

  1. Uzyskaj klucze pośrednie do użycia w poniższych krokach.
  2. Zbuduj i zastosuj rozstawioną szachownicę.
  3. Zbuduj i zastosuj pierwszą tabelę transpozycji.
  4. Skonstruuj i zastosuj drugą (zakłóconą) tabelę transpozycji.
  5. Sfinalizuj wiadomość, wstawiając grupę wskaźników wiadomości.

Submechanizmy

Jeszcze dwie rzeczy do wyjaśnienia, zanim przejdziemy do sedna sprawy: procesy dodawania łańcucha i sekwencjonowania.

Dodawanie łańcucha, znane również jako opóźniony generator Fibonacciego, polega na pobraniu początkowej sekwencji cyfr, dodaniu pierwszych dwóch cyfr bez przenoszenia (następnie ich dodaniu mod 10) i dołączeniu wyniku na końcu. Na przykład:

79081
7 + 9 = 6

790816
9 + 0 = 9

7908169
0 + 8 = 8

79081698
8 + 1 = 9

790816989
1 + 6 = 7

7908169897
... and so on

Sekwencjonowanie polega zasadniczo na ciągnięciu sekwencji liter lub cyfr i oznaczaniu ich według kolejności alfabetycznej / numerycznej. Duplikaty są oznaczone od lewej do prawej. Na przykład:

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

Używam tutaj indeksowania zerowego, ale indeksuj, jak chcesz.

1. Klucze pośrednie

Podziel pierwsze 20 liter frazy kluczowej na dwie grupy po 10 i zsekwencjonuj każdą z osobna, którą nazwiemy S1i S2.

    THEFIRSTPR
S1: 8201357946

    INCIPLEIST
S2: 2603751489

Wybierz losowy 5-cyfrowy identyfikator wiadomości M(może to być jedno z danych wejściowych, jeśli wolisz):

M = 47921

Odejmij, bez pożyczania (odejmij mod 10), pierwsze pięć cyfr kluczowej daty 3172016od M:

M      47921
date - 31720
     = 16201

Dodaj łańcuch, aż uzyskasz dziesięć cyfr:

1620178218

Dodaj te cyfry S1, bez przenoszenia lub mod 10, aby uzyskać G:

     1620178218
S1 + 8201357946
G  = 9821425154

Powyżej S2wpisz sekwencję 0123456789. Znajdź każdą cyfrę Gw sekwencji 0123456789 i zastąp ją cyfrą bezpośrednio poniżej S2. Rezultatem jest T.

   0123456789
S2 2603751489

G  9821425154
T  9806705657

Użyj dodawania łańcucha, aby rozwinąć Tdo 60 cyfr.

9806705657

becomes

980670565778637511245490262369939288595822106344304316978734

Te ostatnie 50 cyfr, w pięciu rzędach po dziesięć cyfr, tworzą Ublok.

T  9806705657
U  7863751124
   5490262369
   9392885958
   2210634430
   4316978734

Ostatnie dwie nierówne cyfry Ubloku są indywidualnie dodawane do numeru osobistego agenta, aby podać szerokość dwóch transpozycji, poraz q.

9 + 3 = 12 (p, pierwsza szerokość transpozycji) 9 + 4 = 13 (q, druga szerokość transpozycji)

Sequentialize Ti używać tej sekwencji skopiować off kolumny z Ubloku, od góry do dołu, do nowego rzędu cyfr V.

T     9806705657
seqT  9804612537

U     7863751124
      5490262369
      9392885958
      2210634430
      4316978734

V     69911 56837 12548 26533 30206 13947 72869 49804 84323 75924

Sekwencjonuj pierwsze pcyfry, aby uzyskać klucz dla pierwszej transpozycji K1, oraz kolejne qcyfry dla klucza dla drugiej 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

Na koniec zsekwencjonuj ostatni wiersz Ubloku, aby uzyskać C, nagłówki kolumn dla szachownic okiennych:

U5  4316978734
C   3105968724

2. Straddling Checkerboard

Najpierw dam przykładową szachownicę, a następnie wyjaśnię zasady jej tworzenia w następujący sposób:

  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 #

Pierwszy wiersz liter to nasze krótkie słowo kluczowe SENATORI. Twoim słowem kluczowym może być dowolny ciąg bez duplikatów, ale ponieważ określa górny rząd twojej szachownicy, wybierz mądrze. Powyżej słowa kluczowego jest C, a pozostałe wiersze to reszta alfabetu w dowolnej kolejności. W moim przypadku wypełniłem szachownicę resztą alfabetu łacińskiego, znakiem interpunkcyjnym .i znakiem dla oznaczania liczb #. Zasadniczo szachownica jest fantazyjnym szyfrem zastępczym. Na przykład „E” zostanie zastąpione przez 1, a „W” zostanie zastąpione przez 27.

Po zakodowaniu naszej wiadomości w postaci zwykłego tekstu za pomocą tej szachownicy, najpierw musimy uczynić początek naszej wiadomości mniej oczywistym, dzieląc ją w losowej pozycji i nadając jej wielkie litery. Aby oznaczyć drugi oryginalny początek, używamy dwóch kropek..

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

staje się

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

Kodujemy za pomocą szachownicy, co daje nam:

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

Jeśli długość wiadomości nie jest podzielna przez 5, dodajemy puste znaki, aby wypisać wiadomość. Nasza wiadomość ma 109 cyfr, więc dodam jeden null: „4”.

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

Uwaga: Ponieważ moja przykładowa wiadomość nie zawiera liczb, powiem tutaj, że możesz wyznaczyć, powiedzmy, as #3#, który jest zakodowany jak 44344tutaj.

3. Pierwsza transpozycja

Utwórz tabelę transpozycji, pisząc K1(z sekcji Klawisze pośrednie), a następnie zakodowaną wiadomość z poprzedniego kroku, w wierszach o tej samej długości, poniżej klucza:

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

Biorąc ponumerowane kolumny w kolejności ich liczb, otrzymujemy:

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

4. Druga transpozycja

Pierwsza transpozycja była stosunkowo prosta. Ta jednak jest zakłóconą transpozycją. Wzorzec zakłóceń zależy od szerokości stołu i klucza. W naszym przykładzie mamy 110 cyfr i 13 kolumn, co oznacza, że ​​będziemy mieli 8 pełnych wierszy i 6 resztek. Zaczynamy wypełniać pierwszy wiersz, ale zatrzymujemy się w kolumnie 0 i kontynuujemy w następujący sposób:

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

Następnie wypełniamy kilka ostatnich miejsc pozostałymi cyframi.

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

Teraz odczytujemy kolumny dokładnie w taki sam sposób, jak w pierwszej transpozycji.

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

I podziel wszystko na 5-cyfrowe grupy:

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

5. Sfinalizuj wiadomość

Ostatnim krokiem jest wstawienie naszego losowego identyfikatora 47921wiadomości do samej wiadomości. Ostatnia cyfra kluczowej daty 6wskazuje odległość, jaką powinna przebyć grupa od końca.

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

Uwagi do tego wyzwania

  • Otrzymujesz co najmniej pięć danych wejściowych: wiadomość, słowo kluczowe z literą, frazę kluczową, datę i numer osobisty. Możesz dołączyć dwa dodatkowe dane wejściowe: identyfikator losowej wiadomości i wartości zerowe potrzebne do uzupełnienia wiadomości, lub twoja funkcja może wygenerować kilka liczb losowych samodzielnie.
  • Możesz założyć, że wszystkie dane wejściowe są prawidłowe, z poprawną liczbą cyfr i liter (5-cyfrowy identyfikator wiadomości, co najmniej 20 cyfr dla frazy kluczowej i tak dalej). Możesz założyć, że w twoich ciągach (komunikat i słowa kluczowe) zostały już usunięte wszystkie znaki interpunkcyjne i spacje, z wyjątkiem tych, na które zezwalasz w swojej wersji, a liczby są już oznaczone znakami liczbowymi.
  • Pierwsze słowo kluczowe nie powinno zawierać zduplikowanych liter, a w kodzie możesz założyć, że nigdy nie ma zduplikowanych liter.
  • Język, w którym kodujesz, nie ma znaczenia, o ile istnieje on wcześniej, alfabet już istnieje i określasz, którego języka użyjesz w odpowiedzi.
  • Niezależnie od tego, który alfabet zastosujesz do swojej szachownicy, możesz dodawać lub usuwać symbole, aby wypchnąć szachownicę. Określ, do czego używasz tych symboli (na przykład interpunkcja, osobny symbol „początek wiadomości”, symbole popularnych słów). Możesz całkowicie zrezygnować ze znaku liczbowego i przeliterować cyfry lub dołączyć każdą cyfrę do szachownicy, używając szczeliny, w której znak liczbowy oznaczał coś innego. Proszę podać, której szachownicy użyłeś w swojej odpowiedzi.
  • Dane wyjściowe powinny być ciągiem oddzielonych spacjami pięciocyfrowych grup, listą pięciocyfrowych liczb całkowitych lub czymś podobnym.
  • Użyłem indeksowania zerowego i 0123456789w moim przykładzie. Możesz użyć 1-indeksowania i 1234567890/ lub innego systemu w swojej odpowiedzi, pod warunkiem, że określisz, czego użyłeś.

Oto przykładowa implementacja Ideone .

To jest długi post i napisałem go większość ręcznie, więc jeśli w tym poście są jakieś mylące części lub błędy w liczeniu i transpozycji, daj mi znać. Powodzenia i dobrej gry w golfa!


1
adding the first two digits without addingMasz na myśli noszenie?
isaacg

@isaacg Tak, zrobiłem. Edytowane.
Sherlock9,

Czy możesz wyjaśnić, co rozumiesz przez without borrowingi without carrying? Masz na myśli dodawanie i odejmowanie mod 10, tj. (6+7) mod 10 = 3I (6-8) mod 10 = 8?
R. Kap

@ R.Kap Tak, pozwól mi wyjaśnić.
Sherlock9,

Czy możemy mieć do numerów wyznaczyć?
R. Kap

Odpowiedzi:


10

Python 3 , 1423 1348 1324 1316 1300 1286 1250 1249 1209 1206 1204 bajtów

To zdecydowanie najdłuższy golf, jaki kiedykolwiek uprawiałem, i jedyny golf, w którym bardzo martwiłem się brakiem nazw zmiennych jednoznakowych. Sugestie dotyczące gry w golfa mile widziane. Wypróbuj online!

Koduję przy użyciu wielkich liter alfabetu łacińskiego z dodatkowymi znakami .oraz #przy użyciu indeksowania 0 i 0123456789podczas konwersji gna t. Mój szachownica ma format podobny do następującego przykładu:

  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

Edycja: -63 bajty dzięki sugestii TuukkaX, aby skrócić niektóre często używane funkcje za pomocą zmiennych jednoliterowych. -12 bajtów od uczynienia a, g, tbardziej kompaktowym.

Edytować: -24 bajtów od utworzenia poprzez usunięcie nazw zmiennych dla kluczy pośrednich, które są używane tylko raz, a mianowicie a, g, s, S, k, K.

Edytować: -74 bajty z konsolidacji H(), T() and C().

Edycja: -1 bajtów dzięki Nickowi A za sugestię zmiany ord(s[i])+ord(s[i+1])na sum(map(ord,s[i:i+2])). -2 bajty ze zmiany 2 +=[a]wywołań na +=a,. -13 bajtów od zmiany sposobu G()znalezienia indeksu minimum s. -2 bajty od zmiany y=(y+1)%vna y=-~y%v. -15 bajtów od przypisania k.index()do K. -4 bajty od przypisania 10do W. -5 bajtów od przypisania 1-I(d[-1])do Xwewnątrz V. -3 bajty z C()głównej pętli przepisywania . -2 bajty z reorganizacji 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 zezwala na stosowanie znaków Unicode jako zmiennych, FYI.
Paul,

Zmiana ord(seq[i])+ord(seq[i+1])na sum(map(ord,seq[i:i+2]))zapisywanie 1 postaci, którą wierzę.

3

C, 2880 2769 2766 2762 2743 2741 2739 2699 2458 bajtów

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

Mój Boże. To najdłuższy program, jaki kiedykolwiek miałem miałem do gry w golfa. Jest to również pierwszy przypadek, w którym skończyły mi się nazwy zmiennych jednoznakowych dla zakresu globalnego i dlatego musiałem przejść do korzystania z kilku 2-znakowych zmiennych (fakt, że najwyraźniej nie mogę ponownie zmienić zmiennych, nie pomaga). Wskazówki dotyczące gry w golfa są zatem bardzo mile widziane.

Bez golfa

Kompiluje bez ostrzeżeń, w przeciwieństwie do wersji golfowej. Niewielkie zmiany wprowadzone w wersji golfowej nie zostaną odzwierciedlone w tej wersji bez golfa.

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

Notatki

  • Używa szachownicy podobnej do poniższej, aby zakodować wiadomość:

      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 . #
    
  • Zakłada się, że wszystkie odpowiednie ciągi znaków są podane wielkimi literami. Wiadomość powinna również zawierać wszystkie znaki interpunkcyjne z wyjątkiem kropek i wszystkie cyfry wyznaczone przez #s, a fraza kluczowa powinna mieć usunięte wszystkie znaki interpunkcyjne.

  • Wynikowy zakodowany komunikat jest wyprowadzany do STDOUT jako ciąg oddzielonych spacjami pięciocyfrowych grup.

  • Komunikat wejściowy powinien być w języku angielskim.

  • Połączyłbym kilka funkcji, których użyłem, ale musiałbym użyć więcej dwuliterowych nazw zmiennych, dzięki czemu końcowy program byłby dłuższy niż przy kilku dodatkowych funkcjach.

  • Obecnie nie zakłada się, że słowo kluczowe (przynajmniej w języku angielskim) zawsze będzie zawierało ten sam zestaw liter, a więc rekompensuje to poprzez usunięcie duplikatów, manipulowanie szachownicą itp. OP nie ma takiej możliwości, więc obecnie gram w zbędne dodatkowe niepotrzebne bajty. Zaktualizowano dla wersji golfowej.


2

JavaScript (ES6), 946 938 953 bajtów

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}

W weekend widziałem, że nie było jeszcze wpisu do JS, więc oto moja (ostatnia minuta) próba. Wdrożenie i gra w golfa były szalone i zabawne!

Fragment demonstracyjny

Edycja: -8 bajtów

Uświadomiono sobie, że istnieją dodatkowe nawiasy wokół funkcji S,J,A,Q

Edycja: +15 bajtów

Zaktualizowano logikę dotyczącą sposobu message idumieszczania znaku w końcowym komunikacie (teraz indeksowany 1, a 0 nie uwzględnia go w danych wyjściowych).

Bez golfa

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

Notatki

  • Używa szachownicy podobnej do poniższej, aby zakodować wiadomość:

      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 #
    
  • Wszystkie ciągi znaków są podane wielkimi literami. Wiadomość jest alfanumeryczna łacińska (plus .i #) i powinna zostać usunięta cała interpunkcja (z wyjątkiem kropek). Wszystkie liczby powinny już być oznaczone #s. Fraza kluczowa powinna zawierać wszystkie znaki interpunkcyjne / spacje.

  • Wynikowy komunikat jest zwracany jako tablica 5-cyfrowych ciągów znaków.

Ulepszenia

  • Wydaje mi się, że istnieje sposób na nadużycie „Wszystkich języków” w celu zaoszczędzenia niektórych bajtów. Gdybym miał więcej czasu, skonfigurowałbym to tak, aby zakładać, że język jest podobny do hawajskiego, który ma tylko 12 liter.

  • Wszelkie sugestie dotyczące gry w golfa są zawsze mile widziane.


Czy możesz dodać fragment kodu, aby sprawdzić, czy to działa? Jeśli tak, to mogę przyznać nagrodę.
R. Kap

@ R.Kap Jasne, dodałem fragment demonstracyjny
SLuck49

Hmm ... w wersji demo message identifierwydaje się być 7daleko od końca 6. Również w twojej wersji bez golfa to samo Idwydaje się być 6od początku zamiast od końca.
R. Kap

@ R.Kap Tak, pojawił się błąd, kiedy pierwszy raz go opublikowałem (nie mogłem go naprawić w nie golfowym). Jeśli chodzi o golfa, założyłem, że był on zindeksowany, ponieważ inaczej, jeśli 1oznacza to sam koniec, gdzie powiedziałbyś, że message identifierpowinieneś iść na 0? Mogę to zmienić, muszę tylko wiedzieć.
SLuck49,

Powiedziałbym, że na powinny być pominięte z wyjścia. 0message identifier
R. Kap

1

Clojure, 1197 1212 bajtów

Och, jestem wykończony.

Aktualizacja: Dodano wymaganą losową lokalizację podziału wiadomości, wersja bez golfa używa tej samej lokalizacji jak w podanym przykładzie, dzięki czemu algorytm można łatwo zweryfikować.

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

Przykładowe dane wejściowe i przypadek testowy:

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

Nie golfowany:

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

Ma alternatywną implementację na szachownicy, Bktóra jest taka sama jak w definicji zadania. Ale zgłoszenie wykorzystuje inny, w którym nieużywane alfabety najpierw wypełniają drugi wiersz, a następnie trzeci zamiast wypełnienia kolumna po kolumnie.


Zastanawiałem się nad napisaniem rozwiązania Clojure, ale moja głowa eksplodowała podczas czytania pytania. Jak długo trwało pisanie?
Carcigenicate

Może 3 godziny podczas oglądania YouTube na boku. Zaczęło się to dość łatwo, ale miałem się poddać, kiedy musiałem wdrożyć drugą „zakłóconą transpozycję”. Teraz coordsjest generowany dwukrotnie, najpierw generując kształt trójkąta, a następnie wypełniając brakujące współrzędne. Również „wypełnienie do długości wielokrotności N” może mieć bardziej eleganckie rozwiązanie niż połączenie elementów N-1 i podział na długości N.
NikoNyrh

O cholera, zapomniałem zmienić zakodowany na stałe punkt podziału na (split-at 49 mymsg)49, powinno to być coś w rodzaju, (rand-int(count mymsg))więc poprawna odpowiedź to nieco ponad 1200 bajtów. zzz
NikoNyrh

Cholera. Prawdopodobnie wciąż mniej niż odpowiedź c.
Carcigenicate 11.01.17
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.