# Goal: Turn # # A -> B C # A -> B D # A -> B C D # A -> B D C # A -> C B # B -> B E # B -> B E C D # # into # # A -> B C # A -> C B # - # A -> B D # - # A -> B C D # A -> B D C # - # B -> B E # - # B -> B E C D # # Both the order of the groups and the order of rules within each # group are irrelevant. # # Idea: Do this for each lhs: as we read each line, sort its rhs and # use that sort as the key for a listhash (i.e. each key maps to a # list of values). At the end, for each key in the hash, print out its # list of values followed by the delimiter. $curlhs = ""; $first = 1; while (<>) { if (m/=>/) { print; next; } ($lhs, $rhs) = m/(.*) -> (.*)/; if (!$first && ($lhs ne $curlhs)) { @values = values(%map); while (@values) { @curlist = pop(@values); while (@curlist) { print @{pop(@curlist)}; } print "-\n"; } %map = (); } $curlhs = $lhs; $first = 0; @rhslist = split(" ", $rhs); @srhslist = sort(@rhslist); $srhs = join(" ", @srhslist); push(@{$map{$srhs}}, $_); } @values = values(%map); while (@values) { @curlist = pop(@values); while (@curlist) { print @{pop(@curlist)}; } print "-\n"; } %map = ();