T9 키보드 만들기


12

이 질문 은 매우 흥미로운 문제인 T9 사전 일치 기능을 요구합니다. 그러나 T9에는 다른 입력 방법이 있으며 문자별로 입력하는 것입니다. 이 키보드를 구현하기 위해 사전이 필요하지 않습니다.

잊어 버린 경우 T9 키보드의 키맵은 다음과 같습니다.

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

T9 작동 방식

T9로 문자를 입력하려면 해당 문자 n시간을 나타내는 숫자 키를 눌러야 합니다. n해당 키에 작성된 문자의 순서입니다. 숫자는 각 키에 입력 할 수있는 마지막 문자입니다. 예를 들어, BI 를 입력하려면 2두 번 누르 거나 5I 를 입력하려면 5네 번 누릅니다 . 이 문자 입력을 마치려면을 누릅니다 #. *단순히 백 스페이스입니다. 우리의 키보드 버전에는 대문자가 없습니다.

입력 및 출력 예 :

8#99999#055#33#999#22#666#2#777#3# → T9 KEYBOARD

설명:

  • 8선택 T하고 #다음 문자로 이동
  • 99999마지막의 문자 선택 9입니다 키 9#다음 charachter로 이동합니다
  • 0 공백을 삽입
  • 33두 번째의 문자 선택 3이다 키 K#다음 문자로 이동
  • 등등...

규칙

함수 또는 프로그램은 T9 키 누르기를 나타내는 문자열을 허용해야합니다. 출력은 위에서 설명한 키 누르기 결과 텍스트입니다.

이것은 기본 코드 골프이므로 승자가 바이트 단위로 짧으며 표준 규칙 / 루프 홀이 적용됩니다.


보너스는 점수에 영향을 미치지 않습니까? 내가 왜 갈까?
Optimizer

2
또한 귀하의 예 T9 KEYBOARD는 완전히 잘못되었습니다. 그 사람은 읽습니다T9 JEYBARD
Optimizer

1
@Mohsen은 일반적으로 코드 골프 보너스는 점수에서 고정 금액을 뺍니다. 얼마나 합리적인지 알아 내야합니다. 첫 번째 보너스는 아마도 10 또는 20 바이트를 넘지 않아야합니다. 두 번째 보너스, 나는 이해조차하지 못합니다. 키 누르기 시퀀스를 함수에 문자열로 제공하면 키 누르기 사이에 어떤 시간이 있습니까? #어쨌든 연속 버튼이 다른 경우 생략을 허용하는 것이 더 합리적인 보너스라고 생각 합니다. 즉, 보너스가 없으면 #생략하면 어떻게됩니까?
Martin Ender

1
이 보너스에 대해 가능한 바이트 수 이점을 추가해야합니다. 보너스는 선택 사항이지만 모든 답변을 마치 보너스 인 것처럼 보너스를 구현하도록 요청하는 것 같습니다. 필수 사항이면 규칙을 따르십시오. 그렇지 않은 경우 보너스를 구현하기 위해 모든 답변을 요청하지 마십시오. 투표가 불분명하게 마감되기 전에 귀하의 회신을 위해 몇 시간 동안 기다릴 것입니다.
최적화

2
18 시간이 지난 후에도 응답이 없습니다. 불분명 한 투표 마감.
Optimizer

답변:


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

여기에서 온라인으로 사용해보십시오


첫 번째 보너스를받을 수 있습니까?
Mohsen

3
@Mohsen 보너스를받을 수있는 실제 혜택이있을 때까지는 없습니다! 최종 점수에서 코드 길이가 25 % 줄어 듭니다.
Optimizer

2

자바 스크립트 ES6, 220-10 = 210178 바이트

Helka의 CMC 의 일환으로 첫 도전 과제를 능가했습니다.

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]

이것은 문자, modulo a길이를 가져옵니다 .

.join``

이것은 *s의 처리 및 제거를 위해 문자열을 준비합니다 .


1
첫 보너스와 함께 사용할 수 있습니까?
Mohsen

@Mohsen 예, 실제로 도움이 될 수 있습니다. 나는 오늘과 내일을 통해 그것을 할 것입니다.
Conor O'Brien

답변이 사양에 맞지 않기 때문에 적어도 잘못된 점수를 광고하지 마십시오.
Optimizer

@Mohsen 그것은 이제 첫 번째 보너스와 함께 작동합니다.
Conor O'Brien

t("2#2");B대신에 제공 합니다 AA. #제거 하지 말고 일치 시키십시오.
Titus

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가 시도했지만 실제로 *에서는 작동하지 않습니다. 실제로 필요합니까? "백 스페이스 용으로 *를 포함 할 수 있습니다 ..."
Def

보너스의 일부가 아니기 때문에. 필수 규칙입니다.
Optimizer

그렇게 말하고 있습니다. 규칙이 무엇이고 보너스가 무엇인지에 대한 질문은 명확하지 않습니다. 몇 시간 전에 OP에게 설명을 요청했습니다. 응답이 없으면이 질문을 명확하지 않은 것으로 마무리합니다.
Optimizer

죄송합니다. * 읽을 수없는 언어로 된 현재 답변으로 오해되었습니다 *.
nutki December

내 파이썬 답변을 언급한다면 맞습니다. 나는 그 질문을 잘못 해석했다.
데프

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

이것은 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 .

인쇄 할 문자의 조회 테이블로 2 차원 배열을 사용합니다. 프로그램은 다음으로 구분 된 문자를 읽습니다.'#' .

각 그룹에 대해 입력 번호는 1 차원 배열 인덱스를 결정하고 입력 번호의 반복 횟수는 2 차원 배열 인덱스를 결정합니다. '*'이전 문자를 덮어 쓰도록 이동 출력 문자열의 배열의 인덱스를 다시.

따라서 입력 문자열 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대답은 해키 솔루션처럼 조금 보인다. 내가 시간이되면 그것을 조사합니다.


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)에 오프셋 한 다음 (keystrokes = word length-1) -1을 추가하고 해당 위치의 문자를 추가합니다.
  • 태그가없는 간단한 버전 : 거의 동일하지만, (키 입력 = 단어 길이); 다른 캐릭터를 제거하기 위해 맵 문자열에 문자를 추가했습니다 -1.
  • 회전 버전 : 맵 배열에서 항목 (키)을 가져 와서 해당 항목의 문자 (keystrokes % item length-1)를 결과에 추가합니다.

0

자바 스크립트, 147 바이트

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