สร้างแป้นพิมพ์ T9


12

คำถามนี้ขอฟังก์ชั่นการจับคู่พจนานุกรม T9 ซึ่งเป็นปัญหาที่น่าสนใจมาก แต่ T9 มีวิธีพิมพ์อีกวิธีหนึ่งและนั่นคือการพิมพ์ตัวอักษรต่ออักขระ คุณไม่จำเป็นต้องใช้พจนานุกรมในการใช้คีย์บอร์ดนี้

นี่คือคีย์แผนที่ของแป้นพิมพ์ T9 หากคุณลืม:

+-------+-------+-------+
|   1   |   2   |   3   |
|  .?!  |  ABC  |  DEF  |
+-------+-------+-------+
|   4   |   5   |   6   |
|  GHI  |  JKL  |  MNO  |
+-------+-------+-------+
|   7   |   8   |   9   |
| PQRS  |  TUV  |  WXYZ |
+-------+-------+-------+
|   *   |   0   |   #   |
|   ←   | SPACE |   →   |
+-------+-------+-------+

T9 ทำงานอย่างไร

ในการพิมพ์อักขระด้วย T9 คุณจะต้องกดปุ่มตัวเลขเพื่อแสดงnเวลานั้น nคือลำดับของอักขระที่เขียนบนคีย์นั้น ตัวเลขเป็นอักขระตัวสุดท้ายที่คุณสามารถพิมพ์สำหรับแต่ละคีย์ ตัวอย่างเช่นในการพิมพ์Bฉันกด2สองครั้งหรือพิมพ์5ฉันกด5สี่ครั้ง #เมื่อเสร็จสิ้นการพิมพ์ตัวละครตัวนี้ผมกด *เป็นเพียง backspace ในคีย์บอร์ดรุ่นของเราไม่มีตัวพิมพ์ใหญ่

ตัวอย่างอินพุตและเอาต์พุต:

8#99999#055#33#999#22#666#2#777#3# → T9 KEYBOARD

คำอธิบาย:

  • 8เลือกTและ#ย้ายไปยังตัวละครถัดไป
  • 99999เลือกอักขระตัวสุดท้ายของ9คีย์ซึ่งคือ9และ#ย้ายไปยังอักขระตัวถัดไป
  • 0 แทรกช่องว่าง
  • 33เลือกอักขระตัวที่สองของ 3คีย์ซึ่งคือKและ#ย้ายไปยังอักขระถัดไป
  • และอื่น ๆ ...

กฎระเบียบ

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

นี่คือรหัสกอล์ฟพื้นฐานดังนั้นผู้ชนะจะสั้นที่สุดในหน่วยไบต์และใช้กฎ / ช่องโหว่มาตรฐาน


โบนัสไม่มีผลต่อคะแนนหรือไม่ ทำไมฉันจะไปเพื่อมันได้หรือไม่
เครื่องมือเพิ่มประสิทธิภาพ

2
นอกจากนี้ตัวอย่างของคุณT9 KEYBOARDผิดอย่างสมบูรณ์ สิ่งนั้นอ่านT9 JEYBARD
เครื่องมือเพิ่มประสิทธิภาพ

1
@Mohsen โดยปกติแล้วโบนัสในรหัสกอล์ฟจะลบจำนวนคงที่ออกจากคะแนน คุณจะต้องคิดออกว่ามีเหตุผลมากเพียงใด สำหรับโบนัสแรกอาจไม่เกิน 10 หรือ 20 ไบต์ โบนัสที่สองฉันไม่เข้าใจ ถ้าฉันให้ลำดับของการกดปุ่มเป็นสตริงกับฟังก์ชันการเรียงลำดับของเวลาระหว่างการกดแป้นพิมพ์จะเป็นอย่างไร ฉันคิดว่าโบนัสที่สมเหตุสมผลมากขึ้นคืออนุญาตให้ข้าม#หากปุ่มต่อเนื่องแตกต่างกัน ที่ถูกกล่าวว่า: โดยไม่ต้องโบนัสที่สิ่งที่ควรจะเกิดขึ้นถ้า#ถูกละไว้?
Martin Ender

1
คุณต้องเพิ่มจำนวนไบต์ที่เป็นไปได้สำหรับโบนัสเหล่านี้ โบนัสเป็นทางเลือก แต่คุณดูเหมือนจะถามทุกคำตอบในการใช้โบนัสราวกับว่าเป็นข้อบังคับ โปรดล้างข้อมูลเสียงถ้าพวกเขาจำเป็นต้องย้ายพวกเขาไปที่กฎหากพวกเขาไม่ได้อย่าถามทุกคำตอบในการใช้โบนัส ฉันจะรอสองสามชั่วโมงก่อนที่คำตอบของคุณจะลงคะแนนให้ปิดอย่างชัดเจน
เครื่องมือเพิ่มประสิทธิภาพ

2
ไม่มีการตอบกลับแม้หลังจาก 18 ชั่วโมง การลงคะแนนให้ปิดเท่าที่ไม่ชัดเจน
เครื่องมือเพิ่มประสิทธิภาพ

คำตอบ:


5

CJam, 109 94 ไบต์ ( โบนัสครั้งที่ 2 )

ทางออกที่ไร้เดียงสาและยาวนาน

q'#/);{__'*-:A-,_g{){;}*A_}*;'0/{_,g{)~".?~1"a'[,65>292994 5b{/(X):X+\s}%+1:Xm>=\,=}*}%S*1/~}%

นี่เป็นโปรแกรมเต็มแม้ว่าฟังก์ชั่นจะมีความยาวเท่ากัน

อินพุตจะเข้าสู่ STDIN

ตัวอย่าง:

8#99999#055#33#999#***22#666#2#777#3#

เอาท์พุท:

T9 BOARD

ลองออนไลน์ได้ที่นี่


คุณสามารถทำให้มันใช้กับโบนัสแรกได้หรือไม่?
Mohsen

3
@Mohsen ไม่ได้จนกว่าจะได้รับโบนัสจริง ๆ ! ให้บอกว่าลดความยาวโค้ด 25% ในคะแนนสุดท้าย
เครื่องมือเพิ่มประสิทธิภาพ

2

JavaScript ES6, 220-10 = 210 178 ไบต์

ในฐานะส่วนหนึ่งของCMC ของ Helkaฉันได้ก้าวข้ามความท้าทายครั้งแรกของฉัน

n=>(g=n=>n==(k=n.replace(/.\*/,""))?n:g(k))(n.match(/(\d)\1*|\*/g).map(e=>e<"0"?e:(a=" |.?!|ABC|DEF|GHI|JKL|MNO|PQRS|TUV|WXYZ".split`|`[+e[0]]+e[0])[~-e.length%a.length]).join``)

ตัวอย่างผลลัพธ์:

> f=n=>(g=n=>n==(k=n.replace(/.\*/,""))?n:g(k))(n.match(/(\d)\1*|\*/g).map(e=>e<"0"?e:(a=" |.?!|ABC|DEF|GHI|JKL|MNO|PQRS|TUV|WXYZ".split`|`[+e[0]]+e[0])[~-e.length%a.length]).join``)
[Function]
> f("8#99999#055#33#999#***22#666#2#777#3#")
'T9 BOARD'
> f("8#44#33#0#999#*77#88#444#222#55#0#22#777#666#9#66#0#333#666#99#0#5#88#6#7#7777#0#666#888#33#777#0#8#44#33#0#555#2#99#*9999#999#0#3#666#4#111#")
'THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG!'
> f("8#99999#055#33#999#***22#666#2#777#3#")
'T9 BOARD'

คำอธิบาย

(g=n=>n==(k=n.replace(/.\*/,""))?n:g(k))

ใช้การแทนที่แบบเรียกซ้ำโดยแทนที่อักขระทั้งหมดตามด้วย*จนกว่าจะไม่มี*s เหลืออยู่

n.match(/(\d)\1*|\*/g)

ซึ่งตรงกับตัวเลขทั้งหมดที่ต่อเนื่องกันหรือ*s

a=" |.?!|ABC|DEF|GHI|JKL|MNO|PQRS|TUV|WXYZ".split`|`[+e[0]]+e[0]

สิ่งนี้จะสร้างพจนานุกรมที่ต้องการรับส่วนที่เข้ารหัสจากสตริงขนาดใหญ่จากนั้นต่อท้ายตัวเลขที่ต้องการ

a[~-e.length%a.length]

นี่ทำให้ตัวละครaมีความยาวแบบโมดูโล

.join``

นี่เป็นการเตรียมสตริงสำหรับการประมวลผลและการเอาออกของ*s


1
คุณสามารถทำให้มันใช้กับโบนัสแรกได้หรือไม่?
Mohsen

@Mohsen ใช่และนั่นอาจช่วยได้จริง ฉันจะทำงานผ่านวันนี้และวันพรุ่งนี้
Conor O'Brien

อย่างน้อยโปรดอย่าโฆษณาคะแนนที่ไม่ถูกต้องเนื่องจากคำตอบนั้นไม่ตรงตามข้อกำหนด
เครื่องมือเพิ่มประสิทธิภาพ

@Mohsen ตอนนี้ทำงานกับโบนัสแรก
Conor O'Brien

t("2#2");ให้แทนB AAลองจับคู่ใด ๆ#แทนการลบออก
ติตัส

1

Python, 167 157 151 ไบต์

(ไม่รองรับ '*')

ไม่มีอะไรพิเศษ. ฉันใช้ regex เพื่อแปลงอินพุตเป็นรายการจากนั้นฉันวนซ้ำรายการ ฉันใช้อักขระตัวแรกและความยาวของแต่ละรายการเพื่อค้นหาในรายการค้นหา:

def f(i):
  import re
  t9 = [" 0",".?!1","ABC2","DEF3","GHI4","JKL5","MNO6","PQRS7","TUV9","WXYZ9"]
  i = re.findall(r'[1-9]+|0+',i)
  answer = []
  for j in i:
    answer = answer + [t9[int(j[0])][len(j)-1]]
  return ''.join(answer)

หลังจากเล่นกอล์ฟมาแล้วดูเหมือนว่านี้:

import re;m=lambda i:"".join([" 0,.?!1,ABC2,DEF3,GHI4,JKL5,MNO6,PQRS7,TUV9,WXYZ9".split(",")[int(j[0])][len(j)-1] for j in re.findall(r'[1-9]+|0+',i)])

ไม่มีโบนัส (ยัง) ฉันไม่รู้ว่าฉันจะใช้โบนัสแรกใน regex ได้อย่างไร โบนัสที่สองจะเพิ่มจำนวนมากไบต์เนื่องจากองค์ประกอบการค้นหามีขนาดไม่เท่ากัน ไม่เข้าใจโบนัสที่สามจริงๆ


1

Perl 5: 106 (104 รหัส + 2 ธง)

ดัดแปลงเพื่อจัดการกับการลบ

#!perl -lp
s/((\d)\2*)#?|./chr$2*5+length$1/ge;y//d 0-3.?!1 ABC2 DEF3 GHI4 JKL5 MNO6 P-S7TUV8 W-Z9/c;1while s/.?d//

การใช้งาน:

perl t9.pl <<<'8#99999#055#33#999#22#666#2#777#3#'
perl t9.pl <<<'899999055339992266627773'

Perl 5: 88 (ธง 86 รหัส + 2 ธง)

เวอร์ชันเก่าที่ไม่มีดาวลบ

#!perl -lp
s/(\d)(\1*)#?/chr$1*5+length$2/ge;y// 0-3.?!1 ABC2 DEF3 GHI4 JKL5 MNO6 P-S7TUV8 W-Z9/c

@Optimizer ทดลองใช้และไม่สามารถใช้กับ * ได้ จำเป็นจริงหรือไม่ มันบอกว่า: "โปรดทราบว่ามันสามารถรวม * สำหรับ backspace ... "
กำหนด

เนื่องจากไม่ใช่ส่วนหนึ่งของโบนัส มันเป็นกฎบังคับ
เครื่องมือเพิ่มประสิทธิภาพ

ที่ถูกกล่าวว่า คำถามไม่ชัดเจนว่ากฎคืออะไรและมีโบนัสอะไร ฉันขอ OP เพื่อการชี้แจงหลายชั่วโมงที่ผ่านมา หากไม่มีการตอบกลับฉันลงคะแนนให้ปิดคำถามนี้โดยไม่ชัดเจน
เครื่องมือเพิ่มประสิทธิภาพ

ขออภัยฉันเข้าใจผิดว่าเป็นคำตอบปัจจุบันในภาษาที่ฉันสามารถอ่านได้และไม่สนับสนุน *
nutki

หากคุณอ้างถึงคำตอบของฉันหลามคุณพูดถูก ฉันตีความคำถามผิด ๆ
กำหนด

1

AWK 211 ไบต์ (พร้อมโบนัส)

{split(".?!1-ABC2-DEF3-GHI4-JKL5-MNO6-PQRS7-TUV8-WXYZ9- 0",k,"-");split($0"#",a,"");while(1+(b=a[++i])){if(b==p)++c;else{for(g in k)if(p==substr(k[g],l=length(k[g])))printf(substr(k[g],1+((c-1)%l),1));c=1;p=b}}}

นี่เป็นโปรแกรมเต็มรูปแบบที่อ่านอินพุตจาก stdin มันจะมีประสิทธิภาพมากกว่าหากไม่ใส่แป้นพิมพ์ซ้ำสำหรับแต่ละบรรทัด แต่จะทำให้สคริปต์ยาวขึ้น

นอกจากนี้หากคีย์ "0" เป็นอย่างอื่นมากกว่า 0 สคริปต์จะสั้นลง 4 ไบต์ แต่นั่นเป็นส่วนหนึ่งของเกม: o)


1

C (245 ไบต์)

#define M "8#44#33#0#999#*77#88#444#222#55#0#22#777#666#9#66#0#333#666#99#0#5#88#6#7#7777#0#666#888#33#777#0#8#44#33#0#555#2#99#*9999#999#0#3#666#4#111#"

#include<stdio.h>
char K[][4]={" ",".?!","ABC","DEF","GHI","JKL","MNO","PQRS","TUV","WXYZ"},I[]=M;int       
i,j,k,r;main(){for(;I[i];++i){if(I[i]=='#')I[j++]=K[k][--r],r=k=0;else               
if(I[i]=='*')j?--j:0;else if(!r++)k=I[i]-'0';}I[j]=0;printf("%s\n",I);}

เอาท์พุต

THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG!

คำอธิบาย

#defineนับไบต์ไม่รวมสายเข้าที่ได้รับในครั้งแรก

ฉันใช้อาเรย์สองมิติเป็นตารางค้นหาสำหรับอักขระที่จะพิมพ์ '#'โปรแกรมอ่านตัวอักษรที่คั่นด้วย

สำหรับแต่ละกลุ่มหมายเลขอินพุตจะกำหนดดัชนีอาร์เรย์ลำดับแรกและจำนวนการทำซ้ำของหมายเลขอินพุตจะกำหนดดัชนีอาร์เรย์อาร์เรย์มิติที่สอง '*'ย้ายกลับดัชนีของอาร์เรย์สตริงการส่งออกเพื่อให้เป็นไปเขียนทับตัวอักษรก่อน

ดังนั้นสายป้อน44#(1 ซ้ำ'4') จะแปลให้ค้นหาตารางซึ่งเป็นตัวอักษรK[4][1]H


เวอร์ชันที่ไม่ดี

#define INPUT "8#44#33#0#999#*77#88#444#222#55#0#22#777#666#9#66#0#333#666#99#0#5#88#6#7#7777#0#666#888#33#777#0#8#44#33#0#555#2#99#*9999#999#0#3#666#4#"

#include<stdio.h>

static const char keyboard[10][4] = {" ", ".?!", "ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ"};

int main(void)
{
  char input[] = INPUT;
  char output[256];
  int i, j;
  int key = 0;
  int reps = 0;

  for (i = j = 0; input[i] != '\0'; ++i) {
    switch (input[i]) {
    case '#':
      output[j] = keyboard[key][reps - 1];
      ++j;
      reps = key = 0;
      break;
    case '*':
      if (j > 0) --j;
      break;
    default:
      if (reps == 0)  {
        key = (int)input[i] - '0';
      }
      ++reps;
      break;
    }
  }

  output[j] = '\0';
  printf("%s\n", output);

  return(0);
}

1

Ruby 254 , 248 , 229 ไบต์

แข็งแรงเล่นกอล์ฟ:

n=->(t){r,m,b=[]," _.?!1_ABC2_DEF3_GHI4_JKL5_MNO6_PQRS7_TUV8_WXYZ9_*_0_#".split("_"),nil;t.scan(/((.)\2*)/){|l,_|(!(l=~/\#/)?(l=~/\*/?(r.pop l.size):(l=="00"?r<<(b ? "0 ":" 0"):(c=m[l[0].to_i];r<<c[l.size%c.size-1]))):b=l)};r*""}

Ungolfed:

def t9totext(t)
  bonq = nil
  numpad = [" ",".?!1","ABC2","DEF3","GHI4","JKL5","MNO6","PQRS7","TUV8","WXYZ9","*","0","#"]

  r = []
  t.scan(/((.)\2*)/) do |l, _|
    if !(l =~ /\#/)
      if l =~ /\*/
        r.pop(l.size)
      elsif l == "00"
        r << (bonq ? "0 " : " 0")
      else
        c = numpad[l[0].to_i]
        r << c[l.size % c.size - 1]
      end
    else
      bonq = l
    end
  end
  r.join
end

รายละเอียดทั้งหมดเหล่านี้ควรจะประสบความสำเร็จ:

  it "outputs the correct word" do
    expect(n.call('8#99999#055#33#999#22#666#2#777#3#1')).to eq("T9 KEYBOARD.")
    expect(n.call('4433555#55566609666666677755533*3111')).to eq("HELLO WORLD!")
    expect(n.call('7##222#222**7#222#4')).to eq('PPCG')
    expect(n.call('00#0#00')).to eq(' 0 0 ')
  end

0 0คำตอบที่มีลักษณะบิตเช่นการแก้ปัญหา hacky จะดูมันเมื่อฉันมีเวลา


0

PHP, 183-10 = 173 ไบต์

ทุกรุ่นรับอินพุตจากอาร์กิวเมนต์บรรทัดคำสั่ง php -r '<code>' <string>โทร

หมายเหตุ : *ทุกรุ่นโยนเตือนถ้าใส่เริ่มต้นด้วย
ย่อหน้า$o=[];รหัสเพื่อลบข้อบกพร่องที่

preg_match_all("%(\d)\1*|\*%",$argv[1],$m);foreach($m[0]as$w)if("*"==$w)array_pop($o);else$o[]="- 0   .?!1 ABC2 DEF3 GHI4 JKL5 MNO6 PQRS7TUV8 WXYZ9"[$w[0]*5+strlen($w)];echo join($o);
  • ไม่ต้องใช้แท็กแฮช
  • ล้มเหลวหากกดปุ่มบ่อยเกินไป

210-10 - ?? = ??? ไบต์

$a=[" 0",".?!1",ABC2,DEF3,GHI4,JKL5,MNO6,PQRS7,TUV8,WXYZ9];preg_match_all("%(\d)\1*|\*%",$argv[1],$m);foreach($m[0]as$w)if("*"==$w)array_pop($o);else$o[]=$a[$w[0]][strlen($w)%strlen($a[$w[0]])-1];echo join($o);
  • ไม่ต้องใช้แท็กแฮช
  • หมุนหากกดปุ่มบ่อยเกินไป

181 ไบต์ไม่มีโบนัส

preg_match_all("%\d+#|\*%",$argv[1],$m);foreach($m[0]as$w)if("*"==$w)array_pop($o);else$o[]=" 0   .?!1 ABC2 DEF3 GHI4 JKL5 MNO6 PQRS7TUV8 WXYZ9"[$w[0]*5+strlen($w)-2];echo join($o);

แตกหัก

เวอร์ชัน "ไม่มีแท็กแฮช" แยกสตริงเป็น (ริ้วจำนวนเท่ากัน) และ (เครื่องหมายดอกจัน) และลืมทุกอย่างอื่น เวอร์ชันไม่มีโบนัสจะใช้เวลา (ตามจำนวนตัวเลขตามด้วย#) และ (เครื่องหมายดอกจัน)

จากนั้นวนซ้ำการจับคู่: หากพบ '*' ให้ลบองค์ประกอบสุดท้ายของอาร์เรย์ผลลัพธ์

ความแตกต่างระหว่างรุ่นต่าง ๆ อยู่ในelseส่วน:

  • ไม่มีเวอร์ชันโบนัส: ชดเชยสตริงแผนที่เป็น (คีย์ * 5) จากนั้นเพิ่ม (การกดแป้น = word length-1) -1 เพิ่มอักขระจากตำแหน่งนั้นไปยังผลลัพธ์
  • เวอร์ชั่นธรรมดาไม่มีแท็ก: เกือบเหมือนกัน แต่: (การกดแป้น = ความยาวคำ); -1เพิ่มตัวอักษรสตริงแผนที่เพื่อกำจัดของอื่น ๆ
  • เวอร์ชันการหมุน: ใช้ไอเท็ม (คีย์) จากอาเรย์แผนที่เพิ่มอักขระ (การกดคีย์% ไอเท็มความยาว -1) จากไอเท็มนั้นไปยังผลลัพธ์

0

JavaScript, 147 ไบต์

แก้ไขคำตอบของ Conorด้วย regex จากคำตอบ PHP ของฉันและเล่นกอล์ฟลง

t=i=>i.match(/(\d)\1*|\*/g).map(w=>(" 0~.?!1~ABC2~DEF3~GHI4~JKL5~MNO6~PQRS7~TUV8~WXYZ9".split`~`[w[0]]||"*")[w.length-1]).join``.replace(/.\*/g,"")

แตกหัก

t=i=>i
    .match(/(\d)\1*|\*/g)   // split input to streaks of equal numbers and single `*`
    .map(w=>                // replace each item with ...
                            // .. take string depending on the digit
        (" 0~.?!1~ABC2~DEF3~GHI4~JKL5~MNO6~PQRS7~TUV8~WXYZ9".split`~`[w[0]]
        ||"*")              // .. ("*" for not a digit)
        [w.length-1]        // -> the (item length)th character of that string
    )
    .join``                 // join without delimiter
    .replace(/.\*/g,"")     // and recursively remove every (letter,asterisk) combination

เวอร์ชันที่หมุนได้ 158 ไบต์

เพิ่มs=ไปยังจำสตริงและ%s.lengthเพื่อหมุน

t=i=>i.match(/(\d)\1*|\*/g).map(w=>(s=" 0~.?!1~ABC2~DEF3~GHI4~JKL5~MNO6~PQRS7~TUV8~WXYZ9".split`~`[w[0]]||"*")[w.length%s.length-1]).join``.replace(/.\*/g,"")
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.