T9 klavye oluşturma


12

Bu soru çok ilginç bir sorun olan bir T9 sözlük eşleştirme işlevselliği ister. Ancak T9'un başka bir yazma yöntemi vardır ve bu karakter karakter yazmaktır. Bu klavyeyi uygulamak için bir sözlüğe ihtiyacınız YOKTUR.

Unutursanız, bir T9 klavyenin tuş haritası:

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

T9 nasıl çalışır

T9 ile bir karakter yazmak için, o karakter nzamanlarını temsil eden sayı tuşuna basmanız gerekir . no tuşa yazılan karakterin sırasıdır. Sayılar, her tuş için yazabileceğiniz son karakterdir. Örneğin, yazmak için iki kez Bbasın 2veya yazmak için dört kez 5basın 5. Bu karakteri yazmayı bitirmek için tuşuna basın #. *sadece geri almaktır. Klavye sürümümüzde büyük harf kullanımı yoktur.

Girdi ve çıktı örnekleri:

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

Açıklama:

  • 8seçer Tve #sonraki karaktere geçer
  • 99999bir sonraki karaktere 9olan 9ve #sonraki karaktere geçen anahtarın son karakterini seç
  • 0 boşluk ekler
  • 33İkinci karakterini seçer 3olduğunu tuşu Kve #sonraki karaktere hamle
  • Ve bunun gibi...

kurallar

İşleviniz veya programınız T9 tuş basımlarını temsil eden bir dize kabul etmelidir. Çıktı, yukarıda ana hatlarıyla belirtildiği gibi, bu tuşlara basıldığında elde edilen metindir.

Bu temel kod golf, bu yüzden kazanan bayt olarak en kısa ve standart kurallar / boşluklar geçerlidir.


Bonus'un puan üzerinde bir etkisi yok mu? Neden gideyim ki?
Optimize Edici

2
Ayrıca, örneğin T9 KEYBOARDtamamen yanlış. Biri okuyorT9 JEYBARD
Optimizer

1
@Mohsen genellikle, kod golfündeki bonuslar puandan sabit bir miktar çıkaracaktır. ne kadar makul olduğunu bulmanız gerekecek. ilk bonus için muhtemelen 10 veya 20 bayttan fazla değil. ikinci bonus, anlamıyorum bile. Eğer tuşa basma dizisini işleve bir dize olarak verirsem, tuş basma arasında nasıl bir zaman olur? Bence #birbirini takip eden düğmeler farklıysa daha makul bir bonus ihmal edilebilir. söyleniyor: bu bonus olmadan #ihmal edilirse ne olmalı ?
Martin Ender

1
Bu bonuslar için olası bir bayt sayısı avantajı eklemeniz gerekir. Bonuslar isteğe bağlıdır ancak bonusların uygulanması zorunludur sanki her cevabı soruyorsunuz. Lütfen tonu temizleyin, eğer zorunlularsa, bunları kurallara taşıyın, eğer değilse, her cevabı bonusları uygulamak için sormayın. Oy vermeden önce net olmayan bir şekilde kapanması için cevabınız için birkaç saat bekleyeceğim.
Optimize Edici

2
18 saat sonra bile cevap yok. Belirsiz olarak kapatmak için oylama.
Optimize Edici

Yanıtlar:


5

CJam, 109 94 bayt ( 2. bonus)

Çok saf ve uzun bir çözüm

q'#/);{__'*-:A-,_g{){;}*A_}*;'0/{_,g{)~".?~1"a'[,65>292994 5b{/(X):X+\s}%+1:Xm>=\,=}*}%S*1/~}%

Bir işlev aynı uzunlukta olmasına rağmen, bu tam bir programdır.

Giriş STDIN'e gider

Misal:

8#99999#055#33#999#***22#666#2#777#3#

Çıktı:

T9 BOARD

Buradan çevrimiçi deneyin


İlk bonus için işe yarayabilir misin?
Mohsen

3
@Mohsen Bonus kazanmanın gerçek bir yararı oluncaya kadar değil! Diyelim ki final skorunda% 25 kod uzunluğu azalması.
Optimize Edici

2

JavaScript ES6, 220-10 = 210178 bayt

Bir parçası olarak Helka'nın CMC , benim ilk meydan outgolfed ettik.

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

Örnek çıktılar:

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

açıklama

(g=n=>n==(k=n.replace(/.\*/,""))?n:g(k))

Tüm karakterleri değiştirilmesi Bu uygular özyinelemeli değiştirme, ardından *hiçbir kalmayıncaya kadar *kaldıysa.

n.match(/(\d)\1*|\*/g)

Bu, ardışık basamak veya *s'nin tüm çalışmalarıyla eşleşir .

a=" |.?!|ABC|DEF|GHI|JKL|MNO|PQRS|TUV|WXYZ".split`|`[+e[0]]+e[0]

Bu, kodlanan parçayı büyük dizeden alarak, ardından istenen basamağı ekleyerek istenen sözlüğü oluşturur.

a[~-e.length%a.length]

Bu karakteri alır, modulo auzunluğu.

.join``

Bu, dizeyi *s'nin işlenmesi ve kaldırılması için hazırlar .


1
İlk bonusla çalışmasını sağlayabilir misiniz?
Mohsen

@Mohsen Evet ve bu gerçekten yardımcı olabilir. Bugün ve yarın üzerinde çalışacağım.
Conor O'Brien

Lütfen en azından yanlış bir puanın reklamını yapmayın, çünkü cevap spesifikasyona kadar değildir.
Optimize Edici

@Mohsen Şimdi ilk bonus ile çalışıyor.
Conor O'Brien

t("2#2");Byerine verir AA. #Bunları kaldırmak yerine herhangi biriyle eşleştirmeye çalışın .
Titus

1

Python, 167 157 151 bayt

('*' özelliğini desteklemez)

Özel birşey yok. Giriş bir listeye dönüştürmek için regex kullanın, sonra girişleri döngü. Bir arama listesinde aramak için her girişin ilk karakterini ve uzunluğunu kullanıyorum:

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)

Biraz golf oynadıktan sonra şöyle görünür:

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

Bonus yok (henüz). Normal ikramiyede ilk bonusu nasıl uygulayacağımı bilmiyorum. İkinci bonus, arama öğeleri aynı boyutta olmadığından çok sayıda bayt ekleyecektir. Üçüncü bonusu gerçekten anlamayın.


1

Perl 5: 106 (104 kod + 2 bayrak)

Silme işlemlerini gerçekleştirmek için değiştirildi.

#!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//

Kullanımı:

perl t9.pl <<<'8#99999#055#33#999#22#666#2#777#3#'
perl t9.pl <<<'899999055339992266627773'

Perl 5: 88 (86 kod + 2 bayrak)

Yıldız silmeden eski sürüm.

#!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 denedi ve gerçekten * ile çalışmıyor. Gerçi gerçekten gerekli mi? Diyor ki: "Backspace için * içerebileceğini unutmayın ..."
Def

Bonus beri onun bir parçası değil. Bu zorunlu bir kuraldır.
Doktor

Söyleniyor ki. soru, kuralın ne olduğu ve bonusun ne olduğu konusunda çok net değil. OP'den birkaç saat önce açıklama istedim. Yanıt yoksa, bu soruyu belirsiz olarak kapatmak için oy kullanıyorum.
Optimize Edici

Özür dilerim, okuyabileceğim dillerdeki güncel cevaplar da desteklenmediği için yanıldım *.
nutki

Python cevabımdan bahsediyorsanız haklısınız. Soruyu yanlış yorumladım.
Def

1

AWK 211 bayt (bonuslarla birlikte)

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

Bu stdin girdisini okuyan tam bir programdır. Her satır için klavyeyi gözden kaçırmamak daha etkili olur, ancak komut dosyasını daha uzun hale getirir.

Ayrıca "0" tuşu 0'dan başka bir şey olsaydı, komut dosyası 4 bayt daha kısa olurdu, ancak bu oyunun bir parçası: o)


1

C (245 bayt)

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

Çıktı

THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG!

açıklama

Bayt sayısı ilkinde verilen giriş dizesini içermez #define.

Hangi karakteri yazdırmak için arama tablosu olarak iki boyutlu bir dizi kullanın. Program, sınırlandırılmış karakterlerle okur '#'.

Her grup için, girdi numarası birinci boyutlu dizi dizinini belirler ve girdi numarasının tekrar sayısı ikinci boyutlu dizi dizinini belirler. '*'Bir önceki mektubu üzerine şekilde hareket eder çıkış dizesi için dizinin indeksi destekliyor.

Böylece girdi dizesi 44#(1 tekrarı '4') K[4][1]karakter olan arama tablosuna çevrilir H.


Ungolfed Sürümü

#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

Yakut 254 , 248 , 229 bayt

golfed:

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

Ungolfed:

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

Tüm bu özellikler başarılı olmalıdır:

  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 0Cevap Bir Hacky çözümü biraz benzemekle. Zamanı bulduğumda ona bakacağım.


0

PHP, 183-10 = 173 bayt

Tüm sürümler komut satırı bağımsız değişkeninden girdi alır; ile arayın php -r '<code>' <string>.

Not : Giriş ile başlarsa tüm sürümler bir uyarı verir *. Bu kusuru kaldırmak için koda
ekleyin $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);
  • karma etiketlere ihtiyaç duymaz
  • bir tuşa çok sık basıldığında başarısız olur

210-10 - ?? = ??? bayt

$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);
  • karma etiketlere ihtiyaç duymaz
  • bir tuşa çok sık basılırsa döner

181 bayt, bonus yok

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

Yıkmak

"Karma etiket yok" sürümleri dizeyi (eşit sayıda çizgi) ve (yıldız işareti) olarak böler ve diğer her şeyi unutur. Bonus olmayan sürüm (sayıların ardından gelen çizgi #) ve (yıldız işareti) alır.

Ardından eşleşmeler arasında dolaşın: '*' bulunursa, sonuç dizisinin son öğesini kaldırın.

Sürümler arasındaki fark elsekısmen:

  • bonus sürüm yok: harita dizesini (anahtar * 5) olarak kaydırın, ardından (tuş vuruşları = kelime uzunluğu-1) -1 ekleyin, o konumdan sonuca karakter ekleyin.
  • basit etiketsiz sürüm: neredeyse aynı, ancak: (tuş vuruşları = kelime uzunluğu); harita dizesine diğerinden kurtulmak için bir karakter ekledi -1.
  • dönen sürüm: harita dizisinden öğe (anahtar) alın, o öğeden sonuca karakter (tuş vuruşları% öğe uzunluğu-1) ekleyin.

0

JavaScript, 147 bayt

Conor´un cevabı PHP cevabımdaki normal ifadeyle düzeltildi ve golf oynadı.

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,"")

Yıkmak

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

dönen versiyon, 158 bayt

s=dizeyi hatırlamak ve %s.lengthdöndürmek için eklendi .

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,"")
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.