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で文字を入力するには、その文字を表す数字キーを押す必要がありますnnそのキーに書かれたその文字の順序です。数字は、各キーに入力できる最後の文字です。たとえば、2回B押すと入力するには2、4回5押すと入力し5ます。この文字の入力を終了するには、を押し#ます。*単にバックスペースです。このバージョンのキーボードでは、大文字は使用できません。

入力および出力の例:

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

説明:

  • 8選択T#て次の文字に移動します
  • 99999最後の文字を選択し9ているキー9#次のcharachterに移動します
  • 0 スペースを挿入します
  • 33第二の文字を選択し 3ているキーK#次の文字に移動します
  • 等々...

ルール

関数またはプログラムは、T9キー押下を表す文字列を受け入れる必要があります。出力は、上記のように、それらのキーを押した結果のテキストです。

これは基本的なコードゴルフであるため、勝者はバイト単位で最短となり、標準のルール/抜け穴が適用されます。


ボーナスはスコアに影響しませんか?なぜ私はそれに行くのですか?
オプティマイザー14

2
また、あなたの例T9 KEYBOARDは完全に間違っています。それは読むT9 JEYBARD
オプティマイザー14

1
@Mohsen通常、コードゴルフのボーナスは、スコアから一定量を差し引きます。どれだけ合理的かを把握する必要があります。最初のボーナスはおそらく10バイトまたは20バイト以下です。第二のボーナス、私も理解していません。キー押下のシーケンスを文字列として関数に渡すと、キー押下の間にどのような時間がありますか?#とにかく連続したボタンが異なる場合は、より合理的なボーナスは省略できると思います。それが言われている:そのボーナスなしで#省略された場合どうなりますか?
マーティンエンダー14

1
これらのボーナスには、可能なバイト数の利点を追加する必要があります。ボーナスはオプションですが、ボーナスを強制するかのようにすべての回答を求めます。トーンをクリアし、必須の場合はルールに移動し、そうでない場合はボーナスを実装するためにすべての回答を求めないでください。不明確として投票する前に、私はあなたの返事を数時間待つでしょう。
オプティマイザー14

2
18時間経っても返信がありません。不明確として終了する投票。
オプティマイザー14

回答:


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

こちらからオンラインでお試しください


最初のボーナスで機能させることはできますか?
モーセン14

3
@Mohsenボーナスを獲得するメリットが実際に得られるまではありません!たとえば、最終スコアのコード長を25%削減します。
オプティマイザー14

2

JavaScript ES6、220-10 = 210 178バイト

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]

これは、モジュロaの長さの文字を取得します。

.join``

これにより、*sの処理と削除のために文字列が準備されます。


1
最初のボーナスで動作させることはできますか?
モーセン14

@Mohsenはい、それが実際に役立つかもしれません。今日と明日を通して取り組んでいきます。
コナーオブライエン14

少なくとも、答えが仕様に達していないため、誤ったスコアを宣伝しないでください。
オプティマイザー14

@Mohsen現在、最初のボーナスを使用しています。
コナーオブライエン14

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

ボーナスなし(まだ)。正規表現で最初のボーナスをどのように実装するかわかりません。2番目のボーナスは、ルックアップ要素が同じサイズではないため、多くのバイトを追加します。3番目のボーナスを本当に理解しないでください。


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が試してみましたが、実際には*では機能しません。実際には必要ですか?それは言う:「バックスペースのために、それは含めることができます* ...」
デフ

ボーナスの一部ではないので。その義務的なルール。
オプティマイザー14

それは言われています。ルールとボーナスとは何かについての質問は非常に明確ではありません。数時間前にOPに説明を求めました。応答がない場合、私はこの質問を不明確であるとして終了することに投票しています。
オプティマイザー14

申し訳ありませんが、私が読むことができる言語の現在の回答は*をサポートしていないため、誤解されました。
nutki

あなたが私のPythonの答えに言及しているなら、あなたは正しい。質問を誤解しました。
Def 14

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)


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

ルビー254248、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を追加し、その位置から結果に文字を追加します。
  • シンプルなタグなしバージョン:ほとんど同じですが、:(keystrokes = word length); 他を取り除くために文字をマップ文字列に追加しました-1
  • 回転バージョン:マップ配列からアイテム(キー)を取得し、そのアイテムの文字(keystrokes%item length-1)を結果に追加します。

0

JavaScript、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.