Crittografato in numeri!


12

Il problema:

Due agenti segreti nemici hanno ideato un meraviglioso metodo di comunicazione (per te)!

Ecco come funziona il processo di crittografia:

1) Prendi gli equivalenti ASCII di ogni lettera. (Non vengono inviati spazi, numeri o punteggiatura)

2) Per ogni lettera nel messaggio, l'equivalente ascii di esso e la lettera che lo segue (se esiste, in caso contrario, dovrebbe essere considerato 0), vengono moltiplicati (questo prodotto viene archiviato in un array / elenco) e sommato (questo numero è anche memorizzato in un altro elenco).

3) Le due liste (di somme e prodotti) vengono unite (la lista delle somme, quindi la lista dei multipli, nella stessa matrice) e trasmesse.

Devi scrivere il programma più piccolo in grado di invertire questo processo e decrittografare i messaggi inviati in questo formato!

Esempio di coppie di input e output:

[173, 209, 216, 219, 198, 198, 225, 222, 208, 100, 7272, 10908, 11664, 11988, 9657, 9657, 12654, 12312, 10800, 0] -> “HelloWorld”
[131, 133, 164, 195, 197, 99, 4290, 4422, 6499, 9506, 9702, 0] -> “ABCabc”

Questo è , quindi vince la soluzione più piccola in byte.

Sono ammessi messaggi di errore.

È possibile assegnare al proprio programma un array elenco / monodimensionale o una stringa separata da virgola, se specificato nell'invio. L'impostazione predefinita è un array / elenco.


1
Perché l'elenco dei multipli è presente anche lì? Solo le somme sono informazioni sufficienti.
orlp

1
@orlp forse per consentire maggiori opportunità di golf? :)
Jonathan Allan il

1
@orlp oh no, hai rovinato il divertimento!
Erik the Outgolfer

@JonathanAllan è corretto, in parte. Volevo che i due agenti segreti sembrassero super stupidi, in modo che aggiungessero parti non necessarie al loro "codice". Aggiunge anche alcuni altri programmi possibili che possono venire fuori.
iPhoenix

@orlp Solo i multipli non sono abbastanza, giusto?
ericw31415

Risposte:


5

Buccia , 7 6 byte

mcĠ≠←½

Provalo online! Secondo la documentazione, il comando mnon dovrebbe essere necessario, ma al momento sembra esserci un bug.

Modifica: -1 byte grazie a Zgarb!

Spiegazione:

     ½ -- split input list into half
    ←  -- take first list
  Ġ≠   -- subtract each list element from the previous one
mc     -- convert list of code points to string

Penso che `-possa essere . Il comportamento di ceffettivamente sembra un bug.
Zgarb,

@Zgarb Questo è un modo pratico per implementare ineguali. Questo è documentato da qualche parte?
Laikoni,

È sulla pagina della semantica di Husk Wiki.
Zgarb

1
Sembra che tu abbia cambiato la tua spiegazione, ma non lo stesso frammento di codice stesso. :)
iPhoenix

@iPhoenix Grazie, l'ho corretto.
Laikoni,

8

Brainfuck , 66 byte

,[>>>+<[-<+>>-<]<[->+<],]>[<<,>>[-<+>]<-]<<<[>[-<->>+<]<<]>.>>[.>]

L'input è la stringa crittografata. Presuppone celle di dimensioni infinite e 0 su EOF.

Come funziona:

,[>>>+<[-<+>>-<]<[->+<],] Gets input and the number of characters divided by 2
>[<<,>>[-<+>]<-]<<< Remove the second half of the string (the multiplication part)
[>[-<->>+<]<<] Subtract each character from the previous one, while keeping a copy of the previous one.
>.>>[.>] Print the characters

5

Haskell , 45 35 byte

map toEnum.scanr1(-).fst.span(<245)

Provalo online!

Spiegazione

  • fst.span(<245)prende tutti i numeri dall'inizio della lista che sono più piccoli di 245. Questi sono solo i numeri della parte della somma, perché la somma più grande possibile è z + z = 122 + 122 = 244e il prodotto più piccolo possibile A * A = 65 * 65 = 4225.
  • scanr1(-)prende l'ultimo valore dell'elenco e lo usa come accumulatore iniziale. Quindi, dall'inizio alla fine, ogni elemento dell'elenco viene sottratto dall'accumulatore corrente e il risultato viene utilizzato come accumulatore successivo e aggiunto a un elenco.
  • map toEnum sostituisce ogni numero nell'elenco con il carattere corrispondente per ricreare la stringa.




2

Gelatina , 11 byte

œs2Ḣḅ-$ÐƤAỌ

Un collegamento monadico che prende un elenco di numeri interi e restituisce un elenco di caratteri.

Provalo online!

Come?

œs2Ḣḅ-$ÐƤAỌ - Link: list of integers     e.g. [210,211,201,101,10989,11100,10100,0]
  2         - literal two                     2
œs          - split into equal parts          [[210,211,201,101],[10989,11100,10100,0]]
   Ḣ        - head                            [210,211,201,101]
       ÐƤ   - for postfixes:                  [210,211,201,101],[211,201,101],[201,101],[101]
      $     -   last two links as a monad:
     -      -     literal minus one           -1
    ḅ       -     convert from base           -99              ,111          ,-100      ,101
         A  - absolute value (vectorises)     [99,111,100,101]
          Ọ - convert to ordinal (vectorises) "code"

1

Pyt , 60 byte

←ĐĐŁ₂⁻⦋⇹ĐŁřĐŁ₂>*ž0`ŕĐĐŁ⁻⦋3ȘĐ4Ș3Ș4Ș÷⇹ĐŁřĐŁ<*žĐŁ⁻łŕ⇹Đ3Ș⇹÷Á↔áƇǰ

Prende un elenco di numeri interi e restituisce una stringa di caratteri.

Spiegazione:

←ĐĐŁ₂⁻⦋⇹          Gets the ASCII code of the last character
ĐŁřĐŁ₂>*ž         Gets the list of products and removes the 0 from the end of the list
0`ŕ ...  ł        Loops (0 is there so that the length can be removed from the stack)
ĐĐŁ⁻⦋              Gets the last product
3ȘĐ4Ș3Ș4Ș÷        Divides by the last ASCII code obtained
⇹ĐŁřĐŁ<*ž         Removes the last element from the array
ĐŁ⁻ł              Gets the length of the array - 1 (if 0, then exit loop - the last entry still has to be processed)
ŕ⇹Đ3Ș⇹÷           Divides the remaining product by the last ASCII code obtained           
Á↔á               Converts to array of ints
Ƈǰ                Converts to string of ASCII characters

Provalo online!


1

JavaScript (ES6), 80 byte

a=>String.fromCharCode(...eval(`for(a.splice(i=a.length/2);--i;a[i-1]-=a[i])a`))


1

VB Script - 74 71 byte

(Sono riuscito a ridurre da 74 a 71 utilizzando While..Wend anziché Do..Loop)

L'input è in una matrice a (), l'output è nella stringa d

d="":p=0:n=(UBound(a)+1)/2:While n>0:n=n-1:t=a(n)-p:d=Chr(t)&d:p=t:Wend

Spiegazione

d=""          '// initialize the output string
p=0          '// initialize the ansii of following char (working back from last char)
n=(Ubound(a)+1)/2 '// the index of the last summed pair + 1 (base 0)
While n>0    '// begin loop working back from last summed pair
n=n-1        '// move back 1 char
t=a(n)-p     '// calculate the ansii by subtracting the ansii of following char
d=Chr(t)&d   '// prepend the char to output
p=t          '// this char becomes the following char for next
Wend         '// repeat etc.

Ho provato questo in un file vbscript con il codice sopra avvolto come una funzione:

dim s
Dim arr()
s = Split("173, 209, 216, 219, 198, 198, 225, 222, 208, 100, 7272, 10908, 11664, 11988, 9657, 9657, 12654, 12312, 10800, 0", ",")
ReDim arr(UBound(s))
Dim x 
For x = 0 To UBound(s)
    arr(x) = cint(s(x))
Next 

msgbox "=" & d(arr)



Private Function d(a())
d="":p=0:n=(UBound(a)+1)/2:While n>0:n=n-1:t=a(n)-p:d=Chr(t)&d:p=t:Wend
End Function

1

Pulito , 96 81 78 77 byte

zeroè il carattere nullo.
Potrei salvare un altro byte se Clean non fosse così esigente in termini di valori letterali nulli nel file di origine.

import StdEnv
f=init o foldr(\a t=[toChar a-t!!0:t])[zero]o takeWhile((>)245)

Provalo online!


Le funzioni anonime sono generalmente accettabili, quindi se vuoi puoi eliminare f=.
Laikoni,

@Laikoni Non sono sicuro della validità di questo in questo caso, perché ha bisogno di parentesi da usare in linea, ed f=è il compito più breve, quindi una chiamata minima ne aggiunge comunque due.
Οuroso




0

Perl 6 ,  43 39  35 byte

{[~] [R,](produce *R-*,[R,] .[^*/2])».chr}

Provalo

{[~] [R,]([\[&(*R-*)]] [R,] .[^*/2])».chr}

Provalo (fa lo stesso come sopra)

{[~] [R,]([\R[&(*R-*)]] .[^*/2])».chr}

Provalo

{[R~] [\R[&(*R-*)]](.[^*/2])».chr}

Provalo

Spiegazione:

{[R~] [\R[&(*R-*)]](.[^*/2])».chr}

{                                }      # block lambda with parameter `$_`

      [\R[&(*R-*)]](.[^*/2])            # turn sums back into ordinals (reversed)

                    .[^*/2]             # first half of `$_` (implicit method call)
            *R-*                        # lambda, reverse of *-*
         [&(    )]                      # use it as an infix operator
                                        # (same as R- except left associative)
        R                               # reverse arguments and associativity
                                        # (same as - except right associative)
      [\          ](       )            # produce values `[\+] 1,2,3` => `(1,3,6)`
                                        # uses associativity to determine direction
                                        # `[\**] 1,2,3` => `(3,8,1)`

                            ».chr       # call `.chr` method on all values
                                        # (possibly concurrently)

 [R~]                                   # concatenate in reverse
                                        # (shorter than `join '', reverse …`)

0

05AB1E , 9 byte

2ä¬Å«-}çJ

Provalo online!

Spiegazione

2ä        # Split input list in two (equal if possible) parts.
  ¬       # Push head(a).
   Å«-}   # Cumulative reduce the list by subtraction (from the right).
       ç  # Convert each integer in the list to its corresponding ASCII char.
        J # Join list together to string.

Non hai bisogno di Join.
Shaggy,

Tuttavia ç, @Shaggy non trasforma implicitamente l'elenco di caratteri in una stringa. Se capisco correttamente il problema, il programma deve generare una stringa e non un elenco di caratteri.
Wisław,

0

Japt, 12 byte

Deve esserci un modo più breve per ottenere la prima metà dell'array ...

¯UÊz)Ôån Ômd

Provalo


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.