Crea una tastiera T9


12

Questa domanda richiede una funzionalità di corrispondenza del dizionario T9 che è un problema molto interessante. Ma T9 ha un altro modo di scrivere e cioè digitare carattere per carattere. NON è necessario un dizionario per implementare questa tastiera.

Ecco la mappa dei tasti di una tastiera T9 se hai dimenticato:

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

Come funziona T9

Per digitare un carattere con T9, è necessario premere il tasto numerico che rappresenta i ntempi di quel carattere . nè l'ordine di quel personaggio scritto su quella chiave. I numeri sono l'ultimo carattere che puoi digitare per ogni tasto. Ad esempio, per digitare Bpremo 2due volte o per digitare 5premo 5quattro volte. Per finire di digitare questo personaggio premo #. *è semplicemente backspace. Nella nostra versione di tastiera non c'è maiuscola.

Esempi di input e output:

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

Spiegazione:

  • 8seleziona Te #passa al personaggio successivo
  • 99999seleziona l'ultimo carattere del 9tasto che è 9e #passa al carattere successivo
  • 0 inserisce uno spazio
  • 33seleziona il secondo carattere del 3tasto che è Ke #passa al carattere successivo
  • E così via...

Regole

La tua funzione o programma dovrebbe accettare una stringa che rappresenta i tasti T9. L'output è il testo risultante da quei tasti premuti, come indicato sopra.

Questo è il golf di base del codice, quindi il vincitore è il più breve in byte e si applicano le regole / scappatoie standard.


Il bonus non ha alcun effetto sul punteggio? Perché dovrei provarci?
Ottimizzatore

2
Inoltre, il tuo esempio T9 KEYBOARDè completamente sbagliato. Quella diceT9 JEYBARD
Optimizer il

1
@Mohsen di solito, i bonus nel golf del codice sottrarranno un importo fisso dal punteggio. dovrai capire quanto è ragionevole. per il primo bonus probabilmente non più di 10 o 20 byte. il secondo bonus, non capisco nemmeno. se do la sequenza di tasti premuti come una stringa alla funzione, come sarebbe un tempo tra i tasti premuti? Penso che un bonus più ragionevole sarebbe consentire di omettere #se i pulsanti consecutivi sono comunque diversi. detto questo: senza quel bonus cosa dovrebbe succedere se #omesso?
Martin Ender,

1
È necessario aggiungere un possibile vantaggio di conteggio byte per questi bonus. I bonus sono opzionali ma sembra che tu chieda a ogni risposta di implementare i bonus come se fossero obbligatori. Si prega di cancellare il tono, se sono obbligatori, spostarli alle regole, in caso contrario, non chiedere tutte le risposte per attuare i bonus. Aspetterò un paio d'ore per la tua risposta prima di votare per chiudere come poco chiaro.
Ottimizzatore

2
Nessuna risposta anche dopo 18 ore. Votare per chiudere come poco chiaro.
Ottimizzatore

Risposte:


5

CJam, 109 94 byte (2 nd bonus)

Una soluzione molto ingenua e lunga

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

Questo è un programma completo, sebbene una funzione avrà la stessa lunghezza.

L'ingresso va in STDIN

Esempio:

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

Produzione:

T9 BOARD

Provalo online qui


Riesci a farlo funzionare per il primo bonus?
Mohsen,

3
@Mohsen Non fino a quando non ci sarà un reale vantaggio nel ricevere un bonus! Diciamo, una riduzione della lunghezza del codice del 25% nel punteggio finale.
Ottimizzatore

2

JavaScript ES6, 220-10 = 210 178 byte

Come parte della CMC di Helka , ho superato la mia prima sfida.

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

Output di esempio:

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

Spiegazione

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

Questo implementa la sostituzione ricorsiva, sostituendo tutti i caratteri seguiti da *finché non ne rimangono più *.

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

Questo corrisponde a tutte le esecuzioni di cifre consecutive o *s.

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

Questo crea il dizionario desiderato, ottenendo la parte codificata dalla stringa grande, quindi aggiungendo la cifra desiderata ad esso.

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

Questo ottiene il carattere, ala lunghezza del modulo .

.join``

Questo prepara la stringa per l'elaborazione e la rimozione di *s.


1
Riesci a farlo funzionare con il primo bonus?
Mohsen,

@Mohsen Sì, e questo potrebbe effettivamente aiutarlo. Ci lavorerò su oggi e domani.
Conor O'Brien,

Almeno non pubblicizzare un punteggio errato poiché la risposta non è nemmeno conforme alle specifiche.
Ottimizzatore

@Mohsen Ora funziona con il primo bonus.
Conor O'Brien,

t("2#2");Binvece di AA. Prova ad abbinare qualsiasi #invece di rimuoverli.
Tito,

1

Python, 167 157 151 byte

(non supporta '*')

Niente di speciale. Uso regex per convertire l'input in un elenco, quindi eseguo il loop delle voci. Uso il primo carattere e la lunghezza di ciascuna voce per cercarla in un elenco di ricerca:

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)

Dopo un po 'di golf sembra così:

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

Nessun bonus (ancora). Non so come implementerei il primo bonus in regex. Il secondo bonus aggiungerebbe molti byte poiché gli elementi di ricerca non hanno le stesse dimensioni. Non capisco davvero il terzo bonus.


1

Perl 5: 106 (104 codice + 2 bandiere)

Modificato per gestire le eliminazioni.

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

Uso:

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

Perl 5: 88 (codice 86 + 2 bandiere)

Vecchia versione senza cancellazione di stelle.

#!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 l'ha provato e in effetti non funziona con *. In realtà è richiesto però? Dice: "Nota che può includere * per backspace ..."
Def

Dal momento che non fa parte del bonus. È una regola obbligatoria.
Ottimizzatore

Detto ciò. la domanda non è molto chiara su cosa sia una regola e cosa sia un bonus. Ho chiesto chiarimenti all'OP diverse ore fa. Se non ci sono risposte, voterò per chiudere questa domanda come poco chiara.
Ottimizzatore

Siamo spiacenti, sono stato fuorviato perché le risposte correnti nelle lingue che posso leggere non supportano *.
Nutki,

Se ti riferisci alla mia risposta Python, hai ragione. Ho frainteso la domanda.
Def

1

AWK 211 byte (con i bonus)

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

Questo è un programma completo che legge l'input da stdin. Sarebbe più efficiente non sostituire la tastiera per ogni riga, ma allungherebbe lo script.

Inoltre, se il tasto "0" fosse diverso da 0, lo script sarebbe più corto di 4 byte, ma fa parte del gioco: o)


1

C (245 byte)

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

Produzione

THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG!

Spiegazione

Il conteggio dei byte non include la stringa di input fornita nel primo #define.

Uso una matrice bidimensionale come tabella di ricerca per quale personaggio stampare. Il programma legge in caratteri delimitati da '#'.

Per ciascun gruppo, il numero di input determina l'indice di array di prima dimensione e il numero di ripetizioni del numero di input determina l'indice di array di seconda dimensione. I '*'arretra l'indice della matrice per la stringa di output in modo da sovrascrivere la lettera precedente.

Quindi la stringa di input 44#(1 ripetizione di '4') viene tradotta nella tabella di ricerca K[4][1], che è il carattere H.


Versione Ungolfed

#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

Rubino 254 , 248 , 229 byte

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

Tutte queste specifiche dovrebbero avere successo:

  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

La 0 0risposta assomiglia un po 'a una soluzione confusa. Lo esaminerò quando avrò il tempo.


0

PHP, 183-10 = 173 byte

Tutte le versioni accettano input dall'argomento della riga di comando; chiama con php -r '<code>' <string>.

Nota : tutte le versioni generano un avviso se l'input inizia con *.
Preparati $o=[];al codice per rimuovere quel difetto.

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);
  • non ha bisogno di tag hash
  • fallisce se un tasto viene premuto troppo spesso

210-10 - ?? = ??? byte

$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);
  • non ha bisogno di tag hash
  • ruota se un tasto viene premuto troppo spesso

181 byte, nessun bonus

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

abbattersi

Le versioni "no hash tags" dividono la stringa in (sequenza di numeri uguali) e (asterisco) e dimenticano tutto il resto. La versione senza bonus prende (serie di numeri seguita da #) e (asterisco).

Quindi scorrere le corrispondenze: se viene trovato un '*', rimuovere l'ultimo elemento dell'array dei risultati.

La differenza tra le versioni è nella elseparte:

  • nessuna versione bonus: sposta la stringa della mappa su (tasto * 5), quindi aggiungi (sequenze di tasti = lunghezza della parola-1) -1, aggiungi il carattere da quella posizione al risultato.
  • semplice versione senza tag: quasi la stessa, ma: (battute = lunghezza della parola); aggiunto un carattere alla stringa della mappa per sbarazzarsi dell'altro -1.
  • versione rotante: prendi l'oggetto (chiave) dall'array della mappa, aggiungi carattere (sequenze di tasti% lunghezza dell'elemento-1) da quell'elemento al risultato.

0

JavaScript, 147 byte

La risposta di Conor è stata risolta con la regex della mia risposta PHP e si è abbassata.

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

abbattersi

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

versione rotante, 158 byte

aggiunto s=per ricordare la stringa e %s.lengthper ruotare.

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,"")
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.