Điện thoại đánh vần nhiều lần


21

Lấy cảm hứng từ Thử thách mã Google :

Bảng chữ cái Latinh chứa 26 ký tự và điện thoại chỉ có mười chữ số trên bàn phím. Chúng tôi muốn làm cho việc viết tin nhắn cho bạn bè của bạn dễ dàng hơn bằng cách sử dụng một chuỗi các phím bấm để chỉ ra các ký tự mong muốn. Các chữ cái được ánh xạ lên các chữ số như hình dưới đây. Ví dụ, để chèn ký tự B, chương trình sẽ nhấn 22. Để chèn hai ký tự theo thứ tự từ cùng một khóa, người dùng phải tạm dừng trước khi nhấn phím lần thứ hai. Ký tự không gian '' nên được in để biểu thị tạm dừng. Ví dụ: 2 2 chỉ AA trong khi 22 chỉ B.

Mỗi tin nhắn sẽ chỉ bao gồm các ký tự chữ thường az và ký tự khoảng trắng ''. Nhấn zero sẽ phát ra một khoảng trắng.

nhập mô tả hình ảnh ở đây

Thử thách của bạn là viết hàm nhỏ nhất lấy chuỗi đầu vào và trả về chuỗi các phím nhấn cần thiết để tạo đầu vào dưới dạng chuỗi hoặc xuất nó thành thiết bị xuất chuẩn. Hàm số lượng byte ít nhất sẽ thắng.

Ví dụ đầu vào / đầu ra

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

Làm rõ khác

  • Tạm dừng chỉ phải được thêm khi cần thiết và phải là khoảng trắng ''.
  • Mỗi tin nhắn sẽ chỉ bao gồm các tự chữ thường az và ký tự khoảng trắng ''. In 0để biểu thị không gian.
  • Không có thư viện bên ngoài.
  • Chỉ chuỗi đầu vào có thể được chuyển đến chức năng của bạn.
  • Để làm cho các ngôn ngữ khác cạnh tranh, khai báo hàm chính không được tính và cũng không nhập các thư viện chuẩn khác. #includes, imports và usings không được tính. Mọi thứ khác làm. Điều này không bao gồm #definecác chức năng s và trợ giúp. Xem quy tắc 2 trong câu hỏi này nếu bạn bối rối.
  • Nhiều không gian có thể được ký hiệu là 00hoặc 0 0vì bạn không thực sự phải tạm dừng giữa một không gian


Chúng ta có thể giả sử đầu vào là chữ thường / chữ hoa không?
Phil H

@PhilH " tự chữ thường az và ký tự không gian ''"
Danny

Bạn có xem dấu ngoặc {}là một phần của chữ ký hàm không? Ví dụ, nếu mã của tôi là function f(){alert('hi');}, tôi nên đếm các ký tự của alert('hi');hay {alert('hi');}?
Chương trìnhFOX

2
Theo tôi nhớ t9hoạt động khác nhau: bạn phải bấm từng phím một lần để có được một từ.
VisioN

Câu trả lời:


8

Hồng ngọc 129 122 115 111 108 107 105

Đã xong với việc chơi gôn ...

Rất tiếc, hoàn toàn quên xóa các khoảng trống không cần thiết - đã sửa ...

Lưu được 2 ký tự nhờ Peter Taylor.

Phiên bản trực tuyến

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

Giải trình:

không gian được dịch sang char với số thứ tự 96

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

các ký tự được ánh xạ đầu tiên thành chuỗi các số: - a đến 2 - b đến 22 - d đến 3222 - h đến 444333222

một biểu thức regex sau đó khớp với nhóm chữ số đầu tiên bằng nhau

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

mảng được nối

*' ')

tất cả các khoảng trắng trong các lần xuất hiện của "không gian chữ số differ_digit" đều bị xóa

gsub /(\d) (?!\1)/,'\1'

1
Không nhìn đúng để làm việc đúng 100%. Tôi thấy 66666 không bao giờ cần phải nhấn 4 lần liên tiếp.
Danny

Nên sửa, cảm ơn;)
David Herrmann

1
Điểm của \2regex cuối cùng là gì? Chắc chắn nhóm thứ hai là một khẳng định có độ rộng bằng không?
Peter Taylor

Bạn hoàn toàn đúng!
David Herrmann

6

REBEL - 154 110 103

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

'Hàm' này chấp nhận đầu vào từ stdin và gửi kết quả đến thiết bị xuất chuẩn.

Chạy thử (vì vậy bạn không phải cài đặt trình thông dịch):

hi
44 444

hello world
4433555 555666096667775553

yes
999337777

kthxbai
558449922 2444

Tôi không bao giờ có thể tải các liên kết của bạn! :(
luser droog

4

JavaScript (124)

Chạy trong Firefox.

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

4

GolfScript, 46 ký tự

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

Như thường lệ, đọc đầu vào từ stdin, in ra thiết bị xuất chuẩn. Xem bản demo trực tuyến (với đầu vào đóng hộp).

Lưu ý rằng mã này dựa trên một diễn giải rất nghiêm ngặt về thông số kỹ thuật đầu vào (chỉ các chữ cái và dấu cách viết thường): đặc biệt, bất kỳ dòng mới nào trong đầu vào sẽ bị sập nó! Vấn đề này có thể được khắc phục, với chi phí của hai ký tự bổ sung, bằng cách thêm vào n-mã để lọc bất kỳ dòng mới nào.


3

C ++ - 365 ký tự không có 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;}}}

Sử dụng lý do tương tự như câu trả lời của tôi ở đây , chỉ sử dụng forcác vòng lặp để xuất ra mỗi chữ cái số lần thích hợp.


Bạn có thể sử dụng s[i]==32thay vì s[i]==' '. Giá trị ASCII của không gian là 32.
user12205

@ace Chắc chắn rồi.
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

Đây là giải pháp trước đây của tôi trong 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

Các xét nghiệm:

hi
 44 444

hello world
 4433555 555666096667775553

jackdaws loves my big sphinx
 52 222553297777055566688833777706999022444 407777 744 4446699

3

VBA 220 253/258/219

Không tính Functiondòng ở đây:

Với 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

Với Forvòng lặp 258 :

Đã thêm chỉnh sửa cho khóa 7/9 (cảm ơn, Danny), đã thêm rất nhiều ký tự.

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

Sử dụng Choose 219 :

Tôi không muốn chạy với cái này, vì chức năng cơ bản hơn, nhưng nó mã ngắn hơn ...

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

yesnên 999337777. Tôi nhận được 10338bằng cách sử dụng chức năng của bạn.
Daniel

3

C, 165 163 153 149 138 ký tự

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

Nỗ lực đầu tiên của tôi về chơi golf mã, bất kỳ đề xuất nào đều được đánh giá cao.


2

C ++ - 170 168 160

Chơi gôn

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

Ung dung

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

2

C: 136 ký tự

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

Và hơi vô dụng (vâng, đó là cách nó được viết):

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

Tôi có thể cắt giảm nó xuống một chút bằng cách áp dụng một số đệ quy, ma thuật đen và một lượng bột ớt.


2

Java - 243

Giải pháp java khá ngây thơ. Cảm ơn các bình luận cho ý kiến.

Đã sửa lỗi đôi khi chèn các khoảng trắng không cần thiết, ví dụ: đầu vào "hello worlds 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;
    }

4
Khá tốt, nhưng bạn cần phải chơi nó và cung cấp điểm số.
Hosch250

1
Tôi cho rằng đây là java. Bạn có thể đặt nó trong tiêu đề của bạn, giống như các câu trả lời khác không?
Chấn thương kỹ thuật số

1
Một gôn: thay thế t.lengthbằng10
Justin

Ngoài ra, xem xét việc đó ichỉ được sử dụng để lặp qua String, xóa nó và thực hiện một vòng lặp foreach:for(char c:s.toCharArray())
Justin

Ngoài ra, sự thay đổi if(c==' '){o+='0';continue;}để if(c==' ')o+='0';else{và thêm thích hợp }.
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

1

APL, 77 ký tự

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

Giải trình

  • 2+⌊y←7.99,⍨.315×⍳25 hoặc, vô lương tâm, y←(0.315×⍳25),7.99 ◇ 2+⌊y lấy mẫu một đường nghiêng phù hợp (y = 0,315 x) trên các điểm từ 1 đến 25; đường thẳng nghiêng theo cách sàn của các giá trị y này tuân theo mẫu lặp lại 000111 ... 777 ngoại trừ nhóm thứ sáu gồm các chữ số 5555; một số được nối vào cuối để lấy số 7 thứ tư, sao cho mảng cuối cùng cộng với 2 là 22233344455566677778889999;
  • ⌈3.1×y-⌊y khuếch đại sự khác biệt giữa các giá trị y đó và các tầng của chúng, sao cho trần của các khác biệt tạo ra mẫu 123123 ... với 4 trên các chữ số cuối của hai nhóm 4 chữ số;
  • '0',⍨( ... )/¨⍕¨ ...hoặc (( ... ) /¨ ⍕¨ ...),'0' sử dụng kết quả sau để sao chép các chữ số từ số trước, sao cho đầu ra là mảng các chuỗi "2" "22" "222" "3" "33" "333" ... với "7777" và "chính xác" 9999 "tại chỗ và" 0 "được thêm vào cuối;
  • ⍵⍳⍨⎕UCS 96+⍳26hoặc (⎕UCS 96+⍳26)⍳⍵tính chỉ số của mỗi char đầu vào, trong đó "a" là 1, "z" là 26 và khoảng trắng (và mọi char khác) là 27;
  • { ... }/( ... )[ ... ] lấy kết quả sau, chỉ mục cho mỗi char đầu vào, để dịch từng char thành chuỗi chữ số tương ứng, sau đó nối chuỗi bằng cách sử dụng hàm trong dấu ngoặc;
  • {⍵,⍨⍺,''↑⍨=/↑¨⍺⍵}hoặc {(⍺,(=/↑¨⍺,⍵)↑''),⍵}nối thêm mỗi chuỗi mới vào bộ tích lũy, chỉ xen kẽ một khoảng trắng nếu cả hai đối số bắt đầu bằng cùng một char.

Ví dụ

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

1

Con trăn 155 150

Tôi ước tôi đã tốt hơn ở XD này. Định nghĩa hàm không được tính. Cấp độ thụt đầu tiên là một khoảng trắng, thứ hai là một tab và 2 tab thứ ba.

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

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)


0

R 224

Tôi chắc chắn có một cách tốt hơn để làm điều này, vì vậy tôi sẽ tiếp tục làm việc với nó.

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='')
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.