Клавиатура сотового телефона

17

Клавиатура сотового телефона

Этот вопрос был задан некоторое время назад, но был закрыт из-за плохой спецификации. Итак, я переделываю это, с лучшими характеристиками. Этот вопрос связан, но идет в противоположном направлении.

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

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

*Backspace, 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

правила

  • Это , поэтому выигрывает самое короткое правильное решение (в байтах)
  • Победивший ответ будет выбран через неделю
  • Стандартные лазейки запрещены
  • Ваш ответ может быть в форме полной программы, именованной функции или анонимной функции, принимающей ввод и производящей вывод одним из стандартных методов.

Leaderboard

Фрагмент стека в нижней части этого поста создает таблицу лидеров из ответов а) в виде списка кратчайшего решения для каждого языка и б) в качестве общей таблицы лидеров.

Чтобы убедиться, что ваш ответ обнаружен, начните его с заголовка, используя следующий шаблон уценки:

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

Mego
источник
1
Как вы производите числа? У вас есть номер 9 в примере, но ваша спецификация ( 2 -> A, 22 -> B...,2222 -> A ....) не позволяет производить какие-либо числа.
К. Квилли
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)
Johne
источник
Вы можете сократить (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
Cr3
источник
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)

Это, вероятно, можно сделать немного меньше, но я очень доволен результатом. Разбивает символы на повторяющиеся группы из одного или нескольких, затем проходит по массиву, сопоставляя каждый символ его значению в хэше и добавляя его в окончательную строку. Если он встречает любое число «#», он игнорирует его. Если он сталкивается с каким-либо '*', он удаляет это число из конца последней строки.

Mwr247
источник
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
TFeld
источник
-1

Python 2, 265 байт

Это слишком долго. IO: стандартный ввод, стандартный вывод.

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 : invalid для int () с основанием 10: '*'.
cr3