unique_prefixes.sf 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #!/usr/bin/ruby
  2. # Author: Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 28 September 2014
  5. # Website: http://github.com/trizen
  6. # Find the unique prefixes for an array of arrays of strings
  7. func abbrev(array, code=nil) {
  8. var END = "#{{}}"; # some unique value
  9. var CALL = (code != nil && code.is_a(Block));
  10. var table = Hash.new;
  11. array.each { |sub_array|
  12. var ref = table;
  13. sub_array.each { |item|
  14. ref = (ref{item} \\= Hash.new);
  15. };
  16. ref{END} = sub_array;
  17. }
  18. var abbrevs = [];
  19. func(hash) {
  20. var keys = hash.keys.sort;
  21. keys.each { |key|
  22. key == END && next;
  23. __FUNC__(hash{key});
  24. if (keys.len > 1) {
  25. var count = 1;
  26. var ref = hash.delete(key);
  27. while (var key = ref.keys[0]) {
  28. key.is_a(String) || next;
  29. key == END && do {
  30. var arr = ref{key}.ft(0, -count);
  31. CALL ? code.call(arr) : abbrevs.append(arr);
  32. break;
  33. };
  34. ref = ref{key};
  35. count++;
  36. }
  37. }
  38. }
  39. }(table);
  40. return abbrevs;
  41. }
  42. #
  43. ## Example: find the common directory from a list of dirs
  44. #
  45. var dirs = %w(
  46. /home/user1/tmp/coverage/test
  47. /home/user1/tmp/covert/operator
  48. /home/user1/tmp/coven/members
  49. );
  50. var uniq = abbrev(dirs.map{.split('/')}).min_by{.len};
  51. var dir = [uniq.pop, uniq.join('/')][1];
  52. assert_eq('/home/user1/tmp', dir);
  53. var words = %w(
  54. deodorant
  55. decor
  56. decorat
  57. decadere
  58. plecare
  59. placere
  60. plecat
  61. jaguar
  62. );
  63. abbrev(words.map{.split(1)}, func(a) { say a.join });