Chức năng Soundex


13

Viết hàm ngắn nhất để tạo mã Soundex của Mỹ cho họ chỉ chứa các chữ cái in hoa AZ. Hàm của bạn phải tạo đầu ra phù hợp với tất cả các ví dụ của trang được liên kết (được đưa ra dưới đây), mặc dù nó không cần và không nên xóa các tiền tố. Hyphens trong đầu ra là tùy chọn. Chúc vui vẻ!

Lưu ý: Bạn không được sử dụng soundex()hàm có trong PHP hoặc tương đương trong các ngôn ngữ lập trình khác.

Các ví dụ:

WASHINGTON W-252
LEE L-000
GUTIERREZ G-362
PFISTER P-236 
JACKSON J-250 
TYMCZAK T-522
VANDEUSEN V-532
ASHCRAFT A-261

Câu trả lời:


4

Perl, 143 150 ký tự

sub f{$_="$_[0]000";/./;$t=$&;s/(?<=.)[HW]//g;s/[BFPV]+/1/g;s/[CGJKQSXZ]+/2/g;s/[DT]+/3/g;s/L+/4/g;s/[MN]+/5/g;s/R+/6/g;s/(?<=.)\D//g;/.(...)/;"$t$1"}

Giải pháp này chỉ chứa các biểu thức chính quy được áp dụng lần lượt. Thật không may, tôi đã không tìm thấy một đại diện ngắn hơn với một vòng lặp vì vậy tôi đã mã hóa cứng tất cả các cuộc gọi vào kịch bản.

Cùng một phiên bản nhưng dễ đọc hơn một chút:

sub f{
  $_="$_[0]000";        # take first argument and append "000"
  /./;$t=$&;            # save first char to variable $t
  s/(?<=.)[HW]//g;      # remove and H or W but not the first one
  s/[BFPV]+/1/g;        # replace one or more BFPV by 1
  s/[CGJKQSXZ]+/2/g;    # replace one or more CGJKQSXZ by 2
  s/[DT]+/3/g;          # replace one or more DT by 3
  s/L+/4/g;             # replace one or more L by 4
  s/[MN]+/5/g;          # replace one or more MN by 5
  s/R+/6/g;             # replace one or more R by 6
  s/(?<=.)\D//g;        # remove and non-digit from the result but not the first char
  /.(...)/;"$t$1"       # take $t plus the characters 2 to 4 from result
}

Chỉnh sửa 1: Bây giờ giải pháp được viết dưới dạng hàm. Cái trước đó là đọc / viết từ / đến STDIN / STDOUT. Tôi mất bảy ký tự để làm việc xung quanh đó.


2

eTeX, 377.

\let\E\expandafter
\def\x#1;#2#3{\def\s##1#2{##1\s#3}\edef\t{\s#1\iffalse#2\fi}\E\x\t;}
\def\a[#1#2]{\if{{\fi\uppercase{\x#1,#2};B1F1P1V1C2G2J2K2Q2S2X2Z2D3T3L4M5N5R6A7E7I7O7U7
    H{}W{}Y{}{11}1{22}2{33}3{44}4{55}5{66}6{{}\toks0\bgroup}!}\E\$\t0000!#1}}
\def\$#1,#2{\if#1#2\relax\E\%\else\E\%\E#2\fi}
\def\%{\catcode`79 \scantokens\bgroup\^}
\def\^#1#2#3#4!#5{\message{#5#1#2#3}\end}
\E\a

Chạy như etex filename.tex [Ashcraft].


2

Con trăn, 274 285 241 235 225 200 190 183 179 174 166 161

- Đã sửa lỗi mệnh đề cuối (H hoặc W làm dấu tách phụ âm). Ashcraft bây giờ có kết quả đúng. - Made dict nhỏ - Formating là nhỏ hơn (không yêu cầu python 2.6) - tìm kiếm dict Đơn giản hơn cho k - Giá trị nguyên âm đã thay đổi từ '*'đến ''.appendđến +=[i] - Danh sách hiểu FTW - gọi Removed để upper: D

Tôi không thể chơi gôn nữa. Thật ra tôi đã làm. Bây giờ tôi nghĩ rằng tôi không thể chơi gôn nữa! Đã làm lại ...

Sử dụng bảng dịch:

def f(n):z=n.translate(65*'_'+'#123#12_#22455#12623#1_2#2'+165*'_').replace('_','');return n[0]+(''.join(('',j)[j>'#']for i,j in zip(z[0]+z,z)if i!=j)+'000')[:3]

Mã hiểu danh sách cũ:

x=dict(zip('CGJKQSXZDTLMNRBFPV','2'*8+'3345561111'))
def f(n):z=[x.get(i,'')for i in n if i not in'HW'];return n[0]+(''.join(j for i,j in zip([x.get(n[0])]+z,z)if i!=j)+'000')[:3]

Mã cũ:

x=dict(zip('CGJKQSXZDTLMNRBFPV','2'*8+'3345561111'))
def f(n):
 e=a=[];k=n[0]in x
 for i in[x.get(i,'')for i in n.upper()if i not in'HW']:
  if i!=a:e+=[i]
  a=i
 return n[0]+(''.join(e)+'000')[k:3+k]

Kiểm tra:

[f(i) for i in ['WASHINGTON', 'LEE', 'GUTIERREZ', 'PFSTER', 'JACKSON',
                'TYMCZAK', 'VANDEUSEN', 'ASHCRAFT']]

Cung cấp:

['W252', 'L000', 'G362', 'P236', 'J250', 'T522', 'V532', 'A261']

Như mong đợi.


Tuyệt quá. Bạn không cần phải chuyển đổi đầu vào thành chữ hoa; bạn có thể cho rằng nó đã được.
Vui lòng khởi động

»Tôi không thể chơi gôn thêm« những từ đó hiếm khi thích hợp :-)
Joey

@Joey Python không phải là ngôn ngữ tốt nhất cho môn đánh gôn ... Nếu chỉ có nó là regex hạng nhất như Perl ...
JBernardo

Nó bị định danh quá dài nhiều hơn, imho. Thông thường tôi có thể đánh bại Python bằng PowerShell, nhưng việc hiểu danh sách rất khó để đánh bại.
Joey

@Joey Bây giờ bạn sẽ phải làm việc nhiều hơn một chút để đánh bại Python bằng PowerShell: P
JBernardo

2

Perl, 110

sub f{$_="$_[0]000";/./;$t=$&;s/(?<=.)[HW]//g;y/A-Z/:123:12_:22455:12623:1_2:2/s;s/(?<=.)\D//g;/.(...)/;$t.$1}

Tôi đang sử dụng giải pháp của Howard với bảng dịch của tôi ( y/A-Z/table/sthay vì mọi s/[ABC]+/N/g)


2

J - 99

{.,([:-.&' '@":3{.!.0[:(#~1,}.~:}:)^:#,@(;:@]>:@I.@:(e.&>"0 _~)[#~e.))&'BFPV CGJKQSXZ DT L MN R'@}.

Kiểm tra:

  sndx=: {.,([:-.&' '@":3{.!.0[:(#~1,}.~:}:)^:#,@(;:@]>:@I.@:(e.&>"0 _~)[#~e.))&'BFPV CGJKQSXZ DT L MN R'@}.
  test=: ;: 'JACKSON PFISTER TYMCZAK GUTIERREZ ASHCRAFT ASHCROFT VANDEUSEN ROBERT RUPERT RUBIN WASHINGTON LEE'
  (,. sndx&.>) test


+-------+-------+-------+---------+--------+--------+---------+------+------+-----+----------+----+
|JACKSON|PFISTER|TYMCZAK|GUTIERREZ|ASHCRAFT|ASHCROFT|VANDEUSEN|ROBERT|RUPERT|RUBIN|WASHINGTON|LEE |
+-------+-------+-------+---------+--------+--------+---------+------+------+-----+----------+----+
|J250   |P123   |T520   |G362     |A261    |A261    |V532     |R163  |R163  |R150 |W252      |L000|
+-------+-------+-------+---------+--------+--------+---------+------+------+-----+----------+----+

1

GolfScript (74 ký tự)

Việc triển khai này sử dụng một chuỗi ma thuật có các ký tự không in được. Ở xxddạng đầu ra, nó

0000000: 7b2e 313c 5c5b 7b36 3326 2741 4c15 c252  {.1<\[{63&'AL..R
0000010: d056 4c1e 8227 3235 3662 6173 6520 3862  .VL..'256base 8b
0000020: 6173 653d 7d25 7b2e 373d 2432 243d 7b3b  ase=}%{.7=$2$={;
0000030: 7d2a 7d2a 5d31 3e31 2c2d 5b30 2e2e 5d2b  }*}*]1>1,-[0..]+
0000040: 333c 7b2b 7d2f 7d3a 533b                 3<{+}/}:S;

Không sử dụng các thay đổi cơ sở để nén danh sách các số 3 bit, nó sẽ là

{.1<\[{63&[1 0 1 2 3 0 1 2 7 0 2 2 4 5 5 0 1 2 6 2 3 0 1 7 2 0 2]=}%{.7=$2$={;}*}*]1>1,-[0..]+3<{+}/}:S;

Bài kiểm tra trực tuyến

Về cơ bản, đó là một loạt các vòng lặp nhàm chán, nhưng có một mẹo thú vị:

.7=$2$=

Đây là một nếp gấp với mục đích xử lý hai chữ cái. Các chữ cái liền kề có cùng mã được hợp nhất thành một đơn vị, ngay cả khi được phân tách bằng một Hhoặc a W. Nhưng điều này không thể được thực hiện một cách tầm thường bằng cách loại bỏ tất cả Hs và Ws khỏi chuỗi, bởi vì trong trường hợp (không thể thừa nhận trong cuộc sống thực, nhưng không loại trừ trường hợp cụ thể) rằng chữ cái đầu tiên là Hhoặc Wchữ cái thứ hai là phụ âm , chúng ta cần không bỏ qua phụ âm đó khi xóa chữ cái đầu tiên. (Tôi đã thêm một trường hợp thử nghiệm WMsẽ cung cấp W500để kiểm tra điều này).

Vì vậy, cách tôi xử lý đó là thực hiện một lần và xóa từng chữ cái khác với lần đầu tiên (một tác dụng phụ thuận tiện của việc sử dụng nếp gấp) bằng với lần trước hoặc bằng 7, mã nội bộ cho HW.

Cho abtrên ngăn xếp, cách ngây thơ để kiểm tra xem a == b || b == 7sẽ là

.2$=1$7=+

Nhưng có tiết kiệm 2 ký tự bằng cách sử dụng bản sao từ ngăn xếp được tính toán:

.7=$

Nếu bbằng 7thì nó sao chép a; nếu không thì nó sao chép b. Vì vậy, bằng sau đó so sánh với achúng ta có được một giá trị truthy đảm bảo nếu b7không phụ thuộc vào giá trị của a. (Trước khi bất kỳ trẻ em nào cân nhắc, GolfScript không có NaN).


0

PowerShell, 150 161

Lần thử đầu tiên và tôi chắc chắn rằng có thể chơi golf nhiều hơn một chút.

filter s{$s=-join$_[1..9]
1..6+'$1','',$_[0]|%{$s=$s-replace('2[bfpv]2[cgjkqsxz]2[dt]2l2[mn]2r2(.)\1+2\D|^.2^'-split2)[++$a],$_}
-join"${s}000"[0..3]}

Hoạt động chính xác với các trường hợp thử nghiệm từ cả trang được liên kết và bài viết Wikipedia:

Jackson, Pfister, Tymczak, Gutierrez, Ashcraft, Ashcroft, VanDeusen, Robert, Rupert, Rubin, Washington, Lee


0

Ruby 140

Tôi đang sử dụng Ruby 2.0, nhưng tôi nghĩ nó cũng hoạt động với các phiên bản cũ hơn.

def f s
a=s[i=0]
%w(HW BFPV CGJKQSXZ DT L MN R).each{|x|s.gsub!(/[#{x}]+/){i>0&&$`[0]?i: ''};i+=1}
a+(s[1..-1].gsub(/\D/,'')+'000')[0,3]
end

Thí dụ:

puts f "PFISTER" => P236


0

APL (83)

{(⊃⍵),,/⍕¨3↑0~⍨1↓K/⍨~K=1⌽K←0,⍨{7|+/' '=S↑⍨⍵⍳⍨S←' BFPV CGJKQSXZ DT L MN R'}¨⍵~'HW'}⍞
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.