AnalogueLine.scala

package net.snowtiger.analogue

/**
 * An AnalogueLine provides a way of creating a natural number using a pictographic
 * representation. See http://snowtiger.net/scala/analogue for a complete article
 * on the subject.
 *
 * Note that the base class companion object must be imported
 * (using import AnalogueLiteral._) in order to use the required constants and
 * implicit type conversions.
 *
 * @author Mark B Davies
 */
class AnalogueLine(n: Int) extends AnalogueLiteral
{
	val size = floor(n)

	override def equals(obj: Any) =
	{
		obj match
		{
			case i:Int => size==i
			case a:AnalogueLine => size==a.size
			case _ => false
		}
	}

	// Line construction - up to 9 ~ allowed before an O required
	def ~(other: AnalogueLine) = new AnalogueLine(2+size+other.size)
	def ~~(other: AnalogueLine) = new AnalogueLine(3+size+other.size)
	def ~~~(other: AnalogueLine) = new AnalogueLine(4+size+other.size)
	def ~~~~(other: AnalogueLine) = new AnalogueLine(5+size+other.size)
	def ~~~~~(other: AnalogueLine) = new AnalogueLine(6+size+other.size)
	def ~~~~~~(other: AnalogueLine) = new AnalogueLine(7+size+other.size)
	def ~~~~~~~(other: AnalogueLine) = new AnalogueLine(8+size+other.size)
	def ~~~~~~~~(other: AnalogueLine) = new AnalogueLine(9+size+other.size)
	def ~~~~~~~~~(other: AnalogueLine) = new AnalogueLine(10+size+other.size)

	// Helpers for constructing cubes
	def unary_+ = this
	def unary_! = this

	// Arithmetic operations on lines
	def +(other: AnalogueLine) = new AnalogueLine(size+other.size)
	def -(other: AnalogueLine) = new AnalogueLine(size-other.size)
	def *(other: AnalogueLine) = new AnalogueLine(size*other.size)
	def /(other: AnalogueLine) = new AnalogueLine(size/other.size)
	def +(other: Int) = new AnalogueLine(size+other)
	def -(other: Int) = new AnalogueLine(size-other)
	def *(other: Int) = new AnalogueLine(size*other)
	def /(other: Int) = new AnalogueLine(size/other)


	private val TenString = "~~~~~~~~~O"

	def sizeString = ""+size

	def pictureString() =
	{
		if (size==0)
			"O"
		else
		{
			val n = size-1
			"O" + TenString*(n/10) + "~"*(n%10) + "I"
		}
	}
}