Buna kaç kere basmalıyım?


24

Hepimiz eski okul telefon tuş takımına alışkınız değil mi? Başvuru için, işte şöyle görünüyor:

Telephone Keybad


Yalnızca küçük harfli ASCII harflerinden ve tek boşluklardan oluşan bir Dize verildiğinde göreviniz, bir Dize'yi bir telefon tuş takımı ile tam Dize yazmak için yapmanız gereken musluk sayısını döndürmektir.

Buna aşina olmayanlar için, işte nasıl çalıştığı:

  • 2Örneğin basamaklı anahtarın abcüzerinde de yazılı bir dize vardır . Yazmak için abu tuşa bir kez bbasmanız gerekir , çünkü iki kez basmanız ve cüç kere basmanız gerekir.

  • Aynı tuştaki ardışık harfler için, tekrar basmadan önce 1 saniye beklemelisiniz. Bu nedenle, yazmak istiyorsanız cb, 3 kez basmanız c, bir saniye beklemeniz ve sonra iki kez basmanız gerekir b, yine de 5 dokunma.

  • Aynısı , sadece 1 basış gerektiren tek bir boşluk hariç, diğer tüm tuşlar için geçerlidir . Ayrıca, tuşların 7ve 9üzerlerinde dört harf bulunduğunu unutmayın . Aynı algoritma uygulanır, tek fark harf sayısıdır. Her bir tuşa karşılık gelen dizeler yukarıdaki resimde (ancak küçük harf) veya alabileceğiniz tüm karakterleri içeren aşağıdaki listede bulunabilir:

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

Test Kılıfları

Giriş -> Çıkış (Açıklama)

"" -> 0 (hiçbir şey kullanılmamalıdır)
"su" -> 8 ("w, a, t" her biri 1 musluğu gerektirir (9, 2 ve 8 tuşlarında), "e" 2 musluğu gerektirir (3 tuşunda), "r", 3 musluğu gerektirir (7 tuşunda) ), 1 + 1 + 1 + 2 + 3 = 8)
"sabun" -> 9 (4 + 3 + 1 + 1)
"kandela" -> 13 (3 + 1 + 2 + 1 + 2 + 3 + 1)
"kod golf" -> 20 (3 + 3 + 1 + 2 + 1 (alan için) + 1 + 3 + 3 + 3)
"Tepenin Kralı" -> 33 (2 + 3 + 2 + 1 + 1 + 3 + 3 + 1 + 1 + 2 + 2 + 1 + 2 + 3 + 3 + 3)

gözlük

  • Standart G / Ç kuralları ve Varsayılan Loopholes uygulanır.

  • Yalnızca kendi dilinizin yerel String türüne giriş yapabilirsiniz. Çıktı, bir tam sayı veya o tamsayının dizgi gösterimi olabilir.

  • Bu , her dilde kazanılan en kısa cevap .




2
Sanırım saniyede 1 dokunuş yapıp, 1 saniye beklemeniz ve musluklar yerine saniyeler saymanız, daha ilginç bir soru olurdu .
Yakk

@Yakk Bu çok karmaşık olurdu
Bay Xcoder

@ Mr.Xcoder Yine de emin misiniz? Buradaki kod sihirbazlarının tweet'ten daha az uzayda imkansız şeyler yaptıklarını gördüm.
J_F_B_M

Yanıtlar:


11

JavaScript (ES6) 77 66 64 60 bayt

(@Johan Karlsson ve @Arnauld sayesinde bazı baytlar kaydedildi).

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 bayt için
Johan Karlsson 11

Teşekkürler @JohanKarlsson, ben de duşta aynı şeyi anladım! 5 bayt daha tıraş için başka bir optimizasyon bulundu.
Rick Hitchcock

6
Ben 71 bayt için tamamen aritmetik çözüm buldu: 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, bu daha kısa olmasa da, kesinlikle daha akıllıca.
Rick Hitchcock

1
@Neil Göndermelisin.
Bay Xcoder

7

05AB1E , 29 26 25 bayt

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

Çevrimiçi deneyin!

açıklama

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

Maalesef bir boş girişi için bu O başka yerde gayet 10. verir
Sn Xcoder

@ Mr.Xcoder: Boş dize çıktı vermez, ancak yine de yanlıştır. Bildirdiğiniz için teşekkürler, düzelteceğim.
Emigna

2
TIO'da 10 verir.
Bay Xcoder

@ Mr.Xcoder: Evet açıkça boş dizgeyi vermek zorundasınız. Hiçbir giriş boş bir dize ile aynı değil. Bu biraz kafa karıştırıcı biliyorum. Şimdi düzeltildi :)
Emigna

@ Mr.Xcoder: Boş dize girişi gibi verilir bu
Emigna

7

Python 2 , 56 bayt

@ RickHitchcock's Javascript çözümü ile aynı algoritmayı kullanır

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

Çevrimiçi deneyin!


İlginç bir çözüm. Alanlar için nasıl çalışır, anlamıyorum>. <?
Bay Xcoder

@ Mr.Xcoder dizgede olmayan herhangi bir şey için '...'.find(c)döner -1. 2 ekleyerek bir tuşa basıyoruz.
ovs

Geri döndüğünü biliyordum -1, ancak bir +2kazandan sonra kazandığınızı bilmiyordum ... Her neyse, en kısa sürede Python çözümü.
Bay Xcoder

Oml, programımı yavaşça golf oynadıktan sonra da tam olarak aynı çözümü yaptım, bunu size
sunduğuma


5

Dyalog APL, 37 bayt

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

Çevrimiçi deneyin!

Nasıl?

Get dizesinde girdi her char nDex 'adgjmptw behknqux~cfilorvy~'( sve z28'e varsayılan olarak) 9, yuvarlak yukarı ve toplamı bölün.


'adgjmptw ' 'behknqux' 'cfilorvy' 'sz'Bazı baytları kurtarmak için kullanabilirsiniz
Kritixi Lithos


@LeakyNun onice
Uriel

Dizedeki boşluğu bırakabilirsiniz
Kritixi Lithos

@Uriel bekle, saymak zorunda değilsin, f←bu yüzden 47 bayt
Leaky Nun

4

JavaScript (ES6), 71 bayt

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>

Mektup masalarına bakma! @ LeakyNun formülünü pek anlamadım, bu yüzden kendiminkini buldum.


Saf aritmetik :)
Bay Xcoder

Ne yapar s=>[...s]ne neden sadeces=>s.map()...
Evan Carroll

1
@EvanCarroll sbir dizedir, bu yüzden mapdoğrudan yapamazsınız . ...syineler siken, [...s]bir diziye dönüştürür iterasyon, etkili bir bölme skarakter dizisi haline.
Neil

4

C 211 196 bayt

Buraya ilk gönderim ... oldukça uzun görünüyor ve bunun verimli bir yaklaşım olmadığını görüyorum ama en azından işe yarıyor :)

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 versiyonu:

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

Bir sonra boşluk kesebilir *(ör char*n) ve boş için bildirimleri ekleyin fordeyimi (yerine int s=0,j=0;(for(;ederdiniz for(int s=0,k=0;) ve yerine i==0kullanımı!i
Tas

Bu ipuçları için teşekkür ederim. sFor döngüsüne koyamadım çünkü daha sonra kullanıyorum, ancak intbildirimleri bir araya getirdim ve ihtiyaç duyduğum yerde atamalar kullandım.
dbuchmann

Bir arkadaşım C golfçü Yay! Her neyse, bazı işaretçiler: döngüler, neredeyse tüm durumlarda, döngülerden kesinlikle daha iyidir - özellikle yinelemeli ifadede, ücretsiz noktalı virgüllerden yararlanın. Çoğu yerde noktalı virgül yerine virgül kullanın; bu, çoğu yerde kaşlı ayraç kullanmamanızı sağlar. Başka optimizasyonlar da var ama derlediğiniz C versiyonuna daha fazla güveniyorlar.
dj0wns

4

Haskell - 74 71 62 bayt

Düzenleme: filtre yerine bir liste anlama kullanarak 3 bayt kaldırıldı

Düzenleme: Siracusa, Laikoni ve Zgarb sayesinde 9 bayt tasarruf edin!

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

kullanım

λ> f "candela"
13
λ>

Çevrimiçi deneyin!


Çift harflerin amacı nedir?
Bay Xcoder

@ Mr.Xcoder Muslukları saymak için kullanılır, bir açıklama ekleyeceğim.
Henry,

Sen yeniden yazarak bir bayt kaydedebilirsiniz fiçin f=length.(=<<)(\x->x:[y|y<-l,y==x])nerede, (=<<)olduğu concatMapburada.
siracusa

Ve bir başkasına geri dönmek ile filter:f=length.(=<<)(\x->x:filter(==x)l)
siracusa

1
lSadece bir kez kullandığınızda , satır içi olabilir.
Laikoni


3

Clojure, 82 76 bayt

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

Ah sadece filterve countkullanmaktan daha basittir frequencies. Orijinal:

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

Dize, belirli bir karakter için tuşa basmanız gereken bir kereden daha fazla kere kodlar :)





2

Java, 95 73 bayt

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

Fonksiyonunu lambda ifadesi (yapım Kevin Cruijssen sayesinde atiptedirString ). 95 bayt 73 bayt oldu!

Bir lambda ifadesi, kullanan her karakterin baskı sayısını toplar map(). map()Bu matematiği kullanarak her karakteri (küçük harf aralıktaki ASCII 97-122'dir) uygun değere dönüştürür (basit testere dalgası gibi görünür, ancak her iki 4 çevrimi de can sıkıcıdır) 1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112). İşte bu modelin bir desmos grafiği.


Boşluk listesi, bugüne kadar herkesin yaptığı gibi görünse de, kod snippet'lerini göndermemeyi söylüyor. Her iki durumda da, tam programım 130 bayttır . İşte burada: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!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.