Skip to content

Commit a1219f9

Browse files
♻️ refactor(count/sequence): Improve API.
1 parent 8865b82 commit a1219f9

File tree

9 files changed

+145
-48
lines changed

9 files changed

+145
-48
lines changed

README.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,16 @@ See [docs](https://aureooms.github.io/js-set-partition/index.html).
2222
> [regenerator-runtime/runtime](https://www.npmjs.com/package/regenerator-runtime).
2323
2424
```js
25+
import {
26+
enumerate,
27+
count,
28+
_count,
29+
sequence,
30+
_sequence,
31+
isPartition
32+
} from '@aureooms/js-set-partition';
33+
2534
import {range, map} from '@aureooms/js-itertools';
26-
import {enumerate, count, sequence, isPartition} from '@aureooms/js-set-partition';
2735

2836
enumerate(range(0)); // []
2937
enumerate(range(1)); // [[0]]
@@ -38,10 +46,11 @@ count(5); // 52n
3846
count(6); // 203n
3947
count(26); // 49631246523618756274n
4048

41-
_count(6); // 203
42-
_count(26); // ???
49+
_count(1,6); // 203
50+
_count(1,26); // ???
4351

4452
sequence(); // 1n 1n 2n 3n 5n 15n 52n 203n ...
53+
_sequence(1); // 1 1 2 3 5 15 52 203 ...
4554

4655
isPartition(range(5), [range(5)]); // true
4756
isPartition(range(5), map(x => [x], range(5))); // true
@@ -66,8 +75,6 @@ isPartition(range(5), [[5], [0], [1], [2], [3], [4]]); // false
6675
[![Code issues](https://img.shields.io/codeclimate/issues/aureooms/js-set-partition.svg)](https://codeclimate.com/github/aureooms/js-set-partition/issues)
6776
[![Code maintainability](https://img.shields.io/codeclimate/maintainability/aureooms/js-set-partition.svg)](https://codeclimate.com/github/aureooms/js-set-partition/trends/churn)
6877
[![Code coverage (cov)](https://img.shields.io/codecov/c/gh/aureooms/js-set-partition/main.svg)](https://codecov.io/gh/aureooms/js-set-partition)
69-
<!--[![Code coverage (alls)](https://img.shields.io/coveralls/github/aureooms/js-set-partition/main.svg)](https://coveralls.io/r/aureooms/js-set-partition)-->
70-
<!--[![Code coverage (clim)](https://img.shields.io/codeclimate/coverage/aureooms/js-set-partition.svg)](https://codeclimate.com/github/aureooms/js-set-partition/trends/test_coverage_new_code)-->
7178
[![Code technical debt](https://img.shields.io/codeclimate/tech-debt/aureooms/js-set-partition.svg)](https://codeclimate.com/github/aureooms/js-set-partition/trends/technical_debt)
7279
[![Documentation](https://aureooms.github.io/js-set-partition/badge.svg)](https://aureooms.github.io/js-set-partition/source.html)
7380
[![Package size](https://img.shields.io/bundlephobia/minzip/@aureooms/js-set-partition)](https://bundlephobia.com/result?p=@aureooms/js-set-partition)

src/_count.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import {nth} from '@aureooms/js-itertools';
2+
3+
import _sequence from './_sequence';
4+
5+
const _count = (init, k) => nth(_sequence(init), k);
6+
export default _count;

src/_sequence.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export default function* _sequence(init) {
2+
yield init;
3+
const a = [init];
4+
while (true) {
5+
const n = a.length;
6+
let current = a[n - 1];
7+
yield current;
8+
for (let i = 0; i < n; ++i) {
9+
const next = current + a[i];
10+
a[i] = current;
11+
current = next;
12+
}
13+
14+
a.push(current);
15+
}
16+
}

src/count.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import {nth} from '@aureooms/js-itertools';
1+
import _count from './_count';
22

3-
import sequence from './sequence';
4-
5-
const count = (k) => nth(sequence(), k);
3+
const count = (k) => _count(1n, k);
64
export default count;

src/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1+
import _count from './_count';
12
import _enumerate from './_enumerate';
3+
import _sequence from './_sequence';
24
import count from './count';
35
import enumerate from './enumerate';
46
import isPartition from './isPartition';
57
import sequence from './sequence';
68

79
/* eslint import/no-anonymous-default-export: [2, {"allowObject": true}] */
810
export default {
11+
_count,
912
_enumerate,
13+
_sequence,
1014
count,
1115
enumerate,
1216
isPartition,
1317
sequence,
1418
};
1519

16-
export {_enumerate, count, enumerate, isPartition, sequence};
20+
export {_count, _enumerate, _sequence, count, enumerate, isPartition, sequence};

src/sequence.js

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,4 @@
1-
export default function* sequence() {
2-
yield 1n;
3-
const a = [1n];
4-
while (true) {
5-
const n = a.length;
6-
let current = a[n - 1];
7-
yield current;
8-
for (let i = 0; i < n; ++i) {
9-
const next = current + a[i];
10-
a[i] = current;
11-
current = next;
12-
}
1+
import _sequence from './_sequence';
132

14-
a.push(current);
15-
}
16-
}
3+
const sequence = () => _sequence(1n);
4+
export default sequence;

test/src/count.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import test from 'ava';
22

3-
import {count} from '../../src';
3+
import {count, _count} from '../../src';
44

55
const macro = (t, k, Bk) => {
66
t.is(count(k), Bk);
@@ -16,3 +16,17 @@ test(macro, 4, 15n);
1616
test(macro, 5, 52n);
1717
test(macro, 6, 203n);
1818
test(macro, 26, 49631246523618756274n);
19+
20+
const _macro = (t, k, Bk) => {
21+
t.is(_count(1, k), Bk);
22+
};
23+
24+
_macro.title = (title, k, Bk) => `_count(1, ${k}) = ${Bk}`;
25+
26+
test(_macro, 0, 1);
27+
test(_macro, 1, 1);
28+
test(_macro, 2, 2);
29+
test(_macro, 3, 5);
30+
test(_macro, 4, 15);
31+
test(_macro, 5, 52);
32+
test(_macro, 6, 203);

test/src/isPartition.js

Lines changed: 77 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,90 @@ import {iter, range, list, map} from '@aureooms/js-itertools';
44

55
import {isPartition} from '../../src';
66

7-
const macro = (t, n, partition, is) => {
8-
t.is(isPartition(range(n), partition), is, 'partition');
9-
t.is(isPartition(range(n), map(iter, partition)), is, 'map(iter, partition)');
7+
const macro = (t, set, partition, is) => {
8+
t.is(isPartition(set, partition), is, 'isPartition(set, partition)');
9+
10+
t.is(
11+
isPartition(set, map(iter, partition)),
12+
is,
13+
'isPartition(set, map(iter, partition))',
14+
);
15+
16+
t.is(
17+
isPartition(set, list(map(iter, partition))),
18+
is,
19+
'isPartition(set, list(map(iter, partition)))',
20+
);
21+
22+
t.is(
23+
isPartition(set, list(map((x) => x, partition))),
24+
is,
25+
'isPartition(set, list(map((x) => x, partition)))',
26+
);
27+
28+
t.is(
29+
isPartition(iter(set), partition),
30+
is,
31+
'isPartition(iter(set), partition)',
32+
);
33+
34+
t.is(
35+
isPartition(iter(set), map(iter, partition)),
36+
is,
37+
'isPartition(iter(set), map(iter, partition))',
38+
);
39+
1040
t.is(
11-
isPartition(range(n), list(map(iter, partition))),
41+
isPartition(iter(set), list(map(iter, partition))),
1242
is,
13-
'list(map(iter, partition))',
43+
'isPartition(iter(set), list(map(iter, partition)))',
1444
);
45+
1546
t.is(
16-
isPartition(range(n), list(map((x) => x, partition))),
47+
isPartition(iter(set), list(map((x) => x, partition))),
1748
is,
18-
'list(map(x => x, partition))',
49+
'isPartition(iter(set), list(map((x) => x, partition)))',
1950
);
2051
};
2152

22-
macro.title = (title, n, partition, is) =>
23-
`isPartition(${n}, ${JSON.stringify(partition)} = ${is})`;
53+
macro.title = (title, set, partition, is) =>
54+
`isPartition(${JSON.stringify(set)}, ${JSON.stringify(partition)} = ${is})`;
55+
56+
const yea = (t, set, partition) => macro(t, set, partition, true);
57+
yea.title = (title, set, partition) => macro.title(title, set, partition, true);
58+
59+
const nay = (t, set, partition) => macro(t, set, partition, false);
60+
nay.title = (title, set, partition) =>
61+
macro.title(title, set, partition, false);
62+
63+
const _5 = list(range(5));
64+
65+
test(yea, _5, [[0, 1, 2, 3, 4]]);
66+
test(yea, _5, [[0], [1], [2], [3], [4]]);
67+
test(yea, _5, [[0, 1], [2], [3], [4]]);
68+
test(yea, _5, [[2, 1], [3], [0, 4]]);
69+
70+
test(nay, _5, [[], [0], [1], [2], [3], [4]]);
71+
test(nay, _5, [[0], [0], [1], [2], [3], [4]]);
72+
test(nay, _5, [[5], [0], [1], [2], [3], [4]]);
73+
test(nay, _5, [[-1], [0], [1], [2], [3], [4]]);
74+
test(nay, _5, [[2 ** 53 - 1], [0], [1], [2], [3], [4]]);
75+
test(nay, _5, [[-(2 ** 53)], [0], [1], [2], [3], [4]]);
76+
77+
// From Wikipedia: https://en.wikipedia.org/wiki/Partition_of_a_set#Examples
78+
const _3 = [1, 2, 3];
2479

25-
test(macro, 5, [[0, 1, 2, 3, 4]], true);
26-
test(macro, 5, [[0], [1], [2], [3], [4]], true);
27-
test(macro, 5, [[0, 1], [2], [3], [4]], true);
28-
test(macro, 5, [[2, 1], [3], [0, 4]], true);
80+
// The set { 1, 2, 3 } has these five partitions (one partition per item):
81+
test(yea, _3, [[1], [2], [3]]);
82+
test(yea, _3, [[1, 2], [3]]);
83+
test(yea, _3, [[1, 3], [2]]);
84+
test(yea, _3, [[1], [2, 3]]);
85+
test(yea, _3, [[1, 2, 3]]);
2986

30-
test(macro, 5, [[], [0], [1], [2], [3], [4]], false);
31-
test(macro, 5, [[0], [0], [1], [2], [3], [4]], false);
32-
test(macro, 5, [[5], [0], [1], [2], [3], [4]], false);
33-
test(macro, 5, [[-1], [0], [1], [2], [3], [4]], false);
34-
test(macro, 5, [[2 ** 53 - 1], [0], [1], [2], [3], [4]], false);
35-
test(macro, 5, [[-(2 ** 53)], [0], [1], [2], [3], [4]], false);
87+
// The following are not partitions of { 1, 2, 3 }:
88+
test(nay, _3, [[], [1, 3], [2]]);
89+
test(nay, _3, [
90+
[1, 2],
91+
[2, 3],
92+
]);
93+
test(nay, _3, [[1], [2]]);

test/src/sequence.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,16 @@ import test from 'ava';
22

33
import {list, take} from '@aureooms/js-itertools';
44

5-
import {sequence} from '../../src';
5+
import {sequence, _sequence} from '../../src';
66

7-
test('sequence', (t) => {
8-
const n = 7;
7+
test('sequence()', (t) => {
98
const expected = [1n, 1n, 2n, 5n, 15n, 52n, 203n];
9+
const n = expected.length;
1010
t.deepEqual(list(take(sequence(), n)), expected);
1111
});
12+
13+
test('_sequence(1)', (t) => {
14+
const expected = [1, 1, 2, 5, 15, 52, 203];
15+
const n = expected.length;
16+
t.deepEqual(list(take(_sequence(1), n)), expected);
17+
});

0 commit comments

Comments
 (0)