Skip to content

Instantly share code, notes, and snippets.

@Mouq
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Mouq/c4be050479e563c71408 to your computer and use it in GitHub Desktop.
Save Mouq/c4be050479e563c71408 to your computer and use it in GitHub Desktop.
my ($f,&t,&r,&c)=lines.comb(/<-[{}]>+/).SetHash,&substr,&return,&chars;while $f>1
{@$f.sort(-*.&c).combinations(2).map({sub
(\a,\b){r \(a,b,:m(a):v(c b))if a.index(b);for b.&c...1
->\v{->\x,\y{r \(a,b,:m(x~t y,v):v(v))if t(x,*-v)eq t y,0,v}(|$_)for
[a,b],[b,a]}}(|$_)}).sort(-*.<v>).uniq(:as{any @$_}:with(&[eq])).map:{$f{@$_}»--;$f{.<m>}++}}
say @$f
class Text::Merge { ... }
my @frags = lines.comb(/\{ <( <-[{}]>+ <?[}]>/);
say Text::Merge.new(@frags).merge;
class Text::Merge {
has SetHash $.fragments;
method new (*@frags) {
self.bless: :fragments(@frags.SetHash);
}
my class MergeCandidate {
has @.originals;
has Int $.overlap;
has Str $.merge;
method gist {
"Merge from {@!originals.>>.perl.join(", ")} into {$!merge.perl}.\n"
}
}
method merge returns Str {
while $!fragments > 1 {
my @cands = @$!fragments.sort(-*.chars).combinations(2).map: -> [$a, $b] {
$.find-merge-candidate($a, $b) // Nil
}
die join "\n ", "Could not find overlap between any of:", @$!fragments unless @cands;
@cands = @cands.sort(-*.overlap).uniq(:as{any .originals}, :with(&[eq]));
$.mini-merge($_) for @cands;
}
@$!fragments[0]
}
method find-merge-candidate (Str $a, Str $b where .chars <= $a.chars) {
# a contains b
if $a.index($b) {
return MergeCandidate.new: :originals($a, $b),
:merge($a),
:overlap($b.chars);
}
my Bool $b-start = defined $a.index: $b.substr(0, 1);
my Bool $b-end = defined $a.index: $b.substr(*-1);
if $b-start || $b-end {
my &merge-end = -> $s1, $s2, $overlap {
if $s1.substr(*-$overlap) eq $s2.substr(0, $overlap) {
return MergeCandidate.new: :originals($a, $b),
:merge($s1 ~ $s2.substr($overlap)),
:$overlap;
}
}
for $b.chars ... 1 {
# a ends with start of b (i.e. b begins with end of a)
merge-end $a, $b, $_ if $b-start;
# b ends with start of a (i.e. a begins with end of b)
merge-end $b, $a, $_ if $b-end;
}
}
}
method mini-merge (MergeCandidate $_) {
$!fragments{.originals}:delete;
$!fragments{.merge}++;
}
}
{hat end}{all is well}{ell that en}{t ends well}{ends}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment