using System; public interface Visitor{ int Visit (IntInterval iv); int Visit (IntSingular iv); int Visit (IntCompSeq iv); } public abstract class IntSequence { public abstract int Accept(Visitor v); } public class IntInterval: IntSequence{ private int from, to; public IntInterval(int from, int to){ this.from = from; this.to = to; } public int From{ get{return from;} } public int To{ get{return to;} } public override int Accept(Visitor v){ return v.Visit(this); } } public class IntSingular: IntSequence{ private int it; public IntSingular(int it){ this.it = it; } public int TheInt{ get{return it;} } public override int Accept(Visitor v){ return v.Visit(this); } } public class IntCompSeq: IntSequence{ private IntSequence s1, s2; // Binary sequence: Exactly two subsequences. public IntCompSeq(IntSequence s1, IntSequence s2) { this.s1 = s1; this.s2 = s2; } public IntSequence First{ get{return s1;} } public IntSequence Second{ get{return s2;} } public override int Accept(Visitor v){ return v.Visit(this); } } public class MinVisitor: Visitor{ public int Visit (IntInterval iv){ return Math.Min(iv.From, iv.To); } public int Visit (IntSingular iv){ return iv.TheInt; } public int Visit (IntCompSeq iv){ return Math.Min(iv.First.Accept(this), iv.Second.Accept(this)); } } public class MaxVisitor: Visitor{ public int Visit (IntInterval iv){ return Math.Max(iv.From, iv.To); } public int Visit (IntSingular iv){ return iv.TheInt; } public int Visit (IntCompSeq iv){ return Math.Max(iv.First.Accept(this), iv.Second.Accept(this)); } } public class SumVisitor: Visitor{ public int Visit (IntInterval iv){ int res = 0; int lower = Math.Min(iv.From,iv.To), upper = Math.Max(iv.From,iv.To); for (int i = lower; i <= upper; i++) res += i; return res; } public int Visit (IntSingular iv){ return iv.TheInt; } public int Visit (IntCompSeq iv){ return (iv.First.Accept(this) + iv.Second.Accept(this)); } }