전화 멀티탭 맞춤법


21

Google 코드 챌린지 에서 영감을 얻음 :

라틴 알파벳은 26 자이며 전화기에는 10 자리 숫자 만 있습니다. 원하는 문자를 나타 내기 위해 일련의 키 누름을 사용하여 친구에게 메시지를보다 쉽게 ​​작성할 수 있도록하고 싶습니다. 문자는 아래와 같이 숫자에 매핑됩니다. 예를 들어 문자 B를 삽입하려면 프로그램에서 22를 누릅니다. 동일한 키에서 두 문자를 순서대로 삽입하려면 키를 두 번 누르기 전에 일시 중지해야합니다. 공백 문자 ''를 인쇄하여 일시 중지를 나타냅니다. 예를 들어 2 2는 AA를 나타내고 22는 B를 나타냅니다.

각 메시지는 소문자 az와 공백 문자 ''로만 구성됩니다. 0을 누르면 공백이 나타납니다.

여기에 이미지 설명을 입력하십시오

입력 문자열을 취하는 가장 작은 함수를 작성하고 입력을 문자열로 생성하거나 stdout에 출력하는 데 필요한 일련의 키 누르기를 리턴해야합니다. 바이트 수가 가장 적은 함수가 이깁니다.

입력 / 출력 예

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

다른 설명

  • 일시 정지 필요할 때만 추가해야하며 공백 ''이어야합니다.
  • 각 메시지는 소문자 az와 공백 문자 '' 로만 구성됩니다 . 0공백을 나타내려면 인쇄 하십시오.
  • 외부 라이브러리가 없습니다.
  • 입력 문자열 만 함수에 전달 될 수 있습니다.
  • 다른 언어의 경쟁력을 높이기 위해 기본 함수 선언은 중요하지 않으며 다른 표준 라이브러리를 가져 오지 않습니다. #includes, imports 및 usings는 포함되지 않습니다. 그 밖의 모든 것. 여기에는 #defines 및 도우미 기능 이 포함 됩니다. 혼란 스러우면이 질문의 규칙 2 를 참조하십시오 .
  • 여러 공백은 실제로 공백 사이에서 일시 중지 할 필요가 없기 때문에 00또는 로 표시 될 수 있습니다.0 0


입력이 소문자 / 대문자라고 가정 할 수 있습니까?
Phil H

@PhilH " 소문자 az 및 공백 문자 ''"
Danny

괄호를 {}함수 서명의 일부로 간주 합니까? 예를 들어 내 코드가 인 경우 또는 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*/]}

배열이 결합되었습니다

*' ')

"digit space different_digit"발생에서 모든 공백이 제거됩니다.

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

1
100 % 제대로 작동하지 않는 것 같습니다. 나는 66666이 연속으로 4 번 눌러 질 필요가 없다는 것을 알았습니다 .
Danny

고맙습니다;)
David Herrmann

1
\2최종 정규 표현식 의 요점은 무엇입니까 ? 분명히 두 번째 그룹은 너비가 0 인 주장입니까?
피터 테일러

당신 말이 맞아요!
David Herrmann

6

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

자바 스크립트 (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

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

A의 For루프 (258) :

7/9 키에 대한 수정 사항 (감사, Danny)이 추가되어 많은 문자가 추가되었습니다.

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));}

그리고 약간 ungolfed (그렇습니다, 그것이 쓰여진 방법입니다) :

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

순진한 자바 솔루션. 의견을 제시해 주신 분들께 감사드립니다.

입력 "hello worlds 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.length10
저스틴

또한을 i통해 반복하는 데에만 사용 된다는 점을 고려 하여 String제거하고 foreach 루프를 수행하십시오.for(char c:s.toCharArray())
Justin

또한, 변화 if(c==' '){o+='0';continue;}if(c==' ')o+='0';else{및 적절한 추가 }.
Justin

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+⌊y1 내지 25의 지점에서 적합하게 경 사진 선 (y = 0.315 x)을 샘플링하고; 이 y 값의 바닥이 반복 패턴 000111 ... 777을 따르도록 선이 기울어진다. 마지막 배열에 2를 더한 22233344455566677778889999가되도록 네 번째 7을 얻기 위해 끝에 숫자가 추가됩니다.
  • ⌈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가 더 좋았 으면 좋겠다. 함수 정의가 계산되지 않습니다. 첫 번째 들여 쓰기 수준은 공백이고, 두 번째 들여 쓰기는 탭이고 세 번째 들여 쓰기 수준은 세 개입니다.

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

자바 스크립트 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='')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.