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.


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.

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.


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)

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.


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 .



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

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

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!


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!


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


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<>'

Wow, saya tidak percaya Anda mendapat 29 byte dari saya! Saya cukup senang dengan itu awalnya ...
Dom Hastings


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]


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.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.