これを何回押すべきですか?


24

私たちは皆、昔ながらの電話キーパッドに慣れていますよね?参考までに、次のようになります。

Telephone Keybad


小文字のASCII文字と単一のスペースのみで構成される文字列を考える、あなたの仕事は、上記のように電話のキーパッドで文字列全体を入力するために必要なタップ数を返すことです。

これに不慣れな方のために、以下にその仕組みを示します。

  • 2たとえば、数字が付いたキーには、文字列もabc書き込まれています。を入力するにはa、このキーを1回b押すc必要があります。2回押す必要があり、3回押す必要があります。

  • 同じキーにある連続した文字の場合、もう一度押す前に1秒待つ必要があります。したがって、を入力する場合はcb、を3回押してc、1秒待ってから、を2回押しbて5タップする必要があります。

  • 同じことが他のすべてのキーにも当てはまりますが、1回押すだけでよい1 つのスペースを除きます。また、キー79は4つの文字があります。同じアルゴリズムが適用され、唯一の違いは文字数です。各キーに対応する文字列は、上の画像(ただし小文字)、または受信する可能性のあるすべての文字を含む次のリストにあります。

    "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz", " "
    

テストケース

入力->出力(説明)

""-> 0(何もタップしないでください)
"water"-> 8( "w、a、t"はそれぞれ1タップ(キー9、2および8)、 "e"は2タップ(キー3)、 "r"は3タップ(キー7) )、1 + 1 + 1 + 2 + 3 = 8)
「石鹸」-> 9(4 + 3 + 1 + 1)
「カンデラ」-> 13(3 + 1 + 2 + 1 + 2 + 3 + 1)
「コードゴルフ」-> 20(3 + 3 + 1 + 2 + 1(スペース用)+ 1 + 3 + 3 + 3)
「丘の王」-> 33(2 + 3 + 2 + 1 + 1 + 3 + 3 + 1 + 1 + 2 + 2 + 1 + 2 + 3 + 3 + 3)

スペック

  • 標準のI / Oルールとデフォルトの抜け穴が適用されます。

  • 言語のネイティブString型でのみ入力を取得できます。出力は、整数またはその整数の文字列表現のいずれかです。

  • これはであり、すべての言語で最短の答えが得られます。




2
毎秒1タップし、1秒間待たなければならず、タップの代わりにをカウントする場合、これはより興味深い質問になると思います。
ヤック

あまりにも複雑になる@Yakk
ミスターXcoder

@ Mr.Xcoder確かですか?ここでのコードウィザードは、ツイートよりも少ないスペースで不可能なことをするのを見てきました。
J_F_B_M

回答:


11

JavaScript(ES6)77 66 64 60バイト

(@Johan Karlssonと@Arnauldのおかげで数バイト節約されました)。

s=>[...s].map(l=>s=~~s+2+'behknquxcfilorvysz'.search(l)/8)|s


(s,t=0)=>[...s].map(l=>t+=(1+'behknquxcfilorvysz'.indexOf(l)/8|0)+1)&&t71バイト
ヨハンカールソン

ありがとう、@ JohanKarlsson、私はシャワーを浴びている間も同じことを考え出した!さらに5バイト削る最適化を見つけました。
リックヒッチコック

6
71バイトの純粋な算術ソリューションを見つけました:f=s=>[...s].map(c=>t+=((c=parseInt(0+c,36))>23?c+3:c&&~-c%3)%7%4+1,t=0)|t
ニール

1
@Neil、それは短くはないかもしれませんが、確かに賢いです。
リックヒッチコック

1
@Neil投稿してください。
ミスターXcoder

7

05AB1E29 26 25バイト

ð¢svA•22ā₂•S£ð«øðδKy.åƶOO

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

説明

ð¢                         # count spaces in input
  sv                       # for each char y in input
    A                      # push the lowercase alphabet
     •22ā₂•S               # push the base-10 digit list [3,3,3,3,3,4,3,4]
            £              # split the alphabet into pieces of these sizes
             ð«            # append a space to each
               ø           # transpose
                ðδK        # deep remove spaces
                   y.å     # check y for membership of each
                      ƶ    # lift each by their index in the list
                       O   # sum the list
                        O  # sum the stack

申し訳ありませんが、空の入力のために、これは10を与えることは、他の場所で結構です
氏Xcoder

@ Mr.Xcoder:空の文字列は出力されませんが、まだ間違っています。お知らせいただきありがとうございます、修正します。
エミグナ

2
TIOに10を与えます。
ミスターXcoder

@ Mr.Xcoder:空の文字列を明示的に指定する必要があります。入力は空の文字列と同じではありません。ちょっとわかりにくいです。ただし、今すぐ修正:)
エミグナ

@ Mr.Xcoder:空の文字列入力が同様に与えられたこの
Emigna

7

Python 2、56バイト

@RickHitchcockのJavascriptソリューションと同じアルゴリズムを使用します

lambda x:sum('behknquxcfilorvysz'.find(c)/8+2for c in x)

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


興味深いソリューション。スペースではどのように機能しますか?>。<
ミスターXcoder

@ Mr.Xcoderは、文字列にないものを'...'.find(c)返します-1。2を追加すると、キーを1回押すだけです。
-ovs

私はそれが戻ってきたことを知って-1いまし+2たが、定型文の後を持っていることに気づきませんでした...とにかく、はるかに短いPythonソリューション。
ミスターXcoder

Oml、私はあなたがそれを投稿したことに気づくまで、私のプログラムをゆっくりとゴルフした後、まったく同じ解決策をたまたま作りました:(この解決策を見つけるための素晴らしい仕事:)
マリオ・イシャック


5

Dyalog APL、37バイト

+/⌈9÷⍨'adgjmptw behknqux~cfilorvy~'⍳⍞

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

どうやって?

取得した文字列に入力のすべての文字のNDEXを'adgjmptw behknqux~cfilorvy~'sz28がデフォルトになります)9、ラウンドアップと合計することによって、除算。


'adgjmptw ' 'behknqux' 'cfilorvy' 'sz'いくつかのバイトを保存するために使用できます
Kritixi Lithos


@LeakyNun onice
ウリエル

あなたは、文字列にスペースをドロップすることができます
KritixiのLithos

@Uriel待って、カウントf←する必要がないので47バイト
リーキー修道女

4

JavaScript(ES6)、71バイト

f=
s=>[...s].map(c=>t+=((c=parseInt(0+c,36))>23?c+3:c&&~-c%3)%7%4+1,t=0)|t
<input oninput=o.textContent=f(this.value)><pre id=o>

レターテーブルはありません!私は@LeakyNunの式をよく理解していなかったので、自分で考えました。


純粋な算術:)
Mr. Xcoder

何をする s=>[...s]理由だけではなく、やるs=>s.map()...
エヴァンキャロル

1
@EvanCarroll sは文字列なので、map直接はできません。...s反復しs[...s]反復を配列に変換し、効果的に分割しますs文字の配列に。
ニール

4

C、 211 196バイト

ここでの最初の提出...非常に長く見え、これは効率的なアプローチではないことがわかりますが、少なくとも動作します:)

f(char*n){char*k=" abcdefghijklmnopqrstuvwxyz";int t[]={0,3,3,3,3,3,4,3,4};int l=0,s,j,i;while(*n){i=0;while(k[i]){if(k[i]==*n){s=0;for(j=0;s<i-t[j];s+=t[j++]);*n++;l+=(!i?1:i-s);}i++;}}return l;}

ゴルフされていないバージョン:

int f(char *n){
  char *k=" abcdefghijklmnopqrstuvwxyz";
  int t[]={0,3,3,3,3,3,4,3,4};
  int l=0,s,j,i;
  while(*n){                          // loop through input characters
    i=0;
    while(k[i]){
      if(k[i]==*n){                   // find matching char in k
        s=0;
        for(j=0;s<i-t[j];s+=t[j++]);  // sum up the "key sizes" up to the key found
        *n++;
        l+=(!i?1:i-s);                // key presses are i-s except for space (1)
      }
      i++;
    }
  }
  return l;
}

*(k+i)することができますk[i]
電卓

あなたは後にスペースを削減することができます*(例char*n)、そしてあなたの空にあなたの宣言を追加for声明(の代わりに、int s=0,j=0;(for(;あなたは持っているだろうfor(int s=0,k=0;)との代わりにi==0使用!i
タス

それらのヒントをありがとう。s後で使用するためforループに入れることはできませんでしたが、int宣言をまとめて、必要な場所に割り当てを使用しました。
-dbuchmann

Cゴルファーの仲間だ とにかく、いくつかのポインター:forループはほぼすべての状況でwhileループよりも厳密に優れています-特に反復式で、フリーセミコロンを利用してください。ほとんどの場所でセミコロンの代わりにコンマを使用します。これにより、ほとんどの場所で中括弧を使用しないで済みます。他の最適化もありますが、コンパイルするCのバージョンにより依存しています。
dj0wns

4

ハスケル- 74 71 62バイト

編集:フィルターの代わりにリスト内包表記を使用して3バイトを削除

編集:シラクーサ、ライコニ、ズガルブのおかげで9バイト節約!

f=sum.(>>= \x->1:[1|y<-"bcceffhiikllnooqrrsssuvvxyyzzz",y==x])

使用法

λ> f "candela"
13
λ>

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


重複した手紙の目的は何ですか?
ミスターXcoder

@ Mr.Xcoderタップのカウントに使用されます。説明を追加します。
ヘンリー

あなたは書き換えることにより、1バイト保存することができますff=length.(=<<)(\x->x:[y|y<-l,y==x])(=<<)あるconcatMapここに。
シラクーサ

そして、別のものfilterf=length.(=<<)(\x->x:filter(==x)l)
シラクーサ

1
l一度しか使用しないので、インライン化できます。
ライコニ


3

Clojure、82 76バイト

#(apply +(for[c %](+(count(filter #{c}"bcceffhiikllnooqrrsssuvvxyyzzz"))1)))

ああ、それだけに簡単ですfilterし、count使用よりfrequencies。元の:

#(apply +(count %)(for[c %](get(frequencies"bcceffhiikllnooqrrsssuvvxyyzzz")c 0)))

文字列は、指定された文字のキーを押す必要がある回数をエンコードします:)





2

Java、95 73バイト

a->a.chars().map(b->1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112)).sum()

Thanks to Kevin Cruijssen for making the function a lambda expression (where a is of type String). 95 bytes became 73 bytes!

A lambda expression sums up the press count of each character using map(). map() converts each character (ASCII in lower case range is 97-122) in the stream to the appropriate value (looks like simple saw wave, but taking into account both 4 cycles is annoying) using this math: 1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112). Here's a desmos graph of that model.


The loophole list says not to post code snippets even though it looks like everyone so far has done that. Either way, my full program is 130 bytes. Here it is: interface Z{static void main(String a){System.out.print(a.chars().map(b->1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112)).sum());}}
Adam Mendenhall

1
Welcome to PPCG! You're indeed right that snippets aren't allowed, but the default is program or function. And with Java 8 you can use lambdas. So in this case a->{return a.chars().map(b->1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112)).sum();} is allowed. And since it's a single return statement, a->a.chars().map(b->1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112)).sum() (73 bytes) would be your answer. Also, here is a TryItOnline-link of your answer you might want to add to your answer. Again: welcome, and nice answer. +1 from me.
Kevin Cruijssen

2
Some things to note about lambdas. You don't have to count f= nor the leading semi-colon ;. And you also don't have to add the type of the parameter as long as you mention what the type is (so instead of (String a)-> you can use a-> and mention that input a is a String in your answer). Oh, and Tips for golfing in Java and Tips for golfing in <all languages> might be interesting to read, in case you haven't yet.
Kevin Cruijssen

1

Mathematica, 83 bytes

c=Characters;Tr[Tr@Mod[c@"bc1def1ghi1jkl1mno1pqrstuv1wxyz "~Position~#,4]+1&/@c@#]&

It seems to be generally accepted that Mathematica answers are allowed to use lists of characters for string variables, such as the input to this function. (Also is there an a missing at the start of "bc1..."?)
Greg Martin

this is code golf.this gives the right result without a."Tr " does the job
J42161217

1

QBIC, 94 bytes

[_l;||_SA,a,1|p=p-(instr(@sz`,B)>0)-(instr(@cfilorvy`+C,B)>0)-(instr(@behknqux`+C+D,B)>0)+1}?p

Explanation

[    |      FOR a = 1 TO
 _l |         the length of
   ;            the input string (A$)
_SA,a,1|    Take the a'th char of A$ and assign it to B$
p=p         p is our tap-counter, and in each iteration it gets increased by the code below
            which consist of this pattern:
                instr(@xyz`,B)>0    where 
                - instr tests if arg 2 is in arg 1 (it either returns 0 or X where X is the index of a2 in a1)
                - @...` defines the letters we want to test as arg1
                - B is the current letter to count the taps for
            Each of these blocks adds 1 tap to the counter, and each block has the letters of its level
            (4-taps, 3-taps or 2-taps) and the level 'above' it.
    -(instr(@sz`,B)>0)              <-- letters that require 4 taps
    -(instr(@cfilorvy`+C,B)>0)      <-- 3 or 4 taps
    -(instr(@behknqux`+C+D,B)>0)    <-- 2, 3,or 4 taps
    +1                              <-- and always a 1-tap
}           NEXT
?p          PRINT the number of taps

1

Bash, 69 68 bytes

bc<<<`fold -1|tr "\n "adgjmptwbehknquxcfilorvysz +[1*9][2*8][3*8]44`

Try it online!

Folds one char per line, transliterates each newline with +, each space with 1 and each letter with the corresponding number of pushes. bc does the sum.


on your machine you may need bc <(fold -1|tr "\n "adgjmptwbehknquxcfilorvysz +[1*9][2*8][3*8]44;echo 0)
marcosm

1

C, 92 88 bytes

c,n;f(char*s){n=0;while(c=*s++)n+=(c=='s')+3*(c>'y')+1+(c+1+(c<'s'))%3-(c<33);return n;}

you may use s=n to replace return n, and combine s++; with c=*s. It could be 9 bytes shorter.
Keyu Gan

@KeyuGan s=n wouldn't work, since s is a local. And *s=n wouldn't work since there are only CHAR_BIT bits in *s, which wouldn't be enough for some messages. But you're right about the s++. Thanks.
Ray

1

APL (Dyalog), 36 bytes

{+/(3×⍵∊'sz'),1+31+⍵⍳⍨819⌶⎕A~'SZ'}

Try it online!

Finds the mod-3 indices in the alphabet without S and Z. Since space, S, and Z are not found, they "have" index 25 (one more than the max index), which is good for space. Then we just need to add 3 for each S or Z.

{ anonymous function where the argument is represented by :

⎕A~'SZ' the uppercase Alphabet, except for S and Z

819⌶ lowercase

⍵⍳⍨ the ɩndices of the argument in that

¯1+ add negative one

3| mod-3

1+ add one (this converts all 0-mods to 3)

(), prepend:

  ⍵∊'sz' Boolean where the argument is either s or z

   multiply by 3

+/ sum



1

Pip, 100 90 bytes

a:qb:["abc""def""ghi""jkl""mno""pqrs""tuv""wxyz"s]Fc,#a{Fd,#b{e:((bd)@?(ac))e<4?i+:e+1x}}i

Check each character of the input for a match in each element of b. The index of that match plus 1 gets added to the total.

Try it online!

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