Keyboard Shift Cipher

21

Diberikan input berikut:

  • Bilangan bulat di nmana n > 0.
  • Sebuah string sdi mana stidak kosong dan s~=[0-9A-Z]+(ibukota alpha-numeric saja).

Menggunakan keyboard QWERTY standar yang disederhanakan (seperti yang ditunjukkan di bawah):

1234567890
QWERTYUIOP
ASDFGHJKL
ZXCVBNM

Lakukan operasi berikut:

  • Temukan baris asli setiap karakter di keyboard.
  • Ganti surat dengan padanan bergeser yang benar untuk nberdasarkan posisi aslinya + n.
    • EG s="AB"dan n=2: Aakan menjadi Ddan Bakan menjadi M.
  • Jika keyboard_row[position + n] > keyboard_row.length, bungkus kembali ke awal.
    • EG s="0P"dan n=2: 0akan menjadi 2dan Pakan menjadi W.

Contoh:

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

Aturan

  • Ini adalah , kemenangan byte-count terendah.

Ini sedikit lebih sulit daripada yang terlihat pada pandangan pertama.

Guci Gurita Ajaib
sumber
2
Apakah kita diperbolehkan mengambil input sebagai karakter-array bukan string? Saat ini kami mengira kami, tetapi lupa bertanya ..
Kevin Cruijssen
@KevinCruijssen mengangkat bahu yakin, itu tidak terlalu aneh. Kecuali jika Anda menghemat satu byte untuk memutuskan dasi saya tidak mengeluh.
Magic Gurita Guci

Jawaban:

11

Jelly , 13 byte

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

Cobalah online!

Bagaimana itu bekerja

Ø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.
Dennis
sumber
2
Jelly memiliki tata letak keyboard bawaan eh?
Magic Gurita Guci
4
@MagicOctopusUrn Tidak, hanya QWERTY sekarang :-P
Erik the Outgolfer
13 byte? Set karakter apa yang seharusnya? Dalam UTF-8 itu 26 byte!
Cephalopod
2
@Cephalopod Jelly menggunakan halaman kode 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)

Cobalah online!

Ini menggunakan string yang cukup besar (99 salinan dari setiap baris) dan LCM antara panjang baris (630) untuk menemukan substitusi yang benar menghindari koreksi individu di antara setiap baris.

tongkat
sumber
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 terima kasih kepada @ OlivierGrégoire yang memodifikasi input-array alih-alih mencetak secara langsung.

Penjelasan:

Cobalah 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)
Kevin Cruijssen
sumber
1
158 byte , dengan biaya input-output the char[].
Olivier Grégoire
5

Retina , 49 byte

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

Cobalah online! Mengambil input ndan spada jalur yang terpisah. Penjelasan:

"$&"+

Ulangi nkali.

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

Geser semua karakter satu tombol ke kanan.

0A`

Hapus n.

Neil
sumber
5

JavaScript (ES6), 101 99 byte

Mengambil input dalam sintaks currying (s)(n). Bekerja dengan array karakter.

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

Uji kasus

Bagaimana?

Kami mencari posisi p dari setiap karakter input dalam string S di mana baris keyboard disisipkan: 4 karakter pertama adalah '1QAZ' (kolom pertama keyboard), 4 karakter berikutnya adalah '2WSX' (kolom kedua keyboard) dan sebagainya. Posisi yang tidak digunakan diisi dengan garis bawah dan yang terakhir dibuang begitu saja.

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

Ini memungkinkan kita untuk dengan mudah mengidentifikasi baris dengan p mod 4 dan menghilangkan kebutuhan untuk pemisah eksplisit antara baris.

Kami maju dengan 4n posisi, menerapkan modulo benar untuk baris ini (40, 40, masing-masing 36 dan 28) dan memilih karakter pengganti ditemukan di posisi baru ini di S .

Arnauld
sumber
3

Jelly , 18 byte

ØQØDṭẋ€‘}Ẏ©iЀ⁸+ị®

Cobalah online!

Erik the Outgolfer
sumber
3

C,  152  149 byte

Terima kasih kepada @gastropner karena telah menghemat tiga 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]);}

Cobalah online!

Belum dibuka:

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]);
}
Steadybox
sumber
Entah aku berhalusinasi, atau lingkaran dalam bisa diubah, for(j=l;j--;)tetapi aku tidak tahu mengapa tanpa ada perubahan lainnya. Namun, Anda harus sampai 149.
gastropner
@gastropner Ah, ya, urutan pencarian tidak masalah, jadi itu berfungsi. Terima kasih!
Steadybox
2

Merah , 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)]]]]

Cobalah online!

Tidak Disatukan:

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) ]]]]
Galen Ivanov
sumber
2

Haskell , 99 byte

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

Cobalah online!

Roman Czyborra
sumber
Anda bisa menggunakan s#n= ...bukan f(s,n)= ...yang hanya contoh notasi yang digunakan untuk contoh.
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/"}

Cobalah online!

Xcali
sumber
Sial, saya tidak melihat jawaban Anda. Mereka pada dasarnya sama, jangan ragu untuk menggunakan optimasi saya dan saya akan menghapus jawaban saya. Biarkan saya tahu, jika tidak, saya hanya akan menghapus komentar ini :)
Dom Hastings
@HomHastings Mereka cukup berbeda. Harap simpan keduanya. Saya suka melihat variasi dalam pendekatan. Saya belajar dari mereka semua ...
Ton Hospel
1

Japt, 20 byte

Kehabisan pintu untuk makan malam jadi lebih banyak bermain golf dan penjelasan untuk diikuti.

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

Cobalah

Shaggy
sumber
1

Perl, 59 58 57 56 byte

Termasuk +untuk-p

Berikan input pada STDIN sebagai 2 baris, pertama string, lalu ulangi

(echo 0PLM; echo 2130) | perl -pe '$a="OPQWERTYUILASDF-MZXCVBNM0-90";eval"y/HI$a/J$a/;"x<>'
Ton Hospel
sumber
Wow, saya tidak percaya Anda mendapat 29 byte dari saya! Saya cukup senang dengan itu awalnya ...
Dom Hastings
0

Perl 5 , 85 byte

84 byte kode +1 untuk -p.

eval join"",map"y/$_/@{[/./&&$'.$&]}/;",(1234567890,QWERTYUIOP,ASDFGHJKL,ZXCVBNM)x<>

Cobalah online!

Dom Hastings
sumber
0

Bersih , 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]

Cobalah online!

Fungsi Lambda dengan tanda tangan Int ![Char] -> [Char]

Suram
sumber
0

Ruby , 101 byte

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

Cobalah online!

Sejujurnya saya sedikit kecewa karena saya tidak bisa berbuat lebih baik dengan metode 'pintar'. Yang paling dekat saya adalah di sepanjang garis

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

untuk keuntungan bersih 7 karakter.

benj2240
sumber