Telefon numaralarındaki harfler


23

Sorun:

Örneğin, insanların özel telefon numaralarını yazabilecekleri yeni bir telefon hazırlıyorsunuz 1-800-programve 1-800-7764726(önceki örnekte olduğu gibi) otomatik olarak kullanılabilir bir telefon numarasına dönüştürülüyorlardı .

Herhangi bir uzunluk, sayılar, harfler ve kısa çizgilerle yazılmışsa, programınız bir dize alır ve tüm harfleri karşılık gelen sayılara dönüştürür.

İşte referans için bir tuş takımı:

klavye

Kurallar:

  • Programınız bir dize alacak
  • İşleyecek ve başka bir dize döndürecek / yazdıracak
  • Herhangi bir dil kabul edilir
  • O olduğu için , en kısa kod kazanır

Program, girişteki hem büyük hem de küçük harfleri kullanmalı mı?
mattnewport

3
@mattnewport - hayır, değişken varsayalım zaten küçük harf haline getirilmiştir
TheDoctor

Yanıtlar:


8

GolfScript, 24 karakter

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

Test girişi:

0123456789-abcdefghijklmnopqrstuvwxyz

Test çıkışı:

0123456789-22233344455566677778889999

Açıklama:

  • { }% Kodu, girişin her karakterine parantezler arasına uygular.

  • .96>{ }* Yalnızca, karakterin ASCII kodu 96'dan büyükse (yani küçük harf ise) iç parantezler arasındaki kodu uygular.

  • Birincisi ,, karakteri ASCII kodları daha düşük olan tüm karakterlerin listesine dönüştürür ve 91,'qx'+-ASCII kodları 91'den küçük olan tüm karakterleri , listedeki harfleri qve harfleri filtreler x. Böylece, örneğin, a6 karakterlik listeye [\]^_`, z29 karakterlik listeye dönüşür [\]^_`abcdefghijklmnoprstuvwy.

  • İkincisi ,, listede kalan öğeleri sayar ve 3/bu sayıyı üçe (yuvarlama) böler. Son olarak, `ortaya çıkan sayıyı (2 - 9 aralığında) bir dizgeye dönüştürür.

Böylece, spesifikasyonlara göre, kısa çizgiler ve sayılar değişmeden bırakılırken, küçük harfler referans tuş takımı diyagramına göre sayılarla eşleştirilir. Kod aslında temiz küçük (aynı anlatıldığı gibi eşleştirilmiş) harfler ve karakterleri dışındaki tüm yazdırılabilir ASCII karakterleri geçecek {, |ve }(iki karakter dizesi eşlenir 10). ASCII olmayan 8 bit giriş her tür garip sayısal çıkışın üretilmesine neden olur.

Bütün bunlardan sonra, bunun sadece altı karakterle önemsiz bash çözümünü yenmesi biraz hayal kırıklığı yarattı .


50

Bash, 30

Düzenleme: 3 karakter ortadan kaldırmak için teşekkür ederiz Doorknob

tr a-z 22233344455566677778889

Örnek:


10
Son 3 9saniyeyi kaldıramaz mısın?
Doorknob

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
Güzel matematik Sadece ~(c=getchar())
EOF'ın

Kullanmak Could getch()yerine getchar()?
starsplusplus

Açıkça konuşmak gerekirse, getch()standart C değil, sonuç olarak ideone ile bağlantılı olmadığını tahmin ediyorum. Yine de MSVC'de test ettim ve gerçekten ne yazık ki işe yaramadı - doğrudan klavye girdisini kullandığı için programdan çıkmanın hiçbir yolu yoktu, ancak anında ne yazdığınızın ne kadar zarif olduğunu çeviriyor.
mattnewport

4

Javascript - 103 karakter

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
Bunu .replace ile yapabileceğini bilmiyordum. Sana oy ver!
SuperJedi224

Sen değiştirebilir charCodeAt(0)ile charCodeAt()ve sizin için ok fonksiyonunu kullanabilirsiniz function(y)...için birkaç byte kaydetmek ve ~~(y/3)kullanabilirsinizy/3|0
Chau giang

3

Ruby, 75 karakter

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

Kullanımdan kaldırılan charsblok ile kullanılır ve her harfi ayrı ayrı yazdırır $><<. Ben de severim [[*?a..?z].index(c)||-1]; Bir harf ise, o alfabenin harfine karşılık gelen karakteri, değişmemişse son karakter (test karakteri değişmeden kalır) alır.

Ruby, 43 (veya 35) karakter

@Ace'dan açıkça çalmak;)

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

sDizge olarak değişkenli IRB'de çalıştırabilirsem 8 karakteri tıraş edin :

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

3

C ++ - 222 karakter

Şimdiye kadarki en uzun çözüm:

#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, en uzun çözümün burada amaç olduğunu sanmıyorum ...
Danny

@ Danny C ++ kod-golf için kendini iyi ödünç vermez . Java ve C #, daha kötü, bildiğim tek dillerdir (tüm sınıflar, nesne oluşturma ve çıktı için uzun adlar ...).
Hosch250,

Biliyorum, "En uzun çözüm" den bahsetmenin komik olduğunu düşündüm.
Danny

3

Frink, 92

Oldukça ayrıntılı bir dil biliyorum. Bu, karşılaştırma yapmak zorunda kalmadan 26 yerine 8 değeri kontrol eder. Yukarıdaki "222333444 .." çözümlerinden herhangi biri benzer şekilde azaltılabilir mi?

Yerleşik yapıların kullanımı, 107

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

Özel bir özyinelemeli işlev kullanma, 92

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

Dizi çevirme yöntemini 8 karakterlik bir aramaya düşürmek için +1. Güzel dokunuş.
Jonathan Van Matre

2

Smalltalk, 79 70

giriş s:

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

Muhtemelen en kısa olduğu için aday değil - fakat bulunmayan bir durum için bir test yapmaktan kaçınmak için eski bir numaraya ilgi duyabilir (indexOf: bu durumda 0 döndürür). Bu nedenle, harfler için özel bir test gerekmez. Bununla birlikte, bazı Smalltalks'ler değişmez dizgelere sahiptir ve 4 karaktere daha ihtiyacımız vardır ("kopya").

Ah, 70 karakterde değişmeyen karakter dizileriyle bile ilgilenen daha iyi bir versiyon:

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

2

Mathematica 90

Bu @ ace'ın çözümünün mantığını izler:

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

Örnek

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

8437889


Ok karakter gösterimi Mma tarafından bir kopyala / yapıştır olarak kabul edilmedi
Dr. belisarius

Ayrıca, gerek yok 1içinde #1:)
Belisarius Dr.

Belisarius, oku geri değiştirdim ve çıkarttım 1. Hala 90 karakter ama kes ve yapıştır çalışacak. Tek char okunu kullanma motivasyonunu elbette anlıyorsunuz.
DavidC

Orada yaptım, :) yaptım
Dr. belisarius

2

Perl, 50

Ace'nin bash cevabının bir başka açık kopyası

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

1
Bu kod doğru çalışıyor ancak iyileştirme için yer var. $ ARGV [0] 'dan kurtulalım ve -pbunun yerine her bir stdin satırından güzelce geçmenizi sağlayan anahtarı kullanın. Oyundayken y /// içindeki aralığın köşeli parantez içine alınması gerekmez. Üç 9'dan sadece bir tanesini bırakarak kurtulabiliriz ve son yarı kolonu kaldırabiliriz: -p y/a-z/22233344455566677778889/ İşte, 30 + 1 -p. Enterprise Chinese Perl Golf ve Optimizasyon Hizmetlerini kullandığınız için teşekkür ederiz ve iyi günler.
çince perl goth

2

R, çok uzun ama eğlenceli

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

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

kullanım

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

2

JavaScript, 85

JavaScript asla golf savaşlarını kazanmayacak, ama hoşuma gitti ve @ ace çoğunluğuna atlamaktan farklı bir şey yapmak istedim.

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

2

PHP, 141

En kısa değil, daha eğlenceli:

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

Daha okunabilir:

<?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 girişin zaten küçük harf olduğunu söyledi, bu yüzden strtolower
14'te Einacio'yu

2

Python 2.7, 80

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

Python'a yeniyim , bu yüzden bundan daha fazla golf oynamanın bir yolu olmalı , bu farklı bir yaklaşım, umarız beğenirsiniz, Tanrım, piton tatlı!

Örnek çalıştır:

  • giriş: 01-800-abcdefghijklmnopqrstuvwxyz
  • çıktı: 01-800-22233344455566677778889999

2

T-SQL, 216 bayt

Geçtiğimiz birkaç gecede, alfabetik ASCII kodlarından sayılar için uygun ASCII kodları oluşturmak için doğru şekilde dönecek bir matematiksel sıralama işlevi yaratarak özenle biraz zaman geçirdim. Katsayılarda çok sayıda ondalık basamak vardı, ama işe yaradı.

Ancak mattnewport'un rasyonel yaklaşımı SQL'de de çok düşük byte maliyetiyle çalışıyor, bu yüzden utanmadan kendi matematiği kendi lehine hurdaya atıyorum. Ona oy ver, zarif bir çözüm!

Benimki burada:

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

Bu, telefon numarasındaki karakterlerin hazırlıksız bir yığını haline getirmek ve anında harfleri çevirmek için özyinelemeli bir CTE kullanır, ardından CTE'den gerektirmeden dizeyi yeniden oluşturmak için bir miktar SQL kandırması (SELECT @ p = @ p ​​+ columnValue) başka bir özyinelemeli yapı.

Çıktı:

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

2

Python 2.7, 66 65


Anakata'nın Orijinali

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


Daha golf

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


@ Anakata'nın cevabı hakkında yorum yapacak kadar itibarım yok, bu yüzden burada ayrı bir yazı yaptım. Ben de aynı fikre sahiptim (3. yönetmeliğe göre). s - z .

Neyse, yaptığım golf iyileştirmeleri:

  • değişti raw_inputetmekinput

  • yabancı '\b've parantez ve tek tırnak

  • +2ofset kaldırıldı ve orijinal çıkarma işlemine yerleştirildi (97 - (3 * 2) = 91)

Python 2.7.6 tercümanı ile test edilmiştir. Kurallara göre bir dize girdisi olduğunu varsayar.


Ayrıca) ve if arasındaki boşluğu kaldırabilirsiniz
Willem

Haklısın. iyi yakalamak willem
zheshishei 14:14

1

PHP, 87

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

1

q [38 Karakter]

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

@ Ace'ın çözümünden ilham aldı

Örnek

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

1

XQuery, 71

BaseX , XQuery işlemci olarak kullanıldı. $igiriş.

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

En kısa cevap değil, fakat oldukça kısa ve çok okunaklı.


1

Python, çok yalın

Herkes as kopyaladığından, soruyu göndermeden önce oluşturduğum kodu göndermeye karar verdim:

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 bayt):

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

iDize içermeyi bekler .

Firefox’un herhangi yeni bir sürümünde deneyin. Google Chrome'u denemedim.


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, 93C

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

kullanım

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

piton

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

0

ECMASCRIPT, 101 (giriş ile)

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

Netlik için Newline eklendi. Girdi değişkende ise 85 karakter.


0

Perl, 54

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

Vur, @RobHoare hala 4 karakterle beni dövdü. :)


0

QBasic, 155

Ah, hatıralar ...

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

Bu daha kısa olmalıydı, ancak tek satırlı ifadelere izin vermeyen ve değişkeni kapalı tutarsanız garip davranan repl.it ile test ediyordum . Ayrıca bu işlevi tanımıyor , bu nedenle kodu çalıştırmak için bu geçici çözümü baştan eklemeniz gerekecek:IFNEXT iASC

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

(İkinci kez çalıştırdığınızda, DECLARE FUNCTIONçizgiyi kaldırmadığınız sürece tercüman şikayet edecektir .)


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

Örnek:

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