Створіть клавіатуру T9


12

Це питання задає функціональну відповідність словника T9, що є дуже цікавою проблемою. Але у Т9 є інший спосіб введення тексту, а це введення символів за символом. Вам НЕ потрібен словник для реалізації цієї клавіатури.

Ось ключова карта клавіатури 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чотири рази. Щоб закінчити введення цього символу, я натискаю #. *це просто зворотний простір. У нашій версії клавіатури відсутнє використання великих літер.

Приклади введення та виведення:

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 байт. другий бонус, я навіть не розумію. якщо я даю послідовності натискань клавіш як рядок функції, як би існував якийсь час між натисканнями клавіш? Я думаю, що більш розумним бонусом було б дозволити пропуск, #якщо послідовні кнопки все одно відрізняються. що говориться: без цього бонусу, що має статися, якщо #пропущено?
Мартін Ендер

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 в я outgolfed мій перший виклик.

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 Так, і це може фактично допомогти. Я буду працювати над цим сьогодні і завтра.
Conor O'Brien

Принаймні не рекламуйте неправильну оцінку, оскільки відповідь навіть не відповідає специфікації.
Оптимізатор

@Mohsen Зараз він працює з першим бонусом.
Conor O'Brien

t("2#2");дає Bзамість AA. Спробуйте відповідати будь-якому #замість того, щоб видаляти їх.
Тит

1

Пітон, 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

@Optimizer спробував це, і він дійсно не працює з *. Потрібно це насправді? У ній написано: "Зауважте, що він може містити * для зворотного простору ..."
Деф

Так як це не є частиною премії. Його обов'язкове правило.
Оптимізатор

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

На жаль, мене не ввели в оману, оскільки поточні відповіді мовами, які я можу прочитати, також не підтримують *.
nutki

Якщо ви маєте на увазі мою відповідь пітона, ви маєте рацію. Я неправильно трактував питання.
Деф

1

211 байт AWK (з бонусами)

{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

Рубіни 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*""}

Безголівки:

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), потім додати (натискання клавіш = довжина слова-1) -1, до результату додайте символ із цієї позиції.
  • проста версія без тегів: майже однакова, але: (натискання клавіш = довжина слова); додав символ до рядка карти, щоб позбутися іншого -1.
  • обертована версія: виберіть елемент (ключ) з масиву карт, додайте символ (натискання клавіш% довжина елемента-1) з цього елемента для отримання результату.

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,"")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.