add kata
This commit is contained in:
89
5kyu/closest-and-smallest/description.md
Normal file
89
5kyu/closest-and-smallest/description.md
Normal file
@@ -0,0 +1,89 @@
|
||||
Input
|
||||
a string strng of n positive numbers (n = 0 or n >= 2)
|
||||
Let us call weight of a number the sum of its digits. For example 99 will have "weight" 18, 100 will have "weight" 1.
|
||||
|
||||
Two numbers are "close" if the difference of their weights is small.
|
||||
|
||||
Task:
|
||||
For each number in strng calculate its "weight" and then find two numbers of strng that have:
|
||||
|
||||
the smallest difference of weights ie that are the closest
|
||||
with the smallest weights
|
||||
and with the smallest indices (or ranks, numbered from 0) in strng
|
||||
Output:
|
||||
an array of two arrays, each subarray in the following format:
|
||||
[number-weight, index in strng of the corresponding number, original corresponding number in strng]
|
||||
|
||||
or a pair of two subarrays (Haskell, Clojure, FSharp) or an array of tuples (Elixir, C++)
|
||||
|
||||
or a (char*) in C or a string in some other languages mimicking an array of two subarrays or a string
|
||||
|
||||
or a matrix in R (2 rows, 3 columns, no columns names)
|
||||
|
||||
The two subarrays are sorted in ascending order by their number weights if these weights are different, by their indexes in the string if they have the same weights.
|
||||
|
||||
Examples:
|
||||
Let us call that function closest
|
||||
|
||||
strng = "103 123 4444 99 2000"
|
||||
the weights are 4, 6, 16, 18, 2 (ie 2, 4, 6, 16, 18)
|
||||
|
||||
closest should return [[2, 4, 2000], [4, 0, 103]] (or ([2, 4, 2000], [4, 0, 103])
|
||||
or [{2, 4, 2000}, {4, 0, 103}] or ... depending on the language)
|
||||
because 2000 and 103 have for weight 2 and 4, their indexes in strng are 4 and 0.
|
||||
The smallest difference is 2.
|
||||
4 (for 103) and 6 (for 123) have a difference of 2 too but they are not
|
||||
the smallest ones with a difference of 2 between their weights.
|
||||
....................
|
||||
|
||||
strng = "80 71 62 53"
|
||||
All the weights are 8.
|
||||
closest should return [[8, 0, 80], [8, 1, 71]]
|
||||
71 and 62 have also:
|
||||
- the smallest weights (which is 8 for all)
|
||||
- the smallest difference of weights (which is 0 for all pairs)
|
||||
- but not the smallest indices in strng.
|
||||
....................
|
||||
|
||||
strng = "444 2000 445 544"
|
||||
the weights are 12, 2, 13, 13 (ie 2, 12, 13, 13)
|
||||
|
||||
closest should return [[13, 2, 445], [13, 3, 544]] or ([13, 2, 445], [13, 3, 544])
|
||||
or [{13, 2, 445}, {13, 3, 544}] or ...
|
||||
444 and 2000 have the smallest weights (12 and 2) but not the smallest difference of weights;
|
||||
they are not the closest.
|
||||
Here the smallest difference is 0 and in the result the indexes are in ascending order.
|
||||
...................
|
||||
|
||||
closest("444 2000 445 644 2001 1002") --> [[3, 4, 2001], [3, 5, 1002]] or ([3, 4, 2001],
|
||||
[3, 5, 1002]]) or [{3, 4, 2001}, {3, 5, 1002}] or ...
|
||||
Here the smallest difference is 0 and in the result the indexes are in ascending order.
|
||||
...................
|
||||
|
||||
closest("239382 162 254765 182 485944 468751 49780 108 54")
|
||||
The weights are: 27, 9, 29, 11, 34, 31, 28, 9, 9.
|
||||
closest should return [[9, 1, 162], [9, 7, 108]] or ([9, 1, 162], [9, 7, 108])
|
||||
or [{9, 1, 162}, {9, 7, 108}] or ...
|
||||
108 and 54 have the smallest difference of weights too, they also have
|
||||
the smallest weights but they don't have the smallest ranks in the original string.
|
||||
..................
|
||||
|
||||
closest("54 239382 162 254765 182 485944 468751 49780 108")
|
||||
closest should return [[9, 0, 54], [9, 2, 162]] or ([9, 0, 54], [9, 2, 162])
|
||||
or [{9, 0, 54}, {9, 2, 162}] or ...
|
||||
Notes :
|
||||
If n == 0 closest("") should return []
|
||||
|
||||
or ([], []) in Haskell, Clojure, FSharp
|
||||
|
||||
or [{}, {}] in Elixir or '(() ()) in Racket
|
||||
|
||||
or {{0,0,0}, {0,0,0}} in C++
|
||||
|
||||
or "[(), ()]" in Go, Nim,
|
||||
|
||||
or "{{0,0,0}, {0,0,0}}" in C, NULL in R
|
||||
|
||||
or "" in Perl.
|
||||
|
||||
See Example tests for the format of the results in your language.
|
||||
60
5kyu/closest-and-smallest/solution.ts
Normal file
60
5kyu/closest-and-smallest/solution.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
const weight = (s: string): number => s.split('').reduce((acc, cur) => acc + parseInt(cur), 0);
|
||||
|
||||
const sortWeightInfo = <T extends WeightInfo | DiffInfo>(a: T, b: T): number => {
|
||||
if (a[0] !== b[0]) {
|
||||
return a[0] - b[0];
|
||||
} else if (a[1] !== b[1]) {
|
||||
return a[1] - b[1];
|
||||
} else {
|
||||
return a[2] - b[2];
|
||||
}
|
||||
}
|
||||
|
||||
type WeightInfo = [
|
||||
number, // weight
|
||||
number, // index
|
||||
number // number
|
||||
];
|
||||
type DiffInfo = [
|
||||
number, // weight difference
|
||||
number, // weight sum
|
||||
number, // index sum
|
||||
number, // index of first number
|
||||
number // index of second number
|
||||
];
|
||||
|
||||
export function closest(strng: string): number[][] {
|
||||
if (strng === '') return [];
|
||||
|
||||
const weights: WeightInfo[] = strng
|
||||
.split(' ')
|
||||
.map((s, i) => [weight(s), i, parseInt(s)]);
|
||||
|
||||
// calculate all weight differences, weight sum, and index sum
|
||||
const diffs: DiffInfo[] = [];
|
||||
for (const [weight, index, num] of weights) {
|
||||
for (let i = index + 1; i < weights.length; i++) {
|
||||
if(i >= weights.length) break;
|
||||
|
||||
const [weight2, index2, num2] = weights[i];
|
||||
const weightDiff = Math.abs(weight - weight2);
|
||||
const weightSum = weight + weight2;
|
||||
const indexSum = index + index2;
|
||||
diffs.push([weightDiff, weightSum, indexSum, index, index2]);
|
||||
}
|
||||
}
|
||||
|
||||
// sort by weight difference, weight sum, and index sum
|
||||
diffs.sort(sortWeightInfo);
|
||||
|
||||
const minimumDiff = diffs[0]
|
||||
const firstNumIndex = minimumDiff[3];
|
||||
const secondNumIndex = minimumDiff[4];
|
||||
|
||||
const result = [
|
||||
weights[firstNumIndex],
|
||||
weights[secondNumIndex]
|
||||
].sort(sortWeightInfo)
|
||||
|
||||
return result;
|
||||
}
|
||||
14
5kyu/closest-and-smallest/tests.ts
Normal file
14
5kyu/closest-and-smallest/tests.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { closest } from './solution';
|
||||
import { assert } from "chai";
|
||||
// chai.config.truncateThreshold = 0;
|
||||
|
||||
describe("Fixed Tests", function() {
|
||||
it("Basic tests closest", function() {
|
||||
assert.deepEqual(closest(""), []);
|
||||
assert.deepEqual(closest("103 123 4444 99 2000"), [[2, 4, 2000], [4, 0, 103]]);
|
||||
assert.deepEqual(closest("456899 50 11992 176 272293 163 389128 96 290193 85 52"), [[13, 9, 85], [14, 3, 176]]);
|
||||
assert.deepEqual(closest("239382 162 254765 182 485944 134 468751 62 49780 108 54"), [[8, 5, 134], [8, 7, 62]]);
|
||||
assert.deepEqual(closest("241259 154 155206 194 180502 147 300751 200 406683 37 57"), [[10, 1, 154], [10, 9, 37]]);
|
||||
assert.deepEqual(closest("89998 187 126159 175 338292 89 39962 145 394230 167 1"), [[13, 3, 175], [14, 9, 167]]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user