Thực hiện chức năng giống như t9


10

Thử thách của bạn hôm nay là triển khai chức năng giống như t9 .

Bạn sẽ thực hiện một chức năng sẽ chỉ có 2 tham số.
Bạn sẽ nhận được 1 số điện thoại trong một chuỗi và nội dung của tệp văn bản với một danh sách các từ (không giả sử một kiểu dòng mới cụ thể).
Bạn có thể sử dụng liên kết https://raw.githubusercontent.com/eneko/data-reposeective/master/data/words.txt để kiểm tra chức năng hoặc sử dụng /usr/share/dict/words(kiểm tra tệp văn bản có danh sách các từ [đã đóng] để biết thêm thông tin).

Bạn có thể cho rằng bạn sẽ luôn nhận được ít nhất 2 số.

Cho số, bạn sẽ đọc từ một danh sách các từ và trả về các từ bắt đầu bằng ánh xạ các chữ cái cho các từ đó. Điều này có nghĩa là đầu vào chỉ nên là các số từ 2 đến 9.
Bạn có thể làm bất cứ điều gì bạn muốn nếu bạn nhận được đầu vào không hợp lệ.

Nếu không tìm thấy kết quả khớp, bạn có thể trả về một danh sách trống, null/ nilhoặc 0.

Hãy nhớ rằng các phím điện thoại di động được ánh xạ tới ký tự tương đương của chúng:

  • 0 và 1 không hợp lệ
  • 2 trận đấu [abc]
  • 3 trận đấu [def]
  • 4 trận đấu [ghi]
  • 5 trận đấu [jkl]
  • 6 trận đấu [mno]
  • 7 trận đấu [pqrs]
  • 8 trận đấu [tuv]
  • và 9 trận đấu [wxyz]

Ví dụ:

f('52726')
//returns ["Japan","japan","Japanee","Japanese","Japanesque"...,"larbowlines"]

f('552')
//returns ["Kjeldahl","kjeldahlization","kjeldahlize"...,"Lleu","Llew"]

f('1234')
//makes demons fly out your nose or divide by 0

f('9999')
//returns ["Zyzzogeton"]

f('999999')
//returns [] or null/nil or 0

Sau khi bạn chạy chức năng của mình, bạn có thể in nó theo bất kỳ cách nào bạn muốn.

Quy tắc:

  • Các sơ hở tiêu chuẩn là HÓA ĐƠN
  • Bạn phải trả lại một cái gì đó, ngay cả khi nó là null/ nil
    Javascript sẽ trả lại undefinednếu bạn không trả lại một cái gì đó, do đó, quy tắc này.
  • Bạn không thể sử dụng hoặc thực hiện lại câu trả lời của người khác hoặc sao chép việc thực hiện của tôi.
  • Bạn có thể giả sử, đối với Javascript, trình duyệt sẽ được mở và innerText/ textContentcủa phần tử tự động sẽ được chuyển qua làm tham số thứ 2
  • Đối với các ngôn ngữ được biên dịch, bạn không thể truyền các đối số đặc biệt cho trình biên dịch
  • Bạn có thể nhận được tên tệp qua đối số trình biên dịch
  • Các biến, macro, biến toàn cục, hằng, các lớp không chuẩn và tất cả các loại sắp xếp các giá trị khác bên trong hàm sẽ được coi là không hợp lệ.
  • Trong Javascript, các biến không có từ khóa varkhiến mã của bạn không hợp lệ
  • Chức năng của bạn sẽ được đặt tên f
  • Bạn chỉ có thể và chỉ có 2 đối số trên hàm của mình
  • Cố gắng giữ mã của bạn dưới 500 giây để chạy.
  • Bạn không phải lo lắng về khoảng trắng
  • Bạn phải chỉ sử dụng các ký tự có thể in ASCII .
    Ngoại lệ là các ngôn ngữ chỉ sử dụng các ký tự không in được (APL và khoảng trắng là 2 ví dụ).

Ghi điểm:

  • Số byte thấp nhất giành được
  • Có các ký tự có thể in ASCII không hợp lệ trong câu trả lời của bạn, sẽ được tính là câu trả lời được mã hóa trong UTF-32
    Ngoại lệ đối với mã hóa sẽ khiến câu trả lời của bạn được tính theo các ký tự .
  • Chỉ có cơ thể chức năng đếm, không đếm bất cứ điều gì khác bạn làm ngoài nó
  • Tiền thưởng -30% nếu bạn tạo một hệ thống dự đoán dựa trên vùng lân cận hoặc các từ phổ biến nhất
  • Phần thưởng có kích thước -20% nếu bạn chỉ trả lại 5 kết quả khớp đầu tiên cho mỗi chữ cái tương ứng với số đầu tiên (ví dụ: 245 sẽ trả về 5 từ bắt đầu bằng 'a', 5 bắt đầu bằng 'b' và 5 bắt đầu bằng 'c' ).

Dưới đây là một ví dụ về việc triển khai, sử dụng Javascript:

function f(phone, words)
{
    var keypad=['','','abc','def','ghi','jkl','mno','pqrs','tuv','wxyz'];
    var regex='';

    for(var i=0,l=phone.length;i<l;i++)
    {
        regex+='['+keypad[phone[i]]+']';
    }

    var regexp=new RegExp('\\s('+regex+'[a-z]*)\\s','gi');

    return words.match(regexp);
}

Để chạy nó, hãy mở liên kết danh sách và chạy, ví dụ:

f('9999',document.getElementsByTagName('pre')[0].innerText);
//returns [" Zyzzogeton "]

Ví dụ này đã được thử nghiệm và hoạt động theo Opera 12,17 64 bit trên Windows 7 Home Edition 64 bit.


Là đối số thứ hai cho chương trình một tên tệp có chứa các từ hoặc danh sách các từ đó không?
Tối ưu hóa

@ MartinBüttner UTF-8 không công bằng (nó vẫn tính các ký tự ASCII là 1 byte), nhưng tôi đã thay đổi quy tắc.
Ismael Miguel

@Optimizer Đối số thứ 2 là danh sách các từ. Bạn có thể chuyển tên tệp qua một đối số trình biên dịch và đọc tệp, nếu bạn muốn. Nhưng điều duy nhất được tính là cơ thể chức năng.
Ismael Miguel

@ MartinBüttner Bằng cách tính là ASCII, nó đang được tính là byte. Bạn muốn tôi nói rằng mã APL sẽ có 1 byte có kích thước 8 bit?
Ismael Miguel

2
-1 cho các hạn chế không phù hợp
AJMansfield 8/12/14

Câu trả lời:


3

CJam, 28 byte

q~{el{'h-_9/-D+3/}%s1$#!},p;

Đưa đầu vào ở dạng "<number>" [<list of words>]

Thí dụ:

"52726" ["Japan" "japan" "Japanee" "Japanese" "Japanesque" "larbowlines" "ablution" "ablutionary" "abluvion" "ably" "abmho" "Abnaki" "abnegate"]

Đầu ra:

["Japan" "japan" "Japanee" "Japanese" "Japanesque" "larbowlines"]

Không đi cho bất kỳ tiền thưởng cho bây giờ.

Hãy thử mã trực tuyến tại đây nhưng để đo thời gian thực tế, hãy chạy nó trên trình biên dịch Java

Lưu ý rằng CJam đại diện cho danh sách trống như ""

Để chuyển đổi danh sách từ thô thành danh sách CJam, hãy sử dụng đoạn mã sau với danh sách từ làm đầu vào:

qN/p

"Bạn sẽ nhận được 1 số điện thoại trong một chuỗi và nội dung của tệp văn bản có danh sách các từ" -> bạn có thể triển khai, trên một khối khác, mã cần thiết để đọc tệp vào danh sách có thể sử dụng không?
Ismael Miguel

@IsmaelMiguel Ý bạn không phải là một phần của mã này, mà chỉ là một mã trợ giúp để chuyển đổi danh sách sang định dạng đúng?
Trình tối ưu hóa

Chính xác. Mã của bạn không đủ để chứng minh nó có thể sử dụng danh sách các từ làm ví dụ được cung cấp. Nhưng dù sao tôi cũng đã nâng cấp, tôi chỉ muốn mã trợ giúp đó.
Ismael Miguel

Bạn có thể thêm nó vào câu trả lời? Như một bản chỉnh sửa, trong một phần khác
Ismael Miguel

Chính xác. Đó là những gì tôi đang nói về! Hãy xem liệu bạn có thể tối ưu hóa nó hơn nữa hay không
Ismael Miguel

2

Java: 395

Điều này tạo thành một mẫu biểu thức chính quy dựa trên các chữ cái được phép cho mỗi số và sau đó xử lý một. * Ở cuối để khớp với bất kỳ ký tự nào sau đây.

Đây là phiên bản chơi gôn:

static ArrayList<String> f(String n,ArrayList<String> d){String[] k={"","","([A-Ca-c])","([D-Fd-f])","([G-Ig-i])","([J-Lj-l])","([M-Om-o])","([P-Sp-s])","([T-Vt-v])","([W-Zw-z])"};String r="";for(int i=0;i<n.length();++i)r+=k[n.charAt(i)-'0'];r += ".*";Pattern p=Pattern.compile(r);ArrayList<String> a=new ArrayList<String>();for(String w:dictionary)if(p.matcher(w).matches())a.add(w);return a;}

Và đây là phiên bản không có khả năng đọc

public static ArrayList<String> f(String phoneNumber, ArrayList<String> dictionary) {

    String[] KEY_VALUES = {"", "", "([A-Ca-c])", "([D-Fd-f])", "([G-Ig-i])",
                                            "([J-Lj-l])", "([M-Om-o])", "([P-Sp-s])",
                                            "([T-Vt-v])", "([W-Zw-z])"};

    String regex = "";
    for (int i = 0; i < phoneNumber.length(); ++i) {
        regex += KEY_VALUES[phoneNumber.charAt(i) - '0'];
    }
    regex += ".*";
    Pattern p = Pattern.compile(regex);
    ArrayList<String> answers = new ArrayList<String>();
    for (String word : dictionary) {
        if (p.matcher(word).matches()) {
            answers.add(word);
        }
    }
    return answers;
}

Mã của bạn đi ngược lại quy tắc số 7: "Biến, macro, biến toàn cục, hằng, lớp không chuẩn và tất cả các loại sắp xếp các giá trị khác bên trong hàm sẽ được coi là không hợp lệ." và nó đi ngược lại quy tắc số 3: "Bạn không thể sử dụng hoặc thực hiện lại các câu trả lời của người khác hoặc sao chép việc thực hiện của tôi.", nhưng trên mã của bạn thì điều đó gây tranh cãi. Và nó cũng đi ngược lại quy tắc 9: "Chức năng của bạn sẽ được đặt tên f".
Ismael Miguel

@IsmaelMiguel Rất tiếc. Quy tắc 7 có thể dễ dàng được sửa bằng cách di chuyển hằng số bên trong hàm. Tôi chỉ kéo nó ra ngoài chức năng cho phong cách lập trình tốt hơn. Quy tắc 9 cũng là một sửa chữa dễ dàng. Tôi thú nhận tôi đã không đọc câu trả lời của bạn, vì vậy tôi đã không cố tình sao chép nó. Tôi có thể xóa câu trả lời của mình nếu bạn nghĩ rằng nó quá gần với cuộc thi.
Brian J

Câu trả lời của bạn là ổn. Bạn có một lỗi trên mã của bạn. Trên hằng số cuối cùng ( ([W-Zw-z)]) nó phải là ([W-Zw-z]). Và trên Code-golf, bạn không phải lo lắng về phong cách lập trình và thực hành tốt: mã của bạn chỉ đơn giản là làm điều đó với các tham số bắt buộc. Nếu bạn kiểm tra câu trả lời của tôi, bạn sẽ thấy dòng này : $s=[2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz];. Đây là một 'tội ác' khủng khiếp trong PHP. Về cơ bản tôi đang buộc PHP chuyển đổi các hằng số không tồn tại thành các chuỗi. Điều này là hoàn toàn chấp nhận được. Bạn cũng sẽ thấy rằng tôi thậm chí không đặt biến $tthành một mảng trước khi sử dụng nó như vậy
Ismael Miguel

@IsmaelMiguel Bắt tốt về lỗi regex. Cảm ơn đã chỉ ra điều đó. Tôi sẽ cố gắng thực sự chơi golf vào ngày mai; có thể tìm thấy một số ví dụ Java trên trang web này.
Brian J

Tôi không phải là một lập trình viên java, nhưng tôi nói với bạn một số điều. Bạn có thể kiểm tra codegolf.stackexchange.com/questions/6671/ cấp để nhận một số mẹo. Các mẹo chung bao gồm xóa khoảng trắng vô dụng (dòng mới, dấu cách, tab), tên biến dài một chữ cái và làm tất cả những gì bạn có thể để giảm kích thước mã càng nhiều càng tốt.
Ismael Miguel

1

C # .NET 4.5 235

Điều này sẽ làm việc:

IEnumerable<string>F(string n,string d){IEnumerable<string>w=d.Split(null).ToList();string[]a={"","","abc","def","ghi", "jkl","mno","pqrs","tuv","wxyz"};foreach(var i in n){w=w.Where(x=>x.IndexOfAny(a[i-'0'].ToArray())>0);}return w;}

Chào mừng đến với PPCG. Mã của bạn sẽ hoạt động, nhưng bạn vẫn cần giảm nó nhiều hơn nữa. Bằng cách xóa tất cả các khoảng trắng vô dụng (khoảng trắng, tab, dòng mới), tôi đã quản lý để giảm mã của bạn xuống còn 167 byte. Mã này có thể được giảm nhiều hơn nữa, tôi chắc chắn về nó. Tôi khuyên bạn nên đọc codegolf.stackexchange.com/questions/173/ cấp để rút ngắn hơn nữa mã của bạn. Để giúp bạn một chút, danh sách từ là một chuỗi được phân tách bằng các dòng mới và dường như bạn cho rằng có thể sử dụng một foreachtừ trong đó. Nếu bạn mong đợi nó đã có IEnumerable, hãy bao gồm mã được sử dụng bên ngoài
Ismael Miguel

@IsmaelMiguel TY Tôi sẽ xem xét nó. Danh sách là một IEnumerable không có mã ngoài những gì tôi đã đăng.
Chaossie

Nếu bạn nhìn vào đặc tả của hàm, bạn sẽ thấy tham số thứ 2 cũng là một chuỗi. (Trích dẫn: "Bạn sẽ nhận được 1 số điện thoại trong một chuỗi và nội dung của tệp văn bản với một danh sách các từ (không giả sử một kiểu dòng mới cụ thể).") Và bạn có 1 khoảng trắng vô dụng trên avar của mình .
Ismael Miguel

Tôi đã nhận thấy những cải thiện cho câu hỏi của bạn và tôi đã đưa cho bạn một upvote. Nhưng bạn vẫn có thể lưu một byte trên avar của bạn . Nhưng tôi thực sự thấy những cải tiến đáng chú ý! Hãy tiếp tục phát huy.
Ismael Miguel

1

Python 2 (155 byte)

Cũng nên hoạt động trong Python 3 với các thay thế phù hợp ( string-> bytes, btiền tố trên chuỗi, v.v.).

Tôi không chắc nếu maketranscuộc gọi bên ngoài chức năng được coi là "công bằng"; nếu không, hàm là 134 byte với nó được di chuyển bên trong.

EDIT: Giảm một byte từ một giám sát ngu ngốc.

Với sự chuẩn bị maketrans, 67 byte:

from string import maketrans
t=maketrans('abcdefghijklmnopqrstuvwxyz','22233344455566677778889999')

def f(n,w):
    return[x for x in w.split()if x.lower().translate(t).startswith(n)]

Với maketranscơ thể, 134 byte:

from string import maketrans

def f(n,w):
    return[x for x in w.split()if x.lower().translate(maketrans('abcdefghijklmnopqrstuvwxyz','22233344455566677778889999')).startswith(n)]

importmaketranstrong cơ thể, 155 byte:

def f(n,w):
    return[x for x in w.split()if x.lower().translate(__import__('string').maketrans('abcdefghijklmnopqrstuvwxyz','22233344455566677778889999')).startswith(n)]

Cuộc gọi thử nghiệm:

print f('9999',open('words.txt','rt').read())

Đây maketranslà một phần của cơ thể chức năng. Bạn nên di chuyển nó. Tôi không biết nếu nó thậm chí có thể, nhưng bạn có thể thử trực tiếp sử dụng import. Tôi nghĩ rằng tôi đã nhìn thấy nó ở đâu đó ... Nhưng mã của bạn thực sự tốt đẹp!
Ismael Miguel

Bạn có nghĩa là để di chuyển nhập khẩu gọi vào cơ thể? Vâng, tôi nghĩ rằng điều đó cũng có thể được thực hiện.
criptych đứng cùng với Monica

Tôi đã suy nghĩ về t=(from stirng import maketrans)([...]). Tôi không biết nếu nó thậm chí có thể. Nhưng có lẽ bạn có thể sử dụng from string import as x t=x([...])mà tôi không chắc là có thể không: /
Ismael Miguel

Phiên bản chính xác là phiên bản cuối cùng. Nhưng theo tôi, câu trả lời là chấp nhận được. +1 cho __import__('string').maketran.
Ismael Miguel

Được rồi cảm ơn. Tôi đã xóa các câu trả lời không hợp lệ.
criptych đứng cùng với Monica

0

PHP 5.4+ (171 186-20% = 148,8 byte):

Vâng, đây là một câu trả lời khá lớn, nhưng tốt.

Tôi hy vọng điều này mang lại nhiều người để trả lời.

Hàm này hy vọng nội dung thô được đọc.

Đây là mã:

function f($_,$a){$s=[2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz];$a=preg_split('@\r\n|\r|\n@',$a);for($i=0;$c=$_[$i];++$i)foreach($a as$k=>$v)if(!strpos(1..$s[$c],$v[$i])||$t[$v[0]]++>4)unset($a[$k]);return$a;}

Điều này hoạt động bằng cách xác minh rằng chữ cái nằm trong danh sách các chữ cái được phép.

Ví dụ: đầu vào 36sẽ thực hiện để kiểm tra xem 1abccó chữ cái đầu tiên của từ đó không và 1defcó chữ cái thứ 2 không.

Tôi viết thêm 1để nó không kiểm tra xem thư có ở vị trí số 1 không (sẽ trả lại 0và sẽ đánh giá false). if(!strpos(1..$s[$c],$v[$i]))hoặc if(!strpos($c.$s[$c],$v[$i]))sẽ có tác dụng tương tự, nhưng thứ 1 gây nhầm lẫn nhiều hơn và tôi thích nó.

Không làm như vậy, sẽ loại bỏ các từ.

Không còn từ nào, nó trả về một mảng trống.

Để kiểm tra trực tuyến này, hãy truy cập http://writecodeonline.com/php/ và tạo một biến đơn giản với một từ cho dòng.

Một ví dụ có thể kiểm chứng:

function f($_,$a)
{
    $s=array(2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz);
    $a=preg_split('@\r\n|\r|\n@',$a);

    for($i=0;$c=$_[$i];++$i)
        foreach($a as$k=>$v)
            if(!strpos(1..$s[$c],$v[$i]) || $t[$v[0]]++>4)
                unset($a[$k]);
    return$a;
}

$lines=<<<WORDS
one
two
three
four
five
six
seven
eight
nine
ten
WORDS;

var_dump(f('36',$lines));

Điều này sẽ xuất ra:

array(1) {
    [3]=>
      string(4) "four"
}

Để làm việc trên các phiên bản php cũ hơn, thay thế $s=[2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz];bằng$s=array(2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz);


Đối với phần thưởng 20%:

Để giảm mã tôi chỉ cần thêm ||$t[$v[0]]++>4, nó kiểm tra số lần chữ cái đầu tiên được sử dụng.

Trong php, $tkhông cần xác định, giúp giảm một lượng lớn 37,2 byte.

Để xem hiệu ứng này, sử dụng biến sau đây làm đối số thứ 2:

$lines=<<<WORDS
one
two
three
four
five
six
seven
eight
nine
ten
twelve
time
tutor
test
truth
WORDS;
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.