Thư trong số điện thoại


23

Vấn đề:

Ví dụ, bạn đang tạo một điện thoại mới, nơi mọi người có thể nhập các số điện thoại chuyên dụng 1-800-program, và chúng sẽ được tự động chuyển đổi thành số điện thoại có thể sử dụng, như 1-800-7764726(ví dụ trước).

Chương trình của bạn sẽ nhận được một chuỗi nếu có độ dài bất kỳ với số, chữ cái và dấu gạch ngang và chuyển đổi tất cả các chữ cái thành số tương ứng của chúng.

Đây là một bàn phím, để tham khảo:

bàn phím

Quy tắc:

  • Chương trình của bạn sẽ nhận được một chuỗi
  • Nó sẽ xử lý nó và trả về / in một chuỗi khác
  • Mọi ngôn ngữ đều được chấp nhận
  • Vì nó là , nên đoạn mã ngắn nhất sẽ thắng

Chương trình có nên xử lý cả chữ in hoa và chữ thường trong đầu vào không?
mattnewport

3
@mattnewport - không, giả sử biến đã được chuyển thành chữ thường
TheDoctor

Câu trả lời:


8

GolfScript, 24 ký tự

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

Kiểm tra đầu vào:

0123456789-abcdefghijklmnopqrstuvwxyz

Đầu ra thử nghiệm:

0123456789-22233344455566677778889999

Giải trình:

  • { }% áp dụng mã giữa các dấu ngoặc cho mỗi ký tự của đầu vào.

  • .96>{ }* thực thi mã giữa các dấu ngoặc trong khi và chỉ khi mã ASCII của ký tự lớn hơn 96 (nghĩa là ký tự viết thường).

  • Đầu tiên ,biến ký tự thành một danh sách tất cả các ký tự có mã ASCII thấp hơn và 91,'qx'+-lọc ra tất cả các ký tự có mã ASCII nhỏ hơn 91, cũng như các chữ cái qx, từ danh sách. Do đó, ví dụ, nhân vật ađược chuyển thành danh sách 6 ký tự [\]^_`, trong khi zđược chuyển thành danh sách 29 ký tự [\]^_`abcdefghijklmnoprstuvwy.

  • Phần thứ hai ,đếm các phần tử còn lại trong danh sách và 3/chia số này cho ba (làm tròn xuống). Cuối cùng, `biến số kết quả (trong phạm vi 2 - 9) thành một chuỗi.

Do đó, theo thông số kỹ thuật, dấu gạch nối và số được giữ nguyên, trong khi các chữ cái viết thường được ánh xạ thành số theo sơ đồ bàn phím tham chiếu. Mã này sẽ thực sự sạch sẽ đi qua tất cả các ký tự ASCII in trừ chữ thường (mà như ánh xạ như mô tả) và các nhân vật {, |}(được ánh xạ tới các chuỗi hai ký tự 10). Đầu vào 8 bit không phải ASCII sẽ tạo ra tất cả các loại đầu ra số lạ.

Sau tất cả, điều này hơi thất vọng khi điều này chỉ đánh bại giải pháp bash tầm thường chỉ bằng sáu ký tự.


50

Bash, 30

Chỉnh sửa: Cảm ơn Doorknob đã loại bỏ 3 ký tự

tr a-z 22233344455566677778889

Thí dụ:


10
Bạn có thể loại bỏ 3 9giây cuối không?
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
Toán tốt đẹp. Chỉ muốn nói rằng bạn có thể giảm 1 char bằng cách giả sử EOF là -1 và làm~(c=getchar())
user12205

Bạn không thể sử dụng getch()thay vì getchar()?
starplusplus

Nói đúng ra, getch()không phải là tiêu chuẩn C, kết quả là tôi đoán nó không liên kết trong ideone. Mặc dù vậy, tôi đã thử nghiệm nó trong MSVC và nó không thực sự hoạt động một cách đáng buồn - vì nó trực tiếp tiêu thụ đầu vào bàn phím, không có cách nào để thoát khỏi chương trình, mặc dù nó dịch những gì bạn gõ một cách gọn gàng.
mattnewport

4

Javascript - 103 ký tự

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
Tôi không biết bạn có thể làm điều đó với .replace. Lên bình chọn cho bạn!
SuperJedi224

Bạn có thể thay thế charCodeAt(0)bằng charCodeAt()và bạn có thể sử dụng chức năng mũi tên function(y)...để lưu vài byte và ~~(y/3)bạn có thể sử dụngy/3|0
chau giang

3

Ruby, 75 ký tự

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

Sử dụng không dùng charsvới khối và in từng chữ cái riêng lẻ với $><<. Tôi cũng thích [[*?a..?z].index(c)||-1]; nó lấy ký tự tương ứng với chữ cái trong bảng chữ cái nếu đó là chữ cái và ký tự cuối cùng (có thể là ký tự kiểm tra không thay đổi) nếu không.

Ruby, 43 (hoặc 35) ký tự

Ăn cắp trắng trợn từ @ace;)

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

Tắt 8 ký tự nếu tôi có thể chạy trong IRB với biến slà chuỗi:

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

3

C ++ - 222 ký tự

Giải pháp dài nhất cho đến nay:

#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, tôi không nghĩ giải pháp lâu nhất là mục tiêu ở đây ...
Danny

@Danny C ++ không cho vay tốt để chơi golf . Java và C # là những ngôn ngữ duy nhất tệ hơn mà tôi biết (tất cả các lớp, tạo đối tượng và tên dài cho đầu ra ...).
Hosch250

Tôi biết, tôi chỉ nghĩ thật buồn cười khi bạn đề cập đến "Giải pháp dài nhất".
Danny

3

Nháy mắt, 92

Một ngôn ngữ khá dài dòng, tôi biết. Điều này kiểm tra 8 giá trị thay vì 26 mà không cần phải so sánh. Có thể giảm bất kỳ giải pháp "222333444 .." nào ở trên theo cách tương tự không?

Sử dụng các cấu trúc được xây dựng, 107

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

Sử dụng chức năng đệ quy tùy chỉnh, 92

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

+1 để giảm phương thức dịch chuỗi thành tìm kiếm 8 ký tự. Liên lạc tốt đẹp.
Jonathan Van Matre

2

Smalltalk, 79 70

đầu vào là s:

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

có lẽ không phải là một ứng cử viên ngắn nhất - nhưng có thể được quan tâm cho một thủ thuật cũ để tránh thử nghiệm cho một điều kiện không tìm thấy (indexOf: trả về 0 trong trường hợp này). Vì vậy, không có bài kiểm tra đặc biệt cho các chữ cái là cần thiết. Tuy nhiên, một số Smalltalk có chuỗi không thay đổi và chúng tôi cần thêm 4 ký tự ("bản sao").

Ồ, một phiên bản tốt hơn, thậm chí còn xử lý các chuỗi bất biến trong 70 ký tự:

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

2

Toán học 90

Điều này tuân theo logic của giải pháp @ ace:

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

Thí dụ

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

8437889


Đại diện nhân vật mũi tên của bạn không được Mma chấp nhận trong một bản sao / dán
Tiến sĩ belisarius

Ngoài ra, bạn không cần 1trong #1:)
Tiến sĩ belisarius

Belisarius, tôi đã thay đổi mũi tên trở lại và loại bỏ 1. Vẫn 90 char nhưng cắt và dán sẽ hoạt động. Tất nhiên bạn hiểu động lực để sử dụng mũi tên char duy nhất.
DavidC

Ở đó, làm điều đó :)
Tiến sĩ belisarius

2

Perl, 50

Một bản sao rõ ràng khác của câu trả lời bash của Ace

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

1
Mã này đang hoạt động chính xác nhưng có chỗ để cải thiện. Hãy loại bỏ $ ARGV [0] và sử dụng -pcông tắc thay vào đó cho phép bạn đi qua từng dòng stdin một cách độc đáo. Trong khi chúng ta đang ở đó, phạm vi trong y /// không cần phải được đặt trong dấu ngoặc vuông. Chúng tôi cũng có thể loại bỏ ba số 9 chỉ còn lại một và xóa dấu chấm phẩy cuối cùng: -p y/a-z/22233344455566677778889/ Có bạn đi, 30 + 1 cho -p. Cảm ơn bạn đã sử dụng Dịch vụ Tối ưu hóa và Chơi gôn Perl của Trung Quốc và chúc một ngày tốt lành.
tiếng Trung Quốc perl goth

2

R, rất dài nhưng vui

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 ký tự]

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

Sử dụng

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

2

JavaScript, 85

JavaScript sẽ không bao giờ chiến thắng trong các cuộc chiến golf, nhưng tôi thích nó và tôi muốn làm một cái gì đó khác hơn là nhảy vào bandwagon @ace.

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

2

PHP, 141

Không phải là ngắn nhất, nhưng vui hơn:

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

Dễ đọc hơn:

<?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 nói rằng đầu vào đã được viết thường, vì vậy bạn có thể xóastrtolower
Einacio

2

Con trăn 2.7, 80

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

Tôi chưa quen với python, vì vậy tôi chắc chắn phải có một cách để chơi golf hơn nữa , đó là một trò chơi khác, hy vọng các bạn thích nó, chúa ơi, là con trăn xinh đẹp!

Chạy ví dụ:

  • đầu vào: 01-800-abcdefghijklmnopqrstuvwxyz
  • đầu ra: 01-800-22233344455566677778889999

2

T-SQL, 216 byte

Tôi đã dành khá nhiều thời gian trong vài đêm qua để tạo ra một hàm chuỗi toán học có thể làm tròn chính xác để tạo mã ASCII thích hợp cho các số từ mã ASCII theo bảng chữ cái. Nó có một số lượng lớn các vị trí thập phân trong các hệ số, nhưng nó đã hoạt động.

Tuy nhiên, cách tiếp cận hợp lý của mattnewport cũng hoạt động trong SQL, với chi phí byte thấp hơn nhiều, vì vậy tôi không biết xấu hổ khi bỏ toán học của mình để ủng hộ toán học của mình. Đi lên - bầu anh ta, đó là một giải pháp tao nhã!

Đây là của tôi:

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

Điều này sử dụng CTE đệ quy để tạo một ngăn xếp đầy đủ các ký tự trong số điện thoại và dịch các chữ cái một cách nhanh chóng, sau đó một chút thủ thuật SQL (SELECT @ p = @ p ​​+ cộtValue) để biên dịch lại chuỗi từ CTE mà không yêu cầu xây dựng đệ quy khác.

Đầu ra:

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

2

Con trăn 2.7, 66 65


Bản gốc của Anakata

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


Hơn nữa chơi golf

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


Tôi không có đủ danh tiếng để bình luận về câu trả lời của @ anakata, vì vậy tôi đã tạo một bài đăng riêng ở đây. Tôi có cùng một ý tưởng (lấy mô-đun pháp lệnh 3) nhưng không thể tìm ra cách in đúng số cho s - z .

Dù sao, những cải tiến golf tôi đã thực hiện:

  • đổi raw_inputthànhinput

  • loại bỏ ngoại lai '\b' dấu ngoặc và dấu ngoặc đơn và dấu ngoặc đơn

  • loại bỏ phần +2bù và đặt nó vào phép trừ ban đầu (97 - (3 * 2) = 91)

Đã thử nghiệm với trình thông dịch Python 2.7.6. Giả sử, theo các quy tắc, một đầu vào chuỗi.


bạn cũng có thể xóa khoảng trắng giữa) và if
Willem

Bạn đúng. ý chí bắt tốt
zheshishei

1

PHP, 87

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

1

q [38 ký tự]

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

Lấy cảm hứng từ giải pháp của @ ace

Thí dụ

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

1

XQuery, 71

BaseX đã được sử dụng làm bộ xử lý XQuery. $ilà đầu vào.

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

Không phải là câu trả lời ngắn nhất, nhưng khá ngắn và rất dễ đọc.


1

Con trăn, rất vô dụng

Vì mọi người đang sao chép ace, tôi quyết định đăng mã tôi đã tạo trước khi gửi câu hỏi:

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

Mong đợi i sẽ chứa chuỗi.

Hãy thử nó trong bất kỳ phiên bản gần đây của Firefox. Tôi chưa thử Google Chrome.


1

Trăn 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")

Sử dụng

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

Con trăn

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

0

ECMASCRIPT, 101 (có đầu vào)

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

Dòng mới được thêm vào cho rõ ràng. 85 ký tự nếu đầu vào là một biến.


0

Perl, 54

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

Bắn, @RobHoare vẫn đánh tôi 4 ký tự. :)


0

QBasic, 155

À, những kỷ niệm ...

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

Điều này đáng lẽ phải ngắn hơn, nhưng tôi đã thử nghiệm với repl.it , điều này không cho phép các IFcâu lệnh đơn và hành xử kỳ lạ nếu bạn bỏ qua biến NEXT i. Nó cũng không nhận ra ASCchức năng, vì vậy để chạy mã bạn sẽ cần thêm cách giải quyết này ngay từ đầu:

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

(Lần thứ hai bạn chạy nó, trình thông dịch sẽ khiếu nại trừ khi bạn xóa DECLARE FUNCTIONdòng, đi hình.)


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

Thí dụ:

> 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.