Создать клавиатуру T9

12

Этот вопрос требует функциональности сопоставления словаря T9, что является очень интересной проблемой. Но у T9 есть другой способ печатать, и это печатать по буквам. Вам НЕ нужен словарь для реализации этой клавиатуры.

Вот карта клавиш клавиатуры T9, если вы забыли:

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

Как работает Т9

Чтобы ввести символ с Т9, вам нужно нажать цифровую клавишу, представляющую время этого символа n. nэто порядок этого символа, написанного на этом ключе. Цифры являются последним символом, который вы можете ввести для каждой клавиши. Например, для ввода Bя нажимаю 2два раза или для 5ввода нажимаю 5четыре раза. Чтобы закончить вводить этот символ, я нажимаю #. *это просто забой. В нашей версии клавиатуры нет заглавных букв.

Примеры ввода и вывода:

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
@ Мохсен обычно, бонусы в коде гольф вычтет фиксированную сумму из оценки. Вы должны выяснить, насколько это разумно. для первого бонуса, вероятно, не более 10 или 20 байтов. Второй бонус, я даже не понимаю. если бы я дал последовательность нажатий клавиш в виде строки функции, как бы было время между нажатиями клавиш? Я думаю, что более разумным бонусом было бы разрешение пропустить, #если последовательные кнопки отличаются в любом случае. это сказанное: без этого бонуса, что должно произойти, если #опущено?
Мартин Эндер
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

Попробуйте онлайн здесь

оптимизатор
источник
Можете ли вы заставить его работать на первый бонус?
Мохсен
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 Теперь работает с первым бонусом.
Конор О'Брайен
t("2#2");дает Bвместо AA. Попробуйте сопоставить любой #вместо того, чтобы удалить их.
Тит
1

Python, 167 157 151 байт

(не поддерживает '*')

Ничего особенного. Я использую регулярное выражение для преобразования ввода в список, а затем я зацикливаю записи. Я использую первый символ и длину каждой записи для поиска в списке поиска:

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

Нет бонусов (пока). Я не знаю, как бы я реализовал первый бонус в регулярных выражениях. Второй бонус добавит много байтов, так как элементы поиска имеют разный размер. Не очень понимаю третий бонус.

Защита
источник
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
nutki
источник
@Optimizer попробовал это, и это действительно не работает с *. Это действительно требуется, хотя? Он говорит: «Обратите внимание, что он может включать * для возврата ...»
Def
Так как это не часть бонуса. Это обязательное правило.
Оптимизатор
Что, как говорится. вопрос очень неясен, что такое правило и что такое бонус. Я попросил у ОП уточнения несколько часов назад. Если ответа нет, я голосую, чтобы закрыть этот вопрос как неясный.
Оптимизатор
Извините, я был введен в заблуждение, так как текущие ответы на языках, которые я могу прочитать, также не поддерживают *.
Nutki
Если вы имеете в виду мой ответ на Python, вы правы. Я неправильно истолковал вопрос.
Def
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}}}

Это полная программа, которая читает входные данные из стандартного ввода. Было бы более эффективно не перераспределять клавиатуру для каждой строки, но это сделало бы скрипт длиннее.

Также, если бы ключ «0» был чем-то отличным от 0, сценарий был бы на 4 байта короче, но это часть игры: o)

LeFauve
источник
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);
}
musarithmia
источник
1

Рубин 254 , 248 , 229 байт

Golfed:

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 решение. Посмотрим на это, когда у меня будет время.

Biketire
источник
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части:

  • нет бонусной версии: сместить строку карты в (key * 5), затем добавить (нажатия клавиш = длина слова-1) -1, добавить символ из этой позиции в результат.
  • простая версия без тегов: почти такая же, но: (нажатия клавиш = длина слова); добавил символ в строку карты, чтобы избавиться от другого -1.
  • вращающаяся версия: взять элемент (ключ) из массива карты, добавить символ (нажатия клавиш% item length-1) из этого элемента в результате.
Titus
источник
0

JavaScript, 147 байт

Ответ Конора был исправлен с помощью регулярного выражения из моего ответа 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,"")
Titus
источник