-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9cbd9ff
commit cf2641d
Showing
8 changed files
with
10,303 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
export default function* _bitsets() { | ||
const bitset = []; | ||
while (true) { | ||
yield new Progress(VALUE, bitset); | ||
yield* _increment(bitset); | ||
} | ||
} | ||
|
||
function* _increment(bitset) { | ||
const n = bitset.length; | ||
for (let i = 0; i < n; ++i) { | ||
if (bitset[i] === 0) { | ||
bitset[i] = 1; | ||
yield new Progress(ADD, i); | ||
return; | ||
} | ||
|
||
bitset[i] = 0; | ||
yield new Progress(REMOVE, i); | ||
} | ||
|
||
bitset.push(1); | ||
yield new Progress(ADD, n); | ||
} | ||
|
||
class Progress { | ||
constructor(type, value) { | ||
this.type = type; | ||
this.value = value; | ||
} | ||
} | ||
|
||
export const VALUE = 0; | ||
export const ADD = 1; | ||
export const REMOVE = 2; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import assert from 'assert'; | ||
import _bitsets, {ADD, REMOVE, VALUE} from './_bitsets.js'; | ||
|
||
import {iter} from '@iterable-iterator/iter'; | ||
import {next, StopIteration} from '@iterable-iterator/next'; | ||
import {filter} from '@iterable-iterator/filter'; | ||
|
||
export default function* _powerset(set) { | ||
const source = iter(set); | ||
const buffer = []; | ||
const stack = []; | ||
yield stack; | ||
for (const progress of filter(({type}) => type !== VALUE, _bitsets())) { | ||
switch (progress.type) { | ||
case ADD: | ||
if (progress.value === buffer.length) { | ||
try { | ||
buffer.push(next(source)); | ||
} catch (error) { | ||
if (error instanceof StopIteration) { | ||
assert(stack.length === 0); | ||
return; | ||
} | ||
|
||
throw error; | ||
} | ||
} | ||
|
||
assert(progress.value < buffer.length); | ||
stack.push(buffer[progress.value]); | ||
yield stack; | ||
break; | ||
default: | ||
assert(progress.type === REMOVE); | ||
assert(stack.length > 0); | ||
assert(stack[stack.length - 1] === buffer[progress.value]); | ||
stack.pop(); | ||
break; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
const answer = 42; | ||
export default answer; | ||
export {default as _bitsets} from './_bitsets.js'; | ||
export {default as _powerset} from './_powerset.js'; | ||
export {default as powerset} from './powerset.js'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import {map} from '@iterable-iterator/map'; | ||
import {list} from '@iterable-iterator/list'; | ||
import {reversed} from '@iterable-iterator/reversed'; | ||
import _powerset from './_powerset.js'; | ||
|
||
const powerset = (set) => | ||
map((subset) => list(reversed(subset)), _powerset(set)); | ||
export default powerset; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import test from 'ava'; | ||
|
||
import {powerset} from '../../src/index.js'; | ||
import {list} from '@iterable-iterator/list'; | ||
import {range} from '@iterable-iterator/range'; | ||
import {count} from '@iterable-iterator/count'; | ||
import {take} from '@iterable-iterator/slice'; | ||
|
||
const repr = (x) => (Array.isArray(x) ? JSON.stringify(x) : x.toString()); | ||
|
||
const whole = (t, set, expected) => { | ||
const result = list(powerset(set)); | ||
t.deepEqual(result, expected); | ||
}; | ||
|
||
whole.title = (title, set, expected) => | ||
title ?? `powerset(${repr(set)}) is ${repr(expected)}`; | ||
|
||
test(whole, range(0), [[]]); | ||
|
||
test(whole, range(1), [[], [0]]); | ||
|
||
test(whole, range(2), [[], [0], [1], [0, 1]]); | ||
|
||
test(whole, range(3), [[], [0], [1], [0, 1], [2], [0, 2], [1, 2], [0, 1, 2]]); | ||
|
||
const startsWith = (t, set, expected) => { | ||
const result = list(take(powerset(set), expected.length)); | ||
t.deepEqual(result, expected); | ||
}; | ||
|
||
startsWith.title = (title, set, expected) => | ||
title ?? `powerset(${repr(set)}) starts with ${repr(expected)}`; | ||
|
||
test('All subsets of NN!', startsWith, count(), [ | ||
[], | ||
[0], | ||
[1], | ||
[0, 1], | ||
[2], | ||
[0, 2], | ||
[1, 2], | ||
[0, 1, 2], | ||
[3], | ||
[0, 3], | ||
[1, 3], | ||
[0, 1, 3], | ||
[2, 3], | ||
[0, 2, 3], | ||
[1, 2, 3], | ||
[0, 1, 2, 3], | ||
]); |
Oops, something went wrong.