Mengetik Keyboard Ponsel

17

Mengetik Keyboard Ponsel

Pertanyaan ini ditanyakan beberapa waktu yang lalu, tetapi ditutup karena spesifikasi yang buruk. Jadi, saya mengulanginya, dengan spesifikasi yang lebih baik. Pertanyaan ini terkait, tetapi berjalan ke arah yang berlawanan.

Sebelum T9 muncul, untuk mengetik karakter dalam pesan teks, Anda harus menekan salah satu tombol angka beberapa kali untuk mendapatkan karakter yang Anda inginkan. Untuk referensi, berikut adalah pemetaan standar:

+-------+-------+-------+
|   1   |   2   |   3   |
|  .?!1 |  ABC2 |  DEF3 |
+-------+-------+-------+
|   4   |   5   |   6   |
|  GHI4 |  JKL5 |  MNO6 |
+-------+-------+-------+
|   7   |   8   |   9   |
| PQRS7 |  TUV8 | WXYZ9 |
+-------+-------+-------+
|   *   |   0   |   #   |
|   ←   |SPACE 0|   →   |
+-------+-------+-------+

*adalah backspace, 0adalah spasi ( ' ') atau angka 0, dan #mengonfirmasi karakter saat ini. Demi kesederhanaan, semua karakter adalah huruf besar.

Ketika Anda menekan tombol beberapa kali, siklus karakter yang dipilih melalui karakter yang mungkin untuk kunci yang: 2 -> A, 22 -> B, 222 -> C, 2222 -> 2, 22222 -> A, dan sebagainya. Perhatikan bahwa, karena *hanya memiliki satu opsi, menekannya berulang kali menyebabkan banyak spasi mundur dimasukkan. Menekan #beberapa kali berturut-turut tidak berpengaruh. Trailing #tidak perlu.

Selain itu, jika tombol yang berbeda ditekan segera setelah menekan tombol, penekanan tombol sebelumnya secara otomatis dikonfirmasi. Dengan demikian, 223secara fungsional identik dengan 22#3.

Tantangan Anda adalah menerjemahkan serangkaian penekanan tombol ke string yang sesuai yang akan ditampilkan ponsel.

Contohnya

8#99999#055#33#999#22#666#2#777#3#1 -> T9 KEYBOARD
4433555#55566609666666677755533*3111 -> HELLO WORLD!
7##222#222**7#222#4 -> PPCG
00#0#00 -> 0 0

Aturan

  • Ini adalah , sehingga solusi terpendek yang benar (dalam byte) menang
  • Jawaban yang menang akan dipilih dalam satu minggu
  • Celah standar dilarang
  • Jawaban Anda mungkin dalam bentuk program lengkap, fungsi bernama, atau fungsi anonim, mengambil input dan menghasilkan output dalam salah satu metode standar

Papan peringkat

Cuplikan Stack di bagian bawah posting ini menghasilkan leaderboard dari jawaban a) sebagai daftar solusi terpendek per bahasa dan b) sebagai leaderboard keseluruhan.

Untuk memastikan bahwa jawaban Anda muncul, silakan mulai jawaban Anda dengan tajuk utama, menggunakan templat Penurunan harga berikut:

## Language Name, N bytes

di mana Nukuran kiriman Anda. Jika Anda meningkatkan skor Anda, Anda dapat menyimpan skor lama di headline, dengan mencoretnya. Contohnya:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Jika Anda ingin memasukkan beberapa angka dalam tajuk Anda (mis. Karena skor Anda adalah jumlah dari dua file atau Anda ingin membuat daftar hukuman penterjemah secara terpisah), pastikan bahwa skor sebenarnya adalah angka terakhir di tajuk:

## Perl, 43 + 2 (-p flag) = 45 bytes

Anda juga dapat membuat nama bahasa menjadi tautan yang kemudian akan muncul di cuplikan:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes

Mego
sumber
1
Bagaimana Anda menghasilkan angka? Anda memiliki angka '9' dalam contoh, tetapi spesifikasi Anda ( 2 -> A, 22 -> B..., 2222 -> A....) tidak mengizinkan angka apa pun untuk diproduksi.
C. Quilley
1
@ C. Quilley Itulah yang saya dapatkan karena menyalin diagram itu secara membabi buta, diperbaiki sekarang.
Mego
1
@AlexA. Bukan penipuan, itu input standar ponsel, bukan pencarian kamus T9.
Mego

Jawaban:

3

K5, 112 byte

{(20#'((" ";".?!"),((3*!6),19 22)_`c$65+!26),'$!10)[.*x]20!#1_x}'(){$[42=*y;(-#y)_x;35=*y;x;x,,y]}/{(&~0=':x)_x}

Yang ini benar-benar berantakan, tapi saya pikir ada cukup banyak ruang untuk bermain golf.

Pertama kita perlu membuat tabel pencarian untuk keymap. Ada kunci dengan 2, 4 dan 5 karakter yang dipetakan padanya, jadi menambahkan setiap entri ke 20 menyederhanakan proses pengindeksan tabel ini secara siklis nanti:

  (20#'((" ";".?!"),((3*!6),19 22)_`c$65+!26),'$!10)
(" 0 0 0 0 0 0 0 0 0 0"
 ".?!1.?!1.?!1.?!1.?!1"
 "ABC2ABC2ABC2ABC2ABC2"
 "DEF3DEF3DEF3DEF3DEF3"
 "GHI4GHI4GHI4GHI4GHI4"
 "JKL5JKL5JKL5JKL5JKL5"
 "MNO6MNO6MNO6MNO6MNO6"
 "PQRS7PQRS7PQRS7PQRS7"
 "TUV8TUV8TUV8TUV8TUV8"
 "WXYZ9WXYZ9WXYZ9WXYZ9")

Lalu saya membagi input menjadi run:

 {(&~0=':x)_x}"8#99999#055#33#999"
(,"8"
 ,"#"
 "99999"
 ,"#"
 ,"0"
 "55"
 ,"#"
 "33"
 ,"#"
 "999")

Jatuhkan setiap # run dan strip trailing running setiap kali saya menemukan *:

  (){$[42=*y;(-#y)_x;35=*y;x;x,,y]}/{(&~0=':x)_x}"8#99999#055#33#999"
(,"8"
 "99999"
 ,"0"
 "55"
 "33"
 "999")

Dan kemudian saya siap untuk hanya mengindeks ke dalam tabel pencarian berdasarkan panjang dan elemen pertama dari setiap proses.

Bersama:

  {(20#'((" ";".?!"),((3*!6),19 22)_`c$65+!26),'$!10)[.*x]20!#1_x}'(){$[42=*y;(-#y)_x;35=*y;x;x,,y]}/{(&~0=':x)_x}"4433555#55566609666666677755533*3111"
"HELLO WORLD!"

Edit:

Hemat 5 byte:

0 3 6 9 12 15 19 22
((3*!6),19 22)
JohnE
sumber
Anda dapat mempersingkat (20#'((" ";".?!"),0 3 6 9 12 15 19 22_`c$65+!26),'$!10)menjadi (20#'((" ";".?!"),((3*!6),19 22)_`c$65+!26),'$!10).
kirbyfan64sos
Ya, saya baru saja menemukan itu beberapa menit yang lalu.
JohnE
3

Python 2, 230 206 byte

import re
f=lambda a,b=dict(zip("0123456789*#"," 0~.?!1~ABC2~DEF3~GHI4~JKL5~MNO6~PQRS7~TUV8~WXYZ9~\b~".split("~"))):"".join([j and b[j][(len(i)-1)%len(b[j])]or b[i]for i,j in re.findall(r"((\d)\2*|.)",a)])

Yang ini menciptakan fungsi f yang mengambil string penekanan tombol sebagai argumen dan mengembalikan string yang sesuai yang akan ditampilkan ponsel. Itu juga terjadi untuk mengambil argumen opsional kedua sebagai kunci pemetaan kamus untuk karakter yang sesuai, misalnya {"0": "0", "1": ".?! 1", ...} .

Pertama, string penekanan tombol dikelompokkan dengan karakter berulang, misalnya ["8", "#", "99999", "#", ...] . Kemudian, karakter pertama dari setiap grup dipetakan dalam kamus yang diteruskan sebagai argumen kedua, misalnya 9 peta ke WXYZ9 . Akhirnya, panjang grup digunakan sebagai offset dalam nilai dari kamus.

Perhatikan bahwa offset harus menggunakan modulo pada panjang grup karakter yang berulang karena penekanan tombol mungkin berputar. Perhatikan juga bahwa karakter # dipetakan ke \ 0 dan hanya dihapus pada akhirnya karena 99 # 99 tidak sama dengan 9999 .

Berikut ini adalah output dari fungsi untuk masing-masing contoh dalam pertanyaan:

>>> print f("8#99999#055#33#999#22#666#2#777#3#1")
T9 KEYBOARD.
>>> print f("4433555#55566609666666677755533*3111")
HELLO WORLD!
>>> print f("7##222#222**7#222#4")
PPCG
>>> print f("00#0#00")
0 0
cr3
sumber
3

JavaScript, 214 184 168 162 byte

x=>(x.match(/(.)\1*/g,f='').map(a=>f=(l=a.length,v=' 0#.?!1#ABC2#DEF3#GHI4#JKL5#MNO6#PQRS7#TUV8#WXYZ9'.split`#`[a[0]])?f+v[--l%v.length]:a<'*'?f:f.slice(0,-l)),f)

Ini mungkin bisa dibuat sedikit lebih kecil, tapi saya cukup senang dengan hasilnya. Pisahkan karakter menjadi kelompok yang diulang satu atau lebih, kemudian langkah-langkah melalui array, memetakan setiap karakter untuk nilainya dalam hash dan menambahkannya ke string terakhir. Jika ia menemukan sejumlah '#', itu mengabaikannya. Jika ia menemukan '*', itu menghilangkan jumlah mereka dari akhir string terakhir.

Mwr247
sumber
0

Python 2, 237 byte

Menggunakan kamus cr3, tetapi tanpa kembali.

def f(i):
 d=dict(zip("0123456789"," 0|.?!1|ABC2|DEF3|GHI4|JKL5|MNO6|PQRS7|TUV8|WXYZ9".split("|")))
 s,x,j='',i[0],0
 for c in i[1:]+'#':
  if c==x:j+=1
  else:
   if x>'/':s+=d[x][j%len(d[x])]
   j=0
  if c=='*':s=s[:-1]
  x=c
 return s
TFeld
sumber
-1

Python 2, 265 byte

Terlalu lama. IO: stdin, stdout.

a=reduce(lambda q,w:q+" "+[w,""][w=="#"]if q[-1]!=w else q+w,raw_input()).split()
while "*" in a:del a[a.index("*")-1:a.index("*")+1]
print"".join([(lambda a:a[len(q)%len(a)-1])(" 0:.?!1:ABC2:DEF3:GHI4:JKL5:MNO6:PQRS7:TUV8:WXYZ9".split(":")[int(q[0])])for q in a])
Hannes Karppila
sumber
Contoh ketiga, 7 ## 222 # 222 ** 7 # 222 # 4 , akan menyebabkan skrip Anda meningkatkan ValueError : literal tidak valid untuk int () dengan basis 10: '*'.
cr3