Telefon-Tipprechtschreibung

21

Inspiriert von der Google Code Challenge :

Das lateinische Alphabet enthält 26 Zeichen und Telefone haben nur zehn Ziffern auf der Tastatur. Wir möchten es Ihnen leichter machen, Ihrem Freund eine Nachricht zu schreiben, indem Sie eine Reihe von Tasten drücken, um die gewünschten Zeichen anzuzeigen. Die Buchstaben werden wie unten gezeigt auf die Ziffern abgebildet. Um beispielsweise das Zeichen B einzufügen, würde das Programm 22 drücken. Um zwei Zeichen nacheinander von derselben Taste aus einzufügen, muss der Benutzer eine Pause einlegen, bevor er die Taste ein zweites Mal drückt. Das Leerzeichen '' sollte gedruckt werden, um eine Pause anzuzeigen. Zum Beispiel steht 2 2 für AA, während 22 für B steht.

Jede Nachricht besteht nur aus Kleinbuchstaben az und Leerzeichen ''. Durch Drücken von Null wird ein Leerzeichen ausgegeben.

Bildbeschreibung hier eingeben

Ihre Herausforderung besteht darin, die kleinste Funktion zu schreiben, die die Eingabezeichenfolge annimmt, und die Folge von Tastendrücken zurückzugeben, die erforderlich sind, um die Eingabe als Zeichenfolge zu erzeugen oder an stdout auszugeben. Die Funktion mit der geringsten Anzahl von Bytes gewinnt.

Beispiel Eingabe / Ausgabe

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

Andere Klarstellungen

  • Pausen dürfen nur bei Bedarf hinzugefügt werden und müssen ein Leerzeichen sein.
  • Jede Nachricht besteht nur aus Kleinbuchstaben az und Leerzeichen ''. Drucken 0, um Leerzeichen zu kennzeichnen.
  • Keine externen Bibliotheken.
  • Nur die Eingabezeichenfolge darf an Ihre Funktion übergeben werden.
  • Um andere Sprachen wettbewerbsfähig zu machen, zählt die Deklaration der primären Funktion nicht und das Importieren anderer Standardbibliotheken auch nicht. #includes, imports und usings zählen nicht. Alles andere macht. Dies beinhaltet #defines und Hilfsfunktionen. Siehe Regel 2 in dieser Frage, wenn Sie verwirrt sind.
  • Mehrere Leerzeichen können als 00oder bezeichnet werden, 0 0da Sie nicht wirklich zwischen Leerzeichen pausieren müssen
Danny
quelle
1
Im Zusammenhang mit diesem: codegolf.stackexchange.com/questions/21327/…
Victor Stafusa
Können wir annehmen, dass die Eingabe in Groß- / Kleinschreibung erfolgt?
Phil H
@PhilH " Kleinbuchstaben az und Leerzeichen"
Danny
Betrachten Sie Klammern {}als Teil der Funktionssignatur? function f(){alert('hi');}Soll ich zum Beispiel bei meinem Code die Zeichen von alert('hi');oder zählen {alert('hi');}?
ProgramFOX
2
Soweit ich mich erinnere, t9funktioniert das anders: Sie müssen auf jede Taste einmal klicken, um ein Wort zu erhalten.
VisioN

Antworten:

8

Rubin, 129 122 115 111 108 107 105

Fertig mit Golfen ...

Hoppla, völlig vergessen, unnötige Leerzeichen zu entfernen - behoben ...

2 Zeichen gespart dank Peter Taylor.

Online Version

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

Erläuterung:

Raum wird mit der Ordnungszahl 96 in das Zeichen übersetzt

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

Zeichen werden zuerst einer Reihe von Zahlen zugeordnet: - a bis 2 - b bis 22 - d bis 3222 - h bis 444333222

Ein regulärer Ausdruck entspricht dann der ersten Gruppe gleicher Ziffern

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

Das Array ist verbunden

*' ')

Alle Leerzeichen in "digit space different_digit" werden entfernt

gsub /(\d) (?!\1)/,'\1'
David Herrmann
quelle
1
Sieht nicht zu 100% richtig aus. Ich sehe, 66666 sollte niemals 4-mal hintereinander gedrückt werden müssen.
Danny
Sollte behoben werden, danke;)
David Herrmann
1
Worum geht es \2in diesem letzten Regex? Sicherlich ist die zweite Gruppe eine Behauptung mit der Breite Null?
Peter Taylor
Du hast absolut recht!
David Herrmann
6

REBEL - 154 110 103

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

Diese 'Funktion' akzeptiert Eingaben von stdin und sendet Ergebnisse an stdout.

Testläufe (damit Sie den Interpreter nicht installieren müssen):

hi
44 444

hello world
4433555 555666096667775553

yes
999337777

kthxbai
558449922 2444
Kendall Frey
quelle
Ich kann Ihre Links niemals zum Laden bringen! :(
luser droog
4

JavaScript (124)

Führen Sie in Firefox.

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

GolfScript, 46 Zeichen

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

Liest wie gewohnt die Eingabe von stdin und druckt auf stdout. Siehe Online-Demo (mit fester Eingabe).

Beachten Sie, dass dieser Code auf einer sehr strengen Interpretation der Eingabespezifikation basiert (nur Kleinbuchstaben und Leerzeichen): Insbesondere werden alle Zeilenumbrüche in der Eingabe zum Absturz bringen! Dieses Problem kann auf Kosten von zwei zusätzlichen Zeichen behoben werden, indem n-der Code vorangestellt wird, um alle Zeilenumbrüche herauszufiltern.

Ilmari Karonen
quelle
3

C ++ - 365 Zeichen ohne 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;}}}

Verwendet die gleiche Argumentation wie meine Antwort hier , verwendet jedoch nur forSchleifen, um jeden Buchstaben in angemessener Anzahl auszugeben.

Hosch250
quelle
Sie können s[i]==32anstelle von verwenden s[i]==' '. Der ASCII-Wert des Leerzeichens ist 32.
user12205
@ace Klar, was.
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

Hier ist meine vorherige Lösung 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

Tests:

hi
 44 444

hello world
 4433555 555666096667775553

jackdaws loves my big sphinx
 52 222553297777055566688833777706999022444 407777 744 4446699
mniip
quelle
3

VBA 220 253/258/219

FunctionZeilen hier nicht mitzählen :

Mit 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

Mit einer ForSchleife 258 :

Korrekturen für die 7/9-Taste hinzugefügt (danke, Danny), die viele Zeichen hinzugefügt haben.

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

Verwendung von Choose 219 :

Ich wollte nicht mit diesem laufen, da es grundlegender in der Funktionalität ist, aber es ist der kürzere Code ...

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
Gaffi
quelle
yessollte sein 999337777. Ich werde 10338Ihre Funktion nutzen.
Danny
3

C 165 163 153 149 138 Zeichen

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

Bei meinem ersten Versuch, Code Golf zu spielen, sind alle Vorschläge willkommen.

user18204
quelle
2

C ++ - 170 168 160

Golf gespielt:

#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;            
    }
}
}
Tharwen
quelle
2

C: 136 Zeichen

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

Und leicht ungolfed (ja, so wurde geschrieben):

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

Ich könnte es ein wenig reduzieren, indem ich etwas Rekursion, schwarze Magie und eine angemessene Menge Chilipulver auftrage.

Fors
quelle
2

Java - 243

Ziemlich naive Java-Lösung. Vielen Dank an Kommentatoren für Vorschläge.

Es wurde ein Fehler behoben, durch den manchmal unnötige Leerzeichen eingefügt wurden, z. B. für die Eingabe "Hallo Welten 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;
    }
Platzhalter
quelle
4
Ziemlich gut, aber Sie müssen Golf spielen und die Punktzahl liefern.
Hosch250
1
Ich nehme an, das ist java. Kannst du das in deine Überschrift schreiben, so wie es die anderen Antworten tun?
Digital Trauma
1
Ein Golf: Ersetzen Sie t.lengthdurch10
Justin
In Anbetracht dessen, dass dies inur zum Durchlaufen des Befehls verwendet wird String, entfernen Sie ihn und führen Sie eine foreach-Schleife aus:for(char c:s.toCharArray())
Justin,
Ändern Sie if(c==' '){o+='0';continue;}auch if(c==' ')o+='0';else{und fügen Sie das entsprechende hinzu }.
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
TimWolla
quelle
1

APL, 77 Zeichen

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

Erläuterung

  • 2+⌊y←7.99,⍨.315×⍳25oder, ungolfed, y←(0.315×⍳25),7.99 ◇ 2+⌊yprobiert eine geeignet geneigte Linie (y = 0,315 x) an den Punkten von 1 bis 25; Die Linie wird so gekippt, dass der Boden dieser y-Werte dem sich wiederholenden Muster 000111 ... 777 mit Ausnahme der sechsten Zifferngruppe 5555 folgt. Am Ende wird eine Zahl angehängt, um die vierte 7 zu erhalten, sodass das letzte Array plus 2 22233344455566677778889999 ist.
  • ⌈3.1×y-⌊y verstärkt die Differenz zwischen diesen y-Werten und ihren Fußböden, so dass die Obergrenzen der Differenzen das Muster 123123 ... mit einer 4 auf den letzten Ziffern der beiden Gruppen von 4 Ziffern ergeben;
  • '0',⍨( ... )/¨⍕¨ ...oder (( ... ) /¨ ⍕¨ ...),'0' verwendet das letztere Ergebnis, um Ziffern aus dem ersteren zu duplizieren, sodass die Ausgabe das Array der Zeichenfolgen "2" "22" "222" "3" "33" "333" ... mit den korrekten Zeichenfolgen "7777" und " 9999 "vorhanden und eine" 0 "am Ende angehängt;
  • ⍵⍳⍨⎕UCS 96+⍳26oder (⎕UCS 96+⍳26)⍳⍵berechnet den Index jedes eingegebenen Zeichens, wobei "a" 1 ist, "z" 26 ist und das Leerzeichen (und jedes andere Zeichen) 27 ist;
  • { ... }/( ... )[ ... ] Nimmt das letztere Ergebnis, den Index für jedes Eingabezeichen, um jedes Zeichen in die jeweilige Ziffernfolge zu übersetzen, und verkettet dann die Zeichenfolgen unter Verwendung der Funktion in geschweiften Klammern.
  • {⍵,⍨⍺,''↑⍨=/↑¨⍺⍵}oder {(⍺,(=/↑¨⍺,⍵)↑''),⍵}fügt jede neue Zeichenfolge an den Akkumulator an und fügt nur dann ein einzelnes Leerzeichen ein, wenn beide Argumente mit dem gleichen Zeichen beginnen.

Beispiele

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

Python 155 150

Ich wünschte, ich wäre besser in diesem XD. Funktionsdefinition nicht gezählt. Die erste Einrückungsstufe ist ein Leerzeichen, die zweite eine Registerkarte und die dritte zwei Registerkarten.

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
gcq
quelle
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)

WallyWest
quelle
0

R 224

Ich bin mir sicher, dass es einen besseren Weg gibt, also werde ich weiter daran arbeiten.

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='')
Gaffi
quelle