From fe7a3d27dfcac49c7092df956c022e4f98062364 Mon Sep 17 00:00:00 2001 From: stdlib-bot Date: Fri, 15 Dec 2023 22:16:06 +0000 Subject: [PATCH] Auto-generated commit --- base/distances/hamming/README.md | 115 +++++++++++++++++ base/distances/hamming/benchmark/benchmark.js | 65 ++++++++++ base/distances/hamming/docs/repl.txt | 36 ++++++ base/distances/hamming/docs/types/index.d.ts | 49 +++++++ base/distances/hamming/docs/types/test.ts | 58 +++++++++ base/distances/hamming/examples/index.js | 36 ++++++ base/distances/hamming/lib/index.js | 47 +++++++ base/distances/hamming/lib/main.js | 71 +++++++++++ base/distances/hamming/package.json | 67 ++++++++++ base/distances/hamming/test/test.js | 120 ++++++++++++++++++ 10 files changed, 664 insertions(+) create mode 100644 base/distances/hamming/README.md create mode 100644 base/distances/hamming/benchmark/benchmark.js create mode 100644 base/distances/hamming/docs/repl.txt create mode 100644 base/distances/hamming/docs/types/index.d.ts create mode 100644 base/distances/hamming/docs/types/test.ts create mode 100644 base/distances/hamming/examples/index.js create mode 100644 base/distances/hamming/lib/index.js create mode 100644 base/distances/hamming/lib/main.js create mode 100644 base/distances/hamming/package.json create mode 100644 base/distances/hamming/test/test.js diff --git a/base/distances/hamming/README.md b/base/distances/hamming/README.md new file mode 100644 index 00000000..88be4d48 --- /dev/null +++ b/base/distances/hamming/README.md @@ -0,0 +1,115 @@ + + +# hammingDistance + +> Calculate the [Hamming distance][hamming-distance] between two equal-length strings. + + + +
+ +## Usage + +```javascript +var hammingDistance = require( '@stdlib/string/base/distances/hamming' ); +``` + +#### hammingDistance( s1, s2 ) + +Calculates the [Hamming distance][hamming-distance] between two equal-length strings. + +```javascript +var dist = hammingDistance( 'frog', 'from' ); +// returns 1 + +dist = hammingDistance( 'tooth', 'froth' ); +// returns 2 + +dist = hammingDistance( 'cat', 'cot' ); +// returns 1 + +dist = hammingDistance( '', '' ); +// returns 0 + +dist = hammingDistance( '1638452297', '2311638451' ); +// returns 10 +``` + +
+ + + + + +
+ +## Notes + +- 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`. +- 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). + +
+ + + + + +
+ +## Examples + +```javascript +var hammingDistance = require( '@stdlib/string/base/distances/hamming' ); + +var dist = hammingDistance( 'algorithms', 'altruistic' ); +// returns 7 + +dist = hammingDistance( 'elephant', 'Tashkent' ); +// returns 6 + +dist = hammingDistance( 'javascript', 'typescript' ); +// returns 4 + +dist = hammingDistance( 'hamming', 'ladybug' ); +// returns 5 +``` + +
+ + + + + + + + + + + + + + diff --git a/base/distances/hamming/benchmark/benchmark.js b/base/distances/hamming/benchmark/benchmark.js new file mode 100644 index 00000000..dc278005 --- /dev/null +++ b/base/distances/hamming/benchmark/benchmark.js @@ -0,0 +1,65 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var pkg = require( './../package.json' ).name; +var hammingDistance = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var values; + var value; + var out; + var i; + + values = [ + [ 'algorithms', 'altruistic' ], + [ '1638452297', '4444884447' ], + [ '', '' ], + [ 'z', 'a' ], + [ 'aaappppk', 'aardvark' ], + [ 'frog', 'flog' ], + [ 'fly', 'ant' ], + [ 'elephant', 'hippopod' ], + [ 'hippopod', 'elephant' ], + [ 'hippo', 'zzzzz' ], + [ 'hello', 'hallo' ], + [ 'congratulations', 'conmgeautlatins' ] + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + value = values[ i%values.length ]; + out = hammingDistance( value[0], value[1] ); + if ( typeof out !== 'number' ) { + b.fail( 'should return a number' ); + } + } + b.toc(); + if ( typeof out !== 'number' ) { + b.fail( 'should return a number' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/base/distances/hamming/docs/repl.txt b/base/distances/hamming/docs/repl.txt new file mode 100644 index 00000000..b637ddb4 --- /dev/null +++ b/base/distances/hamming/docs/repl.txt @@ -0,0 +1,36 @@ + +{{alias}}( s1, s2 ) + Calculates the Hamming distance between two equal-length input strings. + + The function returns a sentinel value of -1 if the input string lengths + differ. + + Parameters + ---------- + s1: string + First input string. + + s2: string + Second input string. + + Returns + ------- + out: number + Hamming distance. + + Examples + -------- + > var d = {{alias}}( 'algorithms', 'altruistic' ) + 7 + > d = {{alias}}( 'elephant', 'hippopod' ) + 7 + > d = {{alias}}( 'javascript', 'typescript' ) + 4 + > d = {{alias}}( 'levenshtein', 'levitations' ) + 8 + > d = {{alias}}( 'sacrifice', 'paradisal' ) + 8 + + See Also + -------- + diff --git a/base/distances/hamming/docs/types/index.d.ts b/base/distances/hamming/docs/types/index.d.ts new file mode 100644 index 00000000..094bb1ac --- /dev/null +++ b/base/distances/hamming/docs/types/index.d.ts @@ -0,0 +1,49 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2023 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// TypeScript Version: 4.1 + +/** +* Calculates the Hamming distance between two equal-length strings. +* +* ## Notes +* +* - The function returns a sentinel value of `-1` if the input string lengths differ. +* +* @param str1 - first input string +* @param str2 - second input string +* @returns Hamming distance +* +* @example +* var dist = hammingDistance( 'fly', 'ant' ); +* // returns 3 +* +* @example +* var dist = hammingDistance( 'algorithms', 'altruistic' ); +* // returns 7 +* +* @example +* var dist = hammingDistance( 'hippopod', 'elephant' ); +* // returns 7 +*/ +declare function hammingDistance( str1: string, str2: string ): number; + + +// EXPORTS // + +export = hammingDistance; diff --git a/base/distances/hamming/docs/types/test.ts b/base/distances/hamming/docs/types/test.ts new file mode 100644 index 00000000..45905bc3 --- /dev/null +++ b/base/distances/hamming/docs/types/test.ts @@ -0,0 +1,58 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2023 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hammingDistance = require( './index' ); + + +// TESTS // + +// The function returns a number... +{ + hammingDistance( '', '' ); // $ExpectType number +} + +// The compiler throws an error if the function is provided a first argument which is not a string... +{ + hammingDistance( true, '' ); // $ExpectError + hammingDistance( false, '' ); // $ExpectError + hammingDistance( null, '' ); // $ExpectError + hammingDistance( undefined, '' ); // $ExpectError + hammingDistance( 5, '' ); // $ExpectError + hammingDistance( [], '' ); // $ExpectError + hammingDistance( {}, '' ); // $ExpectError + hammingDistance( ( x: number ): number => x, '' ); // $ExpectError +} + +// The compiler throws an error if the function is provided a second argument which is not a string... +{ + hammingDistance( '', true ); // $ExpectError + hammingDistance( '', false ); // $ExpectError + hammingDistance( '', null ); // $ExpectError + hammingDistance( '', undefined ); // $ExpectError + hammingDistance( '', 5 ); // $ExpectError + hammingDistance( '', [] ); // $ExpectError + hammingDistance( '', {} ); // $ExpectError + hammingDistance( '', ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided an unsupported number of arguments... +{ + hammingDistance(); // $ExpectError + hammingDistance( '' ); // $ExpectError + hammingDistance( '', '', 3 ); // $ExpectError +} diff --git a/base/distances/hamming/examples/index.js b/base/distances/hamming/examples/index.js new file mode 100644 index 00000000..bd2f7a3e --- /dev/null +++ b/base/distances/hamming/examples/index.js @@ -0,0 +1,36 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var hammingDistance = require( './../lib' ); + +console.log( hammingDistance( 'algorithms', 'altruistic' ) ); +// => 7 + +console.log( hammingDistance( 'elephant', 'hippopod' ) ); +// => 7 + +console.log( hammingDistance( 'javascript', 'typescript' ) ); +// => 4 + +console.log( hammingDistance( 'hamming', 'hamster' ) ); +// => 4 + +console.log( hammingDistance( 'a', 'abcissa' ) ); +// => -1 diff --git a/base/distances/hamming/lib/index.js b/base/distances/hamming/lib/index.js new file mode 100644 index 00000000..9b723ebc --- /dev/null +++ b/base/distances/hamming/lib/index.js @@ -0,0 +1,47 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +/** +* Calculate the Hamming distance between two equal-length strings. +* +* @module @stdlib/string/base/distances/hamming +* +* @example +* var hammingDistance = require( '@stdlib/string/base/distances/hamming' ); +* +* var dist = hammingDistance( 'fly', 'ant' ); +* // returns 3 +* +* dist = hammingDistance( 'frog', 'blog' ); +* // returns 2 +* +* dist = hammingDistance( 'javascript', 'typescript' ); +* // returns 4 +*/ + + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/base/distances/hamming/lib/main.js b/base/distances/hamming/lib/main.js new file mode 100644 index 00000000..5da9dbaa --- /dev/null +++ b/base/distances/hamming/lib/main.js @@ -0,0 +1,71 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var format = require( './../../../../format' ); + + +// MAIN // + +/** +* Calculates the Hamming distance between two equal-length strings. +* +* ## Notes +* +* - The function returns a sentinel value of `-1` if the input string lengths differ. +* +* @param {string} s1 - first input string +* @param {string} s2 - second input string +* @throws {TypeError} first argument must be a string +* @throws {TypeError} second argument must be a string +* @returns {integer} Hamming distance +* +* @example +* var distance = hammingDistance( 'algorithm', 'altruistic' ); +* // returns -1 +*/ +function hammingDistance( s1, s2 ) { + var out; + var i; + + if ( !isString( s1 ) ) { + throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', s1 ) ); + } + if ( !isString( s2 ) ) { + throw new TypeError( format( 'invalid argument. Second argument must be a string. Value: `%s`.', s2 ) ); + } + if ( s1.length !== s2.length ) { + return -1; + } + out = 0; + for ( i = 0; i < s1.length; i++ ) { + if (s1[ i ] !== s2[ i ] ) { + out += 1; + } + } + return out; +} + + +// EXPORTS // + +module.exports = hammingDistance; diff --git a/base/distances/hamming/package.json b/base/distances/hamming/package.json new file mode 100644 index 00000000..05996b10 --- /dev/null +++ b/base/distances/hamming/package.json @@ -0,0 +1,67 @@ +{ + "name": "@stdlib/string/base/distances/hamming", + "version": "0.0.0", + "description": "Calculate the Hamming distance between two equal-length strings.", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "main": "./lib", + "directories": { + "benchmark": "./benchmark", + "doc": "./docs", + "example": "./examples", + "lib": "./lib", + "test": "./test" + }, + "types": "./docs/types", + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "stdstring", + "utilities", + "utility", + "utils", + "util", + "base", + "string", + "str", + "distances", + "distance", + "hamming", + "edit" + ], + "__stdlib__": {} +} diff --git a/base/distances/hamming/test/test.js b/base/distances/hamming/test/test.js new file mode 100644 index 00000000..c7c1dff4 --- /dev/null +++ b/base/distances/hamming/test/test.js @@ -0,0 +1,120 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var hammingDistance = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof hammingDistance, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function throws an error if not provided a string as its first argument', function test( t ) { + var values; + var i; + + values = [ + 5, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + hammingDistance( value, 'foo' ); + }; + } +}); + +tape( 'the function throws an error if not provided a string as its second argument', function test( t ) { + var values; + var i; + + values = [ + 5, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + hammingDistance( 'foo', value ); + }; + } +}); + +tape( 'the function returns -1 as a sentinel value if provided strings of unequal length', function test( t ) { + t.strictEqual( hammingDistance( 'length', 'differs' ), -1, 'returns expected value' ); + t.end(); +}); + +tape( 'the function calculates the Hamming distance between two equal-length strings', function test( t ) { + var expected; + var values; + var i; + + values = [ + [ '1638452297', '4444884442' ], // 10 + [ '', '' ], // 0 + [ 'a', 'a' ], // 0 + [ 'a', 'b' ], // 1 + [ 'xy', 'xy' ], // 0 + [ 'xx', 'xy' ], // 1 + [ 'frog', 'blog' ], // 2 + [ 'fly', 'ant' ], // 3 + [ 'hello', 'hallo' ], // 1 + [ 'congratulations', 'conmgeautlatins' ] // 9 + ]; + + expected = [ 10, 0, 0, 1, 0, 1, 2, 3, 1, 9 ]; + + for ( i = 0; i < values.length; i++ ) { + t.strictEqual( hammingDistance( values[i][0], values[i][1] ), expected[i], 'returns expected value' ); + } + t.end(); +});