電話番号の文字


23

問題:

たとえば1-800-program、のような特殊な電話番号を入力できる新しい電話を作成すると、1-800-7764726(前の例のように)使用可能な電話番号に自動的に変換されます。

プログラムは、数字、文字、ダッシュを含む長さがある場合は文字列を受け取り、すべての文字を対応する数字に変換します。

参照用のキーパッドは次のとおりです。

キーパッド

ルール:

  • プログラムは文字列を受け取ります
  • それを処理し、別の文字列を返し/印刷します
  • すべての言語が受け入れられます
  • それがあるので、最短コードの勝利

プログラムは、入力で大文字と小文字の両方を処理する必要がありますか?
mattnewport 14

3
@mattnewport -いいえ、変数が既に小文字になっていると仮定
TheDoctor

回答:


8

GolfScript、24文字

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

テスト入力:

0123456789-abcdefghijklmnopqrstuvwxyz

テスト出力:

0123456789-22233344455566677778889999

説明:

  • { }% 入力の各文字に中括弧の間にコードを適用します。

  • .96>{ }* 文字のASCIIコードが96を超える場合(つまり小文字の場合)にのみ、内側の中括弧の間のコードを実行します。

  • 1つ目,は、文字をより低いASCIIコードを持つすべての文字のリストに変換し、91,'qx'+-91未満のASCIIコードを持つすべての文字q、およびxリストからの文字とを除外します。したがって、たとえば、文字aは6文字のリスト[\]^_`z変換され、29文字のリストに変換されます[\]^_`abcdefghijklmnoprstuvwy

  • 2番目,は、リストに残っている要素をカウントし、3/このカウントを3で除算します(切り捨て)。最後に、`結果の数値(2〜9の範囲)を文字列に変換します。

したがって、仕様に従って、ハイフンと数字は変更されずに残り、小文字は参照キーパッド図に従って数字にマッピングされます。コードは実際には、小文字(説明どおりにマッピングされている)と文字{|および}(2文字の文字列にマッピングされている)を除くすべての印刷可能なASCII文字をきれいに通過します10。非ASCII 8ビット入力は、あらゆる種類の奇妙な数値出力を生成します。

結局のところ、これは些細なbashソリューションに6文字しか勝てないのは少し残念です。


50

バッシュ、30

編集:3文字を排除するためのDoorknobありがとうございます

tr a-z 22233344455566677778889

例:


10
最後の3 9秒間は削除できませんか?
ドアノブ

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
素敵な数学。ただ、-1あなたはEOFを想定して1つの文字を減らすことができると言うとやるしたい~(c=getchar())
user12205

getch()代わりに使用できませんgetchar()か?
starsplusplus 14

厳密に言えば、getch()標準Cではありません。その結果、ideoneにリンクしないと思います。とにかくMSVCでテストしましたが、実際には悲しいことにはなりません。キーボード入力を直接消費するため、プログラムを終了する方法はありません。
mattnewport 14

4

Javascript-103文字

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
.replaceでそれができるとは知りませんでした。あなたの賛成票!
SuperJedi224

に置き換えcharCodeAt(0)charCodeAt()、矢印機能を使用function(y)...して数バイトを節約し、~~(y/3)使用することができますy/3|0
chau giang

3

ルビー、75文字

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

非推奨のcharswithブロックを使用し、で各文字を個別に印刷し$><<ます。私も好き[[*?a..?z].index(c)||-1]です。アルファベットの場合はアルファベットのその文字に対応する文字を取得し、そうでない場合は最後の文字(テスト文字が変更されない)を取得します。

Ruby、43(または35)文字

@aceから露骨に盗む;)

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

s文字列として変数を使用してIRBで実行できる場合は、8文字を削除します。

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

3

C ++-222文字

これまでの最長ソリューション:

#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
笑、私は...最長のソリューションがここでの目的ではないと思います
ダニー・

@Danny C ++はcode-golfに適していません。JavaとC#は、私が知っている最悪の言語(すべてのクラス、オブジェクト作成、および出力用の長い名前...)だけです。
Hosch250 14

あなたが「最も長い解決策」と言ったことはおもしろいと思っただけです。
ダニー14

3

フリンク、92

かなり冗長な言語です。これにより、比較を入力せずに26ではなく8つの値がチェックされます。上記の「222333444 ..」ソリューションのいずれかを同様の方法で削減できますか?

ビルトイン構造の使用、107

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

カスタム再帰関数の使用、92

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

文字列変換方式を8文字の検索に減らすための+1。いい感じです。
ジョナサンヴァンマトレ14

2

Smalltalk、79 70

入力はs:

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

おそらく最短になる候補ではありませんが、見つからない条件(この場合はindexOf:が0を返す)のテストを回避するための古いトリックにとっては興味深いかもしれません。したがって、手紙の特別なテストは必要ありません。ただし、一部のSmalltalkには不変の文字列があり、さらに4文字(「コピー」)が必要です。

ああ、70文字の不変文字列も処理するより良いバージョン:

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

2

Mathematica 90

これは、@ aceのソリューションのロジックに従います。

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

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

8437889


あなたの矢印の文字表現をコピーしてMMAで受け入れられない/ペースト
博士ベリサリウス

また、あなたは必要としない1#1:)
博士ベリサリウス

ベリサリウス、矢印を元に戻し、を削除しました1。まだ90文字ですが、カットアンドペーストは機能します。もちろん、単一文字の矢印を使用する動機を理解しています。
DavidC 14

そこに行って、それをやった:)
ベリサリウス博士14

2

Perl、50

エースのバッシュ答えのもう一つの明らかなコピー

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

1
このコードは正常に機能していますが、改善の余地があります。$ ARGV [0]を取り除き、-p代わりにswitchを使用して、stdinの各行をうまく行かせます。ここで、y ///の範囲を角括弧で囲む必要はありません。また、3つの9を1つだけ残して取り除き、最後のセミコロンを削除することもでき -p y/a-z/22233344455566677778889/ ます-p。Enterprise Chinese Perl Golfing and Optimization Servicesをご利用いただき、ありがとうございます。
中国perlゴス

2

R、とても長いが楽しい

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文字]

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

使用法

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

2

JavaScript、85

JavaScriptがゴルフ戦争に勝つことは決してありませんが、私はそれが好きで、@ aceの時流に乗ってジャンプする以外の何かをしたかったのです。

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

2

PHP、141

最短ではありませんが、もっと楽しく:

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

より読みやすい:

<?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は、削除することができますので、入力は、小文字に既にあることを言ったstrtolower
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),

私はpythonが初めてなので、これをさらにゴルフする方法が必要だと確信しています。これは別のアプローチです。

例の実行:

  • 入力:01-800-abcdefghijklmnopqrstuvwxyz
  • 出力:01-800-222333444555666777788899999999

2

T-SQL、216バイト

過去数日間、かなり長い時間を費やして、アルファベット順のASCIIコードから適切なASCIIコードを生成するために正しく丸められる数学的なシーケンス関数を作成しました。係数にとんでもない数の小数点以下の桁がありましたが、うまくいきました。

ただし、mattnewportの合理的なアプローチはSQLでも同様に機能し、バイトコストははるかに低くなります。そのため、私は恥ずかしくも自分の数学を捨てて、彼を支持しています。彼に賛成票を投じてください、それはエレガントな解決策です!

これが私のものです:

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

これは、再帰的なCTEを使用して、電話番号の文字の即興スタックを作成し、その場で文字を翻訳し、その後少しのSQLトリック(SELECT @ p = @ p + columnValue)を使用して、CTEから文字列を再構成します。別の再帰構造。

出力:

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

2

Pythonの2.7、66 65


アナカタのオリジナル

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


さらにゴルフ

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


@anakataの答えにコメントするほどの評判はありませんので、ここに別の投稿をしました。私は同じ考えを持っていました(条例法3を採用しています)が、s-zの正しい数値を印刷する方法がわかりませんでした。

とにかく、私が行ったゴルフの改善:

  • に変更されraw_inputましたinput

  • 無関係な'\b'括弧と一重引用符を削除しました

  • +2オフセットを削除し、元の減算に配置しました(97-(3 * 2)= 91)

Python 2.7.6インタープリターでテスト済み。ルールに従って、文字列の入力を想定しています。


)とifの間のスペースを削除することもできます
ウィレム

あなたが正しい。良いキャッチウィレム
zheshishei

1

PHP、87

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

1

q [38文字]

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

@aceのソリューションに触発された

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

1

XQuery、71

BaseXはXQueryプロセッサとして使用されました。$i入力されます。

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

最短の答えではありませんが、非常に短く、非常に読みやすいです。


1

パイソン、非常に自由

誰もがエースをコピーしているため、質問を送信する前に作成したコードを投稿することにしました。

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バイト):

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

i文字列が含まれることが期待されます。

Firefoxの最新バージョンで試してください。Google Chromeを試したことはありません。


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

ハスケル、93C

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

使用法

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(入力あり)

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

明確にするために改行が追加されました。入力が変数にある場合は85文字。


0

Perl、54

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

撃て、@ RobHoareはまだ私を4文字倒した。:)


0

QBasic、155

ああ、思い出...

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

これはもっと短いはずでしたが、私はrepl.itでテストしていました。これは、1行のIFステートメントを許可せず、変数をoffのままにすると奇妙に動作しますNEXT i。また、ASC関数を認識しないため、コードを実行するには、この回避策を最初に追加する必要があります。

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

(2回目に実行すると、DECLARE FUNCTION行を削除しない限り、インタープリターは文句を言います。図に進みます。)


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

例:

> 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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.