Skip to content

Instantly share code, notes, and snippets.

@rkhapov
Created February 11, 2018 06:49
Show Gist options
  • Select an option

  • Save rkhapov/aa14e5e08a2860eaf4b5a8f82e4880b8 to your computer and use it in GitHub Desktop.

Select an option

Save rkhapov/aa14e5e08a2860eaf4b5a8f82e4880b8 to your computer and use it in GitHub Desktop.
cvs
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