Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- public class BlindAbacus : IEnumerable<BlindAbacus.Row>
- {
- public int n;
- public int rows;
- public Row[] data;
- private List<WeakReference> enumerators = new List<WeakReference>();
- public BlindAbacus(int n, int rows)
- {
- this.n = n;
- this.rows = rows;
- this.data = new Row[rows];
- for (int i = 0; i < rows; i++)
- {
- data[i] = new Row(n-1);
- }
- }
- public BlindAbacus(int n, int value, bool x)
- {
- // count rows
- int rows;
- int[] initialData;
- if (value != 0)
- {
- rows = 1;
- int valueAtNextRow = n;
- while (valueAtNextRow <= value)
- {
- rows++;
- valueAtNextRow *= n;
- }
- // prepare data
- initialData = new int[rows];
- for (int i = rows - 1; i >= 0; i--)
- {
- int tmp = 0;
- initialData[i] = 0;
- while (tmp + (int)Math.Pow(n, i) <= value && initialData[i] <= n - 1)
- {
- tmp += (int)Math.Pow(n, i);
- initialData[i]++;
- }
- value -= (int)Math.Pow(n, i) * initialData[i];
- }
- }
- else
- {
- rows = 0;
- initialData = new int[1];
- }
- this.n = n;
- this.rows = rows;
- this.data = new Row[rows];
- for (int i = 0; i < rows; i++)
- {
- data[i] = new Row(n - 1);
- data[i].add(initialData[i]);
- }
- }
- public override string ToString()
- {
- string result = "";
- for (int i = rows - 1; i >= 0; i--)
- {
- result += data[i].ToString();
- if (i != 0) result += "\n";
- }
- return result;
- }
- public Row this[int i]
- {
- get
- {
- return data[i];
- }
- set
- {
- this.data[i] = value;
- }
- }
- public static explicit operator int(BlindAbacus abacus)
- {
- int result = 0;
- int x = 1;
- for (int i = 0; i < abacus.rows; i++, x = x * abacus.n)
- {
- result += abacus[i].State*x;
- }
- return result;
- }
- public static BlindAbacus operator +(BlindAbacus a, BlindAbacus b)
- {
- if (a.n == b.n)
- {
- return new BlindAbacus(a.n, (int)a+(int)b, true);
- }
- else throw new ComputationException();
- }
- public static BlindAbacus operator -(BlindAbacus a, BlindAbacus b)
- {
- if (a.n == b.n)
- {
- return new BlindAbacus(a.n, (int)a-(int)b, true);
- }
- else throw new ComputationException();
- }
- public static BlindAbacus operator ++(BlindAbacus a)
- {
- return new BlindAbacus(a.n, (int)a+1, true);
- }
- public static BlindAbacus operator --(BlindAbacus a)
- {
- if ((int)a > 0)
- {
- return new BlindAbacus(a.n, (int)a - 1, true);
- }
- else throw new ComputationException();
- }
- // enumerator
- public IEnumerator<BlindAbacus.Row> GetEnumerator()
- {
- BlindAbacusEnumerator enumerator = new BlindAbacusEnumerator(this);
- enumerators.Add(new WeakReference(enumerator));
- return enumerator;
- }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- // internal classes
- public class Row
- {
- int rowSize;
- int state;
- public Row(int rowSize)
- {
- this.rowSize = rowSize;
- this.state = 0;
- }
- public void add(int x)
- {
- if (state < rowSize) {
- state += x;
- } else throw new IncorrectRowValueException();
- }
- public void remove(int x)
- {
- if (state != 0)
- {
- state -= x;
- }
- else throw new IncorrectRowValueException();
- }
- public int State {
- get {
- return state;
- }
- }
- public override string ToString()
- {
- string result = "";
- for (int i = 0; i < 2*rowSize; i++) {
- if (i < state || i >= state+rowSize) {
- result += "I";
- } else {
- result += "-";
- }
- }
- return result;
- }
- }
- public class BlindAbacusEnumerator : IEnumerator<BlindAbacus.Row>
- {
- private readonly BlindAbacus outer;
- public int i = -1;
- internal BlindAbacusEnumerator(BlindAbacus outer) {
- this.outer = outer;
- }
- public BlindAbacus.Row Current
- {
- get { return outer.data[i]; }
- }
- void System.Collections.IEnumerator.Reset()
- {
- this.i = -1;
- }
- bool System.Collections.IEnumerator.MoveNext()
- {
- foreach (WeakReference reference in outer.enumerators) {
- if (reference != null && (reference.Target as BlindAbacusEnumerator).i == i+1)
- {
- throw new SomeoneThereException();
- }
- }
- if (++i < outer.data.Length) return true;
- return false;
- }
- void IDisposable.Dispose() {
- WeakReference toRemove = null;
- foreach (WeakReference reference in outer.enumerators)
- {
- if (reference != null && (reference.Target as BlindAbacusEnumerator) == this)
- {
- toRemove = reference;
- }
- }
- outer.enumerators.Remove(toRemove);
- }
- object System.Collections.IEnumerator.Current
- {
- get { return outer.data[i]; }
- }
- }
- public class IncorrectRowValueException : Exception { }
- public class ComputationException : Exception { }
- public class SomeoneThereException : Exception { }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement