Wie oft soll ich das drücken?


24

Wir sind alle an die alte Telefontastatur gewöhnt, oder? Als Referenz sehen Sie hier, wie es aussieht:

Telefon Keybad


Bei einer Zeichenfolge, die nur aus ASCII-Kleinbuchstaben und einzelnen Leerzeichen besteht , müssen Sie die Anzahl der Abgriffe zurückgeben, die erforderlich sind, um die gesamte Zeichenfolge mit einer Telefontastatur wie der oben angegebenen abzutippen.

Für diejenigen, die damit nicht vertraut sind, ist hier, wie es funktioniert:

  • Auf dem Schlüssel mit der Ziffer 2ist beispielsweise auch die Zeichenfolge abcgeschrieben. Um zu tippen a, müssen Sie diese Taste einmal drücken, denn bSie müssen zweimal drücken und cSie müssen dreimal drücken.

  • Bei aufeinanderfolgenden Buchstaben, die sich auf derselben Taste befinden, müssen Sie eine Sekunde warten, bevor Sie erneut drücken. Wenn Sie also tippen möchten cb, müssen Sie 3 Mal drücken c, eine Sekunde warten und dann zweimal drücken b, sodass Sie immer noch 5 Mal tippen müssen .

  • Gleiches gilt für alle anderen Tasten, mit Ausnahme einer einzelnen Leerstelle, für die nur ein Tastendruck erforderlich ist. Beachten Sie auch, dass die Tasten 7und 9vier Buchstaben haben. Es wird derselbe Algorithmus angewendet, der einzige Unterschied besteht in der Anzahl der Buchstaben. Die Zeichenfolgen für die einzelnen Tasten finden Sie in der Abbildung oben (jedoch in Kleinbuchstaben) oder in der folgenden Liste, die alle Zeichen enthält, die Sie möglicherweise erhalten:

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

Testfälle

Eingabe -> Ausgabe (Erläuterung)

"" -> 0 (nichts sollte getippt werden)
"Wasser" -> 8 ("w, a, t" erfordern jeweils 1 Tippen (auf die Tasten 9, 2 und 8), "e" erfordern 2 Tippen (auf die Taste 3), "r" erfordern 3 Tippen (auf die Taste 7) ), 1 + 1 + 1 + 2 + 3 = 8)
"Seife" -> 9 (4 + 3 + 1 + 1)
"candela" -> 13 (3 + 1 + 2 + 1 + 2 + 3 + 1)
"Code Golf" -> 20 (3 + 3 + 1 + 2 + 1 (für das Leerzeichen) + 1 + 3 + 3 + 3)
"König des Hügels" -> 33 (2 + 3 + 2 + 1 + 1 + 3 + 3 + 1 + 1 + 2 + 2 + 1 + 2 + 3 + 3 + 3)

Technische Daten

  • Es gelten Standard-E / A-Regeln und Standard-Regelungslücken.

  • Sie können nur Eingaben in den systemeigenen String-Typ Ihrer Sprache vornehmen. Die Ausgabe kann entweder eine Ganzzahl oder eine Zeichenfolgendarstellung dieser Ganzzahl sein.

  • Dies ist , die kürzeste Antwort in jeder Sprache gewinnt.




2
Ich denke, dass dies eine interessantere Frage wäre, wenn Sie 1 Tippen pro Sekunde ausführen und 1 Sekunde warten müssten und Sekunden anstelle von Tippen zählen würden.
Yakk

@Yakk Das wäre viel zu kompliziert
Mr. Xcoder

@ Mr.Xcoder Bist du dir aber sicher? Ich habe gesehen, dass die Code-Assistenten hier unmögliche Dinge auf weniger Raum tun als ein Tweet.
J_F_B_M

Antworten:


11

JavaScript (ES6) 77 66 64 60 Bytes

(Sparte einige Bytes dank @Johan Karlsson und @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)&&tfür 71 Bytes
Johan Karlsson

Danke, @JohanKarlsson, ich dachte mir dasselbe beim Duschen! Es wurde eine weitere Optimierung gefunden, um 5 weitere Bytes zu sparen.
Rick Hitchcock

6
Ich fand eine rein rechnerische Lösung für 71 Bytes f=s=>[...s].map(c=>t+=((c=parseInt(0+c,36))>23?c+3:c&&~-c%3)%7%4+1,t=0)|t.
Neil

1
@Neil, obwohl das vielleicht nicht kürzer ist, ist es sicherlich klüger.
Rick Hitchcock

1
@Neil Du solltest es posten.
Mr. Xcoder

7

05AB1E , 29 26 25 Bytes

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

Probieren Sie es online!

Erläuterung

ð¢                         # 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

Entschuldigung, aber für eine leere Eingabe ergibt sich 10. Es ist in Ordnung an anderer Stelle
Mr. Xcoder

@ Mr.Xcoder: Die leere Zeichenfolge gibt keine Ausgabe aus, ist aber immer noch falsch. Vielen Dank für die Benachrichtigung, ich werde es beheben.
Emigna

2
Es gibt 10 auf TIO.
Mr. Xcoder

@ Mr.Xcoder: Ja du musst die leere Zeichenkette explizit angeben. Keine Eingabe ist nicht dasselbe wie eine leere Zeichenfolge. Es ist ein bisschen verwirrend, wie ich weiß. Jetzt
behoben

@ Mr.Xcoder: Leerer String - Eingang wird wie angegeben diese
Emigna

7

Python 2 , 56 Bytes

Verwendet den gleichen Algorithmus wie die JavaScript-Lösung von @ RickHitchcock

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

Probieren Sie es online!


Interessante Lösung. Wie funktioniert es für Leerzeichen, ich verstehe es nicht>. <?
Mr. Xcoder

@ Mr.Xcoder für alles , was nicht in dem String '...'.find(c)zurückkehrt -1. Durch Hinzufügen von 2 erhalten wir einen Tastendruck.
Ovs

Ich wusste, dass es zurückkehrte -1, wusste aber nicht, dass Sie eine +2nach dem Boilerplate haben ... Jedenfalls die mit Abstand kürzeste Python-Lösung.
Mr. Xcoder

Oml, ich habe zufällig genau die gleiche Lösung erstellt, nachdem ich mein Programm langsam heruntergolfen hatte, bis mir klar wurde, dass Sie es gepostet haben :(
Gute


5

Dyalog APL, 37 Bytes

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

Probieren Sie es online!

Wie?

Holen Sie sich das ndex jedes Zeichen der Eingabe in der Zeichenfolge 'adgjmptw behknqux~cfilorvy~'( sund zwird standardmäßig bis 28), Division durch 9, rund und Summe.


Sie können verwenden 'adgjmptw ' 'behknqux' 'cfilorvy' 'sz', um einige Bytes zu speichern
Kritixi Lithos


@LeakyNun onice
Uriel

Sie können das Leerzeichen in der Zeichenfolge
löschen

@Uriel warte, du musst nicht zählen f←, es sind also 47 Bytes
Leaky Nun

4

JavaScript (ES6), 71 Byte

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>

Schau mal keine Buchstabentabellen! Ich habe die Formel von @ LeakyNun nicht ganz verstanden und bin auf meine eigene gekommen.


Reine Arithmetik :)
Mr. Xcoder

Was macht s=>[...s]warum nicht einfachs=>s.map()...
Evan Carroll

1
@EvanCarroll sist eine Zeichenfolge, Sie können es also nicht mapdirekt. ...siteriert s, während [...s]die Iteration in ein Array konvertiert und effektiv sin ein Array von Zeichen aufgeteilt wird.
Neil

4

C, 211 196 Bytes

Erste Einreichung hier ... sieht ziemlich lang aus und ich sehe, dass dies kein effizienter Ansatz ist, aber zumindest funktioniert es :)

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

Ungolfed-Version:

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)kann sein k[i].
CalculatorFeline

Sie können das Leerzeichen nach einem *(z. B. char*n) ausschneiden und Ihre Deklarationen zu Ihrer leeren forAnweisung hinzufügen (anstatt int s=0,j=0;(for(;Sie zu haben for(int s=0,k=0;) und stattdessen i==0verwenden!i
Tas

Vielen Dank für diese Hinweise. Ich konnte nicht sin die for-Schleife intschreiben, weil ich sie später benutze, aber ich habe die Deklarationen zusammengestellt und Zuweisungen dort verwendet, wo ich sie brauchte.
Dbuchmann

Yay ein Mit-C-Golfspieler! Wie auch immer, einige Hinweise: for-Schleifen sind in fast allen Situationen strikt besser als while-Schleifen - nutzen Sie die freien Semikolons, insbesondere im Iterationsausdruck. Verwenden Sie an den meisten Stellen Kommas anstelle von Semikolons, damit Sie an den meisten Stellen keine geschweiften Klammern haben. Es gibt andere Optimierungen, diese hängen jedoch eher davon ab, zu welcher Version von C Sie kompilieren.
dj0wns

4

Haskell - 74 71 62 Bytes

Bearbeiten: 3 Bytes wurden entfernt, indem ein Listenverständnis anstelle eines Filters verwendet wurde

Edit: Sparen Sie 9 Bytes dank Siracusa, Laikoni und Zgarb!

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

Verwendung

λ> f "candela"
13
λ>

Probieren Sie es online!


Was ist der Zweck der doppelten Buchstaben?
Mr. Xcoder

@ Mr.Xcoder Es wird verwendet, um die Wasserhähne zu zählen, ich werde eine Erklärung hinzufügen.
Henry

Sie können durch Umschreiben eines Bytes speichern fzu f=length.(=<<)(\x->x:[y|y<-l,y==x]), wo (=<<)ist concatMaphier.
Siracusa

Und noch eine mit zurück zu filter:f=length.(=<<)(\x->x:filter(==x)l)
Siracusa

1
Da Sie es lnur einmal verwenden, kann es inline gesetzt werden.
Laikoni


3

Clojure, 82-76 Bytes

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

Oh, es ist einfacher filterund einfacher zu countbedienen frequencies. Original:

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

Die Zeichenfolge kodiert, wie oft Sie die Taste für ein bestimmtes Zeichen mehrmals drücken müssen :)





2

Java, 95 73 Bytes

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

Vielen Dank an Kevin Cruijssen, der die Funktion zu einem Lambda - Ausdruck gemacht hat (wobei aes sich um einen Typ handelt)String ). 95 Bytes wurden 73 Bytes!

Ein Lambda-Ausdruck summiert die Pressezahl jedes Zeichens mit map(). map()konvertiert jedes Zeichen (ASCII in Kleinbuchstaben 97-122) im Stream in den entsprechenden Wert (sieht aus wie eine einfache Sägewelle, berücksichtigt aber beide 4 Zyklen, ist das ärgerlich) 1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112). Hier ist ein Desmos-Diagramm dieses Modells.


Die Lückenliste besagt, dass Code-Schnipsel nicht veröffentlicht werden sollen, obwohl es so aussieht, als ob dies bisher jeder getan hat. In jedem Fall ist mein volles Programm 130 Bytes . Hier ist es: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
Willkommen bei PPCG! Sie haben in der Tat Recht, dass Snippets nicht zulässig sind, aber die Standardeinstellung ist program oder function . Und mit Java 8 können Sie Lambdas verwenden. Also in diesem Fall a->{return a.chars().map(b->1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112)).sum();}ist erlaubt. Und da es sich um eine einzelne return-Anweisung handelt, wäre a->a.chars().map(b->1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112)).sum()( 73 Byte ) Ihre Antwort. Hier ist auch ein TryItOnline-Link zu Ihrer Antwort, den Sie möglicherweise zu Ihrer Antwort hinzufügen möchten. Nochmals: Willkommen und nette Antwort. +1 von mir.
Kevin Cruijssen

2
Einige Dinge über Lambdas zu beachten. Sie müssen weder zählen f=noch das führende Semikolon ;. Außerdem müssen Sie den Typ des Parameters nicht hinzufügen, solange Sie den Typ angeben (stattdessen (String a)->können Sie auch a->angeben, dass die Eingabe aein Stringin Ihrer Antwort ist). Oh, und Tipps für den Golfsport in Java und Tipps für die in <alle Sprachen> Golf spielen könnten interessant sein zu lesen, falls Sie noch nicht haben.
Kevin Cruijssen

1

Mathematica, 83 Bytes

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

Es scheint allgemein anerkannt zu sein, dass Mathematica-Antworten Listen von Zeichen für Zeichenfolgenvariablen verwenden dürfen, z. B. die Eingabe für diese Funktion. (Wird azu Beginn auch etwas vermisst "bc1..."?)
Greg Martin

Dies ist Code Golf. Dies gibt das richtige Ergebnis ohne ein. "Tr" erledigt den 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

Erläuterung

[    |      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`

Probieren Sie es online!

Faltet ein Zeichen pro Zeile, transkribiert jede neue Zeile mit +, jedes Leerzeichen mit 1und jeden Buchstaben mit der entsprechenden Anzahl von Anschlägen. bc macht die Summe.


Auf Ihrem Computer benötigen Sie möglicherweisebc <(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;}

Sie können verwenden s=nzu ersetzen return n, und verbinden s++;mit c=*s. Es könnte 9 Bytes kürzer sein.
Keyu Gan

@KeyuGan s=nwürde nicht funktionieren, da ses ein lokaler ist. Und *s=nwürde nicht funktionieren, da nur CHAR_BITBits enthalten sind *s, die für einige Nachrichten nicht ausreichen. Aber Sie haben Recht mit dem s++. Vielen Dank.
Ray

1

APL (Dyalog) , 36 Bytes

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

Probieren Sie es online!

Findet den mod-3 - Indizes im Alphabet ohne S und Z . Da Leerzeichen, S und Z nicht gefunden werden, haben sie den Index 25 (einen mehr als den Maximalindex), was für Leerzeichen gut ist. Dann müssen wir nur noch 3 für jedes S oder Z addieren .

{ anonyme Funktion, bei der das Argument durch ⍵ dargestellt wird :

⎕A~'SZ' der Großbuchstabe A lphabet mit Ausnahme von S und Z

819⌶ Kleinbuchstaben

⍵⍳⍨ die Gründe des Arguments darin

¯1+ Fügen Sie ein negatives hinzu

3| mod-3

1+ addiere einen (dies wandelt alle 0-Mods in 3 um)

(), Voranstellen:

  ⍵∊'sz' Boolescher Wert, bei dem das Argument entweder s oder z ist

   multiplizieren mit 3

+/ Summe



1

Pip , 100 bis 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

Überprüfen Sie jedes Zeichen der Eingabe auf eine Übereinstimmung in jedem Element von b. Der Index dieser Übereinstimmung plus 1 wird zur Gesamtsumme hinzugefügt.

Probieren Sie es online!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.