SQ in silver chrome letters, a lab's gear stacked against the S: a rack, two oscilloscopes, pizza boxes and a six-pack. Strange Query Lab

CARDIAC › Tips and tricks

CARDIAC tips and tricks

How to program CARDIAC well. Most of the tricks come from a handful of quirks, so here they are first. Then the tips, each on its own page: a common job done the way you'd probably write it, then the CARDIAC way, and what each costs.

What makes CARDIAC different

One test

CARDIAC's only decision is TAC: jump if the accumulator is negative. There's no compare, no test for zero, and no jump on positive. Every if and every loop is a subtraction and a TAC: "x is below k" is one of those, and "x equals k" takes two. Most of the tips arrange things so the question you ask is "is this negative?"

Decimal, not binary

CARDIAC isn't a binary computer. There are no bits to get at, and none of the ten instructions is AND, OR, XOR or a shift by a power of two. So the binary tricks you may know don't carry over: masking with AND, swapping with XOR, halving with a shift, testing odd or even by the bottom bit. Here, doubling is an ADD, halving is a loop of subtractions, and even "is it odd?" means cutting out the last digit and comparing it.

What you get instead are decimal tricks. A cell holds a signed three-digit number, -999 to 999, and the accumulator holds four digits and a sign. STO keeps the accumulator's last three digits, so storing is a free mod 1000, and a sum can pass 999 in the accumulator as long as what you store fits. Multiplying and dividing by ten, a hundred or a thousand is where CARDIAC is quick.

The strange SFT

SFT xy shifts the accumulator x digits left and then y digits right, and the digits that fall off either end are gone. Its two digits are counts, not an address. One shift can multiply or divide by a power of ten, keep the last two digits (SFT 22), or cut a single digit out and put it somewhere else: from 0abc, SFT 23 leaves 000b, the tens digit.

Instructions are numbers

An instruction is its opcode digit and a two-digit address: 245 is ADD 45. There's no indirect addressing, so a program that walks a table rewrites the address in its own instructions, and adding to an instruction changes what it does. JMP also writes the way back, 8 and the next address, into cell 99, which is how a subroutine returns.

Cell 00 and the loader

Cell 00 always holds 001. That's a constant 1 for free, and as an instruction it's INP 01, the first step of the loader that reads every program in from cards. Programming basics walks through it card by card.

The tips

Comparisons: TAC is the only test

CARDIAC can ask exactly one question: is the accumulator negative? Every comparison you write is built out of that, so it pays to make it the question you need.

Digits: arithmetic in decimal

CARDIAC thinks in decimal: three digits in a cell, four in the accumulator, and SFT moves whole digits around. Lean on that and a lot of arithmetic gets cheap.

Instructions are numbers

An instruction is just a three-digit number, so your program can do arithmetic on its own code. On CARDIAC that isn't a hack, it's how you get things done.

Room: 100 cells and a card reader

Your program and its data share a hundred cells, and everything else arrives on cards. A lot of good CARDIAC code is about where things live.

Silly math tricks

Tricks that use strength reduction to take advantage of the fact that multiplying by 10 is cheap.

Got a CARDIAC trick of your own? Send it to nerd@strangequery.com. The best ones go up here, with your name on them if you'd like.

The tips are made from the tips in cardiac-code on GitHub, beside the manual's programs. Every program in them was run with the input it names, and prints what it says.