ฉันควรกดปุ่มนี้กี่ครั้ง


24

พวกเราทุกคนเคยชินกับปุ่มกดโทรศัพท์เก่า ๆ ใช่มั้ย สำหรับการอ้างอิงนี่คือสิ่งที่ดูเหมือนว่า:

Telephone Keybad


รับสตริงที่ประกอบด้วยตัวอักษร ASCII ตัวพิมพ์เล็กและเว้นวรรคเดียวงานของคุณคือส่งคืนจำนวนก๊อกหนึ่งที่ควรทำเพื่อพิมพ์สตริงเต็มด้วยแป้นกดโทรศัพท์ตามที่กล่าวไว้ข้างต้น

สำหรับผู้ที่ไม่คุ้นเคยกับสิ่งนี้นี่คือวิธีการใช้งาน:

  • 2ตัวอย่างเช่นคีย์ที่มีตัวเลขนั้นยังมีสตริงที่abcจดไว้ ในการพิมพ์aคุณจะต้องกดปุ่มนี้หนึ่งครั้งเพราะbคุณต้องกดสองครั้งและcต้องกดสามครั้ง

  • สำหรับตัวอักษรต่อเนื่องที่อยู่บนคีย์เดียวกันคุณต้องรอ 1 วินาทีก่อนกดอีกครั้ง ดังนั้นหากคุณต้องการพิมพ์cbคุณจะต้องกด 3 ครั้งcรอหนึ่งวินาทีจากนั้นกดสองครั้งเพื่อbให้ยังคง 5 ก๊อก

  • เช่นเดียวกันกับปุ่มอื่น ๆ ทั้งหมดยกเว้นพื้นที่เดียวซึ่งต้องการเพียง 1 กด ยังทราบว่าปุ่ม7และ9มีสี่ตัวอักษรบนพวกเขา มีการใช้อัลกอริทึมเดียวกันความแตกต่างเพียงอย่างเดียวคือจำนวนตัวอักษร สตริงที่เกี่ยวข้องกับแต่ละคีย์สามารถพบได้ในภาพด้านบน (แต่เป็นตัวพิมพ์เล็ก) หรือในรายการต่อไปนี้ที่มีอักขระทั้งหมดที่คุณอาจได้รับ:

    "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)
"soap" -> 9 (4 + 3 + 1 + 1)
"candela" -> 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 + 1 + 2 + 2 + 1 + 2 + 1 + 2 + 3 + 3 + 3 + 3)

รายละเอียด

  • ใช้กฎ I / O มาตรฐานและช่องโหว่เริ่มต้น

  • คุณสามารถป้อนได้เฉพาะในประเภทสตริงดั้งเดิมของภาษาของคุณ เอาต์พุตอาจเป็นจำนวนเต็มหรือเป็นตัวแทนสตริงของจำนวนเต็มนั้น

  • นี่คือคำตอบที่สั้นที่สุดในทุกภาษาชนะ



ที่เกี่ยวข้อง ที่เกี่ยวข้อง
Shaggy

2
ฉันคิดว่านี่น่าจะเป็นคำถามที่น่าสนใจมากกว่านี้ถ้าคุณแตะ 1 ครั้งต่อวินาทีและต้องรอ 1 วินาทีและนับวินาทีแทนการแตะ
Yakk

@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)&&tfor 71 bytes
Johan Karlsson

ขอบคุณ @JohanKarlsson ฉันคิดในสิ่งเดียวกันขณะอาบน้ำ! พบการเพิ่มประสิทธิภาพอื่นเพื่อกำจัด 5 ไบต์เพิ่มเติม
Rick Hitchcock

6
ฉันพบโซลูชันเกี่ยวกับคณิตศาสตร์อย่างf=s=>[...s].map(c=>t+=((c=parseInt(0+c,36))>23?c+3:c&&~-c%3)%7%4+1,t=0)|tแท้จริงสำหรับ 71 ไบต์:
Neil

1
@ Neil แม้ว่ามันจะไม่สั้นลง แต่มันก็ฉลาดกว่า
Rick Hitchcock

1
@Nil คุณควรโพสต์มัน
นาย Xcoder

7

05AB1E , 29 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: สตริงว่างไม่ให้ผลลัพธ์ แต่ก็ยังผิด ขอบคุณที่แจ้งให้ทราบฉันจะแก้ไข
Emigna

2
มันให้ 10 บน TIO
นาย Xcoder

@ Mr.Xcoder: ใช่คุณต้องระบุสตริงว่าง ไม่มีอินพุตไม่เหมือนกับสตริงว่าง มันค่อนข้างสับสนที่ฉันรู้ แก้ไขตอนนี้ :) :)
Emigna

@ Mr.Xcoder: การป้อนสตริงที่ว่างเปล่าจะได้รับเช่นนี้
Emigna

7

Python 2 , 56 ไบต์

ใช้อัลกอริทึมเดียวกับโซลูชัน Javascript ของ @ RickHitchcock

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

ลองออนไลน์!


ทางออกที่น่าสนใจ มันทำงานกับช่องว่างได้อย่างไรฉันไม่เข้าใจ>. <?
นาย Xcoder

@ Mr.Xcoder สำหรับสิ่งที่ไม่ได้อยู่ในสตริงผลตอบแทน'...'.find(c) -1โดยการเพิ่ม 2 เราจะได้รับหนึ่งปุ่มกด
ovs

ฉันรู้ว่ามันส่งคืน-1แล้ว แต่ไม่ได้ตระหนักว่าคุณมีอุปกรณ์+2หม้อน้ำ ... ต่อไปวิธีแก้ปัญหาที่สั้นที่สุดของ Python
Mr. Xcoder

โอ้ฉันเกิดขึ้นเพื่อทำวิธีการแก้ปัญหาเดียวกันแน่นอนหลังจากที่ช้าลงโปรแกรมกอล์ฟของฉันลงจนกว่าฉันรู้ว่าคุณโพสต์มัน :( งานที่ดีสำหรับการหาวิธีแก้ปัญหานี้เช่นกัน :)
Mario Ishac

5

Python 3 , 69 67 65 64 ไบต์

ขอบคุณ 1 ไบต์สำหรับ Mr. Xcoder

ขอบคุณ 1 ไบต์กับ Felipe Nardi Batista

lambda x:sum((ord(i)+~(i>"s"))%3+3*(i in"sz")+(i>" ")for i in x)

ลองออนไลน์!


บันทึกหนึ่งไบต์โดยการแทนที่i==" "ด้วยi<"a"เพราะคุณได้รับเพียงตัวอักษรและช่องว่าง
นาย Xcoder

4
61 นาที ... สายเกินไป!
Erik the Outgolfer

5

Dyalog APL ขนาด 37 ไบต์

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

ลองออนไลน์!

อย่างไร?

รับndex ของถ่านทุกตัวของอินพุตในสตริง'adgjmptw behknqux~cfilorvy~'( sและzจะเป็น 28) หารด้วย 9 ปัดเศษขึ้นและหาผลรวม


คุณสามารถใช้'adgjmptw ' 'behknqux' 'cfilorvy' 'sz'เพื่อบันทึกไบต์
Kritixi Lithos


@LeakyNun onice
Uriel

คุณสามารถปล่อยพื้นที่ในสตริง
Kritixi Lithos

@ Uriel เดี๋ยวก่อนคุณไม่จำเป็นต้องนับf←ดังนั้นมันจึงเป็น 47 bytes
Leaky Nun

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 ดังนั้นฉันจึงตัดสินใจด้วยตัวเอง


เลขคณิตเพียว :)
นาย Xcoder

อะไรs=>[...s]ทำทำไมไม่เพียงs=>s.map()...
อีวานคาร์โรลล์

1
@EvanCarroll sเป็นสตริงดังนั้นคุณจึงไม่สามารถทำได้mapโดยตรง ...sวนซ้ำsในขณะที่[...s]แปลงการวนซ้ำเป็นอาเรย์แยกsออกเป็นอาเรย์ของอักขระได้อย่างมีประสิทธิภาพ
Neil

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]สามารถ
CalculatorFeline

คุณสามารถตัดช่องว่างหลังนั้น*(เช่นchar*n) และเพิ่มการประกาศของคุณไปยังที่ว่างเปล่าของforคำสั่ง (แทนint s=0,j=0;(for(;คุณต้องการมีfor(int s=0,k=0;) และแทนที่จะi==0ใช้!i
Tas

ขอบคุณสำหรับคำแนะนำเหล่านั้น ฉันไม่สามารถใส่sfor for loop ได้เพราะฉันใช้ในภายหลัง แต่ฉันใส่intคำประกาศเข้าด้วยกันและใช้หนังสือมอบหมายที่ฉันต้องการ
dbuchmann

Yay นักกอล์ฟ C! อย่างไรก็ตามพอยน์เตอร์บางตัว: สำหรับลูปนั้นดีกว่าในขณะที่ลูปในเกือบทุกสถานการณ์ - ใช้ประโยชน์จากอัฒภาคฟรีโดยเฉพาะอย่างยิ่งในการแสดงออกซ้ำ ใช้เครื่องหมายจุลภาคแทนเครื่องหมายอัฒภาคในสถานที่ส่วนใหญ่สิ่งนี้ช่วยให้คุณสามารถหลีกหนีได้โดยไม่ต้องใช้เครื่องมือจัดฟันแบบหยิกในสถานที่ส่วนใหญ่ มีการเพิ่มประสิทธิภาพอื่น ๆ แต่พวกเขาพึ่งพาเวอร์ชัน C ที่คุณคอมไพล์มากกว่า
dj0wns

4

Haskell - 74 71 62 ไบต์

แก้ไข: ลบ 3 ไบต์โดยใช้ list comprehension แทนที่จะเป็น filter

แก้ไข: บันทึก 9 ไบต์ด้วย Siracusa, Laikoni และ Zgarb!

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

การใช้

λ> f "candela"
13
λ>

ลองออนไลน์!


วัตถุประสงค์ของตัวอักษรที่ซ้ำกันคืออะไร?
นาย Xcoder

@ Mr.Xcoder มันใช้เพื่อนับก๊อกฉันจะเพิ่มคำอธิบาย
Henry

คุณสามารถบันทึกหนึ่งไบต์โดยเขียนใหม่fไปยังf=length.(=<<)(\x->x:[y|y<-l,y==x])ที่(=<<)ใดconcatMapที่นี่
siracusa

และอีกอันที่กลับไปที่filter:f=length.(=<<)(\x->x:filter(==x)l)
siracusa

1
ตามที่คุณใช้ lเพียงครั้งเดียว
Laikoni


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()

ขอบคุณ Kevin Cruijssen ที่ทำให้ฟังก์ชั่นเป็นแลมบ์ดา (ซึ่งaเป็นประเภทString) 95 ไบต์กลายเป็น 73 ไบต์!

map()นิพจน์แลมบ์ดาจำนวนมากขึ้นนับกดของตัวละครแต่ละตัวใช้ map()แปลงตัวละครแต่ละตัว (ASCII ในช่วงกรณีที่ต่ำกว่าคือ 97-122) ในสตรีมกับมูลค่าเหมาะสม (ลักษณะเหมือนคลื่นเลื่อยที่เรียบง่าย แต่คำนึงถึงทั้ง 4 รอบเป็นที่น่ารำคาญ) 1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112)โดยใช้คณิตศาสตร์นี้: นี่คือกราฟ desmos ของโมเดลนั้น


รายการช่องโหว่บอกว่าจะไม่โพสต์ตัวอย่างโค้ดแม้ว่าจะดูเหมือนว่าทุกคนทำไปแล้ว ทั้งสองวิธีโปรแกรมเต็มรูปแบบของฉันคือ130 ไบต์ นี่คือ: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
ยินดีต้อนรับสู่ PPCG! คุณแน่นอนที่เหมาะสมที่ตัวอย่างไม่ได้รับอนุญาต แต่เริ่มต้นคือโปรแกรมหรือฟังก์ชั่น และด้วย Java 8 คุณสามารถใช้ lambdas ดังนั้นในกรณีนี้a->{return a.chars().map(b->1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112)).sum();}จะได้รับอนุญาต และเนื่องจากเป็นข้อความสั่งคืนเดียวa->a.chars().map(b->1+(b<64?0:b+(Math.abs(b-115)<4?4:5))%(3+b/112)).sum()( 73 ไบต์ ) จึงเป็นคำตอบของคุณ และนี่คือลิงก์ของคำตอบTryItOnline ที่คุณอาจต้องการเพิ่มในคำตอบของคุณ อีกครั้ง: ยินดีต้อนรับและคำตอบที่ดี +1 จากฉัน
Kevin Cruijssen

2
บางสิ่งที่ควรทราบเกี่ยวกับ lambdas คุณไม่ต้องนับf=หรือเซมิโคลอนนำ;หน้า และคุณไม่จำเป็นต้องเพิ่มประเภทของพารามิเตอร์ตราบใดที่คุณพูดถึงว่าเป็นประเภทใด (ดังนั้นแทนที่จะ(String a)->ใช้a->และพูดถึงอินพุตaนั้นเป็นStringคำตอบของคุณ) โอ้และเคล็ดลับสำหรับการเล่นกอล์ฟใน Javaและเคล็ดลับสำหรับการเล่นกอล์ฟใน <ทุกภาษา>อาจน่าสนใจในการอ่านในกรณีที่คุณยังไม่ได้
Kevin Cruijssen

1

Mathematica, 83 ไบต์

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

ดูเหมือนว่าเป็นที่ยอมรับกันโดยทั่วไปว่าคำตอบทางคณิตศาสตร์ได้รับอนุญาตให้ใช้รายการอักขระสำหรับตัวแปรสตริงเช่นอินพุตของฟังก์ชันนี้ (นอกจากนี้ยังมีทางaหายไปในช่วงเริ่มต้นของ"bc1..."?)
เกร็กมาร์ติน

นี่คือรหัส golf.this ให้ผลลัพธ์ที่ถูกต้องโดยไม่มี "Tr" ทำหน้าที่ได้
J42161217

1

QBIC , 94 ไบต์

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

คำอธิบาย

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

ทุบตี ,69 68 ไบต์

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

ลองออนไลน์!

พับหนึ่งอักขระต่อบรรทัด, จะแปลแต่ละบรรทัดใหม่ด้วย+, แต่ละช่องว่างด้วย 1และแต่ละตัวอักษรที่มีจำนวนการกดที่สอดคล้องกัน bc ทำผลรวม


คุณอาจต้องใช้เครื่องของคุณbc <(fold -1|tr "\n "adgjmptwbehknquxcfilorvysz +[1*9][2*8][3*8]44;echo 0)
marcosm

1

C, 92 88 ไบต์

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

คุณอาจจะใช้s=nเพื่อแทนที่return nและรวมกับs++; c=*sมันอาจจะสั้นกว่า 9 ไบต์
Keyu Gan

@KeyuGan s=nไม่ทำงานเนื่องจากsเป็นคนในท้องถิ่น และ*s=nจะไม่ทำงานเนื่องจากมีเพียงCHAR_BITบิตใน*sซึ่งจะไม่เพียงพอสำหรับบางข้อความ s++แต่คุณขวาเกี่ยวกับ ขอบคุณ
Ray

1

APL (Dyalog)ขนาด 36 ไบต์

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

ลองออนไลน์!

พบ mod-3 ดัชนีในตัวอักษรโดยไม่ต้องSและZ เนื่องจากไม่พบช่องว่างSและZพวกเขา "มี" ดัชนี 25 (มากกว่าดัชนีสูงสุด) ซึ่งดีสำหรับพื้นที่ จากนั้นเราก็ต้องเพิ่ม 3 สำหรับแต่ละSหรือZ

{ ฟังก์ชั่นไม่ระบุชื่อที่มีการโต้แย้งโดย :

⎕A~'SZ' ตัวพิมพ์ใหญ่A lphabet ยกเว้นSและZ

819⌶ ตัวพิมพ์เล็ก

⍵⍳⍨ɩ ndices ของการโต้แย้งในการที่

¯1+ เพิ่มค่าลบ

3| mod-3

1+ เพิ่มหนึ่งอัน (สิ่งนี้จะแปลง 0-mods ทั้งหมดเป็น 3)

(…การเติม), :

  ⍵∊'sz' บูลีนที่อาร์กิวเมนต์เป็นsหรือz

   คูณด้วย 3

+/ รวม



1

Pip , 100 90 ไบต์

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

ตรวจสอบอักขระแต่ละตัวของอินพุตเพื่อจับคู่ในแต่ละองค์ประกอบของ b ดัชนีของการแข่งขันนั้นบวก 1 จะถูกเพิ่มเข้าไปในยอดรวม

ลองออนไลน์!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.