キーボードシフト暗号


21

次の入力が与えられた場合:

  • 整数nどこn > 0
  • swhere sが空でない文字列s~=[0-9A-Z]+(英数字のみ)。

標準の簡素化されたQWERTYキーボードを使用します(以下を参照)。

1234567890
QWERTYUIOP
ASDFGHJKL
ZXCVBNM

次の操作を実行します。

  • 各文字がキーボード上にある元の行を見つけます。
  • n元の位置+ nに基づいて、文字を正しいシフト等価文字に置き換えます。
    • EG s="AB"とはn=2AとなるDBなりますM
  • の場合keyboard_row[position + n] > keyboard_row.length、最初に戻ります。
    • EG s="0P"とはn=20となる2PなりますW

例:

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

ルール


これは、一見思われるよりも少し難しいです。


2
入力を文字列ではなく文字配列として使用できますか?現在、我々が、尋ねるのを忘れて...と仮定
ケビンCruijssen

@KevinCruijssenは確かに肩をすくめ、それはあまりにも風変わりではありません。それがネクタイを壊すためにあなたにバイトを節約しない限り、私は文句を言いません。
魔法のタコ

回答:


11

ゼリー、13バイト

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

オンラインでお試しください!

使い方

Ø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にはキーボードレイアウトが組み込まれていますか?
魔法のタコ

4
@MagicOctopusUrnいいえ、今のところQWERTYのみ:-P
エリック・ザ・アウトゴルファー

13バイト?どの文字セットが想定されていますか?UTF-8では26バイトです!
頭足類

2
@Cephalopod JellyはJellyコードページを使用します
デニス

9

Python 2、110バイト

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

オンラインでお試しください!

これは、十分な長さの文字列(各行の99コピー)と行間のLCM(630)を使用して、各行間の個別の修正を回避する正しい置換を見つけます。


7

Java 8、159 158バイト

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バイトは、@OlivierGrégoireが直接印刷する代わりにinput-arrayを変更したおかげです。

説明:

オンラインでお試しください。

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)


5

網膜、49バイト

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

オンラインでお試しください!入力ns別の行に入力します。説明:

"$&"+

繰り返しnます。

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

すべての文字を1キー右にシフトします。

0A`

を削除しnます。


5

JavaScript(ES6)、101 99バイト

カリー化構文の入力を受け取ります(s)(n)。文字の配列で動作します。

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

テストケース

どうやって?

キーボード行がインターリーブされている文字列S内の入力の各文字の位置pを探します。最初の4文字は「1QAZ」(キーボードの最初の列)、次の4文字は「2WSX」(2番目の列)キーボードの)など。未使用の位置にはアンダースコアが埋め込まれ、最後の位置は単純に破棄されます。

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

これにより、p mod 4で行を簡単に識別できるようになり、行間の明示的な区切り文字が不要になります。

4nの位置に進み、この行に正しいモジュロ(それぞれ40、40、36、28)を適用し、Sのこの新しい位置にある置換文字を選択します。



3

C、 152  149バイト

3バイトを節約してくれた@gastropnerに感謝!

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

オンラインでお試しください!

展開:

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

私は幻覚を起こしているか、内側のループを変更することができますがfor(j=l;j--;)、他に変更がなければなぜなのかわかりません。それでも、149に到達する必要があります。
gastropner18年

@gastropnerああ、はい、検索順序は関係ないので、動作します。ありがとう!
Steadybox

2

、152バイト

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

オンラインでお試しください!

ゴルフをしていない:

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


1

Perl 5、94 + 1(-p)= 95バイト

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

オンラインでお試しください!


くそー、私はあなたの答えを見ませんでした。基本的に同じです。最適化を自由に使用してください。回答を削除します。そうでない場合はお知らせください。このコメントを削除します:)
Dom Hastings

@DomHastings彼らは十分に異なっています。両方保管してください。私はアプローチのバリエーションを見るのが好きです。私は...それらのすべてから学ぶ
トンHospel


1

Perl、59 58 57 56バイト

含み+のために-p

STDINに2行で入力します。最初に文字列、次に繰り返し

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

うわー、あなたが私のバイトを29バイト受け取ったなんて信じられない!私は...もともとかなりそれに満足していた
ドムヘイスティングス



0

Ruby、101バイト

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

オンラインでお試しください!

正直言って、「賢い」方法でもっとうまくできなかったことに少しがっかりしています。一番近いのは

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

純利益は7文字です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.