Created
February 11, 2018 06:49
-
-
Save rkhapov/aa14e5e08a2860eaf4b5a8f82e4880b8 to your computer and use it in GitHub Desktop.
cvs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Linq; | |
| using System.Collections.Generic; | |
| namespace Clones | |
| { | |
| public class FastStackNode<T> | |
| { | |
| public FastStackNode<T> Prev; | |
| public T Value; | |
| } | |
| public class FastStack<T> | |
| { | |
| private FastStackNode<T> top; | |
| public bool IsEmpty | |
| { | |
| get | |
| { | |
| return top == null; | |
| } | |
| } | |
| public FastStack() | |
| { | |
| top = null; | |
| } | |
| public FastStack(FastStack<T> st) | |
| { | |
| top = st.top; | |
| } | |
| public void Push(T value) | |
| { | |
| top = new FastStackNode<T> { Prev = top, Value = value }; | |
| } | |
| public T Pop() | |
| { | |
| if (top == null) | |
| throw new InvalidOperationException("The stack is too empty to do Pop operation"); | |
| var value = top.Value; | |
| top = top.Prev; | |
| return value; | |
| } | |
| public T Top | |
| { | |
| get | |
| { | |
| if (top == null) | |
| throw new InvalidOperationException("The stack is too empty for getting Top value"); | |
| return top.Value; | |
| } | |
| } | |
| } | |
| public class Clone | |
| { | |
| public FastStack<int> Programms; | |
| public FastStack<int> History; | |
| public Clone() | |
| { | |
| Programms = new FastStack<int>(); | |
| History = new FastStack<int>(); | |
| } | |
| public Clone(Clone clone) | |
| { | |
| Programms = new FastStack<int>(clone.Programms); | |
| History = new FastStack<int>(clone.History); | |
| } | |
| } | |
| public static class CvsCommandFactory | |
| { | |
| public static ICvsCommand CreateCommandFromQuery(string query, CloneVersionSystem cvs) | |
| { | |
| var tokens = query.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) | |
| .Select(op => op.ToLower()) | |
| .ToList(); | |
| int cloneNumber = int.Parse(tokens[1]); | |
| if (tokens[0] == "learn") | |
| return new LearnCommand(cvs, cloneNumber, int.Parse(tokens[2])); | |
| if (tokens[0] == "rollback") | |
| return new RollbackCommand(cvs, cloneNumber); | |
| if (tokens[0] == "relearn") | |
| return new RelearnCommand(cvs, cloneNumber); | |
| if (tokens[0] == "clone") | |
| return new CloneCommand(cvs, cloneNumber); | |
| if (tokens[0] == "check") | |
| return new CheckCommand(cvs, cloneNumber); | |
| throw new ArgumentException("Invalid query"); | |
| } | |
| } | |
| public abstract class ICvsCommand | |
| { | |
| public readonly CloneVersionSystem Cvs; | |
| public readonly int CloneNumber; | |
| public ICvsCommand(CloneVersionSystem cvs, int cloneNumber) | |
| { | |
| Cvs = cvs; | |
| CloneNumber = cloneNumber; | |
| } | |
| public abstract string Execute(); | |
| } | |
| public class LearnCommand : ICvsCommand | |
| { | |
| private readonly int commandNumber; | |
| public LearnCommand(CloneVersionSystem cvs, int cloneNumber, int commandNumber) : base(cvs, cloneNumber) | |
| { | |
| this.commandNumber = commandNumber; | |
| } | |
| public override string Execute() | |
| { | |
| Cvs.Clones[CloneNumber - 1].Programms.Push(commandNumber); | |
| return null; | |
| } | |
| } | |
| public class RollbackCommand : ICvsCommand | |
| { | |
| public RollbackCommand(CloneVersionSystem cvs, int cloneNumber) : base(cvs, cloneNumber) | |
| { | |
| } | |
| public override string Execute() | |
| { | |
| Cvs.Clones[CloneNumber - 1].History.Push(Cvs.Clones[CloneNumber - 1].Programms.Pop()); | |
| return null; | |
| } | |
| } | |
| public class RelearnCommand : ICvsCommand | |
| { | |
| public RelearnCommand(CloneVersionSystem cvs, int cloneNumber) : base(cvs, cloneNumber) | |
| { | |
| } | |
| public override string Execute() | |
| { | |
| Cvs.Clones[CloneNumber - 1].Programms.Push(Cvs.Clones[CloneNumber - 1].History.Pop()); | |
| return null; | |
| } | |
| } | |
| public class CloneCommand : ICvsCommand | |
| { | |
| public CloneCommand(CloneVersionSystem cvs, int cloneNumber) : base(cvs, cloneNumber) | |
| { | |
| } | |
| public override string Execute() | |
| { | |
| Cvs.Clones.Add(new Clone(Cvs.Clones[CloneNumber - 1])); | |
| return null; | |
| } | |
| } | |
| public class CheckCommand : ICvsCommand | |
| { | |
| public CheckCommand(CloneVersionSystem cvs, int cloneNumber) : base(cvs, cloneNumber) | |
| { | |
| } | |
| public override string Execute() | |
| { | |
| if (Cvs.Clones[CloneNumber - 1].Programms.IsEmpty) | |
| return "basic"; | |
| return Cvs.Clones[CloneNumber - 1].Programms.Top.ToString(); | |
| } | |
| } | |
| public class CloneVersionSystem : ICloneVersionSystem | |
| { | |
| public List<Clone> Clones; | |
| public CloneVersionSystem() | |
| { | |
| Clones = new List<Clone> | |
| { | |
| new Clone() | |
| }; | |
| } | |
| public string Execute(string query) | |
| { | |
| return CvsCommandFactory.CreateCommandFromQuery(query, this).Execute(); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment