12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- #!/usr/bin/ruby
- # Author: Daniel "Trizen" Șuteu
- # License: GPLv3
- # Date: 28 September 2014
- # Website: https://github.com/trizen
- # Find the unique prefixes for an array of arrays of strings
- func abbrev(array, code=nil) {
- var END = "#{{}}"; # some unique value
- var CALL = (code != nil && code.is_a(Block));
- var table = Hash.new;
- array.each { |sub_array|
- var ref = table;
- sub_array.each { |item|
- ref = (ref{item} \\= Hash.new);
- };
- ref{END} = sub_array;
- }
- var abbrevs = [];
- func(hash) {
- var keys = hash.keys.sort;
- keys.each { |key|
- key == END && next;
- __FUNC__(hash{key});
- if (keys.len > 1) {
- var count = 0;
- var ref = hash.delete(key);
- while (var key = ref.keys[0]) {
- key.is_a(String) || next;
- key == END && do {
- var arr = ref{key}.flip.slice(count).flip;
- CALL ? code.call(arr) : abbrevs.append(arr);
- break;
- };
- ref = ref{key};
- count++;
- }
- }
- }
- }(table);
- return abbrevs;
- }
- #
- ## Example: find the common directory from a list of dirs
- #
- var dirs = %w(
- /home/user1/tmp/coverage/test
- /home/user1/tmp/covert/operator
- /home/user1/tmp/coven/members
- );
- var uniq = abbrev(dirs.map{.split('/')}).min_by{.len};
- var dir = [uniq.pop, uniq.join('/')][1];
- assert_eq('/home/user1/tmp', dir);
- var words = %w(
- deodorant
- decor
- decorat
- decadere
- plecare
- placere
- plecat
- jaguar
- );
- assert_eq(
- gather {
- abbrev(words.map{.split(1)}, func(a) { say take(a.join) });
- },
- %w(deca decora deco deo j pla plecar plecat)
- )
|