Telefono Ortografia multi-tocco


21

Ispirato alla Google Code Challenge :

L'alfabeto latino contiene 26 caratteri e i telefoni hanno solo dieci cifre sulla tastiera. Vorremmo semplificare la scrittura di un messaggio al tuo amico utilizzando una sequenza di tasti premuti per indicare i caratteri desiderati. Le lettere sono mappate sulle cifre come mostrato di seguito. Per inserire il carattere B, ad esempio, il programma preme 22. Per inserire due caratteri in sequenza dallo stesso tasto, l'utente deve mettere in pausa prima di premere il tasto una seconda volta. Il carattere spazio '' deve essere stampato per indicare una pausa. Ad esempio, 2 2 indica AA mentre 22 indica B.

Ogni messaggio sarà composto solo da caratteri minuscoli az e caratteri spaziali ''. Premendo zero si genera uno spazio.

inserisci qui la descrizione dell'immagine

La tua sfida è quella di scrivere la funzione più piccola che accetta la stringa di input e restituisce la sequenza di pressioni di tasti necessaria per produrre l'input come stringa o inviarlo a stdout. Vince la funzione che rappresenta il minor numero di byte.

Esempio di input / output

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

Altri chiarimenti

  • Le pause devono essere aggiunte solo quando necessario e devono essere uno spazio ''.
  • Ogni messaggio sarà composto solo da caratteri minuscoli az e caratteri spaziali ''. Stampa 0per indicare gli spazi.
  • Nessuna libreria esterna.
  • Solo la stringa di input può essere passata alla tua funzione.
  • Per rendere le altre lingue competitive, la dichiarazione della funzione primaria non conta, e nemmeno l'importazione di altre librerie standard. #includes, imports e usings non contano. Tutto il resto lo fa. Ciò include le #definefunzioni s e helper. Vedi la regola 2 in questa domanda se sei confuso.
  • Più spazi possono essere indicati come 00o 0 0poiché non è necessario fare una pausa tra uno spazio


Possiamo supporre che l'ingresso sia in minuscolo / maiuscolo?
Phil H

@PhilH " caratteri minuscoli az e caratteri spaziali ''"
Danny

Consideri le parentesi {}una parte della firma della funzione? Ad esempio, se il mio codice è function f(){alert('hi');}, devo contare i caratteri di alert('hi');o {alert('hi');}?
Programma FOX

2
Per quanto mi ricordo t9funziona diversamente: devi fare clic su ogni tasto una volta per ottenere una parola.
VisioN

Risposte:


8

Rubino, 129 122 115 111 108 107 105

Fatto con il golf ...

Oops, completamente dimenticato di rimuovere gli spazi non necessari - risolto ...

Hai salvato 2 caratteri grazie a Peter Taylor.

Versione online

def t9(t)
(t.tr(" ",?`).bytes.map{|c|"09998887777666555444333222"[96-c..-1][/(.)\1*/]}*' ').gsub /(\d) (?!\1)/,'\1'
end

Spiegazione:

lo spazio è tradotto in carattere con l'ordinale 96

(t.tr(" ",?`).bytes

i caratteri vengono prima mappati su serie di numeri: - da a 2 - da b a 22 - da d a 3222 - da h a 444333222

un'espressione regex corrisponde quindi al primo gruppo di cifre uguali

map{|c|"09998887777666555444333222"[96-c..-1][/(.)\1*/]}

l'array è unito

*' ')

tutti gli spazi nelle ricorrenze di "digit space different_digit" vengono rimossi

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

1
Non sembra funzionare correttamente al 100%. Vedo che 66666 non dovrebbe mai essere necessario premere 4 volte di seguito.
Danny

Dovrebbe essere risolto, grazie;)
David Herrmann

1
Qual è il punto \2in quella regex finale? Sicuramente il secondo gruppo è un'asserzione di larghezza zero?
Peter Taylor,

Hai assolutamente ragione!
David Herrmann,

6

REBEL - 154 110 103

;0 2abc3def4ghi5jkl6mno7pqrs8tuv9wxyz/^;/$<;/([^\d-])(?=\D.*(\d)(\w)*\1)/$2$3-/(\d)-+\1/$1 $1/-//;/$>$`

Questa 'funzione' accetta input da stdin e invia risultati a stdout.

Esecuzioni di test (quindi non è necessario installare l'interprete):

hi
44 444

hello world
4433555 555666096667775553

yes
999337777

kthxbai
558449922 2444

Non riesco mai a caricare i tuoi link! :(
luser droog

4

JavaScript (124)

Esegui in Firefox.

t9=s=>s.replace(/./g,c=>'099998887777666555444333222'.slice(36-parseInt(c,36)).match(/(.)\1*/)[0]+' ').replace(/(.) (?!\1)/g,'$1')

4

GolfScript, 46 caratteri

{).," adgjmptw"&.,.1>*`@@)\;-*}/]{.2$^!" "*\}*

Come al solito, legge input da stdin, stampa su stdout. Guarda la demo online (con input fisso).

Si noti che questo codice si basa su un'interpretazione molto rigorosa delle specifiche di input (solo lettere minuscole e spazi): in particolare, qualsiasi nuova riga nell'input lo bloccherà! Questo problema può essere risolto, al costo di due caratteri aggiuntivi, anteponendo n-al codice per filtrare eventuali nuove righe.


3

C ++ - 365 caratteri senza 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;}}}

Usa lo stesso ragionamento della mia risposta qui , usando solo i forloop per emettere ogni lettera il numero appropriato di volte.


Puoi usare s[i]==32invece di s[i]==' '. Il valore ASCII dello spazio è 32.
user12205

@ace Certo.
Hosch250,

3

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

Ecco la mia soluzione precedente in 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

test:

hi
 44 444

hello world
 4433555 555666096667775553

jackdaws loves my big sphinx
 52 222553297777055566688833777706999022444 407777 744 4446699

3

VBA 220 253/258/219

Non contando le Functionrighe qui:

Con 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

Con un Forloop 258 :

Aggiunte correzioni per il tasto 7/9 (grazie, Danny), che ha aggiunto molti caratteri.

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

Usando Choose 219 :

Non volevo correre con questo, dal momento che è più basilare in termini di funzionalità, ma è il codice più breve ...

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

yesdovrebbe essere 999337777. Ricevo la 10338tua funzione.
Danny

3

C, 165 163 153 149 138 caratteri

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

Il mio primo tentativo di giocare a golf con il codice, ogni suggerimento è apprezzato.


2

C ++ - 170 168 160

golfed:

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

Ungolfed

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 caratteri

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

E leggermente non golfato (sì, è così che è stato scritto):

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

Potrei riuscire a ridurlo un po 'applicando un po' di ricorsione, magia nera e una discreta quantità di peperoncino in polvere.


2

Java - 243

Soluzione java abbastanza ingenua. Grazie ai commentatori per i suggerimenti.

Risolto un bug che a volte inseriva spazi non necessari, ad es. Per l'ingresso "ciao mondi 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
Abbastanza buono, ma è necessario giocare a golf e fornire il punteggio.
Hosch250

1
Presumo che lo sia java. Puoi metterlo nella tua rubrica, come fanno le altre risposte?
Digital Trauma

1
Un golf: sostituirlo t.lengthcon10
Justin

Inoltre, considerando che iviene utilizzato solo per iterare attraverso il String, rimuoverlo ed eseguire un ciclo foreach:for(char c:s.toCharArray())
Justin

Inoltre, il cambiamento if(c==' '){o+='0';continue;}per if(c==' ')o+='0';else{e aggiungere l'appropriato }.
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 caratteri

{{⍵,⍨⍺,''↑⍨=/↑¨⍺⍵}/('0',⍨(⌈3.1×y-⌊y)/¨⍕¨2+⌊y←7.99,⍨.315×⍳25)[⍵⍳⍨⎕UCS 96+⍳26]}

Spiegazione

  • 2+⌊y←7.99,⍨.315×⍳25oppure, non golfato, y←(0.315×⍳25),7.99 ◇ 2+⌊ycampiona una linea opportunamente inclinata (y = 0,315 x) sui punti da 1 a 25; la linea è inclinata in modo tale che il pavimento di questi valori y segua il modello ripetitivo 000111 ... 777 ad eccezione del sesto gruppo di cifre 5555; un numero viene aggiunto alla fine per ottenere il quarto 7, in modo che l'array finale più 2 sia 22233344455566677778889999;
  • ⌈3.1×y-⌊y amplifica la differenza tra quei valori y e i loro piani, in modo che i soffitti delle differenze diano il modello 123123 ... con un 4 sulle ultime cifre dei due gruppi di 4 cifre;
  • '0',⍨( ... )/¨⍕¨ ...o (( ... ) /¨ ⍕¨ ...),'0' utilizza quest'ultimo risultato per duplicare le cifre della prima, in modo che l'output sia l'array di stringhe "2" "22" "222" "3" "33" "333" ... con i "7777" e "corretti 9999 "in atto e uno" 0 "aggiunto alla fine;
  • ⍵⍳⍨⎕UCS 96+⍳26oppure (⎕UCS 96+⍳26)⍳⍵calcola l'indice di ciascun carattere di input, dove "a" è 1, "z" è 26 e lo spazio (e ogni altro carattere) è 27;
  • { ... }/( ... )[ ... ] prende l'ultimo risultato, l'indice per ciascun carattere di input, per tradurre ciascun carattere nella rispettiva stringa di cifre, quindi concatena le stringhe utilizzando la funzione tra parentesi graffe;
  • {⍵,⍨⍺,''↑⍨=/↑¨⍺⍵}oppure {(⍺,(=/↑¨⍺,⍵)↑''),⍵}accoda ogni nuova stringa ⍺ all'accumulatore ⍵, interponendo un singolo spazio solo se entrambi gli argomenti iniziano con lo stesso carattere.

Esempi

      {{⍵,⍨⍺,''↑⍨=/↑¨⍺⍵}/('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

Python 155 150

Vorrei essere migliore in questo XD. Definizione della funzione non conteggiata. Il primo livello di rientro è uno spazio, il secondo è una scheda e le terze 2 schede.

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

JavaScript 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

Sono sicuro che c'è un modo migliore per farlo, quindi continuerò a lavorarci su.

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='')
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.