Ile razy mam to naciskać?


24

Wszyscy jesteśmy przyzwyczajeni do old-schoolowej klawiatury telefonu, prawda? W celach informacyjnych wygląda to tak:

Klawiatura telefoniczna


Biorąc pod uwagę ciąg znaków składający się tylko z małych liter ASCII i pojedynczych spacji , Twoim zadaniem jest zwrócenie liczby naciśnięć, które należy wykonać, aby wpisać pełny ciąg za pomocą klawiatury telefonu, jak powyżej.

Dla tych, którzy nie są zaznajomieni z tym, oto jak to działa:

  • Na przykład klucz z cyfrą 2ma również abczapisany ciąg znaków . Aby pisać a, musisz nacisnąć ten klawisz jeden raz, ponieważ bmusisz nacisnąć dwa razy, a także ctrzy razy.

  • W przypadku kolejnych liter tego samego klawisza należy odczekać 1 sekundę przed ponownym naciśnięciem. Tak więc, jeśli chcesz pisać cb, musisz nacisnąć 3 razy c, poczekać sekundę, a następnie nacisnąć dwa razy b, aby nadal 5 dotknięć.

  • To samo dotyczy wszystkich pozostałych klawiszy, z wyjątkiem pojedynczej spacji, która wymaga tylko 1 naciśnięcia. Należy również pamiętać, że klucze 7i 9mają na nich cztery litery. Zastosowano ten sam algorytm, a jedyną różnicą jest liczba liter. Ciągi odpowiadające każdemu kluczowi można znaleźć na obrazku powyżej (ale małymi literami) lub na poniższej liście, która zawiera wszystkie znaki, które możesz otrzymać:

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

Przypadki testowe

Wejście -> Wyjście (objaśnienie)

„” -> 0 (nic nie należy stukać)
„woda” -> 8 („w, a, t” każdy wymaga 1 dotknięcia (na klawiszach 9, 2 i 8), „e” wymaga 2 uderzeń (na klawiszu 3), „r” wymaga 3 uderzeń (na klawiszu 7 ), 1 + 1 + 1 + 2 + 3 = 8)
„mydło” -> 9 (4 + 3 + 1 + 1)
„candela” -> 13 (3 + 1 + 2 + 1 + 2 + 3 + 1)
„kod golfa” -> 20 (3 + 3 + 1 + 2 + 1 (dla miejsca) + 1 + 3 + 3 + 3)
„król wzgórza” -> 33 (2 + 3 + 2 + 1 + 1 + 3 + 3 + 1 + 1 + 2 + 2 + 1 + 2 + 3 + 3 + 3)

Okular

  • Obowiązują standardowe reguły we / wy i domyślne luki.

  • Możesz wprowadzać dane tylko w rodzimym typie łańcucha w swoim języku. Wyjściem może być liczba całkowita lub ciąg znaków reprezentujący tę liczbę całkowitą.

  • To jest , wygrywa najkrótsza odpowiedź w każdym języku .




2
Myślę, że byłoby to bardziej interesujące pytanie, jeśli wykonałeś 1 stuknięcie na sekundę i musiałeś poczekać 1 sekundę, a zamiast stuknięć odliczyć sekundy .
Yakk

@Yakk To byłoby zbyt skomplikowane
Pan Xcoder

@ Mr.Xcoder Czy jesteś jednak pewien? Widziałem, jak tutaj czarodzieje kodu wykonują niemożliwe rzeczy na mniejszej przestrzeni niż tweet.
J_F_B_M

Odpowiedzi:


11

JavaScript (ES6) 77 66 64 60 bajtów

(Zapisano kilka bajtów dzięki @Johan Karlsson i @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)&&tdla 71 bajtów
Johan Karlsson

Dzięki, @JohanKarlsson, wymyśliłem to samo pod prysznicem! Znalazłem kolejną optymalizację, aby zmniejszyć liczbę kolejnych 5 bajtów.
Rick Hitchcock

6
Znalazłem rozwiązanie czysto arytmetycznego 71 bajtów: 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, choć może nie być krótszy, z pewnością jest mądrzejszy.
Rick Hitchcock

1
@Neil Powinieneś to opublikować.
Pan Xcoder

7

05AB1E , 29 26 25 bajtów

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

Wypróbuj online!

Wyjaśnienie

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

Przepraszam, ale dla pustego wejścia daje to 10. W porządku jest gdzie indziej
Pan Xcoder

@ Mr.Xcoder: Pusty ciąg nie daje danych wyjściowych, ale nadal jest nieprawidłowy. Dzięki za powiadomienie, naprawię to.
Emigna

2
Daje 10 na TIO.
Pan Xcoder

@ Mr.Xcoder: Tak, musisz jawnie podać pusty ciąg. Żadne dane wejściowe nie są takie same jak pusty ciąg. Wiem, to trochę mylące. Naprawiono teraz :)
Emigna

@ Mr.Xcoder: Pusty ciąg wejściowy jest podane jak to
Emigna

7

Python 2 , 56 bajtów

Używa tego samego algorytmu, co rozwiązanie Javascript @ RickHitchcock

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

Wypróbuj online!


Ciekawe rozwiązanie Jak to działa na spacje, nie rozumiem>. <?
Pan Xcoder

@ Mr.Xcoder dla wszystkiego, co nie jest w ciągu, '...'.find(c)zwraca -1. Dodając 2, otrzymujemy jedno naciśnięcie klawisza.
ovs

Wiedziałem, że wrócił -1, ale nie zdawałem sobie sprawy, że masz płytę +2główną ... W każdym razie, najkrótsze rozwiązanie Pythona.
Pan Xcoder

Oml, zdarzyło mi się stworzyć dokładnie to samo rozwiązanie po powolnym graniu w golfa mojego programu, dopóki nie zdałem sobie sprawy, że go opublikowałeś :(
Dobra


5

Dyalog APL, 37 bajtów

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

Wypróbuj online!

W jaki sposób?

Uzyskaj ndex każdego znaku wejściowego w ciągu 'adgjmptw behknqux~cfilorvy~'( si zdomyślnie wyniesie 28), podziel przez 9, zaokrąglij w górę i zsumuj.


Możesz użyć, 'adgjmptw ' 'behknqux' 'cfilorvy' 'sz'aby zapisać niektóre bajty
Kritixi Lithos


@LeakyNun onice
Uriel

Możesz upuścić miejsce w ciągu
Kritixi Lithos

@Uriel czekaj, nie musisz liczyć, f←więc jest 47 bajtów
Leaky Nun

4

JavaScript (ES6), 71 bajtów

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>

Nie szukaj tablic z literami! Nie do końca zrozumiałem formułę @ LeakyNun, więc wymyśliłem własną.


Czysta arytmetyka :)
Pan Xcoder

Co robi s=>[...s], dlaczego nie tylkos=>s.map()...
Evan Carroll

1
@EvanCarroll sjest ciągiem, więc nie możesz mapgo bezpośrednio. ...siteruje się s, a [...s]konwertuje iterację do tablicy, skutecznie dzieląc ją sna tablicę znaków.
Neil

4

DO, 211 196 bajtów

Pierwsze zgłoszenie tutaj ... wygląda na dość długie i widzę, że nie jest to skuteczne podejście, ale przynajmniej działa :)

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

Wersja bez golfa:

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)może być k[i].
CalculatorFeline

Możesz wyciąć przestrzeń po *(np. char*n) I dodać swoje deklaracje do pustej forinstrukcji (zamiast int s=0,j=0;(for(;tego for(int s=0,k=0;) i zamiast i==0używać!i
Tas

Dziękuję za te wskazówki. Nie mogłem umieścić sw pętli for, ponieważ używam go później, ale intzłożyłem deklaracje razem i użyłem przypisań tam, gdzie ich potrzebowałem.
dbuchmann

Tak, inny golfista C! Tak czy inaczej, niektóre wskaźniki: dla pętli są zdecydowanie lepsze niż podczas pętli podczas prawie wszystkich sytuacji - skorzystaj z wolnych średników, szczególnie w wyrażeniu iteracyjnym. W większości miejsc używaj przecinków zamiast średników, co pozwala uniknąć zakręconych nawiasów klamrowych w większości miejsc. Istnieją inne optymalizacje, ale są one bardziej zależne od tego, do której wersji C kompilujesz.
dj0wns

4

Haskell - 74 71 62 bajtów

Edycja: usunąłem 3 bajty, używając zrozumienia listy zamiast filtru

Edycja: Zaoszczędź 9 bajtów dzięki Siracusa, Laikoni i Zgarb!

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

Stosowanie

λ> f "candela"
13
λ>

Wypróbuj online!


Jaki jest cel duplikatów liter?
Mr. Xcoder

@ Mr.Xcoder Służy do liczenia uderzeń, dodam wyjaśnienie.
Henry

Możesz zapisać jeden bajt, przepisując fdo f=length.(=<<)(\x->x:[y|y<-l,y==x]), gdzie (=<<)jest concatMaptutaj.
siracusa

I kolejny z powrotem do filter:f=length.(=<<)(\x->x:filter(==x)l)
Siracusa

1
Ponieważ używasz ltylko raz, można wstawić.
Laikoni


3

Clojure, 82 76 bajtów

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

Och, jest prostszy w użyciu filteri countniż w użyciu frequencies. Oryginalny:

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

Ciąg koduje, ile razy więcej niż raz trzeba nacisnąć klawisz dla danego znaku :)





2

Java, 95 73 bajtów

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

Podziękowania dla Kevina Cruijssena za uczynienie tej funkcji wyrażeniem lambda (gdzie ajest typu String). 95 bajtów stało się 73 bajtami!

Wyrażenie lambda podsumowuje liczbę naciśnięć każdego użytego znaku map(). map()konwertuje każdy znak (ASCII w dolnym zakresie sprawa jest 97-122) w strumieniu na odpowiednią wartość (wygląda jak prosty fali piły, ale biorąc pod uwagę zarówno 4 cykle to denerwujące) za pomocą tej matematyki: 1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112). Oto wykres desmos tego modelu.


Lista luk mówi, żeby nie pisać fragmentów kodu, chociaż wygląda na to, że wszyscy do tej pory to zrobili. Tak czy inaczej, mój pełny program ma 130 bajtów . Oto on: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
Witamy w PPCG! Rzeczywiście masz rację, że fragmenty nie są dozwolone, ale domyślnie jest to program lub funkcja . A w Javie 8 możesz używać lambd. Więc w tym przypadku a->{return a.chars().map(b->1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112)).sum();}jest dozwolone. A ponieważ jest to pojedyncza instrukcja zwracająca, a->a.chars().map(b->1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112)).sum()( 73 bajty ) byłaby twoją odpowiedzią. Oto link TryItOnline do odpowiedzi, którą możesz chcieć dodać do swojej odpowiedzi. Ponownie: witamy i miła odpowiedź. +1 ode mnie
Kevin Cruijssen

2
Kilka rzeczy do zapamiętania na temat lambdas. Nie musisz liczyć f=ani wiodącego średnika ;. Nie musisz także dodawać typu parametru, o ile wspominasz, jaki jest typ (więc zamiast tego (String a)->możesz użyć a->i wspomnieć, że dane wejściowe aStringw odpowiedzi). Aha, i porady dotyczące gry w golfa w Javie oraz porady dotyczące gry w golfa w <wszystkich językach> mogą być interesujące do przeczytania, na wypadek gdybyś jeszcze tego nie zrobił.
Kevin Cruijssen

1

Mathematica, 83 bajty

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

Wydaje się, że ogólnie przyjmuje się, że odpowiedzi Mathematica mogą używać list znaków dla zmiennych łańcuchowych, takich jak dane wejściowe do tej funkcji. (Czy też abrakuje na początku "bc1..."?)
Greg Martin

to jest kod golf. daje to właściwy wynik bez a. „Tr” wykonuje robotę
J42161217

1

QBIC , 94 bajty

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

Wyjaśnienie

[    |      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 bajtów

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

Wypróbuj online!

Składa jeden znak w wierszu, transliteruje każdą nową linię, +każdą spację 1i każdą literę z odpowiednią liczbą naciśnięć. bc robi sumę.


na twoim komputerze możesz potrzebowaćbc <(fold -1|tr "\n "adgjmptwbehknquxcfilorvysz +[1*9][2*8][3*8]44;echo 0)
marcosm

1

C, 92 88 bajtów

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

możesz użyć s=ndo zastąpienia return ni połączenia s++;z c=*s. Może być o 9 bajtów krótszy.
Keyu Gan

@KeyuGan s=nnie działa, ponieważ sjest to lokalny. I *s=nnie zadziałałoby, ponieważ są tylko CHAR_BITbity *s, co nie wystarczyłoby dla niektórych wiadomości. Ale masz rację co do s++. Dzięki.
Ray

1

APL (Dyalog) , 36 bajtów

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

Wypróbuj online!

Znajdzie mod-3 wskaźniki alfabetu bez S i Z . Ponieważ nie znaleziono spacji, S i Z , mają one „indeks” 25 (jeden więcej niż indeks maksymalny), co jest dobre dla spacji. Następnie wystarczy dodać 3 dla każdego S lub Z .

{ funkcja anonimowa, w której argument jest reprezentowany przez :

⎕A~'SZ' wielkie litery lphabet wyjątkiem S i Z.

819⌶ małe litery

⍵⍳⍨ z ɩ ndices z argumentem, że

¯1+ dodaj jeden negatywny

3| mod-3

1+ dodaj jeden (konwertuje wszystkie 0-mody do 3)

(), Poprzedzają:

  ⍵∊'sz' Boolean, gdzie argument to s lub z

   pomnóż przez 3

+/ suma



1

Pip , 100 90 bajtów

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

Sprawdź, czy każdy znak wejściowy jest zgodny w każdym elemencie b. Indeks tego meczu plus 1 zostaje dodany do sumy.

Wypróbuj online!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.