Buchstaben in Telefonnummern


23

Problem:

Sie erstellen ein neues Telefon, auf dem beispielsweise spezialisierte Telefonnummern eingegeben werden können, 1-800-programdie dann automatisch in eine verwendbare Telefonnummer umgewandelt werden 1-800-7764726( wie im vorherigen Beispiel).

Ihr Programm empfängt eine beliebige Zeichenfolge mit Zahlen, Buchstaben und Bindestrichen und konvertiert alle Buchstaben in die entsprechenden Zahlen.

Hier ist eine Tastatur als Referenz:

Tastenfeld

Regeln:

  • Ihr Programm erhält einen String
  • Es wird es verarbeiten und eine weitere Zeichenfolge zurückgeben / drucken
  • Jede Sprache wird akzeptiert
  • Da es sich um , gewinnt der kürzeste Code

Sollte das Programm sowohl Groß- als auch Kleinbuchstaben in der Eingabe verarbeiten?
Mattnewport

3
@mattnewport - nein, angenommen, die Variable wurde bereits in Kleinbuchstaben umgewandelt
TheDoctor

Antworten:


8

GolfScript, 24 Zeichen

{.96>{,91,'qx'+-,3/`}*}%

Testeingang:

0123456789-abcdefghijklmnopqrstuvwxyz

Testausgang:

0123456789-22233344455566677778889999

Erläuterung:

  • { }% Wendet den Code zwischen den geschweiften Klammern auf jedes Zeichen der Eingabe an.

  • .96>{ }* Führt den Code zwischen den inneren Klammern genau dann aus, wenn der ASCII-Code des Zeichens größer als 96 ist (dh ein Kleinbuchstabe).

  • Der erste ,verwandelt das Zeichen in eine Liste aller Zeichen mit niedrigeren ASCII-Codes und 91,'qx'+-filtert alle Zeichen mit ASCII-Codes unter 91 sowie die Buchstaben qund xaus der Liste heraus. So wird beispielsweise das Zeichen ain die Liste mit 6 Zeichen umgewandelt [\]^_`, während es zin die Liste mit 29 Zeichen umgewandelt wird [\]^_`abcdefghijklmnoprstuvwy.

  • Die Sekunde ,zählt die in der Liste verbleibenden Elemente und 3/teilt diese Anzahl durch drei (Abrundung). Schließlich `wandelt das die resultierende Zahl (im Bereich von 2 bis 9) in eine Zeichenfolge um.

Somit bleiben Bindestriche und Zahlen gemäß Spezifikation unverändert, während Kleinbuchstaben gemäß dem Referenztastaturdiagramm in Zahlen abgebildet werden. Der Code wird passiert tatsächlich sauber durch alle druckbaren ASCII - Zeichen mit Ausnahme von Kleinbuchstabe (die wie beschrieben abgebildet) und den Charakteren {, |und }(die das Zwei-Zeichen - String abgebildet werden 10). Nicht-ASCII-8-Bit-Eingabe erzeugt alle Arten von seltsamen numerischen Ausgaben.

Nach all dem ist es ein bisschen enttäuschend, dass dies nur das übertrifft triviale Bash-Lösung nur um sechs Zeichen übertrifft.


50

Bash, 30

Edit: Danke Doorknob für die Beseitigung von 3 Zeichen

tr a-z 22233344455566677778889

Beispiel:


10
Kannst du die letzten 3 9s nicht entfernen ?
Türknauf

16

C 83 78 77 65 63 62

main(c){for(;~(c=getchar());putchar(c>96?20-c/122+5*c/16:c));}

http://ideone.com/qMsIFQ


3
Gute Mathe. Ich will nur zu sagen , dass Sie ein Zeichen reduzieren EOF durch die Annahme , -1 und tun~(c=getchar())
user12205

Könnten Sie nicht getch()anstelle von verwenden getchar()?
Starsplusplus

Streng genommen getch()ist es nicht Standard C, weshalb es meiner Meinung nach nicht mit Ideone zusammenhängt. Ich habe es trotzdem in MSVC getestet und es funktioniert nicht wirklich traurig - da es direkt Tastatureingaben verbraucht, gibt es keine Möglichkeit, das Programm zu beenden, obwohl es das übersetzt, was Sie im laufenden Betrieb eingeben, was irgendwie ordentlich ist.
Mattnewport

4

Javascript - 103 Zeichen

alert(prompt().replace(/[a-z]/g,function(y){y=y.charCodeAt(0)-91;return y>27?9:y>24?8:y>20?7:~~(y/3)}))

1
Ich wusste nicht, dass du das mit .replace machen kannst. Up Vote für dich!
SuperJedi224

Sie können ersetzen charCodeAt(0)mit charCodeAt()und Sie können Pfeil Funktion für function(y)...wenige Bytes speichern und für die ~~(y/3)Sie verwenden könneny/3|0
Chau Giang

3

Rubin, 75 Zeichen

gets.chars{|c|$><<"22233344455566677778889999#{c}"[[*?a..?z].index(c)||-1]}

Verwendet den charsmit Block veralteten und druckt jeden Buchstaben einzeln mit$><< . Ich mag auch [[*?a..?z].index(c)||-1]; es erfasst das Zeichen, das dem Buchstaben des Alphabets entspricht, wenn es ein Buchstabe ist, und das letzte Zeichen (das zufällig das unveränderte Testzeichen ist), wenn nicht.

Ruby, 43 (oder 35) Zeichen

Krass von @ace stehlen;)

puts gets.tr'a-z','22233344455566677778889'

Shave off 8 Zeichen, wenn ich in IRB mit der Variablen sals Zeichenfolge ausführen kann :

s.tr'a-z','22233344455566677778889'

3

C ++ - 222 Zeichen

Längste bisherige Lösung:

#include<iostream>
#include<string>
#define o std::cout<<
int main(){std::string s;std::cin>>s;for(int i=0;i<s.size();i++){int j=s[i]-97;if(j<0)o s[i];if(0<=j&j<15)o 2+j/3;if(14<j&j<19)o 7;if(18<j&j<22)o 8;if(21<j&j<26)o 9;}}

1
Lol, ich denke nicht, dass die längste Lösung hier das Ziel ist ...
Danny

@Danny C ++ eignet sich nicht gut für Code-Golf . Java und C # sind die einzigen Sprachen, die schlechter sind, als ich kenne (alle Klassen, Objekterstellung und langen Namen für die Ausgabe ...).
Hosch250

Ich weiß, ich fand es nur lustig, dass du "Längste Lösung" erwähnt hast.
Danny

3

Frink, 92

Eine ziemlich ausführliche Sprache, ich weiß. Dadurch werden 8 statt 26 Werte überprüft, ohne dass die Vergleiche eingegeben werden müssen. Kann eine der oben genannten "222333444 .." - Lösungen auf ähnliche Weise reduziert werden?

Verwenden von eingebauten Strukturen, 107

co=new OrderedList
co.insertAll[charList["cfilosv{"]]
println[input[""]=~%s/([a-z])/co.binarySearch[$1]+2/eg]

Verwenden einer benutzerdefinierten rekursiven Funktion, 92

fn[x,a]:=x<=(charList["cfilosv{"])@a?a+2:fn[x,a+1]
println[input[""]=~%s/([a-z])/fn[$1,0]/eg]

+1 zum Reduzieren der String-Übersetzungsmethode auf eine Suche mit 8 Zeichen. Nette Geste.
Jonathan Van Matre

2

Smalltalk, 79 70

Eingabe ist s:

s collect:[:c|' 22233344455566677778889999'at:1put:c;at:(($ato:$z)indexOf:c)+1]

Wahrscheinlich kein Kandidat für die kürzeste Zeit - aber möglicherweise von Interesse für einen alten Trick, um einen Test auf eine nicht gefundene Bedingung zu vermeiden (indexOf: gibt in diesem Fall 0 zurück). Es ist also kein spezieller Test für Briefe erforderlich. Einige Smalltalks haben jedoch unveränderliche Zeichenfolgen, und wir benötigen 4 weitere Zeichen ("copy").

Oh, eine bessere Version, die sich sogar mit unveränderlichen Zeichenfolgen in 70 Zeichen befasst:

s collect:[:c|c,'22233344455566677778889999'at:(($ato:$z)indexOf:c)+1]

2

Mathematica 90

Dies folgt der Logik der @ ace-Lösung:

StringReplace[#,Thread[CharacterRange["A","Z"]->Characters@"22233344455566677778889999"]]&

Beispiel

StringReplace[#1,Thread[CharacterRange["A","Z"]-> 
Characters@"22233344455566677778889999"]]&["VI37889"]

8437889


Ihre Pfeilzeichendarstellung wird von Mma in Kopieren / Einfügen nicht akzeptiert
Dr. belisarius

Auch brauchen Sie nicht die 1in #1:)
Dr. Belisarius

Belisarius, ich habe den Pfeil zurückgesetzt und den entfernt 1. Immer noch 90 Zeichen, aber das Ausschneiden und Einfügen funktioniert. Sie verstehen natürlich die Motivation, den einzelnen Zeichenpfeil zu verwenden.
DavidC

War

2

Perl, 50

Eine weitere offensichtliche Kopie von Aces heftiger Antwort

($_)=@ARGV;y/a-z/22233344455566677778889999/;print

1
Dieser Code funktioniert ordnungsgemäß, es besteht jedoch noch Verbesserungsbedarf. Lassen Sie uns $ ARGV [0] loswerden und -pstattdessen den Schalter verwenden, mit dem Sie jede Zeile von stdin gut durchgehen können. Während wir gerade dabei sind, muss der Bereich in y /// nicht in eckige Klammern gesetzt werden. Wir können auch drei 9er loswerden und nur eine übrig lassen und das letzte Semikolon entfernen: -p y/a-z/22233344455566677778889/ Los geht's, 30 + 1 für -p. Vielen Dank, dass Sie Enterprise Chinese Perl Golf- und Optimierungsservices nutzen, und einen schönen Tag.
Chinese Perl Goth

2

R, sehr lang, aber lustig

foo <- '1-800-splurghazquieaobuer57'
oof <- unlist(strsplit(foo,''))
#don't count that part - it's input formatting :-) 
digout <- unlist(strsplit('22233344455566677778889999','')) 
oof[oof%in%letters[1:26]] <- unlist(sapply(oof[oof%in%letters[1:26]], function(j) digout[which(letters[1:26]==j)] ))

2

k [32 Zeichen]

{(.Q.a!|,/(4 3 4,5#3)#'|$2+!8)x}

Verwendung

{(.Q.a!|,/(4 3 4,5#3)#'|$2+!8)x}"stack exchange"
"78225 39242643"

2

JavaScript, 85

JavaScript wird niemals die Golfkriege gewinnen, aber es gefällt mir und ich wollte etwas anderes tun, als auf den @ace-Zug zu springen.

alert(prompt().replace(/[a-z]/g,function(a){for(i=7;a<"dgjmptw{"[i--];);return i+4}))

2

PHP, 141

Nicht die kürzeste, aber mehr Spaß:

<?php foreach(str_split($argv[1])as$c){$v=ord($c);if($v>114){$v--;}if($v==121){$v--;}if($v<123&$v>96){echo chr(ceil($v/3+17));}else{echo$c;}}

Besser lesbar:

<?php 
foreach (str_split($argv[1]) as $c) {
  $v=ord($c);
  if ($v>114) {$v--;}
  if ($v==121){$v--;}
  if ($v<123 & $v>96){
    echo chr(ceil($v/3+17));
    } else {echo $c;}
}

OP sagte, dass die Eingabe bereits in Kleinbuchstaben ist, so dass Sie diestrtolower
Einacio

2

Python 2.7, 80

for c in raw_input():print'\b'+(`(ord(c)-97)/3+2-(c in('svyz'))`if c>'`'else c),

Ich bin neu in Python, also bin ich mir sicher, dass es eine Möglichkeit gibt, dies noch weiter zu verbessern. Es ist ein anderer Ansatz. Ich hoffe, es gefällt euch, mein Gott, ist Python hübsch!

Beispiel ausführen:

  • Eingabe: 01-800-abcdefghijklmnopqrstuvwxyz
  • Ausgabe: 01-800-22233344455566677778889999

2

T-SQL, 216 Bytes

In den letzten paar Nächten habe ich einige Zeit damit verbracht, eine mathematische Sequenzfunktion zu erstellen, die richtig rundet, um die richtigen ASCII-Codes für die Zahlen aus den alphabetischen ASCII-Codes zu generieren. Es hatte eine lächerliche Anzahl von Dezimalstellen in den Koeffizienten, aber es funktionierte.

Der rationale Ansatz von mattnewport funktioniert jedoch auch in SQL, und zwar zu einem viel geringeren Preis von Bytes. Daher verzichte ich schamlos auf meine eigene Mathematik zugunsten seiner. Erhöhen Sie ihn, es ist eine elegante Lösung!

Hier ist meins:

DECLARE @p VARCHAR(MAX)='';WITH t AS(SELECT ASCII(LEFT(@s,1))c,2 i UNION ALL SELECT ASCII(SUBSTRING(@s,i,1)),i+1FROM t WHERE i<=LEN(@s))SELECT @p=@p+CHAR(CASE WHEN c>96THEN 20-c/122+5*c/16 ELSE c END)FROM t;SELECT @p

Hierbei wird ein rekursiver CTE verwendet, um einen spontanen Stapel der Zeichen in der Telefonnummer zu erstellen und die Buchstaben im Handumdrehen zu übersetzen. Anschließend müssen Sie mit ein wenig SQL-Trick (SELECT @ p = @ p ​​+ columnValue) die Zeichenfolge aus dem CTE neu zusammensetzen, ohne dies zu erfordern ein weiteres Rekursionskonstrukt.

Ausgabe:

DECLARE @s VARCHAR(MAX)='1-800-abcdefghijklmnopqrstuvwxyz'
--above code runs here
1-800-22233344455566677778889999

2

Python 2.7, 66 65


Anakatas Original

for c in raw_input():print'\b'+(`(ord(c)-97)/3+2-(c in('svyz'))`if c>'`'else c),


Weiter golfen

for c in input():print(ord(c)-91)/3-(c in('svyz'))if c>'`'else c,


Ich habe nicht genug Reputation, um die Antwort von @ anakata zu kommentieren, deshalb habe ich hier einen separaten Beitrag verfasst. Ich hatte die gleiche Idee (unter Verwendung des Ordnungsmoduls 3), konnte aber nicht herausfinden, wie die richtigen Zahlen für s - z gedruckt werden .

Wie auch immer, die Golf Verbesserungen, die ich gemacht habe:

  • geändert raw_inputzuinput

  • entfernt die Fremdwörter '\b'und Klammern und einfache Anführungszeichen

  • entfernte den +2Offset und platzierte diesen in der ursprünglichen Subtraktion (97 - (3 * 2) = 91)

Getestet mit dem Python 2.7.6 Interpreter. Nimmt gemäß den Regeln eine Zeichenfolgeeingabe an.


Sie können auch das Leerzeichen zwischen dem) und dem if
Willem

Du hast recht. guten Fang willem
zheshishei

1

PHP, 87

echo str_ireplace(range('a','z'),str_split('22233344455566677778889999'),fgets(STDIN));

1

q [38 Zeichen]

{(.Q.a!"22233344455566677778889999")x}

Inspiriert von der @ ace-Lösung

Beispiel

{(.Q.a!"22233344455566677778889999")x}"stack exchange"
"78225 39242643"

1

XQuery, 71

BaseX wurde als XQuery-Prozessor verwendet. $ieingegeben wird.

translate($i,"abcdefghijklmnopqrstuvwxyz","22233344455566677778889999")

Nicht die kürzeste Antwort, aber ziemlich kurz und gut lesbar.


1

Python, sehr ungolfed

Da jeder Ace kopiert, habe ich beschlossen, den Code, den ich erstellt habe, zu posten, bevor ich die Frage einreichte:

def phonekeypad(text):
    c = ['','','abc','def','ghi','jkl','mno','pqrs','tuv','wxyz']
    st = ""
    for i in list(text):
        a = False
        for t in range(len(c)):
            if i in c[t]:
                st += str(t)
                a=True
        if a == False:
            st += str(i)
    return st

1

EcmaScript 6 (103 Byte):

i.replace(/[a-z]/g,x=>keys(a='00abc0def0ghi0jkl0mno0pqrs0tuv0wxyz'.split(0)).find(X=>a[X].contains(x)))

Erwartet i , die Zeichenfolge zu enthalten.

Versuchen Sie es in einer neueren Version von Firefox. Ich habe Google Chrome nicht ausprobiert.


1

Python 3, 121

print("".join((lambda x:"22233344455566677778889999"[ord(x)-97] if ord(x)>96 and ord(x)<123 else x)(i) for i in input()))

1

Haskell, 93 ° C

t[]_ a=a
t(b:c)(d:e)a
 |a==b=d
 |True=t c e a
y=map(t['a'..'z']"22233344455566677778889999")

Verwendung

y "1-800-program"

1

C # 140

using System.Linq;class P{static void Main(string[]a){System.Console.Write(string.Concat(a[0].Select(d=>(char)(d>96?20-d/122+5*d/16:d))));}}

0

Python

import string          
trans = str.maketrans(string.ascii_lowercase,
                      '22233344455566677778889999')                                                                                         
print("1-800-ask-usps".translate(trans))

0

ECMASCRIPT, 101 (mit Eingabe)

"1-800-PROGRAM".replace(/./g,function(c){
return "22233344455566677778889999"[c.charCodeAt(0)-65]||c})

Zeilenumbruch zur Verdeutlichung hinzugefügt. 85 Zeichen, wenn die Eingabe in einer Variablen erfolgt.


0

Perl, 54

print map{/[a-y]/?int(5/16*ord)-28:/z/?9:$_}<>=~/./gs

Shoot, @RobHoare hat mich immer noch um 4 Charaktere geschlagen. :)


0

QBasic, 155

Ah, die Erinnerungen ...

INPUT n$
FOR i=1 TO LEN(n$)
c$=MID$(n$,i,1)
a=ASC(c$)
IF 97>a THEN
PRINT c$;
ELSE IF 122>a THEN
PRINT STR$(a\3.2-28);
ELSE
PRINT 9;
END IF
NEXT i

Das hätte kürzer sein sollen, aber ich habe mit repl.it getestet , das keine einzeiligen IFAnweisungen zulässt und sich seltsam verhält, wenn Sie die Variable off von lassen NEXT i. Die ASCFunktion wird auch nicht erkannt. Um den Code auszuführen, müssen Sie diese Problemumgehung zu Beginn hinzufügen:

DECLARE FUNCTION ASC(s$)
FUNCTION ASC(s$)
FOR j=1 TO 255
IF CHR$(j)=LEFT$(s$,1) THEN
ASC=j
END IF
NEXT j
END FUNCTION

(Das zweite Mal, wenn Sie es ausführen, wird der Interpreter sich beschweren, es sei denn, Sie entfernen die DECLARE FUNCTIONLinie, gehen Sie Abbildung.)


0

R 110

s=strsplit(scan(,""),"")[[1]];i=grep("[a-z]",s);s[i]=sort(c(1:24%%8+2,7,9))[match(s[i],letters)];cat(s,sep="")

Beispiel:

> s=strsplit(scan(,""),"")[[1]];i=grep("[a-z]",s);s[i]=sort(c(1:24%%8+2,7,9))[match(s[i],letters)];cat(s,sep="")
1: 1-800-program
2: 
Read 1 item
1-800-7764726
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.