Правопис з декількома телефонами


21

Натхненний викликом Google Code :

Латинський алфавіт містить 26 символів, а телефони мають лише десять цифр на клавіатурі. Ми хотіли б спростити написання повідомлення вашому другу, використовуючи послідовність натискань клавіш, щоб вказати потрібні символи. Букви відображаються на цифрах, як показано нижче. Наприклад, щоб вставити символ B, програма натискатиме 22. Для того, щоб вставити два символи послідовно з однієї клавіші, користувач повинен зробити паузу, перш ніж натиснути клавішу вдруге. Символ пробілу '' повинен бути надрукований для позначення паузи. Наприклад, 2 2 позначає AA, тоді як 22 позначає B.

Кожне повідомлення буде складатися лише з малих символів az та пробілів ''. Натискання нуля випускає пробіл.

введіть тут опис зображення

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

Приклад введення / виводу

phone("hi")
44 444
phone("hello world")
4433555 555666096667775553

Інші роз'яснення

  • Паузи слід додавати лише тоді, коли це необхідно, і вони повинні бути пробілами ''.
  • Кожне повідомлення буде складатися лише з малих символів az та пробілів ''. Друк 0для позначення пробілів.
  • Жодних зовнішніх бібліотек немає.
  • Вашій функції може передаватися лише вхідний рядок.
  • Щоб зробити інші мови конкурентоспроможними, декларація про основні функції не враховується та не імпортує інші стандартні бібліотеки. #includes, imports і usings не рахуються. Все інше робить. Сюди входять функції #defines та помічники. Дивіться правило 2 цього питання, якщо ви плутаєтеся.
  • Кілька пробілів можна позначати як 00або 0 0тому, що вам не потрібно робити паузи між пробілом


Чи можемо ми припустити, що вхід нижній / верхній регістр?
Філ Х

@PhilH " рядкові символи Аз і символи пробілу '« »
Денні

Чи вважаєте ви дужки {}частиною підпису функції? Наприклад, якщо мій код function f(){alert('hi');}, я повинен рахувати символи alert('hi');або {alert('hi');}?
ProgramFOX

2
Наскільки я пам’ятаю, t9працює інакше: вам потрібно клацнути кожну клавішу один раз, щоб отримати слово.
VisioN

Відповіді:


8

Рубі, 129 122 115 111 108 107 105

Зробили гольф ...

На жаль, повністю забув видалити зайві пробіли - виправлено ...

Збережено 2 символи завдяки Пітеру Тейлору.

Інтернет-версія

def t9(t)
(t.tr(" ",?`).bytes.map{|c|"09998887777666555444333222"[96-c..-1][/(.)\1*/]}*' ').gsub /(\d) (?!\1)/,'\1'
end

Пояснення:

простір переведено до знака порядковим 96

(t.tr(" ",?`).bytes

символи спочатку відображаються на ряд чисел: - a - 2 - b - 22 - d - 3222 - h - 444333222

вираз регулярного вираження потім відповідає першій групі рівних цифр

map{|c|"09998887777666555444333222"[96-c..-1][/(.)\1*/]}

масив з'єднаний

*' ')

усі пробіли в виникненні "простору цифр різні_знаки" видаляються

gsub /(\d) (?!\1)/,'\1'

1
Здається, не працює на 100% правильно. Я бачу, що 66666 ніколи не потрібно натискати 4 рази поспіль.
Danny

Слід виправити, спасибі;)
David Herrmann

1
В чому сенс \2цього остаточного виразного курсу ? Невже друга група - це твердження нульової ширини?
Пітер Тейлор

Ви абсолютно праві!
Девід Геррман

6

РЕБЕЛЬ - 154 110 103

;0 2abc3def4ghi5jkl6mno7pqrs8tuv9wxyz/^;/$<;/([^\d-])(?=\D.*(\d)(\w)*\1)/$2$3-/(\d)-+\1/$1 $1/-//;/$>$`

Ця 'функція' приймає вхід від stdin та надсилає результати до stdout.

Тестові запуски (тому вам не доведеться встановлювати інтерпретатор):

hi
44 444

hello world
4433555 555666096667775553

yes
999337777

kthxbai
558449922 2444

Я ніколи не можу завантажити ваші посилання! :(
luser droog

4

JavaScript (124)

Запуск у Firefox.

t9=s=>s.replace(/./g,c=>'099998887777666555444333222'.slice(36-parseInt(c,36)).match(/(.)\1*/)[0]+' ').replace(/(.) (?!\1)/g,'$1')

4

GolfScript, 46 символів

{).," adgjmptw"&.,.1>*`@@)\;-*}/]{.2$^!" "*\}*

Як завжди, читає введення з stdin, друкує до stdout. Дивіться онлайн-демонстрацію (із консервованим введенням).

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


3

C ++ - 365 символів без int main(){}

#include<iostream>
#include<string>
#include<cmath>
#define o std::cout<<
int main(){std::string s;getline(std::cin,s);for(int i=0;i<s.size();i++){if(s[i]==32)o 0;int j=s[i]-97;if(i>0&&j/3==(s[i-1]-97)/3)o ' ';if(-1<j&j<15){for(int k=j-j%3-1;k<j;k++)o 2+j/3;}if(14<j&j<19){for(int k=14;k<j;k++)o 7;}if(18<j&j<22){for(int k=18;k<j;k++)o 8;}if(21<j&j<26){for(int k=21;k<j;k++)o 9;}}}

Використовує ті ж міркування, моя відповідь тут , тільки з допомогою forпетлі для виведення кожної букви відповідне число раз.


Ви можете використовувати s[i]==32замість s[i]==' '. Значення простору ASCII - 32.
user12205

@ace Впевнені речі.
Hosch250

3

Perl - 107 110

$_=<>;y/ /0/;$z='a';$==2;for$l((3)x5,4,3,4){for$q(1..$l){s/$z/$=x$q.$"/ge,$z++}$=++}s/(.) (?!\1)/\1/g;print

Ось моє попереднє рішення в 120 128 130 155 :

$_=<>;s//_/g;y/sz/79/;for$x(cfilorvy,behknqux,adgjmptw){s/(\d)_/\1\1_/g,eval"y/$x/2-9/"}y/ _/0 /;s/(.) (?!\1)/\1/g;print

Тести:

hi
 44 444

hello world
 4433555 555666096667775553

jackdaws loves my big sphinx
 52 222553297777055566688833777706999022444 407777 744 4446699

3

VBA 220 253/258/219

Тут не враховуються Functionрядки:

З String, 253 :

Function t(s)
For Each c In Split(StrConv(s,64),Chr(0))
If c<>""Then If c=" "Then t=t & 0 Else b=Asc(c)-91:n=String(IIf(b>27,(b-4)Mod 4+1,IIf(b>23,(b-1)Mod 4+1,b Mod 3+1)),Trim(Str(Int(b/3)-IIf(b=24Or b=27Or b>29,1,0)))):t=t &IIf(Right(t,1)=Left(n,1)," " &n,n)
Next
End Function

З Forпетлею 258 :

Додано виправлення для клавіші 7/9 (спасибі, Денні), що додало багато символів.

Function t(s)
For Each c In Split(StrConv(s,64),Chr(0))
If c<>""Then
n=""
b=Asc(c)-91
For i=1To IIf(b>27,(b-4)Mod 4+1,IIf(b>23,(b-1)Mod 4+1,b Mod 3+1))
n=n &Int(b/3)-IIf(b=24Or b=27Or b>29,1,0)
Next
t=t &IIf(c=" ",0,IIf(Right(t,1)=Left(n,1)," " &n,n))
End If
Next
End Function

Використання Choose 219 :

Я не хочу працювати з цим, так як це більш простий по функціональності, але це є більш короткий код ...

Function t(s)
For Each c In Split(StrConv(s,64),Chr(0))
If c<>"" Then:b=Asc(c)-96:n=Choose(b,2,22,222,3,33,333,4,44,444,5,55,555,6,66,666,7,77,777,7777,8,88,888,9,99,999,9999):t=t &IIf(c=" ",0,IIf(Right(t,1)=Left(n,1)," " &n,n))
Next
End Function

yesповинно бути 999337777. Я 10338використовую вашу функцію.
Danny

3

C, 165 163 153 149 138 символів

k(char*s){char*m="`cfilosvz",l=0,i,c;while(*s^0){for(i=0;*s>m[i];i++);c=*s-m[i-1];i==0?i=-1,c=1:i==l?putchar(32):1;while(c--)putchar(i+49);l=i;s++;}}

Моя перша спроба кодування в гольф, будь-які пропозиції вдячні.


2

C ++ - 170 168 160

Гольф:

#define t std::cout<< 
void g(char*s){char v,p,b,l=1;while(*s){v=*s++-97;p=(v==18)+(v==25)+(v-=v/18+v/25)%3;b=v<0?48:v/3+50;if(l==b)t' ';while(p--+1){t(l=b);}}}

Безумовно

void numpresses(char* s)
{
char lastbutton = 1;
const char asciiOffset = 97;

while(*s)
{
    char val = *s++ - asciiOffset;

    char presses = 
        (val == 18) + (val == 25)           //Z and S are special cases. Check for their ascii codes.
        + (val -= val / 18 + val / 25) % 3; //Simple mod 3 for number of presses. Also apply offset for characters above s and z.

    char button =
        val < 0                             //If the character is a space...
        ? '0'                               //The button character needs to be 0
        : val / 3 + '2';                    //Buttons are offset by the ascii code for the number 2


    if (lastbutton == button)               //Add a space if we need to pause
    {
        std::cout << ' ';
    }

    while (presses-- + 1)                   //Print the button once for each press required
    {
        std::cout << button;
        lastbutton = button;            
    }
}
}

2

C: 136 символів

p(char*s){int i,c,l=1;while(c=*s%32,*s++)for(i=l!=(l=(c+149-c/18-c/25)/3-!c);i++<(c-!!c-c/18-c/25)%3+(c==19)+c/26+2;putchar(i^1?l:32));}

І злегка необурений (так, так було написано):

p(char*s){
        int i,c,l=1;
        while(c=*s%32,*s++)for(
                i=l!=(l=(c+149-c/18-c/25)/3-!c);
                i++<(c-!!c-c/18-c/25)%3+(c==19)+c/26+2;
                putchar(i^1?l:32)
        );
}

Я міг би трохи скоротити його, застосувавши трохи рекурсії, чорної магії та неабиякої кількості порошку чилі.


2

Ява - 243

Досить наївне рішення Java. Дякуємо коментаторам за пропозиції.

Виправлена ​​помилка, яка іноді вставляла непотрібні пробіли, наприклад, для входу "привіт світів sup".

    private static void t9(String s) {
        String[]t=",,abc,def,ghi,jkl,mno,pqrs,tuv,wxyz".split(",");String o="";int i,j,k,l=0;for(char c:s.toCharArray()){if(c==32){o+='0';l=0;}else for(j=0;j<10;j++){int n=t[j].indexOf(c);if(n>=0){if(j==l)o+=' ';for(k=0;k<n+1;k++)o+=j;l=j;}}}return o;
    }

4
Дуже добре, але вам потрібно пограти в нього і надати рахунок.
Hosch250

1
Я припускаю, що це так java. Чи можете ви помістити це у своєму заголовку, як це роблять інші відповіді?
Цифрова травма

1
Один гольф: замінити t.lengthна10
Джастін

Також, враховуючи, що iвикористовується лише для повторення через String, видаліть його та зробіть цикл foreach:for(char c:s.toCharArray())
Justin

Крім того , зміни if(c==' '){o+='0';continue;}в if(c==' ')o+='0';else{і додати відповідне умова }.
Джастін

1

CoffeeScript - 202 (210 - 8)

t9=(s)->
    t=[3,3,3,3,3,4,3,4];l=-1;r=""
    for c in s
        n="";d=c.charCodeAt(0)-96
        if c is ' '
            n=0
        else((n+=k+2 for x in[0...d];break)if d<=v;d-=v)for v,k in t
        r+=if n[0]is l[0] then " "+n else n
        l=n
    r

1

APL, 77 символів

{{⍵,⍨⍺,''↑⍨=/↑¨⍺⍵}/('0',⍨(⌈3.1×y-⌊y)/¨⍕¨2+⌊y←7.99,⍨.315×⍳25)[⍵⍳⍨⎕UCS 96+⍳26]}

Пояснення

  • 2+⌊y←7.99,⍨.315×⍳25або, без вогонь, y←(0.315×⍳25),7.99 ◇ 2+⌊yвідбирає відповідну нахилену лінію (у = 0,315 х) ​​у точках від 1 до 25; лінія нахилена таким чином, що підлогу цих значень y відповідає повторюваному малюнку 000111 ... 777, за винятком шостої групи цифр 5555; в кінці додається число, щоб отримати четверту 7, так що кінцевий масив плюс 2 є 22233344455566677778889999;
  • ⌈3.1×y-⌊y посилює різницю між тими значеннями y та їхніми поверхами, так що стелі відмінностей дають шаблон 123123 ... з 4 на останніх цифрах двох груп по 4 цифри;
  • '0',⍨( ... )/¨⍕¨ ...або (( ... ) /¨ ⍕¨ ...),'0' використовує останній результат для дублювання цифр з першого, так що вихід є масивом рядків "2" "22" "222" "3" "33" "333" ... з правильними "7777" і " 9999 "на місці, а" 0 "додано до кінця;
  • ⍵⍳⍨⎕UCS 96+⍳26або (⎕UCS 96+⍳26)⍳⍵обчислює індекс кожної вхідної таблиці, де "a" дорівнює 1, "z" - 26, а пробіл (і кожен інший знак) - 27;
  • { ... }/( ... )[ ... ] приймає останній результат, індекс для кожної вхідної діаграми, щоб перевести кожну таблицю у відповідний рядок цифр, а потім об'єднати рядки за допомогою функції в дужки;
  • {⍵,⍨⍺,''↑⍨=/↑¨⍺⍵}або {(⍺,(=/↑¨⍺,⍵)↑''),⍵}додає кожен новий рядок ⍺ до акумулятора ⍵, вставляючи єдиний пробіл, лише якщо обидва аргументи починаються з одного і того ж символу.

Приклади

      {{⍵,⍨⍺,''↑⍨=/↑¨⍺⍵}/('0',⍨(⌈3.1×y-⌊y)/¨⍕¨2+⌊y←7.99,⍨.315×⍳25)[⍵⍳⍨⎕UCS 96+⍳26]} 'hello world'
 4433555 555666096667775553 
      {{⍵,⍨⍺,''↑⍨=/↑¨⍺⍵}/('0',⍨(⌈3.1×y-⌊y)/¨⍕¨2+⌊y←7.99,⍨.315×⍳25)[⍵⍳⍨⎕UCS 96+⍳26]} 'the quick brown fox jumped over the lazy dog'
 84433077884442225502277766696603336669905886733 3066688833777084433055529999 999036664 

1

Пітон 155 150

Я б хотів, щоб я був кращим на цьому XD. Визначення функції не враховується. Перший рівень відступу - пробіл, другий - вкладка, а третій - 2 вкладки.

def p(s,l=None):
 for c in s:
    for i,g in enumerate(" ,,abc,def,ghi,jkl,mno,pqrs,tuv,wxyz".split(",")):
        if c in g:print"\b"+[""," "][l==i]+str(i)*(g.index(c)+1),;l=i

0

JavaScript 234

for(l=-1,r="",I=0,y=(s=prompt()).length;I<y;I++){c=s[I];n="";d=c.charCodeAt(0)-96;if(0>d)n=0;else for(k=J=0;J<8;k=++J){v="33333434"[k];if(d<=v){for(x=K=0;0<=d?K<d:K>d;x=0<=d?++K:--K)n+=k+2;break}d-=v}r+=n[0]==l[0]?" "+n:n;l=n}alert(r)


0

R 224

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

a=strtoi(charToRaw(scan(,'',sep='\n')),16L)-95;a[a<0]=1;b=c(0,2,22,222,3,33,333,4,44,444,5,55,555,6,66,666,7,77,777,7777,8,88,888,9,99,999,9999)[a];c=append(b[-1],0)%%10;d=b%%10;b[c==d]=paste(b[c==d],'');paste(b,collapse='')
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.