Soundex is an algorithm for creating indices for words based on their pronunciation.



Task

The goal is for homophones to be encoded to the same representation so that they can be matched despite minor differences in spelling   (from the   soundex   Wikipedia article).

Caution

There is a major issue in many of the implementations concerning the separation of two consonants that have the same soundex code! According to the official Rules [[1]]. So check for instance if Ashcraft is coded to A-261.

 If a vowel (A, E, I, O, U) separates two consonants that have the same soundex code, the consonant to the right of the vowel is coded. Tymczak is coded as T-522 (T, 5 for the M, 2 for the C, Z ignored (see "Side-by-Side" rule above), 2 for the K). Since the vowel "A" separates the Z and K, the K is coded.
 If "H" or "W" separate two consonants that have the same soundex code, the consonant to the right of the vowel is not coded. Example: Ashcraft is coded A-261 (A, 2 for the S, C ignored, 6 for the R, 1 for the F). It is not coded A-226.


 
class Soundex
 
  method get_soundex(in_) static
    in = in_.upper()
    old_alphabet= 'AEIOUYHWBFPVCGJKQSXZDTLMNR'
    new_alphabet= '@@@@@@**111122222222334556'
    word=''
    loop i=1 for in.length()
      tmp_=in.substr(i, 1) /*obtain a character from word*/
      if tmp_.datatype('M')  then word=word||tmp_
    end
 
    value=word.strip.left(1)                       /*1st character is left alone.*/
    word=word.translate(new_alphabet, old_alphabet) /*define the current  word.   */
    prev=value.translate(new_alphabet, old_alphabet) /*   "    "  previous   "     */
 
    loop j=2  to word.length()                      /*process remainder of word.  */
      q=word.substr(j, 1)
      if q\==prev & q.datatype('W')  then do
	value=value || q;  prev=q
      end
      else if q=='@'  then prev=q
    end   /*j*/
 
    return value.left(4,0)                           /*padded value with zeroes.   */
 
  method main(args=String[]) static
 
    test=''; result_=''
    test['1']= "12346"         ;        result_['1']= '0000'
    test['4']= "4-H"           ;        result_['4']= 'H000'
    test['11']= "Ashcraft"      ;        result_['11']= 'A261'
    test['12']= "Ashcroft"      ;        result_['12']= 'A261'
    test['18']= "auerbach"      ;        result_['18']= 'A612'
    test['20']= "Baragwanath"   ;        result_['20']= 'B625'
    test['22']= "bar"           ;        result_['22']= 'B600'
    test['23']= "barre"         ;        result_['23']= 'B600'
    test['20']= "Baragwanath"   ;        result_['20']= 'B625'
    test['28']= "Burroughs"     ;        result_['28']= 'B620'
    test['29']= "Burrows"       ;        result_['29']= 'B620'
    test['30']= "C.I.A."        ;        result_['30']= 'C000'
    test['37']= "coöp"          ;        result_['37']= 'C100'
    test['43']= "D-day"         ;        result_['43']= 'D000'
    test['44']= "d jay"         ;        result_['44']= 'D200'
    test['45']= "de la Rosa"    ;        result_['45']= 'D462'
    test['46']= "Donnell"       ;        result_['46']= 'D540'
    test['47']= "Dracula"       ;        result_['47']= 'D624'
    test['48']= "Drakula"       ;        result_['48']= 'D624'
    test['49']= "Du Pont"       ;        result_['49']= 'D153'
    test['50']= "Ekzampul"      ;        result_['50']= 'E251'
    test['51']= "example"       ;        result_['51']= 'E251'
    test['55']= "Ellery"        ;        result_['55']= 'E460'
    test['59']= "Euler"         ;        result_['59']= 'E460'
    test['60']= "F.B.I."        ;        result_['60']= 'F000'
    test['70']= "Gauss"         ;        result_['70']= 'G200'
    test['71']= "Ghosh"         ;        result_['71']= 'G200'
    test['72']= "Gutierrez"     ;        result_['72']= 'G362'
    test['80']= "he"            ;        result_['80']= 'H000'
    test['81']= "Heilbronn"     ;        result_['81']= 'H416'
    test['84']= "Hilbert"       ;        result_['84']= 'H416'
    test['100']= "Jackson"       ;        result_['100']= 'J250'
    test['104']= "Johnny"        ;        result_['104']= 'J500'
    test['105']= "Jonny"         ;        result_['105']= 'J500'
    test['110']= "Kant"          ;        result_['110']= 'K530'
    test['116']= "Knuth"         ;        result_['116']= 'K530'
    test['120']= "Ladd"          ;        result_['120']= 'L300'
    test['124']= "Llyod"         ;        result_['124']= 'L300'
    test['125']= "Lee"           ;        result_['125']= 'L000'
    test['126']= "Lissajous"     ;        result_['126']= 'L222'
    test['128']= "Lukasiewicz"   ;        result_['128']= 'L222'
    test['130']= "naïve"         ;        result_['130']= 'N100'
    test['141']= "Miller"        ;        result_['141']= 'M460'
    test['143']= "Moses"         ;        result_['143']= 'M220'
    test['146']= "Moskowitz"     ;        result_['146']= 'M232'
    test['147']= "Moskovitz"     ;        result_['147']= 'M213'
    test['150']= "O'Conner"      ;        result_['150']= 'O256'
    test['151']= "O'Connor"      ;        result_['151']= 'O256'
    test['152']= "O'Hara"        ;        result_['152']= 'O600'
    test['153']= "O'Mally"       ;        result_['153']= 'O540'
    test['161']= "Peters"        ;        result_['161']= 'P362'
    test['162']= "Peterson"      ;        result_['162']= 'P362'
    test['165']= "Pfister"       ;        result_['165']= 'P236'
    test['180']= "R2-D2"         ;        result_['180']= 'R300'
    test['182']= "rÄ≈sumÅ∙"      ;        result_['182']= 'R250'
    test['184']= "Robert"        ;        result_['184']= 'R163'
    test['185']= "Rupert"        ;        result_['185']= 'R163'
    test['187']= "Rubin"         ;        result_['187']= 'R150'
    test['191']= "Soundex"       ;        result_['191']= 'S532'
    test['192']= "sownteks"      ;        result_['192']= 'S532'
    test['199']= "Swhgler"       ;        result_['199']= 'S460'
    test['202']= "'til"          ;        result_['202']= 'T400'
    test['208']= "Tymczak"       ;        result_['208']= 'T522'
    test['216']= "Uhrbach"       ;        result_['216']= 'U612'
    test['221']= "Van de Graaff" ;        result_['221']= 'V532'
    test['222']= "VanDeusen"     ;        result_['222']= 'V532'
    test['230']= "Washington"    ;        result_['230']= 'W252'
    test['233']= "Wheaton"       ;        result_['233']= 'W350'
    test['234']= "Williams"      ;        result_['234']= 'W452'
    test['236']= "Woolcock"      ;        result_['236']= 'W422'
 
    loop i over test
      say test[i].left(10) get_soundex(test[i]) '=' result_[i]
    end
 