Một kỷ niệm để ghi nhớ 23940


19

Các hệ thống chính là một ghi nhớ thiết bị để chuyển đổi số thành chữ để họ có thể được ghi nhớ dễ dàng hơn.

Nó dựa trên cách các từ phát âm theo ngữ âm, nhưng để mọi thứ đơn giản cho thử thách, chúng ta sẽ chỉ quan tâm đến cách các từ được đánh vần. Điều này có nghĩa là sẽ có một số chuyển đổi không chính xác, nhưng không sao.

Để chuyển đổi một số thành một từ bằng cách sử dụng hệ thống chính được đơn giản hóa của chúng tôi:

  • Thay thế 0bằng shoặc z. (Một số có thể svà một số có thể z. Cùng đi bên dưới.)
  • Thay thế từng 1thay dhay th.
  • Thay thế 2bằng n.
  • Thay thế 3bằng m.
  • Thay thế 4bằng r.
  • Thay thế 5bằng l.
  • Thay thế từng 6jhay shhay ch.
  • Thay thế từng 7khay chay ghay q.
  • Thay thế từng 8fhay v.
  • Thay thế từng 9phay b.
  • Thêm các chữ cái aehiouwxyở bất cứ đâu với số lượng bất kỳ để tạo ra một từ tiếng Anh thực sự, nếu có thể .
    Ngoại lệ duy nhất là hcó thể không được chèn sau một shoặc c.

Số thực sự có thể là bất kỳ chuỗi nào trong các chữ số 0-9 (không có số thập phân hoặc dấu phẩy hoặc dấu).
Từ chỉ có thể chứa các chữ cái viết thường az.

Ví dụ

Số 32phải được chuyển đổi thành ?m?n?, trong đó ?đại diện cho bất kỳ chuỗi hữu hạn nào được tạo từ các chữ cái aehiouwxy(một chuỗi từ monoid miễn phí nếu bạn thích). Có nhiều cách điều này có thể được làm thành một từ tiếng Anh thật: mane, moon, yeomanvv

Số 05có thể được chuyển đổi thành ?s?l?hoặc ?z?l?. Một số khả năng là easily, hassle, và hazel. Từ shawlnày không được phép vì hcó thể không được đặt sau s; nó sẽ được đọc không chính xác như là 65.

Thử thách

Viết chương trình hoặc hàm lấy một chuỗi các chữ số 0-9 và tìm tất cả các từ mà nó có thể được chuyển đổi thành sử dụng hệ thống ghi nhớ chính được đơn giản hóa.

Chương trình của bạn có quyền truy cập vào tệp văn bản danh sách từ xác định tất cả các từ tiếng Anh "thực" là gì. Có một từ az chữ thường trên mỗi dòng của tệp này và bạn có thể tùy ý giả sử nó có một dòng mới. Dưới đây là danh sách các từ thực bạn có thể sử dụng để kiểm tra. Bạn có thể giả sử tệp danh sách từ này được gọi f(hoặc một cái gì đó dài hơn) và nằm trong bất kỳ thư mục thuận tiện.

Đối với hình phạt 35 byte (thêm 35 vào điểm số của bạn), bạn có thể giả sử danh sách từ đã được tải vào một biến dưới dạng danh sách các chuỗi. Điều này chủ yếu dành cho các ngôn ngữ không thể đọc tệp, nhưng bất kỳ nội dung gửi nào cũng có thể tận dụng lợi thế của nó.

Chương trình của bạn phải xuất tất cả các từ trong danh sách từ mà số đầu vào có thể được chuyển đổi thành. Chúng nên được in ra thiết bị xuất chuẩn (hoặc tương tự), mỗi dòng trên một dòng (với một dòng mới tùy chọn) hoặc chúng có thể được trả về dưới dạng danh sách các chuỗi nếu bạn chọn viết hàm. Danh sách từ không nhất thiết phải được sắp xếp theo thứ tự chữ cái và đầu ra không cần phải là một trong hai.

Nếu không có từ nào có thể thì đầu ra (hoặc danh sách) sẽ trống. Đầu ra cũng trống nếu chuỗi trống là đầu vào.

Đưa đầu vào qua stdin, dòng lệnh hoặc làm đối số chuỗi cho hàm. Danh sách từ, hoặc tên tệp của nó, không nên là một phần của đầu vào, chỉ là chuỗi chữ số.

Bạn chỉ kết hợp các từ đơn trong danh sách từ, không phải các chuỗi từ. Từ noonnày có thể là một trong những kết quả cho 22, nhưng chuỗi từ no onesẽ không.

Các trường hợp thử nghiệm

Giả sử đây là danh sách từ:

stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
zdnmrlshchvb
sthnmrlchgvb
shthnmrlchgvb
bob
pop
bop
bopy
boppy

Đầu vào 0123456789sẽ cung cấp cho tất cả các từ dài ngoại trừ zdnmrlshchvbshthnmrlchgvb:

stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
sthnmrlchgvb

Đầu vào 99sẽ cho:

bob
pop
bop
bopy

(Các từ đầu ra có thể theo thứ tự bất kỳ.)

Chấm điểm

Đệ trình ngắn nhất tính bằng byte thắng. Tiebreaker đi đến trình gửi đăng đầu tiên.

Trang web liên quan tiện lợi: numzi.com .


1
Bạn đã tình cờ có được ý tưởng cho thử thách này từ video này ? Bởi vì tôi thực sự chỉ xem ngày hôm qua. : P
Doorknob

1
@Doorknob Không phải video đó, mà là anh chàng đó. Cách đây nhiều năm, tôi đã được nghe một trong những bài giảng tuyệt vời của anh ấy . Anh ấy hơi zany nhưng thực sự gọn gàng. :)
Sở thích của Calvin

1
Lưu ý cho những người quan tâm đến việc sử dụng hệ thống chính ghi nhớ trong cuộc sống thực: đó chỉ là âm thanh quan trọng, không phải là chính tả. Vì vậy, "c", trong khi được liệt kê ở đây có nghĩa là 7, thực sự có thể có nghĩa là 0 nếu trong từ này được phát âm với âm "s" (như trong "ace" = 0). Tuy nhiên, tôi chắc chắn rằng OP đã đơn giản hóa thử thách, vì một từ điển với ngữ âm đầy đủ khó hơn nhiều so với một danh sách từ đơn giản. Ồ, và một kết xuất của 23940 là "số".
ErikE

@ErikE Tôi nói rằng chúng tôi đang sử dụng một phiên bản dựa trên chính tả trong câu thứ hai của bài đăng ...
Sở thích của Calvin

Bây giờ tôi thấy điều đó, mặc dù tôi đã bỏ lỡ nó - nhưng dường như tôi vẫn giải thích rằng lời giải thích của bạn có thể được bổ sung thêm một chút nữa và một hoặc hai ví dụ được cung cấp.
ErikE

Câu trả lời:


6

Perl, 87 84

open A,f;"@ARGV"eq s/[cs]h/j/gr=~y/stnmrljkfpzdcgqvb\0-z/0-90177789/dr&&print for<A>

Đưa đầu vào vào làm tham số dòng lệnh:

$perl m.pl 23940

Có thể được thực hiện ngắn hơn một chút nếu danh sách từ sẽ được cho phép trên đầu vào tiêu chuẩn:

$perl -lnE'INIT{$;=pop}$;eq s/[cs]h/j/gr=~y/stnmrljkfpzdcgqvba-z/0-90177789/dr&&say' 99 <f

Anghĩa là open A,fgì?
feerum 23/2/2015

@feersum Một trình xử lý tệp được sử dụng sau này để đọc tệp ( <A>).
nutki 23/2/2015

4

Python 2, 215 208 byte

Giải pháp Python này xây dựng một regex từ các phần được lập chỉ mục bởi đối số dòng lệnh, sau đó kiểm tra từng từ với regex (khá lớn) đó.

import re,sys
a='[sz] (d|th?) n m r l (j|sh|ch) [kcgq] [fv] [pb]'.split()
b=z='((?<![sc])h|[aeiouwxy])*'
for i in sys.argv[1]:b+=a[int(i)]+z
for d in open('f'):
 d=d.strip()
 if re.match('^'+b+'$',d):print d

Nguồn gốc trước khi khai thác:

import re,sys
regexbits = '[sz] (d|th?) n m r l (j|sh|ch) [kcgq] [fv] [pb]'.split()

regex = other = '((?<![sc])h|[aeiouwxy])*'
for i in sys.argv[1] :
    regex += regexbits[int(i)] + other
print regex     # DEBUG

for word in open('f'):
    word = word.strip()
    if re.match('^'+regex+'$', word) :
        print word

Ví dụ: regex cho bài kiểm tra 99là:

^((?<![sc])h|[aeiouwxy])*[pb]((?<![sc])h|[aeiouwxy])*[pb]((?<![sc])h|[aeiouwxy])*$

Các (?<![sc])hbit là một "cái nhìn đằng sau khẳng định tiêu cực" thành phần đảm bảo một hkhông theo một shoặc ctrong các phần phụ nói chung.

Cảm ơn Calvin. Thử thách này đã thúc đẩy tôi cải thiện các kỹ năng regex rỉ sét của mình.


b=c='((?<![sc])h|[aeiouwxy])*'sẽ tiết kiệm hai byte.
matjoyce 23/2/2015

t|th -> th?tiết kiệm một byte
Sp3000

Bạn có thể tránh bản đồ bằng cách lấy int (i) trực tiếp.
xnor

Cảm ơn matjoyce, Sp3000 và xnor cho những lời khuyên chơi golf hữu ích. Bây giờ chỉnh sửa với các đề xuất thực hiện.
Logic Knight

2

Trăn 3, 170

import sys,re
t=str.maketrans('sztdnmrljkcgqfvpb','00112345677778899','aehiouwxy\n')
for s in open('f'):re.sub('sh|ch','j',s).translate(t)!=sys.argv[1] or print(s,end='')

Phiên bản dễ đọc:

import sys, re

table = str.maketrans('sztdnmrljkcgqfvpb', '00112345677778899', 'aehiouwxy\n')

for line in open('f'):
    line = re.sub('sh|ch', 'j', line)
    if line.translate(table) == sys.argv[1]:
        print(line, end='')

Mã này sử dụng thực tế thlà dư thừa (vì nó ánh xạ tới cùng một số với thlà một ký tự đệm).

Hàm tĩnh maketranstạo một bảng ánh xạ các ký tự của đối số thứ nhất sang các đối số thứ hai và các ký tự của đối số thứ ba tới None(điều này sẽ dẫn đến các ký tự đó bị xóa).

Mã cuối cùng có thể được thực hiện ngắn hơn một vài byte bằng cách tạo bảng dưới dạng đối số trực tiếp translate.


Bạn có thể lưu một vài byte bằng cách sử dụng input () thay vì sys.argv [1] và '[sc] h' cho biểu thức thông thường của bạn.
swstephe

@swstephe. Cảm ơn phản hồi, nhưng tôi không nghĩ input()có thể được sử dụng, vì nó được gọi trong vòng lặp. Ngoài ra, biểu thức chính được đề xuất của bạn có cùng độ dài với biểu thức tôi đã sử dụng (5 byte).
ekhumoro

Tôi đã suy nghĩ một cái gì đó như "z, t = input (), str.maketrans ...", sau đó chỉ sử dụng z thay vì sys.argv. Được rồi, tôi nghĩ regex của tôi là 4 byte.
bước vào

2

sed, dán, grep, cắt - 109

sed -e 's/[sc]h/6/g;s/[aehiouwxy]//g;y/sztdnmrljkcqgfvpb/00112345677778899/' w|paste w -|grep " $1$"|cut -f1

Lấy một tập tin "w", chuyển đổi từng từ thành số của nó, dán lại thành bản gốc, grep cho số đó và trả lại từ phù hợp. Lưu ý rằng khoảng trắng sau trích dẫn sau grep là một tab, dán dấu phân cách mặc định.

Tôi biết Perl đang đi trước, chỉ muốn một phiên bản shell tốt hơn làm ví dụ.

Ồ vâng, phần $ 1 có nghĩa là phần này được cho là được chạy từ tập lệnh shell, (hầu hết các shell nên hoạt động), vì vậy nó cần một đối số dòng lệnh.


Tôi đã suy nghĩ về việc chuyển đổi câu trả lời của mình thành thuần túy sedđể tránh mở và @ARGVchi phí của Perl , nhưng việc thiếu phạm vi và xóa các chức năng trong việc y///phá vỡ nó. Đáng ngạc nhiên mặc dù mặc dù không có biến nào bạn có thể thể hiện logic trực tiếp sed. Đây là giải pháp 92 của tôi:sed -e'h;s/[sc]h/6/g;y/sztdnmrljkcqgfvpb/00112345677778899/;s/[^0-9]*//g;T;s/^$1$//;x;t;d' f
nutki

Nó dường như làm việc, tại sao không làm cho nó một câu trả lời?
swstephe

1

Bash + coreutils, 216

sed -n "$(sed 's/[aeiouwxy]//g
:l
s/\([^sc]\)h/\1/g
tl'<w|grep -nf <(eval printf '%s\\n' `sed 's/0/{s,z}/g
s/1/{t,th,d}/g
y/2345/nmrl/
s/6/{j,sh,ch}/g
s/7/{k,c,g,q}/g
s/8/{f,v}/g
s/9/{p,b}/g'<<<$1`)|sed s/:.\*/p/)" w
  • Danh sách từ trong một tập tin gọi là w
  • Trong cùng sedthay thế các chữ số với sự thay thế có thể của họ
  • Việc eval printfsử dụng mở rộng nẹp vỏ để mở rộng tất cả các thay thế có thể
  • Dòng thứ hai sedtrên dòng thứ 1 sẽ xóa aeiouwxyh(khi không đi trước [sc]) khỏi danh sách từ
  • Grep in ra tất cả các trận đấu, với số dòng
  • Vì chúng tôi đã loại bỏ aeiouwxyhtừ danh sách từ, cuối cùng sedbiến kết quả của grep (số dòng của mỗi trận đấu) sang một sedbiểu thức khác , được xử lý bởi ngoài cùng sedđể tiết lộ tất cả các từ có thể từ danh sách từ.

Đầu ra:

Tệp danh sách từ được chỉ định là đối số dòng lệnh, theo sau là số để ghi nhớ:

ubuntu@ubuntu:~$ ./numzi.sh 99
bob
pop
bop
bopy
boppy
$ ./numzi.sh 0123456789
stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
sthnmrlchgvb
$ 

@ Calvin'sHob sở thích Xong.
Chấn thương kỹ thuật số

Có vẻ như bạn quên cập nhật ví dụ của mình.
Sở thích của Calvin

-1

tr, sed, grep, xargs, sh, 77

tr 0123456789 ztnmrljkfp|sed 's/ */[aehiouwxy]*/g'|xargs sh -c 'grep -x $0 f'

Yêu cầu số trong stdin và danh sách từ nên được lưu trữ trong tệp f.

Không sử dụng tất cả các thay thế (1 sẽ luôn là z, 7 sẽ luôn là k), vì vậy nó có thể được gọi là một giải pháp lười biếng, nhưng nó tìm thấy ít nhất một lần ghi nhớ cho 95 số trong [1-100].


3
Câu hỏi yêu cầu bạn tìm thấy tất cả các từ phù hợp trong danh sách từ. Bạn không thể 1luôn luôn zhoặc 7luôn luôn k. Điều này không hợp lệ.
Sở thích của Calvin

Đủ công bằng, tôi sẽ xóa câu trả lời của tôi.
pgy
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.