The Keyboard Shift Cipher


21

Dato il seguente input:

  • Un numero intero ndove n > 0.
  • Una stringa sdove snon è vuota e s~=[0-9A-Z]+(solo maiuscole alfanumeriche).

Utilizzando una tastiera QWERTY standard e semplificata (come mostrato di seguito):

1234567890
QWERTYUIOP
ASDFGHJKL
ZXCVBNM

Eseguire la seguente operazione:

  • Trova la riga originale in cui si trova ciascun personaggio sulla tastiera.
  • Sostituisci la lettera con l'equivalente spostato corretto in nbase alla sua posizione originale + n.
    • EG s="AB"e n=2: Adiventerebbe De Bdiventerebbe M.
  • Se keyboard_row[position + n] > keyboard_row.length, torna all'inizio.
    • EG s="0P"e n=2: 0diventerebbe 2e Pdiventerebbe W.

Esempi:

f("0PLM",1)    = 1QAZ
f("ZXCVB",2)   = CVBNM
f("HELLO",3)   = LYDDW
f("0PLM",11)   = 1QSV
f("0PLM",2130) = 0PHX

Regole

  • Questo è , vince il conteggio di byte più basso.

Questo è leggermente più difficile di quanto sembri a prima vista.


2
È consentito prendere l'input come array di caratteri anziché come stringa? Attualmente ipotizzato, ma abbiamo dimenticato di chiedere ..
Kevin Cruijssen,

@KevinCruijssen scrollata di spalle , certo, non è troppo stravagante. A meno che non ti risparmi un byte per rompere un pareggio, non mi lamento.
Magic Octopus Urn,

Risposte:


11

Gelatina , 13 byte

ØQØDṭ,ṙ€¥⁸F€y

Provalo online!

Come funziona

ØQØDṭ,ṙ€¥⁸F€y  Main link. Left argument: n (integer). Right argument: s (string)

ØQ             Qwerty; set the return value to
               ["QWERTYUIOP", "ASDFGHJKL", "ZXCVBNM"].
  ØD           Digits; yield "0123456789".
    ṭ          Tack, yielding ["QWERTYUIOP", "ASDFGHJKL", "ZXCVBNM", "0123456789"].
        ¥⁸     Call the two links to the left as a dyadic chain, with right
               argument n.
      ṙ€       Rotate each string in the array n units to the left.
     ,         Yield the pair of the unmodified and the rotated string array.
          F€   Flatten each, mapping, e.g., ["QWERTYUIOP", ..., "0123456789"] to
               "QWERTYUIOPASDFGHJKLZXCVBNM0123456789".
            y  Translate s according to the mapping we've built.

2
Jelly ha incorporati layout di tastiera eh?
Magic Octopus Urn

4
@MagicOctopusUrn No, solo QWERTY in questo momento :-P
Erik the Outgolfer,

13 byte? Quale set di caratteri dovrebbe essere? In UTF-8 sono 26 byte!
Cefalopode,

2
@Cephalopod Jelly utilizza la tabella codici Jelly .
Dennis,

9

Python 2 , 110 byte

lambda s,n,y='1234567890'*99+'QWERTYUIOP'*99+'ASDFGHJKL'*99+'ZXCVBNM'*99:''.join(y[y.find(c)+n%630]for c in s)

Provalo online!

Questo utilizza una stringa abbastanza grande (99 copie di ogni riga) e l'LCM tra le lunghezze delle righe (630) per trovare la sostituzione corretta evitando la correzione individuale tra ogni riga.


7

Java 8, 159 158 byte

n->s->{for(int i=s.length,j;i-->0;)for(String x:"1234567890;QWERTYUIOP;ASDFGHJKL;ZXCVBNM".split(";"))if((j=x.indexOf(s[i])+n)>=n)s[i]=x.charAt(j%x.length());}

-1 byte grazie a @ OlivierGrégoire modificando l'input-array invece di stampare direttamente.

Spiegazione:

Provalo online.

n->s->{  // Method with integer and character-array parameters, and no return-type
  for(int i=s.length,j;i-->0;)
         //  Loop over the input character-array with index
    for(String x:"1234567890;QWERTYUIOP;ASDFGHJKL;ZXCVBNM".split(";"))
         //   Inner loop over the qwerty-lines
      if((j=x.indexOf(s[i])+n)>=n)
         //    If the current qwerty-line contains the character
         //     Set `j` to the index of this character on that line + input `n`
        s[i]=x.charAt(j%x.length());}
         //     Replace the character at index `i`
         //     with the new character (at index `j` modulo length_of_qwerty_line)

1
158 byte , al costo di input-output dell'output char[].
Olivier Grégoire,

5

Retina , 49 byte

"$&"+T`9o`dQW\ERTYUI\OPQASDFG\HJK\LAZXC\VBNMZ
0A`

Provalo online! Accetta input ne ssu righe separate. Spiegazione:

"$&"+

Ripeti i ntempi.

T`9o`dQW\ERTYUI\OPQASDFG\HJK\LAZXC\VBNMZ

Sposta tutti i personaggi di una chiave a destra.

0A`

Elimina n.


5

JavaScript (ES6), 101 99 byte

Accetta input nella sintassi del curry (s)(n). Funziona con matrici di personaggi.

s=>n=>s.map(c=>(S='1QAZ2WSX3EDC4RFV5TGB6YHN7UJM8IK_9OL_0P')[(p=S.search(c)+n*4)%(-~'9986'[p%4]*4)])

Casi test

Come?

Cerchiamo la posizione p di ciascun carattere dell'input all'interno di una stringa S in cui le righe della tastiera sono interlacciate: i primi 4 caratteri sono '1QAZ' (prima colonna della tastiera), i successivi 4 caratteri sono '2WSX' (seconda colonna della tastiera) e così via. Le posizioni non utilizzate sono riempite con caratteri di sottolineatura e le ultime vengono semplicemente scartate.

col # | 0    | 1    | 2    | 3    | 4    | 5    | 6    | 7    | 8    | 9
------+------+------+------+------+------+------+------+------+------+---
row # | 0123 | 0123 | 0123 | 0123 | 0123 | 0123 | 0123 | 0123 | 0123 | 01
------+------+------+------+------+------+------+------+------+------+---
char. | 1QAZ | 2WSX | 3EDC | 4RFV | 5TGB | 6YHN | 7UJM | 8IK_ | 9OL_ | 0P

Questo ci consente di identificare facilmente la riga con p mod 4 ed elimina la necessità di separatori espliciti tra le righe.

Avanziamo di 4n posizioni, applichiamo il modulo corretto per questa riga (rispettivamente 40, 40, 36 e 28) e selezioniamo il carattere sostitutivo trovato in questa nuova posizione in S .



3

C,  152  149 byte

Grazie a @gastropner per aver salvato tre byte!

j,l;f(S,n){for(char*s=S,*k;*s;++s)for(k="1234567890\0QWERTYUIOP\0ASDFGHJKL\0ZXCVBNM\0";l=strlen(k);k+=l+1)for(j=l;j--;)k[j]-*s||putchar(k[(j+n)%l]);}

Provalo online!

srotolato:

j,l;
f(S,n)
{
    for (char*s=S, *k; *s; ++s)
        for (k="1234567890\0QWERTYUIOP\0ASDFGHJKL\0ZXCVBNM\0"; l=strlen(k); k+=l+1)
            for (j=l; j--;)
                k[j]-*s || putchar(k[(j+n)%l]);
}

O sto allucinando, o il ciclo interno può essere cambiato in for(j=l;j--;)ma non so perché senza nessun altro cambiamento. Comunque, dovresti
portarti

@gastropner Ah, sì, l'ordine di ricerca non ha importanza, quindi funziona. Grazie!
Steadybox

2

Rosso , 152 byte

f: func[s n][foreach c s[foreach[t l]["1234567890"10"QWERTYUIOP"10"ASDFGHJKL"9"ZXCVBNM"7][if p: find t c[if(i:(index? p)+ n // l)= 0[i: l]prin t/(i)]]]]

Provalo online!

Ungolfed:

f: func [s n][1
    foreach c s [
        foreach [t l] ["1234567890"10"QWERTYUIOP"10"ASDFGHJKL"9"ZXCVBNM"7][
            p: find t c
            if p [ 
                i: (index? p) + n // l
                if i = 0 [i: l]
                prin t/(i) ]]]]

2

Haskell , 99 byte

f(s,n)=[dropWhile(/=c)(cycle r)!!n|c<-s,r<-words"1234567890 QWERTYUIOP ASDFGHJKL ZXCVBNM",elem c r]

Provalo online!


È possibile utilizzare al s#n= ...posto del f(s,n)= ...quale è solo una notazione di esempio utilizzata per gli esempi.
Laikoni,

1

Perl 5 , 94 + 1 ( -p) = 95 byte

$s=<>;for$i(1234567890,QWERTYUIOP,ASDFGHJKL,ZXCVBNM){eval"y/$i/".(substr$i,$s%length$i)."$i/"}

Provalo online!


Accidenti, non ho visto la tua risposta. Sono sostanzialmente gli stessi, sentiti libero di usare le mie ottimizzazioni e rimuoverò la mia risposta. Fammi sapere, in caso contrario, rimuoverò questo commento :)
Dom Hastings il

@DomHastings Sono abbastanza diversi. Si prega di conservare entrambi. Mi piace vedere le variazioni nell'approccio. Imparo da tutti loro ...
Ton Hospel,

1

Japt, 20 byte

Correre fuori dalla porta per cena, quindi più golf e una spiegazione da seguire.

;£=D·i9òs)æøX)gV+UbX

Provalo


1

Perl, 59 58 57 56 byte

include + per-p

Dare input su STDIN come 2 righe, prima la stringa, quindi la ripetizione

(echo 0PLM; echo 2130) | perl -pe '$a="OPQWERTYUILASDF-MZXCVBNM0-90";eval"y/HI$a/J$a/;"x<>'

Wow, non posso credere che tu abbia ottenuto 29 byte dal mio! All'inizio ero abbastanza contento ...
Dom Hastings,


0

Pulito , 144 119 byte

import StdEnv

\n s=[l.[(i+n)rem(size l)]\\c<-s,l<-["1234567890","QWERTYUIOP","ASDFGHJKL","ZXCVBNM"],i<-[0..]&j<-:l|j==c]

Provalo online!

Funzione lambda con la firma Int ![Char] -> [Char]


0

Rubino , 101 byte

->s,n{n.times{s.tr! '1234567890QWERTYUIOPASDFGHJKLZXCVBNM','2345678901WERTYUIOPQSDFGHJKLAXCVBNMZ'};s}

Provalo online!

Sono sinceramente un po 'deluso dal fatto che non potrei fare di meglio con metodi "più intelligenti". Il più vicino che ho avuto è stato sulla falsariga di

a=%w{1234567890 QWERTYUIOP ASDFGHJKL ZXCVBNM}
b=a.map{|r|r[1..-1]<<r[0]}*''
a*=''
n.times{s.tr! a,b}

per un guadagno netto di 7 caratteri.

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.