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.