Skip to content

Instantly share code, notes, and snippets.

@filiph
Last active April 15, 2021 23:22
Show Gist options
  • Save filiph/2ef66f371df91fba6a903ea65ade2d10 to your computer and use it in GitHub Desktop.
Save filiph/2ef66f371df91fba6a903ea65ade2d10 to your computer and use it in GitHub Desktop.
Combine lists
<h1 id="header">Combinations</h1>
<p>This tiny tool will combine any number of lists, combining every option with every other option. Separate lists by a blank line.</p>
<textarea id="input" rows=20 cols=40>
In college, I had
good grades,
bad grades,
I slept well,
I got no sleep,
and
I went to parties.
I had no social life.
</textarea>
<pre id="output">(nothing yet)</pre>
import 'dart:html';
void main() {
final textArea = querySelector('#input')! as TextAreaElement;
final output = querySelector('#output')!;
textArea.onInput.listen((_) => output.text = _update(textArea.value!));
// Run algorithm on the example input on load.
output.text = _update(textArea.value!);
}
/// Takes [text], combines the lists inside, and returns all combinations
/// as lines in a single string.
String _update(String text) {
var listStrings = text.split(RegExp('\n{2,}'));
var lists = listStrings
.map((s) =>
s.split('\n').where((s) => s.isNotEmpty).toList(growable: false))
.where((l) => l.isNotEmpty)
.toList(growable: false);
print(lists.join('x'));
var permutations = _combine(lists.first, lists.sublist(1));
return permutations.join('\n');
}
/// Recursively combines the strings in [head] with the strings in [tail].
List<String> _combine(List<String> head, List<List<String>> tail) {
if (head.isEmpty) return const [];
if (tail.isEmpty) return head;
return _combineTwo(
head,
_combine(
tail.first,
tail.sublist(1),
),
).toList(growable: false);
}
/// Combine just two string.
Iterable<String> _combineTwo(List<String> a, List<String> b) sync* {
for (final first in a) {
for (final second in b) {
yield '$first$second';
}
}
}
body {
color: white;
font-family: Arial, Helvetica, sans-serif;
padding: 4em;
}
#output {
margin: 4em 0;
max-width: 80vw;
overflow-x: scroll;
padding-bottom: 1em;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment