WeixiangYan/CodeTransOcean huggingface dataset:
Task: Sequence of non-squares








VB: Sub Main()
Dim i&, c&, j#, s$
Const N& = 1000000
   s = "values for n in the range 1 to 22 : "
   For i = 1 To 22
      s = s & ns(i) & ", "
   Next
   For i = 1 To N
      j = Sqr(ns(i))
      If j = CInt(j) Then c = c + 1
   Next
   
   Debug.Print s
   Debug.Print c & " squares less than " & N
End Sub

Private Function ns(l As Long) As Long
   ns = l + Int(1 / 2 + Sqr(l))
End Function


COBOL:        IDENTIFICATION DIVISION.
       PROGRAM-ID. NONSQR.
       
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 NEWTON.
          03 SQR-INP           PIC 9(7)V9(5).
          03 SQUARE-ROOT       PIC 9(7)V9(5).
          03 FILLER            REDEFINES SQUARE-ROOT.
             05 FILLER         PIC 9(7).
             05 FILLER         PIC 9(5).
                88 SQUARE      VALUE ZERO.
          03 SQR-TEMP          PIC 9(7)V9(5).
       01 SEQUENCE-VARS.
          03 N                 PIC 9(7).
          03 SEQ               PIC 9(7).
       01 SMALL-FMT.
          03 N-O               PIC Z9.
          03 FILLER            PIC XX VALUE ": ".  
          03 SEQ-O             PIC Z9.
          
       PROCEDURE DIVISION.
       BEGIN.
           DISPLAY "Sequence of non-squares from 1 to 22:"
           PERFORM SMALL-NUMS VARYING N FROM 1 BY 1
               UNTIL N IS GREATER THAN 22.
           
           DISPLAY SPACES.
           DISPLAY "Checking items up to 1 million..."
           PERFORM CHECK-NONSQUARE VARYING N FROM 1 BY 1
               UNTIL SQUARE OR N IS GREATER THAN 1000000.
           
           IF SQUARE, DISPLAY "Square found at N = " N,
           ELSE, DISPLAY "No squares found up to 1 million.".
           STOP RUN.
           
       SMALL-NUMS.
           PERFORM NONSQUARE.
           MOVE N TO N-O.
           MOVE SEQ TO SEQ-O.
           DISPLAY SMALL-FMT.
           
       CHECK-NONSQUARE.
           PERFORM NONSQUARE.
           MOVE SEQ TO SQR-INP.
           PERFORM SQRT.
       
       NONSQUARE.
           MOVE N TO SQR-INP.
           PERFORM SQRT.
           ADD 0.5, SQUARE-ROOT GIVING SEQ.
           ADD N TO SEQ.
       
       SQRT.
           MOVE SQR-INP TO SQUARE-ROOT.
           COMPUTE SQR-TEMP = 
               (SQUARE-ROOT + SQR-INP / SQUARE-ROOT) / 2.
           PERFORM SQRT-LOOP UNTIL SQUARE-ROOT IS EQUAL TO SQR-TEMP.
       SQRT-LOOP.
           MOVE SQR-TEMP TO SQUARE-ROOT.
           COMPUTE SQR-TEMP = 
               (SQUARE-ROOT + SQR-INP / SQUARE-ROOT) / 2.
Task: Sequence of non-squares




Go: package main

import (
    "fmt"
    "math"
)

func remarkable(n int) int {
    return n + int(.5+math.Sqrt(float64(n)))
}

func main() {
    
    fmt.Println("  n  r(n)")
    fmt.Println("---  ---")
    for n := 1; n <= 22; n++ {
        fmt.Printf("%3d  %3d\n", n, remarkable(n))
    }

    
    const limit = 1e6
    fmt.Println("\nChecking for squares for n <", limit)
    next := 2
    nextSq := 4
    for n := 1; n < limit; n++ {
        r := remarkable(n)
        switch {
        case r == nextSq:
            panic(n)
        case r > nextSq:
            fmt.Println(nextSq, "didn't occur")
            next++
            nextSq = next * next
        }
    }
    fmt.Println("No squares occur for n <", limit)
}






COBOL:        IDENTIFICATION DIVISION.
       PROGRAM-ID. NONSQR.
       
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 NEWTON.
          03 SQR-INP           PIC 9(7)V9(5).
          03 SQUARE-ROOT       PIC 9(7)V9(5).
          03 FILLER            REDEFINES SQUARE-ROOT.
             05 FILLER         PIC 9(7).
             05 FILLER         PIC 9(5).
                88 SQUARE      VALUE ZERO.
          03 SQR-TEMP          PIC 9(7)V9(5).
       01 SEQUENCE-VARS.
          03 N                 PIC 9(7).
          03 SEQ               PIC 9(7).
       01 SMALL-FMT.
          03 N-O               PIC Z9.
          03 FILLER            PIC XX VALUE ": ".  
          03 SEQ-O             PIC Z9.
          
       PROCEDURE DIVISION.
       BEGIN.
           DISPLAY "Sequence of non-squares from 1 to 22:"
           PERFORM SMALL-NUMS VARYING N FROM 1 BY 1
               UNTIL N IS GREATER THAN 22.
           
           DISPLAY SPACES.
           DISPLAY "Checking items up to 1 million..."
           PERFORM CHECK-NONSQUARE VARYING N FROM 1 BY 1
               UNTIL SQUARE OR N IS GREATER THAN 1000000.
           
           IF SQUARE, DISPLAY "Square found at N = " N,
           ELSE, DISPLAY "No squares found up to 1 million.".
           STOP RUN.
           
       SMALL-NUMS.
           PERFORM NONSQUARE.
           MOVE N TO N-O.
           MOVE SEQ TO SEQ-O.
           DISPLAY SMALL-FMT.
           
       CHECK-NONSQUARE.
           PERFORM NONSQUARE.
           MOVE SEQ TO SQR-INP.
           PERFORM SQRT.
       
       NONSQUARE.
           MOVE N TO SQR-INP.
           PERFORM SQRT.
           ADD 0.5, SQUARE-ROOT GIVING SEQ.
           ADD N TO SEQ.
       
       SQRT.
           MOVE SQR-INP TO SQUARE-ROOT.
           COMPUTE SQR-TEMP = 
               (SQUARE-ROOT + SQR-INP / SQUARE-ROOT) / 2.
           PERFORM SQRT-LOOP UNTIL SQUARE-ROOT IS EQUAL TO SQR-TEMP.
       SQRT-LOOP.
           MOVE SQR-TEMP TO SQUARE-ROOT.
           COMPUTE SQR-TEMP = 
               (SQUARE-ROOT + SQR-INP / SQUARE-ROOT) / 2.
Task: Sequence of non-squares






PHP: <?php

	for($i=1;$i<=22;$i++){
		echo($i + floor(1/2 + sqrt($i)) . "\n");
	}

	$found_square=False;
	for($i=1;$i<=1000000;$i++){
		$non_square=$i + floor(1/2 + sqrt($i));
		if(sqrt($non_square)==intval(sqrt($non_square))){
			$found_square=True;
		}
	}
	echo("\n");
	if($found_square){
		echo("Found a square number, so the formula does not always work.");
	} else {
		echo("Up to 1000000, found no square number in the sequence!");
	}
?>
Task: Sequence of non-squares






PHP: <?php

	for($i=1;$i<=22;$i++){
		echo($i + floor(1/2 + sqrt($i)) . "\n");
	}

	$found_square=False;
	for($i=1;$i<=1000000;$i++){
		$non_square=$i + floor(1/2 + sqrt($i));
		if(sqrt($non_square)==intval(sqrt($non_square))){
			$found_square=True;
		}
	}
	echo("\n");
	if($found_square){
		echo("Found a square number, so the formula does not always work.");
	} else {
		echo("Up to 1000000, found no square number in the sequence!");
	}
?>






Ada: with Ada.Numerics.Long_Elementary_Functions;
with Ada.Text_IO;  use Ada.Text_IO;

procedure Sequence_Of_Non_Squares_Test is
   use Ada.Numerics.Long_Elementary_Functions;
   
   function Non_Square (N : Positive) return Positive is
   begin
      return N + Positive (Long_Float'Rounding (Sqrt (Long_Float (N))));
   end Non_Square;
   
   I : Positive;
begin
   for N in 1..22 loop 
      Put (Natural'Image (Non_Square (N)));
   end loop;
   New_Line;
   for N in 1..1_000_000 loop 
      I := Non_Square (N);
      if I = Positive (Sqrt (Long_Float (I)))**2 then
         Put_Line ("Found a square:" & Positive'Image (N));
      end if;
   end loop;
end Sequence_Of_Non_Squares_Test;
Task: Sequence of non-squares






PHP: <?php

	for($i=1;$i<=22;$i++){
		echo($i + floor(1/2 + sqrt($i)) . "\n");
	}

	$found_square=False;
	for($i=1;$i<=1000000;$i++){
		$non_square=$i + floor(1/2 + sqrt($i));
		if(sqrt($non_square)==intval(sqrt($non_square))){
			$found_square=True;
		}
	}
	echo("\n");
	if($found_square){
		echo("Found a square number, so the formula does not always work.");
	} else {
		echo("Up to 1000000, found no square number in the sequence!");
	}
?>




COBOL:        IDENTIFICATION DIVISION.
       PROGRAM-ID. NONSQR.
       
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 NEWTON.
          03 SQR-INP           PIC 9(7)V9(5).
          03 SQUARE-ROOT       PIC 9(7)V9(5).
          03 FILLER            REDEFINES SQUARE-ROOT.
             05 FILLER         PIC 9(7).
             05 FILLER         PIC 9(5).
                88 SQUARE      VALUE ZERO.
          03 SQR-TEMP          PIC 9(7)V9(5).
       01 SEQUENCE-VARS.
          03 N                 PIC 9(7).
          03 SEQ               PIC 9(7).
       01 SMALL-FMT.
          03 N-O               PIC Z9.
          03 FILLER            PIC XX VALUE ": ".  
          03 SEQ-O             PIC Z9.
          
       PROCEDURE DIVISION.
       BEGIN.
           DISPLAY "Sequence of non-squares from 1 to 22:"
           PERFORM SMALL-NUMS VARYING N FROM 1 BY 1
               UNTIL N IS GREATER THAN 22.
           
           DISPLAY SPACES.
           DISPLAY "Checking items up to 1 million..."
           PERFORM CHECK-NONSQUARE VARYING N FROM 1 BY 1
               UNTIL SQUARE OR N IS GREATER THAN 1000000.
           
           IF SQUARE, DISPLAY "Square found at N = " N,
           ELSE, DISPLAY "No squares found up to 1 million.".
           STOP RUN.
           
       SMALL-NUMS.
           PERFORM NONSQUARE.
           MOVE N TO N-O.
           MOVE SEQ TO SEQ-O.
           DISPLAY SMALL-FMT.
           
       CHECK-NONSQUARE.
           PERFORM NONSQUARE.
           MOVE SEQ TO SQR-INP.
           PERFORM SQRT.
       
       NONSQUARE.
           MOVE N TO SQR-INP.
           PERFORM SQRT.
           ADD 0.5, SQUARE-ROOT GIVING SEQ.
           ADD N TO SEQ.
       
       SQRT.
           MOVE SQR-INP TO SQUARE-ROOT.
           COMPUTE SQR-TEMP = 
               (SQUARE-ROOT + SQR-INP / SQUARE-ROOT) / 2.
           PERFORM SQRT-LOOP UNTIL SQUARE-ROOT IS EQUAL TO SQR-TEMP.
       SQRT-LOOP.
           MOVE SQR-TEMP TO SQUARE-ROOT.
           COMPUTE SQR-TEMP = 
               (SQUARE-ROOT + SQR-INP / SQUARE-ROOT) / 2.
Task: Quaternion type



C#: using System;

struct Quaternion : IEquatable<Quaternion>
{
    public readonly double A, B, C, D;

    public Quaternion(double a, double b, double c, double d)
    {
        this.A = a;
        this.B = b;
        this.C = c;
        this.D = d;
    }

    public double Norm()
    {
        return Math.Sqrt(A * A + B * B + C * C + D * D);
    }

    public static Quaternion operator -(Quaternion q)
    {
        return new Quaternion(-q.A, -q.B, -q.C, -q.D);
    }

    public Quaternion Conjugate()
    {
        return new Quaternion(A, -B, -C, -D);
    }

    
    public static implicit operator Quaternion(double d)
    {
        return new Quaternion(d, 0, 0, 0);
    }

    public static Quaternion operator +(Quaternion q1, Quaternion q2)
    {
        return new Quaternion(q1.A + q2.A, q1.B + q2.B, q1.C + q2.C, q1.D + q2.D);
    }

    public static Quaternion operator *(Quaternion q1, Quaternion q2)
    {
        return new Quaternion(
            q1.A * q2.A - q1.B * q2.B - q1.C * q2.C - q1.D * q2.D,
            q1.A * q2.B + q1.B * q2.A + q1.C * q2.D - q1.D * q2.C,
            q1.A * q2.C - q1.B * q2.D + q1.C * q2.A + q1.D * q2.B,
            q1.A * q2.D + q1.B * q2.C - q1.C * q2.B + q1.D * q2.A);
    }

    public static bool operator ==(Quaternion q1, Quaternion q2)
    {
        return q1.A == q2.A && q1.B == q2.B && q1.C == q2.C && q1.D == q2.D;
    }

    public static bool operator !=(Quaternion q1, Quaternion q2)
    {
        return !(q1 == q2);
    }

    #region Object Members

    public override bool Equals(object obj)
    {
        if (obj is Quaternion)
            return Equals((Quaternion)obj);

        return false;
    }

    public override int GetHashCode()
    {
        return A.GetHashCode() ^ B.GetHashCode() ^ C.GetHashCode() ^ D.GetHashCode();
    }

    public override string ToString()
    {
        return string.Format("Q({0}, {1}, {2}, {3})", A, B, C, D);
    }

    #endregion

    #region IEquatable<Quaternion> Members

    public bool Equals(Quaternion other)
    {
        return other == this;
    }

    #endregion
}









Ada: generic
   type Real is digits <>;
package Quaternions is
   type Quaternion is record
      A, B, C, D : Real;
   end record;
   function "abs" (Left : Quaternion) return Real;
   function Conj (Left : Quaternion) return Quaternion;
   function "-" (Left : Quaternion) return Quaternion;
   function "+" (Left, Right : Quaternion) return Quaternion;
   function "-" (Left, Right : Quaternion) return Quaternion;
   function "*" (Left : Quaternion; Right : Real) return Quaternion;
   function "*" (Left : Real; Right : Quaternion) return Quaternion;
   function "*" (Left, Right : Quaternion) return Quaternion;
   function Image (Left : Quaternion) return String;
end Quaternions;
Task: Quaternion type




Go: package main

import (
    "fmt"
    "math"
)

type qtn struct {
    r, i, j, k float64
}

var (
    q  = &qtn{1, 2, 3, 4}
    q1 = &qtn{2, 3, 4, 5}
    q2 = &qtn{3, 4, 5, 6}

    r  float64 = 7
)

func main() {
    fmt.Println("Inputs")
    fmt.Println("q:", q)
    fmt.Println("q1:", q1)
    fmt.Println("q2:", q2)
    fmt.Println("r:", r)

    var qr qtn
    fmt.Println("\nFunctions")
    fmt.Println("q.norm():", q.norm())
    fmt.Println("neg(q):", qr.neg(q))
    fmt.Println("conj(q):", qr.conj(q))
    fmt.Println("addF(q, r):", qr.addF(q, r))
    fmt.Println("addQ(q1, q2):", qr.addQ(q1, q2))
    fmt.Println("mulF(q, r):", qr.mulF(q, r))
    fmt.Println("mulQ(q1, q2):", qr.mulQ(q1, q2))
    fmt.Println("mulQ(q2, q1):", qr.mulQ(q2, q1))
}

func (q *qtn) String() string {
    return fmt.Sprintf("(%g, %g, %g, %g)", q.r, q.i, q.j, q.k)
}

func (q *qtn) norm() float64 {
    return math.Sqrt(q.r*q.r + q.i*q.i + q.j*q.j + q.k*q.k)
}

func (z *qtn) neg(q *qtn) *qtn {
    z.r, z.i, z.j, z.k = -q.r, -q.i, -q.j, -q.k
    return z
}

func (z *qtn) conj(q *qtn) *qtn {
    z.r, z.i, z.j, z.k = q.r, -q.i, -q.j, -q.k
    return z
}

func (z *qtn) addF(q *qtn, r float64) *qtn {
    z.r, z.i, z.j, z.k = q.r+r, q.i, q.j, q.k
    return z
}

func (z *qtn) addQ(q1, q2 *qtn) *qtn {
    z.r, z.i, z.j, z.k = q1.r+q2.r, q1.i+q2.i, q1.j+q2.j, q1.k+q2.k
    return z
}

func (z *qtn) mulF(q *qtn, r float64) *qtn {
    z.r, z.i, z.j, z.k = q.r*r, q.i*r, q.j*r, q.k*r
    return z
}

func (z *qtn) mulQ(q1, q2 *qtn) *qtn {
    z.r, z.i, z.j, z.k =
        q1.r*q2.r-q1.i*q2.i-q1.j*q2.j-q1.k*q2.k,
        q1.r*q2.i+q1.i*q2.r+q1.j*q2.k-q1.k*q2.j,
        q1.r*q2.j-q1.i*q2.k+q1.j*q2.r+q1.k*q2.i,
        q1.r*q2.k+q1.i*q2.j-q1.j*q2.i+q1.k*q2.r
    return z
}








Ada: generic
   type Real is digits <>;
package Quaternions is
   type Quaternion is record
      A, B, C, D : Real;
   end record;
   function "abs" (Left : Quaternion) return Real;
   function Conj (Left : Quaternion) return Quaternion;
   function "-" (Left : Quaternion) return Quaternion;
   function "+" (Left, Right : Quaternion) return Quaternion;
   function "-" (Left, Right : Quaternion) return Quaternion;
   function "*" (Left : Quaternion; Right : Real) return Quaternion;
   function "*" (Left : Real; Right : Quaternion) return Quaternion;
   function "*" (Left, Right : Quaternion) return Quaternion;
   function Image (Left : Quaternion) return String;
end Quaternions;
Task: Quaternion type







Python: from collections import namedtuple
import math

class Q(namedtuple('Quaternion', 'real, i, j, k')):
    'Quaternion type: Q(real=0.0, i=0.0, j=0.0, k=0.0)' 

    __slots__ = () 

    def __new__(_cls, real=0.0, i=0.0, j=0.0, k=0.0):
        'Defaults all parts of quaternion to zero'
        return super().__new__(_cls, float(real), float(i), float(j), float(k))

    def conjugate(self):
        return Q(self.real, -self.i, -self.j, -self.k)

    def _norm2(self):
        return sum( x*x for x in self)

    def norm(self):
        return math.sqrt(self._norm2())

    def reciprocal(self):
        n2 = self._norm2()
        return Q(*(x / n2 for x in self.conjugate())) 

    def __str__(self):
        'Shorter form of Quaternion as string'
        return 'Q(%g, %g, %g, %g)' % self

    def __neg__(self):
        return Q(-self.real, -self.i, -self.j, -self.k)

    def __add__(self, other):
        if type(other) == Q:
            return Q( *(s+o for s,o in zip(self, other)) )
        try:
            f = float(other)
        except:
            return NotImplemented
        return Q(self.real + f, self.i, self.j, self.k)

    def __radd__(self, other):
        return Q.__add__(self, other)

    def __mul__(self, other):
        if type(other) == Q:
            a1,b1,c1,d1 = self
            a2,b2,c2,d2 = other
            return Q(
                 a1*a2 - b1*b2 - c1*c2 - d1*d2,
                 a1*b2 + b1*a2 + c1*d2 - d1*c2,
                 a1*c2 - b1*d2 + c1*a2 + d1*b2,
                 a1*d2 + b1*c2 - c1*b2 + d1*a2 )
        try:
            f = float(other)
        except:
            return NotImplemented
        return Q(self.real * f, self.i * f, self.j * f, self.k * f)

    def __rmul__(self, other):
        return Q.__mul__(self, other)

    def __truediv__(self, other):
        if type(other) == Q:
            return self.__mul__(other.reciprocal())
        try:
            f = float(other)
        except:
            return NotImplemented
        return Q(self.real / f, self.i / f, self.j / f, self.k / f)

    def __rtruediv__(self, other):
        return other * self.reciprocal()

    __div__, __rdiv__ = __truediv__, __rtruediv__

Quaternion = Q       

q  = Q(1, 2, 3, 4)
q1 = Q(2, 3, 4, 5)
q2 = Q(3, 4, 5, 6)
r  = 7





Ada: generic
   type Real is digits <>;
package Quaternions is
   type Quaternion is record
      A, B, C, D : Real;
   end record;
   function "abs" (Left : Quaternion) return Real;
   function Conj (Left : Quaternion) return Quaternion;
   function "-" (Left : Quaternion) return Quaternion;
   function "+" (Left, Right : Quaternion) return Quaternion;
   function "-" (Left, Right : Quaternion) return Quaternion;
   function "*" (Left : Quaternion; Right : Real) return Quaternion;
   function "*" (Left : Real; Right : Quaternion) return Quaternion;
   function "*" (Left, Right : Quaternion) return Quaternion;
   function Image (Left : Quaternion) return String;
end Quaternions;
Task: Quaternion type








VB: Option Base 1
Private Function norm(q As Variant) As Double
    norm = Sqr(WorksheetFunction.SumSq(q))
End Function

Private Function negative(q) As Variant
    Dim res(4) As Double
    For i = 1 To 4
        res(i) = -q(i)
    Next i
    negative = res
End Function

Private Function conj(q As Variant) As Variant
    Dim res(4) As Double
    res(1) = q(1)
    For i = 2 To 4
        res(i) = -q(i)
    Next i
    conj = res
End Function

Private Function addr(r As Double, q As Variant) As Variant
    Dim res As Variant
    res = q
    res(1) = r + q(1)
    addr = res
End Function

Private Function add(q1 As Variant, q2 As Variant) As Variant
    add = WorksheetFunction.MMult(Array(1, 1), Array(q1, q2))
End Function

Private Function multr(r As Double, q As Variant) As Variant
    multr = WorksheetFunction.MMult(r, q)
End Function

Private Function mult(q1 As Variant, q2 As Variant)
    Dim res(4) As Double
    res(1) = q1(1) * q2(1) - q1(2) * q2(2) - q1(3) * q2(3) - q1(4) * q2(4)
    res(2) = q1(1) * q2(2) + q1(2) * q2(1) + q1(3) * q2(4) - q1(4) * q2(3)
    res(3) = q1(1) * q2(3) - q1(2) * q2(4) + q1(3) * q2(1) + q1(4) * q2(2)
    res(4) = q1(1) * q2(4) + q1(2) * q2(3) - q1(3) * q2(2) + q1(4) * q2(1)
    mult = res
End Function

Private Sub quats(q As Variant)
    Debug.Print q(1); IIf(q(2) < 0, " - " & Abs(q(2)), " + " & q(2));
    Debug.Print IIf(q(3) < 0, "i - " & Abs(q(3)), "i + " & q(3));
    Debug.Print IIf(q(4) < 0, "j - " & Abs(q(4)), "j + " & q(4)); "k"
End Sub

Public Sub quaternions()
    q = [{ 1, 2, 3, 4}]
    q1 = [{2, 3, 4, 5}]
    q2 = [{3, 4, 5, 6}]
    Dim r_ As Double
    r_ = 7#
    Debug.Print "q            = ";: quats q
    Debug.Print "q1           = ";: quats q1
    Debug.Print "q2           = ";: quats q2
    Debug.Print "r            = "; r_
    Debug.Print "norm(q)      = "; norm(q)
    Debug.Print "negative(q)  = ";: quats negative(q)
    Debug.Print "conjugate(q) = ";: quats conj(q)
    Debug.Print "r + q        = ";: quats addr(r_, q)
    Debug.Print "q1 + q2      = ";: quats add(q1, q2)
    Debug.Print "q * r        = ";: quats multr(r_, q)
    Debug.Print "q1 * q2      = ";: quats mult(q1, q2)
    Debug.Print "q2 * q1      = ";: quats mult(q2, q1)
End Sub




Ada: generic
   type Real is digits <>;
package Quaternions is
   type Quaternion is record
      A, B, C, D : Real;
   end record;
   function "abs" (Left : Quaternion) return Real;
   function Conj (Left : Quaternion) return Quaternion;
   function "-" (Left : Quaternion) return Quaternion;
   function "+" (Left, Right : Quaternion) return Quaternion;
   function "-" (Left, Right : Quaternion) return Quaternion;
   function "*" (Left : Quaternion; Right : Real) return Quaternion;
   function "*" (Left : Real; Right : Quaternion) return Quaternion;
   function "*" (Left, Right : Quaternion) return Quaternion;
   function Image (Left : Quaternion) return String;
end Quaternions;
Task: Quaternion type

C: #include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>

typedef struct quaternion
{
  double q[4];
} quaternion_t;


quaternion_t *quaternion_new(void)
{
  return malloc(sizeof(quaternion_t));
}

quaternion_t *quaternion_new_set(double q1,
				 double q2,
				 double q3,
				 double q4)
{
  quaternion_t *q = malloc(sizeof(quaternion_t));
  if (q != NULL) {
    q->q[0] = q1; q->q[1] = q2; q->q[2] = q3; q->q[3] = q4;
  }
  return q;
}


void quaternion_copy(quaternion_t *r, quaternion_t *q)
{
  size_t i;

  if (r == NULL || q == NULL) return;
  for(i = 0; i < 4; i++) r->q[i] = q->q[i];
}


double quaternion_norm(quaternion_t *q)
{
  size_t i;
  double r = 0.0;
  
  if (q == NULL) {
    fprintf(stderr, "NULL quaternion in norm\n");
    return 0.0;
  }

  for(i = 0; i < 4; i++) r += q->q[i] * q->q[i];
  return sqrt(r);
}


void quaternion_neg(quaternion_t *r, quaternion_t *q)
{
  size_t i;

  if (q == NULL || r == NULL) return;
  for(i = 0; i < 4; i++) r->q[i] = -q->q[i];
}


void quaternion_conj(quaternion_t *r, quaternion_t *q)
{
  size_t i;

  if (q == NULL || r == NULL) return;
  r->q[0] = q->q[0];
  for(i = 1; i < 4; i++) r->q[i] = -q->q[i];
}


void quaternion_add_d(quaternion_t *r, quaternion_t *q, double d)
{
  if (q == NULL || r == NULL) return;
  quaternion_copy(r, q);
  r->q[0] += d;
}


void quaternion_add(quaternion_t *r, quaternion_t *a, quaternion_t *b)
{
  size_t i;

  if (r == NULL || a == NULL || b == NULL) return;
  for(i = 0; i < 4; i++) r->q[i] = a->q[i] + b->q[i];
}


void quaternion_mul_d(quaternion_t *r, quaternion_t *q, double d)
{
  size_t i;

  if (r == NULL || q == NULL) return;
  for(i = 0; i < 4; i++) r->q[i] = q->q[i] * d;
}

bool quaternion_equal(quaternion_t *a, quaternion_t *b)
{
  size_t i;
  
  for(i = 0; i < 4; i++) if (a->q[i] != b->q[i]) return false;
  return true;
}


#define A(N) (a->q[(N)])
#define B(N) (b->q[(N)])
#define R(N) (r->q[(N)])
void quaternion_mul(quaternion_t *r, quaternion_t *a, quaternion_t *b)
{
  size_t i;
  double ri = 0.0;

  if (r == NULL || a == NULL || b == NULL) return;
  R(0) = A(0)*B(0) - A(1)*B(1) - A(2)*B(2) - A(3)*B(3);
  R(1) = A(0)*B(1) + A(1)*B(0) + A(2)*B(3) - A(3)*B(2);
  R(2) = A(0)*B(2) - A(1)*B(3) + A(2)*B(0) + A(3)*B(1);
  R(3) = A(0)*B(3) + A(1)*B(2) - A(2)*B(1) + A(3)*B(0);
}
#undef A
#undef B
#undef R


void quaternion_print(quaternion_t *q)
{
  if (q == NULL) return;
  printf("(%lf, %lf, %lf, %lf)\n", 
	 q->q[0], q->q[1], q->q[2], q->q[3]);
}