Quaternions
From Esolanging
(Redirected from Quaternerions)
Quaternions is an esolang invented by user:phira, it is based on quaternions.
introduction to quaternions
a quaternion is a number with form where , , are imaginary units, , and . NOTE: this means quaternions' multiplication is not commutative.
a quaternion has norm , conjugate , reciporial and negation .
quaternions' addition do what you expect: .
quaternions' multiplication is defined as .
subtracting a quaternion is equal to adding its negation; dividing a quaternion is equal to multiplying its reciporial.
program flow
quaternions is not stack based, but rather works on a array shaped like a 3d sphere called S. there is a data pointer DP which is initially 1. let SP=. it also has an accumulator.
| command | meaning |
|---|---|
^ |
load S[SP] onto accumulator
|
1, i, j, k |
load corresponding imaginary unit onto accumulator |
? |
load random thing from [1,i,j,k] onto accumulator |
+, -, *, / |
accumulator (+=|-=|*=|/=) S[SP] |
= |
stores accumulator into S[SP]
|
` |
DP*=acc. THIS IS THE ONLY WAY TO MODIFY DP. this is equivalent to rotating the DP
|
(...), [...], {...} |
if statements, while loops, and until loops. condition: acc==0
|
. |
output. implementation defined |
, |
input. implementation defined |
Examples
Truth machine
assuming IO inputs/outputs the character codes on the real part
1=+=+=+=+=++=,.-{+.-}
Interpreter
code='1=+=+=+=+=++=,.-{+.-}'
input='1'
function add(a,b){return typeof a=='number'?a+b:[add(a[0],b[0]),add(a[1],b[1])];}
function neg(a,b){return typeof a=='number'?-a:[neg(a[0]),neg(a[1])];}
function sub(a,b){return add(a,neg(b));}
function conj(a){return typeof a=='number'?a:[conj(a[0]),neg(a[1])];}
function mul(a,b){return typeof a=='number'?a*b:[sub(mul(a[0],b[0]),mul(conj(b[1]),a[1])),add(mul(b[1],a[0]),mul(a[1],conj(b[0])))];}//cayley dickson definition
function mul_scalar(a,b){return typeof a=='number'?a*b:[mul_scalar(a[0],b),mul_scalar(a[1],b)];}
function norm(a){return typeof a=='number'?Math.abs(a):Math.hypot(norm(a[0]),norm(a[1]));}
function recip(a){return mul_scalar(conj(a),norm(a)**-2);}
function div(a){return mul(a,recip(b));}
function unit(a){return mul_scalar(a,1/norm(a));}
function strf(x,d=33){return typeof x=='number'?x.toExponential(8):strf(x[0],d+1)+String.fromCodePoint(d)+strf(x[1],d+1)}
s={};iP=0;i=[[0,1],[0,0]];j=[[0,0],[1,0]];k=[[0,0],[0,1]];_1=[[1,0],[0,0]];
function gi(){return input.codePointAt(iP++)||-1;};function po(x){process.stdout.write(String.fromCodePoint(x[0][0]))};
e='acc=[[0,0],[0,0]];dp=[[1,0],[0,0]];';for(let i of code)switch(i){
case'^':e+='acc=s[strf(unit(dp))]||[[0,0],[0,0]];';break;
case'=':e+='s[strf(unit(dp))]=acc;';break;
case'1':e+='acc=_1;';break;
case'i':e+='acc=i;';break;
case'j':e+='acc=j;';break;
case'k':e+='acc=k;';break;
case'?':e+='acc=[i,j,k][~~(Math.random()*3)];';break;
case'+':e+='acc=add(acc,s[strf(unit(dp))]||[[0,0],[0,0]]);';break;
case'-':e+='acc=sub(acc,s[strf(unit(dp))]||[[0,0],[0,0]]);';break;
case'*':e+='acc=mul(acc,s[strf(unit(dp))]||[[0,0],[0,0]]);';break;
case'/':e+='acc=div(acc,s[strf(unit(dp))]||[[0,0],[0,0]]);';break;
case'`':e+='dp=mul(dp,acc);';break;
case'(':e+='if(norm(acc)==0){';break;
case'[':e+='while(norm(acc)==0){';break;
case'{':e+='while(norm(acc)!=0){';break;
case')':case']':case'}':e+='};';break;
case',':e+='acc=[[gi(),0],[0,0]];';break;
case'.':e+='po(acc);';break;}eval(e)