2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,2 +1,11 @@
|
|||
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 [[wp:soundex|the WP article]]).
|
||||
<br><br>
|
||||
|
||||
;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 [[https://www.archives.gov/research/census/soundex.html]]. 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.
|
||||
|
|
|
|||
39
Task/Soundex/Elixir/soundex.elixir
Normal file
39
Task/Soundex/Elixir/soundex.elixir
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
defmodule Soundex do
|
||||
def soundex([]), do: []
|
||||
def soundex(str) do
|
||||
[head|tail] = String.upcase(str) |> to_char_list
|
||||
[head | isoundex(tail, [], todigit(head))]
|
||||
end
|
||||
|
||||
defp isoundex([], acc, _) do
|
||||
case length(acc) do
|
||||
n when n == 3 -> Enum.reverse(acc)
|
||||
n when n < 3 -> isoundex([], [?0 | acc], :ignore)
|
||||
n when n > 3 -> isoundex([], Enum.slice(acc, n-3, n), :ignore)
|
||||
end
|
||||
end
|
||||
defp isoundex([head|tail], acc, lastn) do
|
||||
dig = todigit(head)
|
||||
if dig != ?0 and dig != lastn do
|
||||
isoundex(tail, [dig | acc], dig)
|
||||
else
|
||||
case head do
|
||||
?H -> isoundex(tail, acc, lastn)
|
||||
?W -> isoundex(tail, acc, lastn)
|
||||
n when n in ?A..?Z -> isoundex(tail, acc, dig)
|
||||
_ -> isoundex(tail, acc, lastn) # This clause handles non alpha characters
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@digits '01230120022455012623010202'
|
||||
defp todigit(chr) do
|
||||
if chr in ?A..?Z, do: Enum.at(@digits, chr - ?A),
|
||||
else: ?0 # Treat non alpha characters as a vowel
|
||||
end
|
||||
end
|
||||
|
||||
IO.puts Soundex.soundex("Soundex")
|
||||
IO.puts Soundex.soundex("Example")
|
||||
IO.puts Soundex.soundex("Sownteks")
|
||||
IO.puts Soundex.soundex("Ekzampul")
|
||||
42
Task/Soundex/JavaScript/soundex-2.js
Normal file
42
Task/Soundex/JavaScript/soundex-2.js
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
function soundex(t) {
|
||||
t = t.toUpperCase().replace(/[^A-Z]/g, '');
|
||||
return (t[0] || '0') + t.replace(/[HW]/g, '')
|
||||
.replace(/[BFPV]/g, '1')
|
||||
.replace(/[CGJKQSXZ]/g, '2')
|
||||
.replace(/[DT]/g, '3')
|
||||
.replace(/[L]/g, '4')
|
||||
.replace(/[MN]/g, '5')
|
||||
.replace(/[R]/g, '6')
|
||||
.replace(/(.)\1+/g, '$1')
|
||||
.substr(1)
|
||||
.replace(/[AEOIUHWY]/g, '')
|
||||
.concat('000')
|
||||
.substr(0, 3);
|
||||
}
|
||||
|
||||
// tests
|
||||
[ ["Example", "E251"], ["Sownteks", "S532"], ["Lloyd", "L300"], ["12346", "0000"],
|
||||
["4-H", "H000"], ["Ashcraft", "A261"], ["Ashcroft", "A261"], ["auerbach", "A612"],
|
||||
["bar", "B600"], ["barre", "B600"], ["Baragwanath", "B625"], ["Burroughs", "B620"],
|
||||
["Burrows", "B620"], ["C.I.A.", "C000"], ["coöp", "C100"], ["D-day", "D000"],
|
||||
["d jay", "D200"], ["de la Rosa", "D462"], ["Donnell", "D540"], ["Dracula", "D624"],
|
||||
["Drakula", "D624"], ["Du Pont", "D153"], ["Ekzampul", "E251"], ["example", "E251"],
|
||||
["Ellery", "E460"], ["Euler", "E460"], ["F.B.I.", "F000"], ["Gauss", "G200"],
|
||||
["Ghosh", "G200"], ["Gutierrez", "G362"], ["he", "H000"], ["Heilbronn", "H416"],
|
||||
["Hilbert", "H416"], ["Jackson", "J250"], ["Johnny", "J500"], ["Jonny", "J500"],
|
||||
["Kant", "K530"], ["Knuth", "K530"], ["Ladd", "L300"], ["Lloyd", "L300"],
|
||||
["Lee", "L000"], ["Lissajous", "L222"], ["Lukasiewicz", "L222"], ["naïve", "N100"],
|
||||
["Miller", "M460"], ["Moses", "M220"], ["Moskowitz", "M232"], ["Moskovitz", "M213"],
|
||||
["O'Conner", "O256"], ["O'Connor", "O256"], ["O'Hara", "O600"], ["O'Mally", "O540"],
|
||||
["Peters", "P362"], ["Peterson", "P362"], ["Pfister", "P236"], ["R2-D2", "R300"],
|
||||
["rÄ≈sumÅ∙", "R250"], ["Robert", "R163"], ["Rupert", "R163"], ["Rubin", "R150"],
|
||||
["Soundex", "S532"], ["sownteks", "S532"], ["Swhgler", "S460"], ["'til", "T400"],
|
||||
["Tymczak", "T522"], ["Uhrbach", "U612"], ["Van de Graaff", "V532"],
|
||||
["VanDeusen", "V532"], ["Washington", "W252"], ["Wheaton", "W350"],
|
||||
["Williams", "W452"], ["Woolcock", "W422"]
|
||||
].forEach(function(v) {
|
||||
var a = v[0], t = v[1], d = soundex(a);
|
||||
if (d !== t) {
|
||||
console.log('soundex("' + a + '") was ' + d + ' should be ' + t);
|
||||
}
|
||||
});
|
||||
129
Task/Soundex/JavaScript/soundex-3.js
Normal file
129
Task/Soundex/JavaScript/soundex-3.js
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// Simple Soundex or NARA Soundex (if blnNara = true)
|
||||
|
||||
// soundex :: Bool -> String -> String
|
||||
const soundex = (blnNara, name) => {
|
||||
|
||||
// code :: Char -> Char
|
||||
const code = c => ['AEIOU', 'BFPV', 'CGJKQSXZ', 'DT', 'L', 'MN', 'R', 'HW']
|
||||
.reduce((a, x, i) =>
|
||||
a ? a : (x.indexOf(c) !== -1 ? i.toString() : a), '');
|
||||
|
||||
// isAlpha :: Char -> Boolean
|
||||
const isAlpha = c => {
|
||||
const d = c.charCodeAt(0);
|
||||
return d > 64 && d < 91;
|
||||
};
|
||||
|
||||
const s = name.toUpperCase()
|
||||
.split('')
|
||||
.filter(isAlpha);
|
||||
|
||||
return (s[0] || '0') +
|
||||
s.map(code)
|
||||
.join('')
|
||||
.replace(/7/g, blnNara ? '' : '7')
|
||||
.replace(/(.)\1+/g, '$1')
|
||||
.substr(1)
|
||||
.replace(/[07]/g, '')
|
||||
.concat('000')
|
||||
.substr(0, 3);
|
||||
};
|
||||
|
||||
// curry :: ((a, b) -> c) -> a -> b -> c
|
||||
const curry = f => a => b => f(a, b),
|
||||
[simpleSoundex, naraSoundex] = [false, true]
|
||||
.map(bln => curry(soundex)(bln));
|
||||
|
||||
// TEST
|
||||
return [
|
||||
["Example", "E251"],
|
||||
["Sownteks", "S532"],
|
||||
["Lloyd", "L300"],
|
||||
["12346", "0000"],
|
||||
["4-H", "H000"],
|
||||
["Ashcraft", "A261"],
|
||||
["Ashcroft", "A261"],
|
||||
["auerbach", "A612"],
|
||||
["bar", "B600"],
|
||||
["barre", "B600"],
|
||||
["Baragwanath", "B625"],
|
||||
["Burroughs", "B620"],
|
||||
["Burrows", "B620"],
|
||||
["C.I.A.", "C000"],
|
||||
["coöp", "C100"],
|
||||
["D-day", "D000"],
|
||||
["d jay", "D200"],
|
||||
["de la Rosa", "D462"],
|
||||
["Donnell", "D540"],
|
||||
["Dracula", "D624"],
|
||||
["Drakula", "D624"],
|
||||
["Du Pont", "D153"],
|
||||
["Ekzampul", "E251"],
|
||||
["example", "E251"],
|
||||
["Ellery", "E460"],
|
||||
["Euler", "E460"],
|
||||
["F.B.I.", "F000"],
|
||||
["Gauss", "G200"],
|
||||
["Ghosh", "G200"],
|
||||
["Gutierrez", "G362"],
|
||||
["he", "H000"],
|
||||
["Heilbronn", "H416"],
|
||||
["Hilbert", "H416"],
|
||||
["Jackson", "J250"],
|
||||
["Johnny", "J500"],
|
||||
["Jonny", "J500"],
|
||||
["Kant", "K530"],
|
||||
["Knuth", "K530"],
|
||||
["Ladd", "L300"],
|
||||
["Lloyd", "L300"],
|
||||
["Lee", "L000"],
|
||||
["Lissajous", "L222"],
|
||||
["Lukasiewicz", "L222"],
|
||||
["naïve", "N100"],
|
||||
["Miller", "M460"],
|
||||
["Moses", "M220"],
|
||||
["Moskowitz", "M232"],
|
||||
["Moskovitz", "M213"],
|
||||
["O'Conner", "O256"],
|
||||
["O'Connor", "O256"],
|
||||
["O'Hara", "O600"],
|
||||
["O'Mally", "O540"],
|
||||
["Peters", "P362"],
|
||||
["Peterson", "P362"],
|
||||
["Pfister", "P236"],
|
||||
["R2-D2", "R300"],
|
||||
["rÄ≈sumÅ∙", "R250"],
|
||||
["Robert", "R163"],
|
||||
["Rupert", "R163"],
|
||||
["Rubin", "R150"],
|
||||
["Soundex", "S532"],
|
||||
["sownteks", "S532"],
|
||||
["Swhgler", "S460"],
|
||||
["'til", "T400"],
|
||||
["Tymczak", "T522"],
|
||||
["Uhrbach", "U612"],
|
||||
["Van de Graaff", "V532"],
|
||||
["VanDeusen", "V532"],
|
||||
["Washington", "W252"],
|
||||
["Wheaton", "W350"],
|
||||
["Williams", "W452"],
|
||||
["Woolcock", "W422"]
|
||||
].reduce((a, [name, naraCode]) => {
|
||||
const naraTest = naraSoundex(name),
|
||||
simpleTest = simpleSoundex(name);
|
||||
|
||||
const logNara = naraTest !== naraCode ? (
|
||||
`${name} was ${naraTest} should be ${naraCode}`
|
||||
) : '',
|
||||
logDelta = (naraTest !== simpleTest ? (
|
||||
`${name} -> NARA: ${naraTest} vs Simple: ${simpleTest}`
|
||||
) : '');
|
||||
|
||||
return logNara.length || logDelta.length ? (
|
||||
a + [logNara, logDelta].join('\n')
|
||||
) : a;
|
||||
}, '');
|
||||
})();
|
||||
75
Task/Soundex/Prolog/soundex.pro
Normal file
75
Task/Soundex/Prolog/soundex.pro
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
%____________________________________________________________________
|
||||
% Implements the American soundex algorithm
|
||||
% as described at https://en.wikipedia.org/wiki/Soundex
|
||||
% In SWI Prolog, a 'string' is specified in 'single quotes',
|
||||
% while a "list of codes" may be specified in "double quotes".
|
||||
% So, "abc" is equivalent to [97, 98, 99], while
|
||||
% 'abc' = abc (an atom), and 'Abc' is also an atom. There are
|
||||
% conversion methods that can produce lists of characters:
|
||||
% ?- atom_chars('Abc', X).
|
||||
% X = ['A', b, c].
|
||||
% or lists of codes (mapping to unicode code points):
|
||||
% ?- atom_codes('Abc', X).
|
||||
% X = [65, 98, 99].
|
||||
% and the conversion predicates are bidirectional.
|
||||
% ?- atom_codes(A, [65, 98, 99]).
|
||||
% A = 'Abc'.
|
||||
% A single character code may be specified as 0'C, where C is the
|
||||
% character you want to convert to a code.
|
||||
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
% Relates groups of consonants to representative digits
|
||||
creplace(Ch, 0'1) :- member(Ch, "bfpv").
|
||||
creplace(Ch, 0'2) :- member(Ch, "cgjkqsxz").
|
||||
creplace(Ch, 0'3) :- member(Ch, "dt").
|
||||
creplace(0'l, 0'4).
|
||||
creplace(Ch, 0'5) :- member(Ch, "mn").
|
||||
creplace(0'r, 0'6).
|
||||
|
||||
% strips elements contained in <Set> from a string
|
||||
strip(Set, [H|T], Tr) :- memberchk(H, Set), !, strip(Set, T, Tr).
|
||||
strip(Set, [H|T], [H|Tr]) :- !, strip(Set, T, Tr).
|
||||
strip(_, [], []).
|
||||
|
||||
% Replace consonants with appropriate digits
|
||||
consonants([H|T], [Ch|Tr]) :- creplace(H, Ch), !, consonants(T, Tr).
|
||||
consonants([H|T], [H|Tr]) :- !, consonants(T, Tr).
|
||||
consonants([], []).
|
||||
|
||||
% Replace adjacent digits with single digit
|
||||
adjacent([Ch, Ch|T], [Ch|Tr]) :- between(0'0, 0'9, Ch), !, adjacent(T, Tr).
|
||||
adjacent([H|T], [H|Tr]) :- !, adjacent(T, Tr).
|
||||
adjacent([], []).
|
||||
|
||||
% Replace first character with original one if its a digit
|
||||
chk_digit([H,D|T], [H|T]) :- between(0'0, 0'9, D), !.
|
||||
chk_digit([_,H|T], [H|T]).
|
||||
|
||||
% Faithul representation of soundex rules:
|
||||
% 1: Save 1st letter, strip "hw"
|
||||
% 2: Replace consonants with appropriate digits
|
||||
% 3: Replace adjacent digits with single occurrence
|
||||
% 4: Remove vowels except 1st letter
|
||||
% 5: If 1st symbol is a digit, replace it with saved 1st letter
|
||||
% 6: Ensure trailing zeroes
|
||||
do_soundex([H|T], Res) :-
|
||||
strip("hw", T, Ts), consonants([H|Ts], Tc),
|
||||
adjacent(Tc, [C|Ta]), strip("aeiouy", Ta, Tv),
|
||||
chk_digit([H,C|Tv], Td), append(Td, "0000", Tr),
|
||||
atom_codes(Tf, Tr), sub_string(Tf, 0, 4, _, Res).
|
||||
|
||||
% Prepare string, convert to lower case and do the soundex alogorithm
|
||||
soundex(Text, Res) :-
|
||||
downcase_atom(Text, Lower), atom_codes(Lower, T),
|
||||
do_soundex(T, Res).
|
||||
|
||||
% Perform tests to check that the right values are produced
|
||||
test(S,V) :- not(soundex(S,V)), writef('%w failed\n', [S]).
|
||||
test :- test('Robert', 'r163'), !, fail.
|
||||
test :- test('Rupert', 'r163'), !, fail.
|
||||
test :- test('Rubin', 'r150'), !, fail.
|
||||
test :- test('Ashcroft', 'a261'), !, fail.
|
||||
test :- test('Ashcraft', 'a261'), !, fail.
|
||||
test :- test('Tymczak', 't522'), !, fail.
|
||||
test :- test('Pfister', 'p236'), !, fail.
|
||||
test. % Succeeds only if all the tests succeed
|
||||
|
|
@ -1,100 +1,99 @@
|
|||
/*REXX program demonstrates Soundex codes from some words | commandLine.*/
|
||||
_=; @.= /*set a couple of vars to "null".*/
|
||||
parse arg @.0 . /*allow input from command line. */
|
||||
@.1 = "12346" ; #.1 = '0000'
|
||||
@.4 = "4-H" ; #.4 = 'H000'
|
||||
@.11 = "Ashcraft" ; #.11 = 'A261'
|
||||
@.12 = "Ashcroft" ; #.12 = 'A261'
|
||||
@.18 = "auerbach" ; #.18 = 'A612'
|
||||
@.20 = "Baragwanath" ; #.20 = 'B625'
|
||||
@.22 = "bar" ; #.22 = 'B600'
|
||||
@.23 = "barre" ; #.23 = 'B600'
|
||||
@.20 = "Baragwanath" ; #.20 = 'B625'
|
||||
@.28 = "Burroughs" ; #.28 = 'B620'
|
||||
@.29 = "Burrows" ; #.29 = 'B620'
|
||||
@.30 = "C.I.A." ; #.30 = 'C000'
|
||||
@.37 = "coöp" ; #.37 = 'C100'
|
||||
@.43 = "D-day" ; #.43 = 'D000'
|
||||
@.44 = "d jay" ; #.44 = 'D200'
|
||||
@.45 = "de la Rosa" ; #.45 = 'D462'
|
||||
@.46 = "Donnell" ; #.46 = 'D540'
|
||||
@.47 = "Dracula" ; #.47 = 'D624'
|
||||
@.48 = "Drakula" ; #.48 = 'D624'
|
||||
@.49 = "Du Pont" ; #.49 = 'D153'
|
||||
@.50 = "Ekzampul" ; #.50 = 'E251'
|
||||
@.51 = "example" ; #.51 = 'E251'
|
||||
@.55 = "Ellery" ; #.55 = 'E460'
|
||||
@.59 = "Euler" ; #.59 = 'E460'
|
||||
@.60 = "F.B.I." ; #.60 = 'F000'
|
||||
@.70 = "Gauss" ; #.70 = 'G200'
|
||||
@.71 = "Ghosh" ; #.71 = 'G200'
|
||||
@.72 = "Gutierrez" ; #.72 = 'G362'
|
||||
@.80 = "he" ; #.80 = 'H000'
|
||||
@.81 = "Heilbronn" ; #.81 = 'H416'
|
||||
@.84 = "Hilbert" ; #.84 = 'H416'
|
||||
@.100 = "Jackson" ; #.100 = 'J250'
|
||||
@.104 = "Johnny" ; #.104 = 'J500'
|
||||
@.105 = "Jonny" ; #.105 = 'J500'
|
||||
@.110 = "Kant" ; #.110 = 'K530'
|
||||
@.116 = "Knuth" ; #.116 = 'K530'
|
||||
@.120 = "Ladd" ; #.120 = 'L300'
|
||||
@.124 = "Llyod" ; #.124 = 'L300'
|
||||
@.125 = "Lee" ; #.125 = 'L000'
|
||||
@.126 = "Lissajous" ; #.126 = 'L222'
|
||||
@.128 = "Lukasiewicz" ; #.128 = 'L222'
|
||||
@.130 = "naïve" ; #.130 = 'N100'
|
||||
@.141 = "Miller" ; #.141 = 'M460'
|
||||
@.143 = "Moses" ; #.143 = 'M220'
|
||||
@.146 = "Moskowitz" ; #.146 = 'M232'
|
||||
@.147 = "Moskovitz" ; #.147 = 'M213'
|
||||
@.150 = "O'Conner" ; #.150 = 'O256'
|
||||
@.151 = "O'Connor" ; #.151 = 'O256'
|
||||
@.152 = "O'Hara" ; #.152 = 'O600'
|
||||
@.153 = "O'Mally" ; #.153 = 'O540'
|
||||
@.161 = "Peters" ; #.161 = 'P362'
|
||||
@.162 = "Peterson" ; #.162 = 'P362'
|
||||
@.165 = "Pfister" ; #.165 = 'P236'
|
||||
@.180 = "R2-D2" ; #.180 = 'R300'
|
||||
@.182 = "rÄ≈sumÅ∙" ; #.182 = 'R250'
|
||||
@.184 = "Robert" ; #.184 = 'R163'
|
||||
@.185 = "Rupert" ; #.185 = 'R163'
|
||||
@.187 = "Rubin" ; #.187 = 'R150'
|
||||
@.191 = "Soundex" ; #.191 = 'S532'
|
||||
@.192 = "sownteks" ; #.192 = 'S532'
|
||||
@.199 = "Swhgler" ; #.199 = 'S460'
|
||||
@.202 = "'til" ; #.202 = 'T400'
|
||||
@.208 = "Tymczak" ; #.208 = 'T522'
|
||||
@.216 = "Uhrbach" ; #.216 = 'U612'
|
||||
@.221 = "Van de Graaff" ; #.221 = 'V532'
|
||||
@.222 = "VanDeusen" ; #.222 = 'V532'
|
||||
@.230 = "Washington" ; #.230 = 'W252'
|
||||
@.233 = "Wheaton" ; #.233 = 'W350'
|
||||
@.234 = "Williams" ; #.234 = 'W452'
|
||||
@.236 = "Woolcock" ; #.236 = 'W422'
|
||||
/*REXX program demonstrates Soundex codes from some words or from the command line.*/
|
||||
_=; @.= /*set a couple of vars to "null".*/
|
||||
parse arg @.0 . /*allow input from command line. */
|
||||
@.1 = "12346" ; #.1 = '0000'
|
||||
@.4 = "4-H" ; #.4 = 'H000'
|
||||
@.11 = "Ashcraft" ; #.11 = 'A261'
|
||||
@.12 = "Ashcroft" ; #.12 = 'A261'
|
||||
@.18 = "auerbach" ; #.18 = 'A612'
|
||||
@.20 = "Baragwanath" ; #.20 = 'B625'
|
||||
@.22 = "bar" ; #.22 = 'B600'
|
||||
@.23 = "barre" ; #.23 = 'B600'
|
||||
@.20 = "Baragwanath" ; #.20 = 'B625'
|
||||
@.28 = "Burroughs" ; #.28 = 'B620'
|
||||
@.29 = "Burrows" ; #.29 = 'B620'
|
||||
@.30 = "C.I.A." ; #.30 = 'C000'
|
||||
@.37 = "coöp" ; #.37 = 'C100'
|
||||
@.43 = "D-day" ; #.43 = 'D000'
|
||||
@.44 = "d jay" ; #.44 = 'D200'
|
||||
@.45 = "de la Rosa" ; #.45 = 'D462'
|
||||
@.46 = "Donnell" ; #.46 = 'D540'
|
||||
@.47 = "Dracula" ; #.47 = 'D624'
|
||||
@.48 = "Drakula" ; #.48 = 'D624'
|
||||
@.49 = "Du Pont" ; #.49 = 'D153'
|
||||
@.50 = "Ekzampul" ; #.50 = 'E251'
|
||||
@.51 = "example" ; #.51 = 'E251'
|
||||
@.55 = "Ellery" ; #.55 = 'E460'
|
||||
@.59 = "Euler" ; #.59 = 'E460'
|
||||
@.60 = "F.B.I." ; #.60 = 'F000'
|
||||
@.70 = "Gauss" ; #.70 = 'G200'
|
||||
@.71 = "Ghosh" ; #.71 = 'G200'
|
||||
@.72 = "Gutierrez" ; #.72 = 'G362'
|
||||
@.80 = "he" ; #.80 = 'H000'
|
||||
@.81 = "Heilbronn" ; #.81 = 'H416'
|
||||
@.84 = "Hilbert" ; #.84 = 'H416'
|
||||
@.100 = "Jackson" ; #.100 = 'J250'
|
||||
@.104 = "Johnny" ; #.104 = 'J500'
|
||||
@.105 = "Jonny" ; #.105 = 'J500'
|
||||
@.110 = "Kant" ; #.110 = 'K530'
|
||||
@.116 = "Knuth" ; #.116 = 'K530'
|
||||
@.120 = "Ladd" ; #.120 = 'L300'
|
||||
@.124 = "Llyod" ; #.124 = 'L300'
|
||||
@.125 = "Lee" ; #.125 = 'L000'
|
||||
@.126 = "Lissajous" ; #.126 = 'L222'
|
||||
@.128 = "Lukasiewicz" ; #.128 = 'L222'
|
||||
@.130 = "naïve" ; #.130 = 'N100'
|
||||
@.141 = "Miller" ; #.141 = 'M460'
|
||||
@.143 = "Moses" ; #.143 = 'M220'
|
||||
@.146 = "Moskowitz" ; #.146 = 'M232'
|
||||
@.147 = "Moskovitz" ; #.147 = 'M213'
|
||||
@.150 = "O'Conner" ; #.150 = 'O256'
|
||||
@.151 = "O'Connor" ; #.151 = 'O256'
|
||||
@.152 = "O'Hara" ; #.152 = 'O600'
|
||||
@.153 = "O'Mally" ; #.153 = 'O540'
|
||||
@.161 = "Peters" ; #.161 = 'P362'
|
||||
@.162 = "Peterson" ; #.162 = 'P362'
|
||||
@.165 = "Pfister" ; #.165 = 'P236'
|
||||
@.180 = "R2-D2" ; #.180 = 'R300'
|
||||
@.182 = "rÄ≈sumÅ∙" ; #.182 = 'R250'
|
||||
@.184 = "Robert" ; #.184 = 'R163'
|
||||
@.185 = "Rupert" ; #.185 = 'R163'
|
||||
@.187 = "Rubin" ; #.187 = 'R150'
|
||||
@.191 = "Soundex" ; #.191 = 'S532'
|
||||
@.192 = "sownteks" ; #.192 = 'S532'
|
||||
@.199 = "Swhgler" ; #.199 = 'S460'
|
||||
@.202 = "'til" ; #.202 = 'T400'
|
||||
@.208 = "Tymczak" ; #.208 = 'T522'
|
||||
@.216 = "Uhrbach" ; #.216 = 'U612'
|
||||
@.221 = "Van de Graaff" ; #.221 = 'V532'
|
||||
@.222 = "VanDeusen" ; #.222 = 'V532'
|
||||
@.230 = "Washington" ; #.230 = 'W252'
|
||||
@.233 = "Wheaton" ; #.233 = 'W350'
|
||||
@.234 = "Williams" ; #.234 = 'W452'
|
||||
@.236 = "Woolcock" ; #.236 = 'W422'
|
||||
|
||||
do k=0 for 300; if @.k=='' then iterate; $=soundex(@.k)
|
||||
say word('nope [ok]',1+($==#.k | k==0)) _ $ 'is the Soundex for' @.k
|
||||
do k=0 for 300; if @.k=='' then iterate; $=soundex(@.k)
|
||||
say word('nope [ok]', 1 +($==#.k | k==0)) _ $ "is the Soundex for" @.k
|
||||
if k==0 then leave
|
||||
end /*k*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*───────────────────────────────────SOUNDEX subroutine─────────────────*/
|
||||
soundex: procedure; arg thing /*ARG automatically uppercases it*/
|
||||
old_alphabet = 'AEIOUYHWBFPVCGJKQSXZDTLMNR'
|
||||
new_alphabet = '@@@@@@**111122222222334556'
|
||||
word=
|
||||
do i=1 for length(thing) /*handle special chars: - ' _ etc*/
|
||||
_=substr(thing, i, 1)
|
||||
if datatype(_,'M') then word=word || _ /*it's a letter, then OK*/
|
||||
end /*i*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
soundex: procedure; arg x /*ARG uppercases the var X. */
|
||||
old_alphabet= 'AEIOUYHWBFPVCGJKQSXZDTLMNR'
|
||||
new_alphabet= '@@@@@@**111122222222334556'
|
||||
word= /* [+] exclude non-letters. */
|
||||
do i=1 for length(x); _=substr(x, i, 1) /*obtain a character from word*/
|
||||
if datatype(_,'M') then word=word || _ /*Upper/lower letter? Then OK*/
|
||||
end /*i*/
|
||||
|
||||
value=strip(left(word, 1)) /*first character is left alone. */
|
||||
word=translate(word, new_alphabet, old_alphabet)
|
||||
prev=translate(value,new_alphabet, old_alphabet) /*the previous code.*/
|
||||
value=strip(left(word, 1)) /*1st character is left alone.*/
|
||||
word=translate(word, new_alphabet, old_alphabet) /*define the current word. */
|
||||
prev=translate(value,new_alphabet, old_alphabet) /* " " previous " */
|
||||
|
||||
do j=2 to length(word) /*process remainder of the word. */
|
||||
?=substr(word, j, 1)
|
||||
if ?\==prev & datatype(?,'W') then do; value=value || ?; prev=?; end
|
||||
else if ?=='@' then prev=?
|
||||
end /*j*/
|
||||
do j=2 to length(word) /*process remainder of word. */
|
||||
?=substr(word, j, 1)
|
||||
if ?\==prev & datatype(?,'W') then do; value=value || ?; prev=?; end
|
||||
else if ?=='@' then prev=?
|
||||
end /*j*/
|
||||
|
||||
return left(value,4,0) /*return padded value with zeroes*/
|
||||
return left(value,4,0) /*padded value with zeroes. */
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@
|
|||
(if (zerop (length s))
|
||||
""
|
||||
(let* ((su (upcase-str s))
|
||||
(o (chr-str su 0)))
|
||||
(o [su 0]))
|
||||
(for ((i 1) (l (length su)) cp cg)
|
||||
((< i l) (sub-str (cat-str ^(,o "000") nil) 0 4))
|
||||
((< i l) [`@{o}000` 0 4])
|
||||
((inc i) (set cp cg))
|
||||
(set cg (get-code (chr-str su i)))
|
||||
(if (and cg (null (eql cg cp)))
|
||||
(set o (cat-str ^(,o ,cg) nil))))))))
|
||||
(set cg (get-code [su i]))
|
||||
(if (and cg (not (eql cg cp)))
|
||||
(set o `@o@cg`)))))))
|
||||
@(next :args)
|
||||
@(repeat)
|
||||
@arg
|
||||
|
|
|
|||
8
Task/Soundex/UNIX-Shell/soundex-1.sh
Normal file
8
Task/Soundex/UNIX-Shell/soundex-1.sh
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
declare -A value=(
|
||||
[B]=1 [F]=1 [P]=1 [V]=1
|
||||
[C]=2 [G]=2 [J]=2 [K]=2 [Q]=2 [S]=2 [X]=2 [Z]=2
|
||||
[D]=3 [T]=3
|
||||
[L]=4
|
||||
[M]=5 [N]=5
|
||||
[R]=6
|
||||
)
|
||||
36
Task/Soundex/UNIX-Shell/soundex-2.sh
Normal file
36
Task/Soundex/UNIX-Shell/soundex-2.sh
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
soundex() {
|
||||
local -u word=${1//[^[:alpha:]]/.}
|
||||
local letter=${word:0:1}
|
||||
local soundex=$letter
|
||||
local previous=$letter
|
||||
|
||||
word=${word:1}
|
||||
word=${word//[AEIOUY]/.}
|
||||
word=${word//[WH]/=}
|
||||
|
||||
while [[ ${#soundex} -lt 4 && -n $word ]]; do
|
||||
letter=${word:0:1}
|
||||
|
||||
if [[ $letter == "." ]]; then
|
||||
previous=""
|
||||
|
||||
elif [[ $letter == "=" ]]; then
|
||||
if [[ $previous == [A-Z] && ${word:1:1} == [A-Z] ]] &&
|
||||
[[ ${value[$previous]} -eq ${value[${word:1:1}]} ]]
|
||||
then
|
||||
word=${word:1}
|
||||
fi
|
||||
|
||||
elif [[ -z $previous ]] ||
|
||||
[[ $letter != $previous && ${value[$letter]} -ne ${value[$previous]} ]]
|
||||
then
|
||||
previous=$letter
|
||||
soundex+=${value[$letter]}
|
||||
fi
|
||||
|
||||
word=${word:1}
|
||||
done
|
||||
# right pad with zeros
|
||||
soundex+="000"
|
||||
echo "${soundex:0:4}"
|
||||
}
|
||||
44
Task/Soundex/UNIX-Shell/soundex-3.sh
Normal file
44
Task/Soundex/UNIX-Shell/soundex-3.sh
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
soundex2() {
|
||||
local -u word=${1//[^[:alpha:]]/}
|
||||
|
||||
# 1. Save the first letter. Remove all occurrences of 'h' and 'w' except first letter.
|
||||
local first=${word:0:1}
|
||||
word=${word:1}
|
||||
word=$first${word//[HW]/}
|
||||
|
||||
# 2. Replace all consonants (include the first letter) with digits as in [2.] above.
|
||||
local consonants=$(IFS=; echo "${!value[*]}")
|
||||
local tmp letter
|
||||
local -i i
|
||||
for ((i=0; i < ${#word}; i++)); do
|
||||
letter=${word:i:1}
|
||||
if [[ $consonants == *$letter* ]]; then
|
||||
tmp+=${value[$letter]}
|
||||
else
|
||||
tmp+=$letter
|
||||
fi
|
||||
done
|
||||
word=$tmp
|
||||
|
||||
# 3. Replace all adjacent same digits with one digit.
|
||||
local char
|
||||
tmp=${word:0:1}
|
||||
local previous=${word:0:1}
|
||||
for ((i=1; i < ${#word}; i++)); do
|
||||
char=${word:i:1}
|
||||
[[ $char != [[:digit:]] || $char != $previous ]] && tmp+=$char
|
||||
previous=$char
|
||||
done
|
||||
word=$tmp
|
||||
|
||||
# 4. Remove all occurrences of a, e, i, o, u, y except first letter.
|
||||
tmp=${word:1}
|
||||
word=${word:0:1}${tmp//[AEIOUY]/}
|
||||
|
||||
# 5. If first symbol is a digit replace it with letter saved on step 1.
|
||||
[[ $word == [[:digit:]]* ]] && word=$first${word:1}
|
||||
|
||||
# 6. right pad with zeros
|
||||
word+="000"
|
||||
echo "${word:0:4}"
|
||||
}
|
||||
21
Task/Soundex/UNIX-Shell/soundex-4.sh
Normal file
21
Task/Soundex/UNIX-Shell/soundex-4.sh
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
soundex3() {
|
||||
local -u word=${1//[^[:alpha:]]/}
|
||||
|
||||
# 1. Save the first letter. Remove all occurrences of 'h' and 'w' except first letter.
|
||||
local first=${word:0:1}
|
||||
word=$first$( tr -d "HW" <<< "${word:1}" )
|
||||
|
||||
# 2. Replace all consonants (include the first letter) with digits as in [2.] above.
|
||||
# 3. Replace all adjacent same digits with one digit.
|
||||
local consonants=$( IFS=; echo "${!value[*]}" )
|
||||
local values=$( IFS=; echo "${value[*]}" )
|
||||
word=$( tr -s "$consonants" "$values" <<< "$word" )
|
||||
|
||||
# 4. Remove all occurrences of a, e, i, o, u, y except first letter.
|
||||
# 5. If first symbol is a digit replace it with letter saved on step 1.
|
||||
word=$first$( tr -d "AEIOUY" <<< "${word:1}" )
|
||||
|
||||
# 6. right pad with zeros
|
||||
word+="000"
|
||||
echo "${word:0:4}"
|
||||
}
|
||||
28
Task/Soundex/UNIX-Shell/soundex-5.sh
Normal file
28
Task/Soundex/UNIX-Shell/soundex-5.sh
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
declare -A tests=(
|
||||
[Soundex]=S532 [Example]=E251 [Sownteks]=S532 [Ekzampul]=E251
|
||||
[Euler]=E460 [Gauss]=G200 [Hilbert]=H416 [Knuth]=K530
|
||||
[Lloyd]=L300 [Lukasiewicz]=L222 [Ellery]=E460 [Ghosh]=G200
|
||||
[Heilbronn]=H416 [Kant]=K530 [Ladd]=L300 [Lissajous]=L222
|
||||
[Wheaton]=W350 [Burroughs]=B620 [Burrows]=B620 ["O'Hara"]=O600
|
||||
[Washington]=W252 [Lee]=L000 [Gutierrez]=G362 [Pfister]=P236
|
||||
[Jackson]=J250 [Tymczak]=T522 [VanDeusen]=V532 [Ashcraft]=A261
|
||||
)
|
||||
|
||||
run_tests() {
|
||||
local func=$1
|
||||
echo "Testing with function $func"
|
||||
local -i all=0 fail=0
|
||||
for name in "${!tests[@]}"; do
|
||||
s=$($func "$name")
|
||||
if [[ $s != "${tests[$name]}" ]]; then
|
||||
echo "FAIL - $s - $name -- EXPECTING ${tests[$name]}"
|
||||
((fail++))
|
||||
fi
|
||||
((all++))
|
||||
done
|
||||
echo "$fail out of $all failures"
|
||||
}
|
||||
|
||||
run_tests soundex
|
||||
run_tests soundex2
|
||||
run_tests soundex3
|
||||
Loading…
Add table
Add a link
Reference in a new issue