Bao nhiêu lần tôi nên nhấn này?


24

Chúng ta đều quen với bàn phím điện thoại trường học cũ, phải không? Để tham khảo, đây là những gì nó trông giống như:

Điện thoại Keybad


Đưa ra một Chuỗi chỉ bao gồm các chữ cái ASCII chữ thường và các khoảng trắng đơn , nhiệm vụ của bạn là trả về số lượng vòi cần thực hiện để nhập xuống Chuỗi đầy đủ bằng bàn phím điện thoại như trên.

Đối với những người không quen thuộc với điều này, đây là cách nó hoạt động:

  • 2Ví dụ, khóa có chữ số cũng có chuỗi abcđược ghi trên đó. Để gõ a, bạn phải bấm phím này một lần, vì bbạn phải bấm hai lần và đối với cbạn phải nhấn ba lần.

  • Đối với các chữ cái liên tiếp nằm trên cùng một phím, bạn phải đợi 1 giây trước khi nhấn lại. Vì vậy, nếu bạn muốn gõ cb, bạn phải nhấn 3 lần cho c, đợi một giây rồi nhấn hai lần cho b, vì vậy vẫn còn 5 lần nhấn .

  • Điều tương tự cũng áp dụng cho tất cả các phím khác, ngoại trừ một đơn không gian, mà chỉ yêu cầu 1 báo chí. Cũng lưu ý rằng các phím 79có bốn chữ cái trên chúng. Thuật toán tương tự được áp dụng, sự khác biệt duy nhất là số lượng chữ cái. Các chuỗi tương ứng với mỗi khóa có thể được tìm thấy trong hình trên (nhưng chữ thường) hoặc trong danh sách sau, có chứa tất cả các ký tự bạn có thể nhận được:

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

Các trường hợp thử nghiệm

Đầu vào -> Đầu ra (Giải thích)

"" -> 0 (không nên gõ gì)
"nước" -> 8 ("w, a, t" mỗi yêu cầu 1 lần nhấn (trên các phím 9, 2 và 8), "e" yêu cầu 2 lần nhấn (trên phím 3), "r" cần 3 lần nhấn (trên phím 7 ), 1 + 1 + 1 + 2 + 3 = 8)
"xà phòng" -> 9 (4 + 3 + 1 + 1)
"candela" -> 13 (3 + 1 + 2 + 1 + 2 + 3 + 1)
"mã golf" -> 20 (3 + 3 + 1 + 2 + 1 (cho không gian) + 1 + 3 + 3 + 3)
"vua đồi" -> 33 (2 + 3 + 2 + 1 + 1 + 3 + 3 + 1 + 1 + 2 + 2 + 1 + 2 + 3 + 3 + 3)

Thông số kỹ thuật

  • Áp dụng quy tắc I / O tiêu chuẩn và lỗ hổng mặc định.

  • Bạn chỉ có thể nhận đầu vào trong loại Chuỗi gốc của ngôn ngữ của bạn. Đầu ra có thể là số nguyên hoặc biểu diễn chuỗi của số nguyên đó.

  • Đây là , câu trả lời ngắn nhất trong mọi ngôn ngữ đều thắng.




2
Tôi nghĩ rằng đây sẽ là một câu hỏi thú vị hơn nếu bạn thực hiện 1 lần nhấn mỗi giây và phải đợi 1 giây và đếm giây thay vì chạm.
Yakk

@Yakk Điều đó sẽ quá phức tạp
Ông Xcoder

@ Mr.Xcoder Bạn có chắc không? Tôi đã thấy các trình hướng dẫn mã ở đây làm những thứ không thể trong không gian ít hơn một tweet.
J_F_B_M

Câu trả lời:


11

JavaScript (ES6) 77 66 64 60 byte

(Đã lưu một số byte nhờ @Johan Karlsson và @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)&&tcho 71 byte
Johan Karlsson

Cảm ơn, @JohanKarlsson, tôi đã tìm ra điều tương tự khi đang tắm! Tìm thấy một tối ưu hóa khác để cạo thêm 5 byte.
Rick Hitchcock

6
Tôi tìm thấy một giải pháp hoàn toàn đối xứng cho 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.
Neil

1
@Neil, trong khi đó có thể không ngắn hơn, nó chắc chắn là thông minh hơn.
Rick Hitchcock

1
@Neil Bạn nên đăng nó.
Ông Xcoder

7

05AB1E , 29 26 25 byte

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

Hãy thử trực tuyến!

Giải trình

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

Xin lỗi, nhưng đối với một đầu vào trống, điều này mang lại 10. Nó vẫn ổn ở nơi khác
Ông Xcoder

@ Mr.Xcoder: Chuỗi trống không cho đầu ra, nhưng nó vẫn sai. Cảm ơn đã thông báo, tôi sẽ sửa nó.
Emigna

2
Nó cho 10 trên TIO.
Ông Xcoder

@ Mr.Xcoder: Vâng, bạn phải đưa ra chuỗi trống. Không có đầu vào không giống như một chuỗi rỗng. Đó là một chút bối rối tôi biết. Đã sửa ngay bây giờ :)
Emigna

@ Mr.Xcoder: Đầu vào chuỗi rỗng được đưa ra như thế này
Emigna

7

Python 2 , 56 byte

Sử dụng thuật toán tương tự như giải pháp Javascript của @ RickHitchcock

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

Hãy thử trực tuyến!


Giải pháp thú vị. Làm thế nào nó hoạt động cho không gian, tôi không nhận được nó>. <?
Ông Xcoder

@ Mr.Xcoder cho bất cứ điều gì không có trong chuỗi '...'.find(c)trả về -1. Bằng cách thêm 2, chúng tôi nhận được một phím nhấn.
trứng

Tôi biết nó đã quay trở lại -1, nhưng không nhận ra bạn có một cái gì đó +2sau khi đun sôi ... Dù sao, giải pháp Python ngắn nhất cho đến nay.
Ông Xcoder

Oml, tôi tình cờ đưa ra giải pháp chính xác tương tự sau khi từ từ đánh golf chương trình của mình xuống, cho đến khi tôi nhận ra bạn đã đăng nó :( Công việc tuyệt vời vì đã tìm ra giải pháp này :)
Mario Ishac


5

APL Dyalog, 37 byte

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

Hãy thử trực tuyến!

Làm sao?

Lấy ndex của mỗi char của đầu vào trong chuỗi 'adgjmptw behknqux~cfilorvy~'( szsẽ mặc định là 28), chia cho 9, làm tròn và tính tổng.


Bạn có thể sử dụng 'adgjmptw ' 'behknqux' 'cfilorvy' 'sz'để lưu một số byte
Kritixi Lithos


@LeakyNun onice
Uriel

Bạn có thể thả khoảng trống trong chuỗi
Kritixi Lithos

@Uriel chờ đợi, bạn không cần phải đếm f←vì vậy nó là 47 byte
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>

Nhìn không có bảng chữ cái! Tôi không hiểu lắm về công thức của @ LeakyNun vì vậy tôi đã tự mình nghĩ ra.


Số học thuần túy :)
Ông Xcoder

Điều gì s=>[...s]làm tại sao không chỉs=>s.map()...
Evan Carroll

1
@EvanCarroll slà một chuỗi, vì vậy bạn không thể maptrực tiếp. ...slặp đi lặp lại s, trong khi [...s]chuyển đổi phép lặp thành một mảng, phân chia hiệu quả sthành một mảng các ký tự.
Neil

4

C, 211 196 byte

Lần gửi đầu tiên ở đây ... có vẻ khá dài và tôi thấy rằng đây không phải là một cách tiếp cận hiệu quả, nhưng ít nhất nó cũng hoạt động :)

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

Phiên bản bị đánh cắp:

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)có thể k[i].
Máy

Bạn có thể cắt khoảng trắng sau một *(ví dụ char*n) và thêm các khai báo của bạn vào forcâu lệnh trống (thay vì int s=0,j=0;(for(;bạn có for(int s=0,k=0;) và thay vì i==0sử dụng!i
TAS

Cảm ơn bạn cho những gợi ý. Tôi không thể đưa svào vòng lặp for vì tôi sử dụng nó sau này, nhưng tôi đặt các intkhai báo lại với nhau và sử dụng các phép gán khi tôi cần chúng.
dbuchmann

Yay một người chơi golf C! Dù sao, một số gợi ý: đối với các vòng lặp hoàn toàn tốt hơn so với các vòng lặp trong hầu hết mọi tình huống - hãy tận dụng các dấu chấm phẩy miễn phí, đặc biệt là trong biểu thức lặp. Sử dụng dấu phẩy thay vì dấu chấm phẩy ở hầu hết các nơi, điều này cho phép bạn thoát khỏi việc không có dấu ngoặc nhọn ở hầu hết các nơi. Có những tối ưu hóa khác nhưng chúng phụ thuộc nhiều hơn vào phiên bản C mà bạn biên dịch.
dj0wns

4

Haskell - 74 71 62 byte

Chỉnh sửa: xóa 3 byte bằng cách sử dụng một danh sách hiểu thay vì bộ lọc

Chỉnh sửa: Lưu 9 byte nhờ Siracusa, Laikoni và Zgarb!

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

Sử dụng

λ> f "candela"
13
λ>

Hãy thử trực tuyến!


Mục đích của các chữ cái trùng lặp là gì?
Ông Xcoder

@ Mr.Xcoder Nó được sử dụng để đếm các vòi, tôi sẽ thêm một lời giải thích.
Henry

Bạn có thể tiết kiệm một byte bằng cách viết lại fđể f=length.(=<<)(\x->x:[y|y<-l,y==x]), nơi (=<<)concatMapở đây.
siracusa

Và một số khác sẽ quay trở lại filter:f=length.(=<<)(\x->x:filter(==x)l)
siracusa

1
Khi bạn lchỉ sử dụng một lần, nó có thể được nội tuyến.
Laikoni


3

Clojure, 82 76 byte

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

Oh nó là đơn giản để chỉ filtercounthơn sử dụng frequencies. Nguyên:

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

Chuỗi mã hóa số lần nhiều hơn một lần bạn cần nhấn phím cho một ký tự đã cho :)





2

Java, 95 73 byte

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

Cảm ơn Kevin Cruijssen vì đã biến hàm này thành biểu thức lambda ( athuộc loại nào String). 95 byte trở thành 73 byte!

Một biểu thức lambda tổng hợp số lượng báo chí của mỗi nhân vật sử dụng map(). map()chuyển đổi từng ký tự (ASCII trong phạm vi chữ thường là 97-122) trong luồng thành giá trị phù hợp (trông giống như sóng cưa đơn giản, nhưng tính đến cả 4 chu kỳ đều gây khó chịu) bằng cách sử dụng toán học này : 1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112). Đây là một đồ thị desmos của mô hình đó.


Danh sách kẽ hở nói rằng không đăng đoạn mã mặc dù có vẻ như mọi người cho đến nay đã làm điều đó. Dù bằng cách nào, chương trình đầy đủ của tôi là 130 byte . Đây là: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
Chào mừng đến với PPCG! Bạn thực sự đúng khi đoạn trích không được phép, nhưng mặc định là chương trình hoặc chức năng . Và với Java 8, bạn có thể sử dụng lambdas. Vì vậy, trong trường hợp a->{return a.chars().map(b->1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112)).sum();}này được cho phép. Và vì đó là một câu trả về duy nhất, a->a.chars().map(b->1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112)).sum()( 73 byte ) sẽ là câu trả lời của bạn. Ngoài ra, đây là một liên kết TryItOnline của câu trả lời của bạn mà bạn có thể muốn thêm vào câu trả lời của mình. Một lần nữa: chào mừng, và câu trả lời tốt đẹp. +1 từ tôi.
Kevin Cruijssen

2
Một số điều cần lưu ý về lambdas. Bạn không cần phải đếm f=cũng không phải là dấu chấm phẩy hàng đầu ;. Và bạn cũng không phải thêm loại tham số miễn là bạn đề cập loại đó là gì (vì vậy thay vì (String a)->bạn có thể sử dụng a->và đề cập rằng đầu vào alà một Stringcâu trả lời của bạn). Ồ, và Mẹo chơi golf trong JavaMẹo chơi gôn bằng <tất cả các ngôn ngữ> có thể rất thú vị để đọc, trong trường hợp bạn chưa đọc.
Kevin Cruijssen

1

Toán học, 83 byte

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

Nhìn chung, có vẻ như được chấp nhận rằng các câu trả lời Mathicala được phép sử dụng danh sách các ký tự cho các biến chuỗi, chẳng hạn như đầu vào cho hàm này. (Cũng có amất tích khi bắt đầu "bc1..."?)
Greg Martin

đây là mã golf. Đây là kết quả đúng mà không cần. "Tr" thực hiện công việc
J42161217

1

QBIC , 94 byte

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

Giải trình

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

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

Hãy thử trực tuyến!

Gấp một char trên mỗi dòng, chuyển ngữ từng dòng mới +, mỗi khoảng trắng với 1và mỗi chữ cái với số lần đẩy tương ứng. bc làm tổng.


trên máy của bạn, bạn có thể cầnbc <(fold -1|tr "\n "adgjmptwbehknquxcfilorvysz +[1*9][2*8][3*8]44;echo 0)
marcosm

1

C, 92 88 byte

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

bạn có thể sử dụng s=nđể thay thế return nvà kết hợp s++;với c=*s. Nó có thể ngắn hơn 9 byte.
Keyu Gan

@KeyuGan s=nsẽ không hoạt động, vì slà người địa phương. Và *s=nsẽ không hoạt động vì chỉ có CHAR_BITbit trong *sđó, sẽ không đủ cho một số tin nhắn. Nhưng bạn nói đúng về s++. Cảm ơn.
Ray

1

APL (Dyalog) , 36 byte

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

Hãy thử trực tuyến!

Tìm mod-3 chỉ số trong bảng chữ cái mà không SZ . Vì không gian, SZ không được tìm thấy, chúng "có" chỉ số 25 (nhiều hơn một chỉ số tối đa), rất tốt cho không gian. Sau đó, chúng ta chỉ cần thêm 3 cho mỗi S hoặc Z .

{ Hàm ẩn danh trong đó đối số được biểu thị bằng :

⎕A~'SZ' chữ hoa A lph.us, ngoại trừ SZ

819⌶ chữ thường

⍵⍳⍨ các ý kiến của cuộc tranh luận trong đó

¯1+ thêm một phủ định

3| mod-3

1+ thêm một (điều này chuyển đổi tất cả 0-mod thành 3)

(... ), thêm vào trước:

  ⍵∊'sz' Boolean trong đó đối số là s hoặc z

   nhân với 3

+/ tổng



1

Pip , 100 90 byte

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

Kiểm tra từng ký tự của đầu vào cho khớp trong từng phần tử của b. Chỉ số của trận đấu đó cộng với 1 được thêm vào tổng số.

Hãy thử trực tuyến!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.