Skip to content

Commit 165ab63

Browse files
rgizzkgryte
andauthored
feat: add string/base/distances/hamming (#1166)
PR-URL: #1166 Co-authored-by: Athan Reines <kgryte@gmail.com> Reviewed-by: Athan Reines <kgryte@gmail.com> Ref: #836 Ref: #151
1 parent 330fef2 commit 165ab63

File tree

10 files changed

+664
-0
lines changed

10 files changed

+664
-0
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2023 The Stdlib Authors.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
19+
-->
20+
21+
# hammingDistance
22+
23+
> Calculate the [Hamming distance][hamming-distance] between two equal-length strings.
24+
25+
<!-- Package usage documentation. -->
26+
27+
<section class="usage">
28+
29+
## Usage
30+
31+
```javascript
32+
var hammingDistance = require( '@stdlib/string/base/distances/hamming' );
33+
```
34+
35+
#### hammingDistance( s1, s2 )
36+
37+
Calculates the [Hamming distance][hamming-distance] between two equal-length strings.
38+
39+
```javascript
40+
var dist = hammingDistance( 'frog', 'from' );
41+
// returns 1
42+
43+
dist = hammingDistance( 'tooth', 'froth' );
44+
// returns 2
45+
46+
dist = hammingDistance( 'cat', 'cot' );
47+
// returns 1
48+
49+
dist = hammingDistance( '', '' );
50+
// returns 0
51+
52+
dist = hammingDistance( '1638452297', '2311638451' );
53+
// returns 10
54+
```
55+
56+
</section>
57+
58+
<!-- /.usage -->
59+
60+
<!-- Package notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
61+
62+
<section class="notes">
63+
64+
## Notes
65+
66+
- If the two strings differ in length, the [Hamming distance][hamming-distance] is not defined. Consequently, when provided two input strings of unequal length, the function returns a sentinel value of `-1`.
67+
- As the function calculates the [Hamming distance][hamming-distance] by comparing UTF-16 code units, the function should behave as expected for strings composed of most characters. However, the function is likely to not behave as expected if strings contain visual characters composed of multiple Unicode code points, such as certain mathematical symbols and grapheme clusters (e.g., emojis).
68+
69+
</section>
70+
71+
<!-- /.notes -->
72+
73+
<!-- Package usage examples. -->
74+
75+
<section class="examples">
76+
77+
## Examples
78+
79+
```javascript
80+
var hammingDistance = require( '@stdlib/string/base/distances/hamming' );
81+
82+
var dist = hammingDistance( 'algorithms', 'altruistic' );
83+
// returns 7
84+
85+
dist = hammingDistance( 'elephant', 'Tashkent' );
86+
// returns 6
87+
88+
dist = hammingDistance( 'javascript', 'typescript' );
89+
// returns 4
90+
91+
dist = hammingDistance( 'hamming', 'ladybug' );
92+
// returns 5
93+
```
94+
95+
</section>
96+
97+
<!-- /.examples -->
98+
99+
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
100+
101+
<section class="related">
102+
103+
</section>
104+
105+
<!-- /.related -->
106+
107+
<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
108+
109+
<section class="links">
110+
111+
[hamming-distance]: https://en.wikipedia.org/wiki/Hamming_distance
112+
113+
</section>
114+
115+
<!-- /.links -->
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2023 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MODULES //
22+
23+
var bench = require( '@stdlib/bench' );
24+
var pkg = require( './../package.json' ).name;
25+
var hammingDistance = require( './../lib' );
26+
27+
28+
// MAIN //
29+
30+
bench( pkg, function benchmark( b ) {
31+
var values;
32+
var value;
33+
var out;
34+
var i;
35+
36+
values = [
37+
[ 'algorithms', 'altruistic' ],
38+
[ '1638452297', '4444884447' ],
39+
[ '', '' ],
40+
[ 'z', 'a' ],
41+
[ 'aaappppk', 'aardvark' ],
42+
[ 'frog', 'flog' ],
43+
[ 'fly', 'ant' ],
44+
[ 'elephant', 'hippopod' ],
45+
[ 'hippopod', 'elephant' ],
46+
[ 'hippo', 'zzzzz' ],
47+
[ 'hello', 'hallo' ],
48+
[ 'congratulations', 'conmgeautlatins' ]
49+
];
50+
51+
b.tic();
52+
for ( i = 0; i < b.iterations; i++ ) {
53+
value = values[ i%values.length ];
54+
out = hammingDistance( value[0], value[1] );
55+
if ( typeof out !== 'number' ) {
56+
b.fail( 'should return a number' );
57+
}
58+
}
59+
b.toc();
60+
if ( typeof out !== 'number' ) {
61+
b.fail( 'should return a number' );
62+
}
63+
b.pass( 'benchmark finished' );
64+
b.end();
65+
});
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
{{alias}}( s1, s2 )
3+
Calculates the Hamming distance between two equal-length input strings.
4+
5+
The function returns a sentinel value of -1 if the input string lengths
6+
differ.
7+
8+
Parameters
9+
----------
10+
s1: string
11+
First input string.
12+
13+
s2: string
14+
Second input string.
15+
16+
Returns
17+
-------
18+
out: number
19+
Hamming distance.
20+
21+
Examples
22+
--------
23+
> var d = {{alias}}( 'algorithms', 'altruistic' )
24+
7
25+
> d = {{alias}}( 'elephant', 'hippopod' )
26+
7
27+
> d = {{alias}}( 'javascript', 'typescript' )
28+
4
29+
> d = {{alias}}( 'levenshtein', 'levitations' )
30+
8
31+
> d = {{alias}}( 'sacrifice', 'paradisal' )
32+
8
33+
34+
See Also
35+
--------
36+
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2023 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
// TypeScript Version: 4.1
20+
21+
/**
22+
* Calculates the Hamming distance between two equal-length strings.
23+
*
24+
* ## Notes
25+
*
26+
* - The function returns a sentinel value of `-1` if the input string lengths differ.
27+
*
28+
* @param str1 - first input string
29+
* @param str2 - second input string
30+
* @returns Hamming distance
31+
*
32+
* @example
33+
* var dist = hammingDistance( 'fly', 'ant' );
34+
* // returns 3
35+
*
36+
* @example
37+
* var dist = hammingDistance( 'algorithms', 'altruistic' );
38+
* // returns 7
39+
*
40+
* @example
41+
* var dist = hammingDistance( 'hippopod', 'elephant' );
42+
* // returns 7
43+
*/
44+
declare function hammingDistance( str1: string, str2: string ): number;
45+
46+
47+
// EXPORTS //
48+
49+
export = hammingDistance;
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2023 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
import hammingDistance = require( './index' );
20+
21+
22+
// TESTS //
23+
24+
// The function returns a number...
25+
{
26+
hammingDistance( '', '' ); // $ExpectType number
27+
}
28+
29+
// The compiler throws an error if the function is provided a first argument which is not a string...
30+
{
31+
hammingDistance( true, '' ); // $ExpectError
32+
hammingDistance( false, '' ); // $ExpectError
33+
hammingDistance( null, '' ); // $ExpectError
34+
hammingDistance( undefined, '' ); // $ExpectError
35+
hammingDistance( 5, '' ); // $ExpectError
36+
hammingDistance( [], '' ); // $ExpectError
37+
hammingDistance( {}, '' ); // $ExpectError
38+
hammingDistance( ( x: number ): number => x, '' ); // $ExpectError
39+
}
40+
41+
// The compiler throws an error if the function is provided a second argument which is not a string...
42+
{
43+
hammingDistance( '', true ); // $ExpectError
44+
hammingDistance( '', false ); // $ExpectError
45+
hammingDistance( '', null ); // $ExpectError
46+
hammingDistance( '', undefined ); // $ExpectError
47+
hammingDistance( '', 5 ); // $ExpectError
48+
hammingDistance( '', [] ); // $ExpectError
49+
hammingDistance( '', {} ); // $ExpectError
50+
hammingDistance( '', ( x: number ): number => x ); // $ExpectError
51+
}
52+
53+
// The compiler throws an error if the function is provided an unsupported number of arguments...
54+
{
55+
hammingDistance(); // $ExpectError
56+
hammingDistance( '' ); // $ExpectError
57+
hammingDistance( '', '', 3 ); // $ExpectError
58+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2023 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
var hammingDistance = require( './../lib' );
22+
23+
console.log( hammingDistance( 'algorithms', 'altruistic' ) );
24+
// => 7
25+
26+
console.log( hammingDistance( 'elephant', 'hippopod' ) );
27+
// => 7
28+
29+
console.log( hammingDistance( 'javascript', 'typescript' ) );
30+
// => 4
31+
32+
console.log( hammingDistance( 'hamming', 'hamster' ) );
33+
// => 4
34+
35+
console.log( hammingDistance( 'a', 'abcissa' ) );
36+
// => -1

0 commit comments

Comments
 (0)