Advertisement
Guest User

Untitled

a guest
May 26th, 2017
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.02 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. public class BlindAbacus : IEnumerable<BlindAbacus.Row>
  7. {
  8.     public int n;
  9.     public int rows;
  10.     public Row[] data;
  11.     private List<WeakReference> enumerators = new List<WeakReference>();
  12.  
  13.     public BlindAbacus(int n, int rows)
  14.     {
  15.         this.n = n;
  16.         this.rows = rows;
  17.         this.data = new Row[rows];
  18.         for (int i = 0; i < rows; i++)
  19.         {
  20.             data[i] = new Row(n-1);
  21.         }
  22.     }
  23.  
  24.     public BlindAbacus(int n, int value, bool x)
  25.     {
  26.         // count rows
  27.         int rows;
  28.         int[] initialData;
  29.         if (value != 0)
  30.         {
  31.             rows = 1;
  32.             int valueAtNextRow = n;
  33.             while (valueAtNextRow <= value)
  34.             {
  35.                 rows++;
  36.                 valueAtNextRow *= n;
  37.             }
  38.  
  39.             // prepare data
  40.             initialData = new int[rows];
  41.  
  42.             for (int i = rows - 1; i >= 0; i--)
  43.             {
  44.                 int tmp = 0;
  45.                 initialData[i] = 0;
  46.                 while (tmp + (int)Math.Pow(n, i) <= value && initialData[i] <= n - 1)
  47.                 {
  48.                     tmp += (int)Math.Pow(n, i);
  49.                     initialData[i]++;
  50.                 }
  51.                 value -= (int)Math.Pow(n, i) * initialData[i];
  52.             }
  53.         }
  54.         else
  55.         {
  56.             rows = 0;
  57.             initialData = new int[1];
  58.         }
  59.         this.n = n;
  60.         this.rows = rows;
  61.         this.data = new Row[rows];
  62.         for (int i = 0; i < rows; i++)
  63.         {
  64.             data[i] = new Row(n - 1);
  65.             data[i].add(initialData[i]);
  66.         }
  67.     }
  68.  
  69.     public override string ToString()
  70.     {
  71.         string result = "";
  72.  
  73.         for (int i = rows - 1; i >= 0; i--)
  74.         {
  75.             result += data[i].ToString();
  76.             if (i != 0) result += "\n";
  77.         }
  78.  
  79.         return result;
  80.     }
  81.  
  82.     public Row this[int i]
  83.     {
  84.         get
  85.         {
  86.             return data[i];
  87.         }
  88.  
  89.         set
  90.         {
  91.             this.data[i] = value;
  92.         }
  93.     }
  94.  
  95.     public static explicit operator int(BlindAbacus abacus)
  96.     {
  97.         int result = 0;
  98.         int x = 1;
  99.  
  100.         for (int i = 0; i < abacus.rows; i++, x = x * abacus.n)
  101.         {
  102.             result += abacus[i].State*x;
  103.         }
  104.  
  105.         return result;
  106.     }
  107.  
  108.     public static BlindAbacus operator +(BlindAbacus a, BlindAbacus b)
  109.     {
  110.         if (a.n == b.n)
  111.         {
  112.             return new BlindAbacus(a.n, (int)a+(int)b, true);
  113.         }
  114.         else throw new ComputationException();
  115.     }
  116.  
  117.     public static BlindAbacus operator -(BlindAbacus a, BlindAbacus b)
  118.     {
  119.         if (a.n == b.n)
  120.         {
  121.             return new BlindAbacus(a.n, (int)a-(int)b, true);
  122.         }
  123.         else throw new ComputationException();
  124.     }
  125.  
  126.     public static BlindAbacus operator ++(BlindAbacus a)
  127.     {
  128.         return new BlindAbacus(a.n, (int)a+1, true);
  129.     }
  130.  
  131.     public static BlindAbacus operator --(BlindAbacus a)
  132.     {
  133.         if ((int)a > 0)
  134.         {
  135.             return new BlindAbacus(a.n, (int)a - 1, true);
  136.         }
  137.         else throw new ComputationException();
  138.     }
  139.  
  140.     // enumerator
  141.     public IEnumerator<BlindAbacus.Row> GetEnumerator()
  142.     {
  143.         BlindAbacusEnumerator enumerator = new BlindAbacusEnumerator(this);
  144.         enumerators.Add(new WeakReference(enumerator));
  145.         return enumerator;
  146.     }
  147.     System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  148.     {
  149.         return GetEnumerator();
  150.     }
  151.  
  152.  
  153.     // internal classes
  154.     public class Row
  155.     {
  156.         int rowSize;
  157.         int state;
  158.  
  159.         public Row(int rowSize)
  160.         {
  161.             this.rowSize = rowSize;
  162.             this.state = 0;
  163.         }
  164.  
  165.         public void add(int x)
  166.         {
  167.             if (state < rowSize) {
  168.                 state += x;
  169.             } else throw new IncorrectRowValueException();
  170.         }
  171.         public void remove(int x)
  172.         {
  173.             if (state != 0)
  174.             {
  175.                 state -= x;
  176.             }
  177.             else throw new IncorrectRowValueException();
  178.         }
  179.  
  180.         public int State {
  181.             get {
  182.                 return state;
  183.             }
  184.         }
  185.  
  186.         public override string ToString()
  187.         {
  188.             string result = "";
  189.  
  190.             for (int i = 0; i < 2*rowSize; i++) {
  191.                 if (i < state || i >= state+rowSize) {
  192.                     result += "I";
  193.                 } else {
  194.                     result += "-";
  195.                 }
  196.             }
  197.  
  198.             return result;
  199.         }
  200.     }
  201.  
  202.     public class BlindAbacusEnumerator : IEnumerator<BlindAbacus.Row>
  203.     {
  204.         private readonly BlindAbacus outer;
  205.         public int i = -1;
  206.  
  207.         internal BlindAbacusEnumerator(BlindAbacus outer) {
  208.             this.outer = outer;
  209.         }
  210.  
  211.         public BlindAbacus.Row Current
  212.         {
  213.             get { return outer.data[i]; }
  214.         }
  215.  
  216.         void System.Collections.IEnumerator.Reset()
  217.         {
  218.             this.i = -1;
  219.         }
  220.  
  221.         bool System.Collections.IEnumerator.MoveNext()
  222.         {
  223.             foreach (WeakReference reference in outer.enumerators) {
  224.                 if (reference != null && (reference.Target as BlindAbacusEnumerator).i == i+1)
  225.                 {
  226.                     throw new SomeoneThereException();
  227.                 }
  228.             }
  229.             if (++i < outer.data.Length) return true;
  230.             return false;
  231.         }
  232.  
  233.         void IDisposable.Dispose() {
  234.             WeakReference toRemove = null;
  235.             foreach (WeakReference reference in outer.enumerators)
  236.             {
  237.                 if (reference != null && (reference.Target as BlindAbacusEnumerator) == this)
  238.                 {
  239.                     toRemove = reference;
  240.                 }
  241.             }
  242.             outer.enumerators.Remove(toRemove);
  243.         }
  244.  
  245.         object System.Collections.IEnumerator.Current
  246.         {
  247.             get { return outer.data[i]; }
  248.         }
  249.     }
  250.  
  251.     public class IncorrectRowValueException : Exception { }
  252.     public class ComputationException : Exception { }
  253.     public class SomeoneThereException : Exception { }
  254. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement