fork download
  1. #!/usr/bin/perl
  2. use 5.016;
  3. use warnings;
  4. use List::Util qw(first max reduce);
  5. use Data::Dumper;
  6. local $Data::Dumper::Terse = 1;
  7. local $Data::Dumper::Indent = 0;
  8.  
  9. sub combi {
  10. my ($n, $s, $r) = @_;
  11.  
  12. ($n > 0) or return $r;
  13.  
  14. combi($n - 1, [@{$s}[$_ + 1 .. $#{$s}]], [@{$r}, $s->[$_]])
  15. } (0 .. $#{$s});
  16. }
  17.  
  18. sub del { [@{$_[0]}[0 .. $_[1] - 1, $_[1] + 1 .. $#{$_[0]}]] }
  19.  
  20. sub find { first{ $_[0]->[$_]->[0] eq $_[1]->[0] } (0 .. $#{$_[0]}) }
  21.  
  22. sub diff {
  23. reduce{
  24. sub{ defined $_[0] ? del($a, $_[0]) : $a }->(find($a, $b))
  25. } $_[0], @{$_[1]}
  26. }
  27.  
  28. sub go_end {
  29. my ($s, $e, $t, $r) = @_;
  30.  
  31. go_start(
  32. diff($s, $_),
  33. [@{$e}, @{$_}],
  34. $t + max(map{ $_->[1] } @{$_}),
  35. [@{$r}, [map{ $_->[0] } @{$_}]]
  36. )
  37. } combi(2, $s, []);
  38. }
  39.  
  40. sub go_start {
  41. my ($s, $e, $t, $r) = @_;
  42.  
  43. (@{$s} > 0) or return [$t, $r];
  44.  
  45. go_end(
  46. [@{$s}, $_],
  47. diff($e, [$_]),
  48. $t + $_->[1],
  49. [@{$r}, $_->[0]]
  50. )
  51. } @{$e};
  52. }
  53.  
  54. sub f {
  55. reduce{$b->[0] < $a->[0] ? $b : $a } go_end([@_], [], 0, [])
  56. }
  57.  
  58. say Dumper(f(['A', 1], ['B', 2], ['C', 5], ['D', 10]));
  59.  
Success #stdin #stdout 0.03s 7476KB
stdin
Standard input is empty
stdout
[17,[['A','B'],'A',['C','D'],'B',['A','B']]]