Qter Documentation

Example Programs

Simple

.registers {
A, B <- 3x3 builtin (4, 4)
}
input "First number:" A
input "Second number:" B
while not-solved B {
inc A
dec B
}
halt "(A + B) % 4 =" A
.registers {
A, B <- 3x3 builtin (4, 4)
}
input "First number:" A
input "Second number:" B
while not-solved B {
inc A
dec B
}
halt "(A + B) % 4 =" A

Fibonacci

.registers {
A, B, C, COUNTER <- 3x3 builtin (30, 18, 10, 9)
}
.macro fib-shuffle {
// Let `fib(n)` be the nth fibonacci number
// Expects $R1 = fib(n), $R2 = fib(n-1), $R3 = 0
// Sets the registers to $R1 = 0, $R2 = fib(n+1), $R3 = fib(n) by adding $R1 to $R2 and $R3
($R1:reg $R2:reg $R3:reg) => {
dec COUNTER
if solved COUNTER {
halt "The number is" $R1
}
while not-solved $R1 {
dec $R1
inc $R2
inc $R3
}
}
}
input "Which Fibonacci number to calculate:" COUNTER
if solved COUNTER {
halt "The number is 0"
}
inc B
loop {
fib-shuffle B A C
fib-shuffle A C B
fib-shuffle C B A
}
/*
A B C COUNTER
0 1 0 8
1 0 1 7
0 1 2 6
2 3 0 5
5 0 3 4
0 5 8 3
8 13 0 2
21 0 3 1
*/
.registers {
A, B, C, COUNTER <- 3x3 builtin (30, 18, 10, 9)
}
.macro fib-shuffle {
// Let `fib(n)` be the nth fibonacci number
// Expects $R1 = fib(n), $R2 = fib(n-1), $R3 = 0
// Sets the registers to $R1 = 0, $R2 = fib(n+1), $R3 = fib(n) by adding $R1 to $R2 and $R3
($R1:reg $R2:reg $R3:reg) => {
dec COUNTER
if solved COUNTER {
halt "The number is" $R1
}
while not-solved $R1 {
dec $R1
inc $R2
inc $R3
}
}
}
input "Which Fibonacci number to calculate:" COUNTER
if solved COUNTER {
halt "The number is 0"
}
inc B
loop {
fib-shuffle B A C
fib-shuffle A C B
fib-shuffle C B A
}
/*
A B C COUNTER
0 1 0 8
1 0 1 7
0 1 2 6
2 3 0 5
5 0 3 4
0 5 8 3
8 13 0 2
21 0 3 1
*/

Average

.registers {
A, B <- 3x3 builtin (90, 90)
}
.macro floor-div-2 {
($IN:reg $OUT:reg) => {
loop {
solved-goto $IN break
dec $IN
solved-goto $IN break
dec $IN
inc $OUT
}
}
}
input "First number:" A
input "Second number:" B
while not-solved B {
inc A
dec B
solved-goto A overflow
}
floor-div-2 A B
halt "The average is" B
overflow:
while not-solved B {
inc A
dec B
}
floor-div-2 A B
add B 45
halt "The average is" B
.registers {
A, B <- 3x3 builtin (90, 90)
}
.macro floor-div-2 {
($IN:reg $OUT:reg) => {
loop {
solved-goto $IN break
dec $IN
solved-goto $IN break
dec $IN
inc $OUT
}
}
}
input "First number:" A
input "Second number:" B
while not-solved B {
inc A
dec B
solved-goto A overflow
}
floor-div-2 A B
halt "The average is" B
overflow:
while not-solved B {
inc A
dec B
}
floor-div-2 A B
add B 45
halt "The average is" B

Multiplication

// Multiplication by repeatedly dividing the second input by its factors and multiplying the first input by the same factors.
.registers {
// Registers are (10, 3), (10, 3), (15, 2)
SCRATCH, Y, X <- 3x3 builtin (30, 30, 30)
}
.macro divide {
($N:int) => {
while not-solved Y {
sub Y $N
inc SCRATCH
}
move SCRATCH to Y
move X to SCRATCH
multiply SCRATCH $N at X
}
}
input "Enter number X" X
input "Enter number Y" Y
// We need Y to be non-zero
if solved Y {
halt "X×Y mod 30 = 0"
}
// First, we need to divide by all factors of 30 which are 2, 3, and 5.
// We can only directly test divisibility by 3 and 10, so we will try dividing by two until we either find that it's divisible mod 10 in which case it's definitely divisble by two so we can finish the division, or until Y becomes solved and we determine that it isn't divisible, in which case we undo the division.
print "Factorizing out two"
loop {
if solved Y%10 {
divide 2
goto continue
}
dec Y
if solved Y%10 {
inc Y
multiply SCRATCH 2 at Y
goto break
}
dec Y
inc SCRATCH
}
print "Factorizing out three"
// We can directly test divisibility by 3
while solved Y%3 {
divide 3
}
print "Factorizing out five"
// We know that since Y is no longer divisible by 2, it cannot also be divisible by 10. Therefore if it is divisible by 5, it must be 5 above a divisor of 10.
while Y%10 equals 5 {
divide 5
}
print "Factorizing out seven"
// Now, we know that Y is non-zero and coprime with 30. Therefore, it is a member of the multiplicative group mod 30. This means that it's necessarily representable by 7^a × 11^b, where 0 <= a <= 3, 0 <= b <= 1.
// First, we need to factor out 7 and we can actually directly test divisibility.
// Since 11 = 1 mod 10, 11^b = 1 mod 10. 7^a mod 10 must be one of { 1, 7, 9, 3 } and is only one when a = 0. Therefore, Y%10 is not one if and only if it is divisible by 7.
while Y%10 not-equals 1 {
divide 7
}
print "Factorizing out eleven"
// Finally, factorize out 11 if necessary.
if Y not-equals 1 {
divide 11
}
halt "X×Y mod 30 =" X
// Multiplication by repeatedly dividing the second input by its factors and multiplying the first input by the same factors.
.registers {
// Registers are (10, 3), (10, 3), (15, 2)
SCRATCH, Y, X <- 3x3 builtin (30, 30, 30)
}
.macro divide {
($N:int) => {
while not-solved Y {
sub Y $N
inc SCRATCH
}
move SCRATCH to Y
move X to SCRATCH
multiply SCRATCH $N at X
}
}
input "Enter number X" X
input "Enter number Y" Y
// We need Y to be non-zero
if solved Y {
halt "X×Y mod 30 = 0"
}
// First, we need to divide by all factors of 30 which are 2, 3, and 5.
// We can only directly test divisibility by 3 and 10, so we will try dividing by two until we either find that it's divisible mod 10 in which case it's definitely divisble by two so we can finish the division, or until Y becomes solved and we determine that it isn't divisible, in which case we undo the division.
print "Factorizing out two"
loop {
if solved Y%10 {
divide 2
goto continue
}
dec Y
if solved Y%10 {
inc Y
multiply SCRATCH 2 at Y
goto break
}
dec Y
inc SCRATCH
}
print "Factorizing out three"
// We can directly test divisibility by 3
while solved Y%3 {
divide 3
}
print "Factorizing out five"
// We know that since Y is no longer divisible by 2, it cannot also be divisible by 10. Therefore if it is divisible by 5, it must be 5 above a divisor of 10.
while Y%10 equals 5 {
divide 5
}
print "Factorizing out seven"
// Now, we know that Y is non-zero and coprime with 30. Therefore, it is a member of the multiplicative group mod 30. This means that it's necessarily representable by 7^a × 11^b, where 0 <= a <= 3, 0 <= b <= 1.
// First, we need to factor out 7 and we can actually directly test divisibility.
// Since 11 = 1 mod 10, 11^b = 1 mod 10. 7^a mod 10 must be one of { 1, 7, 9, 3 } and is only one when a = 0. Therefore, Y%10 is not one if and only if it is divisible by 7.
while Y%10 not-equals 1 {
divide 7
}
print "Factorizing out eleven"
// Finally, factorize out 11 if necessary.
if Y not-equals 1 {
divide 11
}
halt "X×Y mod 30 =" X

Modulus

.registers {
B, A ← 3x3 builtin (24, 210)
}
.define MOD 13
input "Number to modulus:" A
// Calculate `B = -A mod 13`
while not-solved A {
if solved B {
add B $MOD
}
dec A
dec B
}
if not-solved B {
// Calculate `A = -B`
while not-solved B {
dec A
dec B
}
// B is in the range -12 through -1, so add 13 to put it in the range 1 through 12
add A $MOD
}
halt "The modulus is" A
.registers {
B, A ← 3x3 builtin (24, 210)
}
.define MOD 13
input "Number to modulus:" A
// Calculate `B = -A mod 13`
while not-solved A {
if solved B {
add B $MOD
}
dec A
dec B
}
if not-solved B {
// Calculate `A = -B`
while not-solved B {
dec A
dec B
}
// B is in the range -12 through -1, so add 13 to put it in the range 1 through 12
add A $MOD
}
halt "The modulus is" A