Task: Balanced ternary



C#: using System;
using System.Text;
using System.Collections.Generic;

public class BalancedTernary
{
	public static void Main()
	{
		BalancedTernary a = new BalancedTernary("+-0++0+");
		System.Console.WriteLine("a: " + a + " = " + a.ToLong());
		BalancedTernary b = new BalancedTernary(-436);
		System.Console.WriteLine("b: " + b + " = " + b.ToLong());
		BalancedTernary c = new BalancedTernary("+-++-");
		System.Console.WriteLine("c: " + c + " = " + c.ToLong());
		BalancedTernary d = a * (b - c);
		System.Console.WriteLine("a * (b - c): " + d + " = " + d.ToLong());
	}

	private enum BalancedTernaryDigit
	{
		MINUS = -1,
		ZERO = 0,
		PLUS = 1
	}

	private BalancedTernaryDigit[] value;

	
	public BalancedTernary()
	{
		this.value = new BalancedTernaryDigit[0];
	}

	
	public BalancedTernary(String str)
	{
		this.value = new BalancedTernaryDigit[str.Length];
		for (int i = 0; i < str.Length; ++i)
		{
			switch (str[i])
			{
				case '-':
					this.value[i] = BalancedTernaryDigit.MINUS;
					break;
				case '0':
					this.value[i] = BalancedTernaryDigit.ZERO;
					break;
				case '+':
					this.value[i] = BalancedTernaryDigit.PLUS;
					break;
				default:
					throw new ArgumentException("Unknown Digit: " + str[i]);
			}
		}
		Array.Reverse(this.value);
	}

	
	public BalancedTernary(long l)
	{
		List<BalancedTernaryDigit> value = new List<BalancedTernaryDigit>();
		int sign = Math.Sign(l);
		l = Math.Abs(l);
		
		while (l != 0)
		{
			byte rem = (byte)(l % 3);
			switch (rem)
			{
				case 0:
				case 1:
					value.Add((BalancedTernaryDigit)rem);
					l /= 3;
					break;
				case 2:
					value.Add(BalancedTernaryDigit.MINUS);
					l = (l + 1) / 3;
					break;
			}
		}

		this.value = value.ToArray();
		if (sign < 0)
		{
			this.Invert();
		}
	}

	
	public BalancedTernary(BalancedTernary origin)
	{
		this.value = new BalancedTernaryDigit[origin.value.Length];
		Array.Copy(origin.value, this.value, origin.value.Length);
	}

	
	private BalancedTernary(BalancedTernaryDigit[] value)
	{
		int end = value.Length - 1;
		while (value[end] == BalancedTernaryDigit.ZERO)
			--end;
		this.value = new BalancedTernaryDigit[end + 1];
		Array.Copy(value, this.value, end + 1);
	}

	
	private void Invert()
	{
		for (int i=0; i < this.value.Length; ++i)
		{
			this.value[i] = (BalancedTernaryDigit)(-(int)this.value[i]);
		}
	}

	
	override public String ToString()
	{
		StringBuilder result = new StringBuilder();
		for (int i = this.value.Length - 1; i >= 0; --i)
		{
			switch (this.value[i])
			{
				case BalancedTernaryDigit.MINUS:
					result.Append('-');
					break;
				case BalancedTernaryDigit.ZERO:
					result.Append('0');
					break;
				case BalancedTernaryDigit.PLUS:
					result.Append('+');
					break;
			}
		}
		return result.ToString();
	}

	
	public long ToLong()
	{
		long result = 0;
		int digit;
		for (int i = 0; i < this.value.Length; ++i)
		{
			result += (long)this.value[i] * (long)Math.Pow(3.0, (double)i);
		}
		return result;
	}

	
	public static BalancedTernary operator -(BalancedTernary origin)
	{
		BalancedTernary result = new BalancedTernary(origin);
		result.Invert();
		return result;
	}

	
	private static BalancedTernaryDigit carry = BalancedTernaryDigit.ZERO;
	private static BalancedTernaryDigit Add(BalancedTernaryDigit a, BalancedTernaryDigit b)
	{
		if (a != b)
		{
			carry = BalancedTernaryDigit.ZERO;
			return (BalancedTernaryDigit)((int)a + (int)b);
		}
		else
		{
			carry = a;
			return (BalancedTernaryDigit)(-(int)b);
		}
	}

	
	public static BalancedTernary operator +(BalancedTernary a, BalancedTernary b)
	{
		int maxLength = Math.Max(a.value.Length, b.value.Length);
		BalancedTernaryDigit[] resultValue = new BalancedTernaryDigit[maxLength + 1];
		for (int i=0; i < maxLength; ++i)
		{
			if (i < a.value.Length)
			{
				resultValue[i] = Add(resultValue[i], a.value[i]);
				resultValue[i+1] = carry;
			}
			else
			{
				carry = BalancedTernaryDigit.ZERO;
			}
			
			if (i < b.value.Length)
			{
				resultValue[i] = Add(resultValue[i], b.value[i]);
				resultValue[i+1] = Add(resultValue[i+1], carry);
			}
		}
		return new BalancedTernary(resultValue);
	}

	
	public static BalancedTernary operator -(BalancedTernary a, BalancedTernary b)
	{
		return a + (-b);
	}

	
	public static BalancedTernary operator *(BalancedTernary a, BalancedTernary b)
	{
		BalancedTernaryDigit[] longValue = a.value;
		BalancedTernaryDigit[] shortValue = b.value;
		BalancedTernary result = new BalancedTernary();
		if (a.value.Length < b.value.Length)
		{
			longValue = b.value;
			shortValue = a.value;
		}

		for (int i = 0; i < shortValue.Length; ++i)
		{
			if (shortValue[i] != BalancedTernaryDigit.ZERO)
			{
				BalancedTernaryDigit[] temp = new BalancedTernaryDigit[i + longValue.Length];
				for (int j = 0; j < longValue.Length; ++j)
				{
					temp[i+j] = (BalancedTernaryDigit)((int)shortValue[i] * (int)longValue[j]);
				}
				result = result + new BalancedTernary(temp);
			}
		}
		return result;
	}
}



Java: 
public class BalancedTernary 
{
	public static void main(String[] args)
	{
 		BTernary a=new BTernary("+-0++0+");
		BTernary b=new BTernary(-436);
		BTernary c=new BTernary("+-++-");
		
		System.out.println("a="+a.intValue());
		System.out.println("b="+b.intValue());
		System.out.println("c="+c.intValue());
		System.out.println();
		
		
		BTernary result=a.mul(b.sub(c));
		
		System.out.println("result= "+result+" "+result.intValue());
	}
	
	
	public static class BTernary
	{
		String value;
		public BTernary(String s)
		{
			int i=0;
			while(s.charAt(i)=='0')
				i++;
			this.value=s.substring(i);
		}
		public BTernary(int v)
		{
			this.value="";
			this.value=convertToBT(v);
		}
		
		private String convertToBT(int v)
		{
			if(v<0)
				return flip(convertToBT(-v));
			if(v==0)
				return "";
			int rem=mod3(v);
			if(rem==0)
				return convertToBT(v/3)+"0";
			if(rem==1)
				return convertToBT(v/3)+"+";
			if(rem==2)
				return convertToBT((v+1)/3)+"-";
			return "You can't see me";
		}
		private String flip(String s)
		{
			String flip="";
			for(int i=0;i<s.length();i++)
			{
				if(s.charAt(i)=='+')
					flip+='-';
				else if(s.charAt(i)=='-')
					flip+='+';
				else
					flip+='0';
			}
			return flip;
		}
		private int mod3(int v)
		{
			if(v>0)
				return v%3;
			v=v%3;
			return (v+3)%3;
		}
		
		public int intValue()
		{
			int sum=0;
			String s=this.value;
			for(int i=0;i<s.length();i++)
			{
				char c=s.charAt(s.length()-i-1);
				int dig=0;
				if(c=='+')
					dig=1;
				else if(c=='-')
					dig=-1;
				sum+=dig*Math.pow(3, i);
			}
			return sum;
		}
		
		
		public BTernary add(BTernary that)
		{
			String a=this.value;
			String b=that.value;
			
			String longer=a.length()>b.length()?a:b;
			String shorter=a.length()>b.length()?b:a;
			
			while(shorter.length()<longer.length())
				shorter=0+shorter;
			
			a=longer;
			b=shorter;
			
			char carry='0';
			String sum="";
			for(int i=0;i<a.length();i++)
			{
				int place=a.length()-i-1;
				String digisum=addDigits(a.charAt(place),b.charAt(place),carry);
				if(digisum.length()!=1)
					carry=digisum.charAt(0);
				else
					carry='0';
				sum=digisum.charAt(digisum.length()-1)+sum;
			}
			sum=carry+sum;
			
			return new BTernary(sum);
		}
		private String addDigits(char a,char b,char carry)
		{
			String sum1=addDigits(a,b);
			String sum2=addDigits(sum1.charAt(sum1.length()-1),carry);
			
			if(sum1.length()==1)
				return sum2;
			if(sum2.length()==1)
				return sum1.charAt(0)+sum2;
			return sum1.charAt(0)+"";
		}
		private String addDigits(char a,char b)
		{
			String sum="";
			if(a=='0')
				sum=b+"";
			else if (b=='0')
				sum=a+"";
			else if(a=='+')
			{
				if(b=='+')
					sum="+-";
				else
					sum="0";
			}
			else
			{
				if(b=='+')
					sum="0";
				else
					sum="-+";
			}
			return sum;
		}
		
		public BTernary neg()
		{
			return new BTernary(flip(this.value));
		}
		
		public BTernary sub(BTernary that)
		{
			return this.add(that.neg());
		}
		
		public BTernary mul(BTernary that)
		{
			BTernary one=new BTernary(1);
			BTernary zero=new BTernary(0);
			BTernary mul=new BTernary(0);
			
			int flipflag=0;
			if(that.compareTo(zero)==-1)
			{
				that=that.neg();
				flipflag=1;
			}
			for(BTernary i=new BTernary(1);i.compareTo(that)<1;i=i.add(one))
				mul=mul.add(this);
			
			if(flipflag==1)
				mul=mul.neg();
			return mul;
		}
		
		public boolean equals(BTernary that)
		{
			return this.value.equals(that.value);
		}
		public int compareTo(BTernary that)
		{
			if(this.intValue()>that.intValue())
				return 1;
			else if(this.equals(that))
				return 0;
			 return -1;
		}
		
		public String toString()
		{
			return value;
		}
	}
}