How to resolve the algorithm Imaginary base numbers step by step in the Wren programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Imaginary base numbers step by step in the Wren programming language

Table of Contents

Problem Statement

Imaginary base numbers are a non-standard positional numeral system which uses an imaginary number as its radix. The most common is quater-imaginary with radix 2i. The quater-imaginary numeral system was first proposed by Donald Knuth in 1955 as a submission for a high school science talent search. [Ref.] Other imaginary bases are possible too but are not as widely discussed and aren't specifically named. Task: Write a set of procedures (functions, subroutines, however they are referred to in your language) to convert base 10 numbers to an imaginary base and back. At a minimum, support quater-imaginary (base 2i). For extra kudos, support positive or negative bases 2i through 6i (or higher). As a stretch goal, support converting non-integer numbers ( E.G. 227.65625+10.859375i ) to an imaginary base. See Wikipedia: Quater-imaginary_base for more details. For reference, here are some some decimal and complex numbers converted to quater-imaginary.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Imaginary base numbers step by step in the Wren programming language

Source code in the wren programming language

import "./complex" for Complex
import "./fmt" for Fmt

class QuaterImaginary {
    construct new(b2i) {
       if (b2i.type != String || b2i == "" || !b2i.all { |d| "0123.".contains(d) } ||
           b2i.count { |d| d == "." } > 1) Fiber.abort("Invalid Base 2i number.")
        _b2i = b2i
    }

    // only works properly if 'c.real' and 'c.imag' are both integral
    static fromComplex(c) {
        if (c.real == 0 && c.imag == 0) return QuaterImaginary.new("0")
        var re = c.real.truncate
        var im = c.imag.truncate
        var fi = -1
        var sb = ""
        while (re != 0) {
            var rem = re % (-4)
            re = (re/(-4)).truncate
            if (rem < 0) {
                rem = 4 + rem
                re = re + 1
            }
            if (rem == -0) rem = 0 // get rid of minus zero
            sb = sb + rem.toString + "0"
        }
        if (im != 0) {
            var f = (Complex.new(0, c.imag) / Complex.imagTwo).real
            im = f.ceil
            f = -4 * (f - im)
            var index = 1
            while (im != 0) {
                var rem = im % (-4)
                im = (im/(-4)).truncate
                if (rem < 0) {
                    rem = 4 + rem
                    im = im + 1
                }
                if (index < sb.count) {
                    var sbl = sb.toList
                    sbl[index] = String.fromByte(rem + 48)
                    sb = sbl.join()
                } else {
                    if (rem == -0) rem = 0 // get rid of minus zero
                    sb = sb + "0" + rem.toString
                }
                index = index + 2
            }
            fi = f.truncate
        }
        if (sb.count > 0) sb = sb[-1..0]
        if (fi != -1) {
            if (fi == -0) fi = 0 // get rid of minus zero
            sb = sb + ".%(fi)"
        }
        sb = sb.trimStart("0")
        if (sb.startsWith(".")) sb = "0" + sb
        return QuaterImaginary.new(sb)
    }

    toComplex {
        var pointPos = _b2i.indexOf(".")
        var posLen = (pointPos != -1) ? pointPos : _b2i.count
        var sum = Complex.zero
        var prod = Complex.one
        for (j in 0...posLen) {
            var k = _b2i.bytes[posLen-1-j] - 48
            if (k > 0) sum = sum + prod * k
            prod = prod * Complex.imagTwo
        }
        if (pointPos != -1) {
            prod = Complex.imagTwo.inverse
            var j = posLen + 1
            while (j < _b2i.count) {
                var k = _b2i.bytes[j] - 48
                if (k > 0) sum = sum + prod * k
                prod = prod / Complex.imagTwo
                j = j + 1
            }
        }
        return sum
    }

    toString { _b2i }
}

var imagOnly = Fn.new { |c| c.imag.toString + "i" }

var fmt = "$4s -> $8s -> $4s"
Complex.showAsReal = true
for (i in 1..16) {
    var c1 = Complex.new(i, 0)
    var qi = QuaterImaginary.fromComplex(c1)
    var c2 = qi.toComplex
    Fmt.write("%(fmt)     ", c1, qi, c2)
    c1 = -c1
    qi = QuaterImaginary.fromComplex(c1)
    c2 = qi.toComplex
    Fmt.print(fmt, c1, qi, c2)
}
System.print()
for (i in 1..16) {
    var c1 = Complex.new(0, i)
    var qi = QuaterImaginary.fromComplex(c1)
    var c2 = qi.toComplex
    Fmt.write("%(fmt)     ", imagOnly.call(c1), qi, imagOnly.call(c2))
    c1 = -c1
    qi = QuaterImaginary.fromComplex(c1)
    c2 = qi.toComplex
    Fmt.print(fmt, imagOnly.call(c1), qi, imagOnly.call(c2))
}


  

You may also check:How to resolve the algorithm Tic-tac-toe step by step in the Prolog programming language
You may also check:How to resolve the algorithm Continued fraction step by step in the Racket programming language
You may also check:How to resolve the algorithm Factorions step by step in the Lambdatalk programming language
You may also check:How to resolve the algorithm User input/Text step by step in the Swift programming language
You may also check:How to resolve the algorithm Find the missing permutation step by step in the K programming language