soundex.sf 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #!/usr/bin/ruby
  2. #
  3. ## https://rosettacode.org/wiki/Soundex
  4. #
  5. func soundex(word, length=3) {
  6. # Uppercase the argument passed in to normalize it
  7. # and drop any non-alphabetic characters
  8. word.uc!.tr!('A-Z', '', 'cd')
  9. # Return if word does not contain 'A-Z'
  10. return(nil) if (word.is_empty)
  11. var firstLetter = word.char(0)
  12. # Replace letters with corresponding number values
  13. word.tr!('BFPV', '1', 's')
  14. word.tr!('CGJKQSXZ', '2', 's')
  15. word.tr!('DT', '3', 's')
  16. word.tr!('L', '4', 's')
  17. word.tr!('MN', '5', 's')
  18. word.tr!('R', '6', 's')
  19. # Discard the first letter
  20. word.slice!(1)
  21. # Remove A, E, H, I, O, U, W, and Y
  22. word.tr!('AEHIOUWY', '', 'd')
  23. # Return the soundex code
  24. firstLetter + (word.chars + length.of('0') -> first(length).join)
  25. }
  26. func testSoundex {
  27. # Key-value pairs of names and corresponding Soundex codes
  28. var sndx = Hash(
  29. "Euler" => "E4600",
  30. "Gauss" => "G2000",
  31. "Hilbert" => "H4163",
  32. "Knuth" => "K5300",
  33. "Lloyd" => "L3000",
  34. "Lukasieicz" => "L2220",
  35. 'fulkerson' => 'F4262',
  36. 'faulkersuhn' => 'F4262',
  37. 'fpfffffauhlkkersssin' => 'F4262',
  38. 'Aaeh' => 'A0000',
  39. )
  40. sndx.keys.sort.each { |name|
  41. var findSdx = soundex(name, 4)
  42. say "The soundex for #{name} should be #{sndx{name}} and is #{findSdx}"
  43. if (findSdx != sndx{name}) {
  44. die "\tHowever, that is incorrect!\n"
  45. }
  46. }
  47. }
  48. testSoundex()