/* * Input: - Two INCLUSIVE ranges * - ...that must have a part in common * - ...and must be canonicalized as follows: * a.from <= b.from is always true * a.to < b.to if a.from==b.from is always true * from <= to is always true for a & b * Output: Three disjoint sets: (A - common, common, B - common) * each set can be zero, one or more char ranges * This code is very tricky, needs a lot of testing */ private static Untangle untangle__(int aFrom, int aTo, int bFrom, int bTo) { Untangle ret = new Untangle(); int f1 = aFrom; int t1 = bFrom - 1; if (f1 <= t1) { ret.onlyA.Add(new CharRange((char)f1, (char)t1)); } f1 = bTo + 1; t1 = aTo; if (f1 <= t1) { ret.onlyA.Add(new CharRange((char)f1, (char)t1)); } f1 = aTo + 1; t1 = bTo; if (f1 <= t1) { ret.onlyB.Add(new CharRange((char)f1, (char)t1)); } f1 = bFrom; t1 = Math.Min(aTo, bTo); ret.common = new CharRange((char)f1, (char)t1); return(ret); }
private Untangle _untangle(Tuple <Trans, int> t1, Tuple <Trans, int> t2) { CharRange a = (CharRange)t1.Item1; CharRange b = (CharRange)t2.Item1; Untangle u = Untangle.untangle(a.From, a.To, b.From, b.To); return(u); }
public static Untangle untangle(int aFrom, int aTo, int bFrom, int bTo) { if (aFrom > bTo || aFrom > aTo) { Untangle result = new Untangle(); result.onlyA.Add(new CharRange((char)aFrom, (char)aTo)); result.onlyB.Add(new CharRange((char)bFrom, (char)bTo)); result.common = null; return(result); } else { bool swap = false; if (aFrom > bFrom) { swap = true; int temp = aFrom; aFrom = bFrom; bFrom = temp; temp = aTo; aTo = bTo; bTo = temp; } if (aFrom == bFrom && aTo > bTo) { swap = true; int temp = aFrom; aFrom = bFrom; bFrom = temp; temp = aTo; aTo = bTo; bTo = temp; } Untangle ret = untangle__(aFrom, aTo, bFrom, bTo); if (swap) { List <CharRange> temp = ret.onlyA; ret.onlyA = ret.onlyB; ret.onlyB = temp; } return(ret); } }
private List <Tuple <Trans, int> > removeCommonTransitions(List <Tuple <Trans, int> > _transitions) { List <Tuple <Trans, int> > transitions = new List <Tuple <Trans, int> > (); transitions.AddRange(_transitions); while (true) { bool toSplit = false; Tuple <Trans, int> split1 = null, split2 = null; for (int i = 0; i < transitions.Count; ++i) { Tuple <Trans, int> a = transitions[i]; for (int j = i + 1; j < transitions.Count; ++j) { Tuple <Trans, int> b = transitions[j]; if (a.Item2 != b.Item2 && (!equal(a.Item1, b.Item1)) && hasCommon(a.Item1, b.Item1)) { toSplit = true; split1 = a; split2 = b; goto outer; } } } outer: if (toSplit) { Untangle unt = _untangle(split1, split2); // todo: does erase handle this specialized item type? transitions.Remove(split1); // todo: same transitions.Remove(split2); addTranss(transitions, unt.onlyA, split1.Item2); addTranss(transitions, unt.onlyB, split2.Item2); transitions.Add(new Tuple <Trans, int>(unt.common, split1.Item2)); transitions.Add(new Tuple <Trans, int>(unt.common, split2.Item2)); } else { break; } } return(transitions); }