Набір клавіатури стільникового телефону


17

Набір клавіатури стільникового телефону

Це запитання було задано деякий час назад, але його було закрито через погані характеристики. Отже, я переробляю це, з кращими характеристиками. Це питання пов'язане, але йде у зворотному напрямку.

Перш ніж T9 прийшов, щоб набрати символу в текстовому повідомленні, вам довелося кілька разів натиснути одну з цифрових клавіш, щоб отримати потрібного символу. Для довідки, ось стандартне відображення:

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

*- це зворотний 0простір, це пробіл ( ' ') або число 0і #підтверджує поточний символ. Для простоти всі символи є великими літерами.

При натисканні на клавішу кілька разів, обрані циклів символів через можливі символи для цієї клавіші: 2 -> A, 22 -> B, 222 -> C, 2222 -> 2, 22222 -> A, і так далі. Зауважте, що, *маючи лише один варіант, натискання на нього неодноразово призводить до введення декількох зворотних просторів. Натискання #декількох разів поспіль не впливає. Послідовність #не потрібна.

Крім того, якщо відразу після натискання клавіші натиснути іншу клавішу, попередня клавіша автоматично підтверджується. Таким чином, 223функціонально ідентичний 22#3.

Ваше завдання полягає в тому, щоб перевести серію натискань клавіш у відповідну рядок, на якій відображатиметься стільниковий телефон.

Приклади

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

Правила

  • Це , тому найкоротше правильне рішення (у байтах) виграє
  • Виграшну відповідь буде обрано через один тиждень
  • Стандартні лазівки заборонені
  • Ваша відповідь може бути у вигляді повної програми, названої функції або анонімної функції, приймаючи введення та виробляючи вихід одним із стандартних методів

Таблиця лідерів

Фрагмент стека внизу цієї публікації генерує таблицю лідерів з відповідей а) як список найкоротших варіантів для кожної мови та б) як загальну таблицю лідерів.

Щоб переконатися, що ваша відповідь відображається, будь ласка, почніть свою відповідь із заголовка, використовуючи наступний шаблон Markdown:

## Language Name, N bytes

де Nрозмір вашого подання. Якщо ви покращите свій рахунок, ви можете зберегти старі бали у заголовку, прокресливши їх. Наприклад:

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

Якщо ви хочете включити у свій заголовок декілька чисел (наприклад, тому що ваш результат - це сума двох файлів або ви хочете окремо перерахувати штрафні санкції для перекладача), переконайтесь, що фактичний результат - це останнє число у заголовку:

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

Ви також можете зробити ім'я мови посиланням, яке з’явиться у фрагменті:

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


1
Як ви створюєте числа? У вас є номер «9» як приклад, але ваша специфікація ( 2 -> A, 22 -> B..., 2222 -> A....) не дозволяє будь-які номери , які будуть зроблені.
C. Quilley

1
@ C.Quilley Ось що я отримую за сліпе копіювання цієї діаграми, виправленої зараз.
Мего


1
@AlexA. Це не дуп, це стандартний номер телефону, а не пошук словника T9.
Мего

Відповіді:


3

К5, 112 байт

{(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}

Це справді безлад, але я думаю, що є достатньо місця для його гольфу.

Спочатку нам потрібно побудувати таблицю пошуку для ключової карти. Існують ключі з 2, 4 та 5 символами, нанесені на них, тому додавання кожного запису до 20 спрощує процес циклічної індексації цієї таблиці пізніше:

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

Потім я розділив вхід на прогони:

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

Відміняйте будь-які # прогони та зніміть прогони смуги кожного разу, коли я стикаюся з *:

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

І тоді я готовий просто індексувати цю таблицю пошуку на основі довжини та першого елемента кожного запуску.

Всі разом:

  {(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!"

Редагувати:

Збережіть 5 байт:

0 3 6 9 12 15 19 22
((3*!6),19 22)

Можна скоротити (20#'((" ";".?!"),0 3 6 9 12 15 19 22_`c$65+!26),'$!10)до (20#'((" ";".?!"),((3*!6),19 22)_`c$65+!26),'$!10).
kirbyfan64sos

Так, я насправді це лише кілька хвилин тому знайшов.
JohnE

3

Python 2, 230 206 байт

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

Цей створює функцію f, яка приймає рядок натискання клавіш як аргумент і повертає відповідну рядок, яку відображатиме стільниковий телефон. Також трапляється взяти необов'язковий другий аргумент у вигляді словника, який відображає ключі до відповідних символів, наприклад {"0": "0", "1": ".?! 1", ...} .

Спочатку рядок натискань клавіш групується за допомогою повторень символів, наприклад ["8", "#", "99999", "#", ...] . Тоді перший символ кожної групи відображається у словнику, переданому як другий аргумент, наприклад, 9 карт WXYZ9 . Нарешті, довжина групи використовується як зміщення у значенні зі словника.

Зауважте, що зміщення повинно використовувати модуль по довжині групи повторюваних символів, оскільки натискання клавіш може крутитися. Також зауважте, що символ # відображається на \ 0 і видаляється лише наприкінці, тому що 99 # 99 не є таким, як 9999 .

Ось результат функції для кожного з прикладів запитання:

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

3

JavaScript, 214 184 168 162 байт

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)

Можливо, це можна зробити трохи менше, але я дуже задоволений результатом. Розбиває символи на повторювані групи однієї або декількох, потім переходить через масив, відображаючи кожен символ до його значення у хеші та додаючи його до заключної рядки. Якщо він наштовхується на будь-яку кількість "#", він ігнорує його. Якщо він натрапить на будь-який '*', він видаляє цю кількість з кінця заключного рядка.


0

Python 2, 237 байт

Використання словника cr3, але без повторного використання.

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

-1

Python 2, 265 байт

Це занадто довго. 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])

Третій приклад, 7 ## 222 # 222 ** 7 # 222 # 4 , призведе до того, що ваш сценарій підвищить ValueError : недійсний літерал для int () з базою 10: '*'.
cr3
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.