21. Incident, 9 available bytes
Decoded as codepage 437:
£ñ¥££₧Ç£¢£%₧£%¢£ñ¥ñÇ¢£$¥ñ£¥ñ£¥%Ç₧ñ$¥%ñƒ%ñ¢Ç$₧%Ç¢%ñƒñ$ƒñ$ƒ%ǃñÇ₧ñ%₧ññƒ%%₧%%₧Ç$¥%%ƒ%£ƒ%£¢Ç$¢ñ%¥%£₧ññƒññ¥ñ%¢ñ£¥£$¥£$¥ñÇ¥£%¥Ç£¢Ç£¢££ƒ££¥£ñ¢Ç%ƒÇ%¢Ç%¢ÇñƒÇñ¥Çñ
or as an xxd reversible hexdump:
00000000: 9ca4 9d9c 9c9e 809c 9b9c 259e 9c25 9b9c ..........%..%..
00000010: a49d a480 9b9c 249d a49c 9da4 9c9d 2580 ......$.......%.
00000020: 9ea4 249d 25a4 9f25 a49b 8024 9e25 809b ..$.%..%...$.%..
00000030: 25a4 9fa4 249f a424 9f25 809f a480 9ea4 %...$..$.%......
00000040: 259e a4a4 9f25 259e 2525 9e80 249d 2525 %....%%.%%..$.%%
00000050: 9f25 9c9f 259c 9b80 249b a425 9d25 9c9e .%..%...$..%.%..
00000060: a4a4 9fa4 a49d a425 9ba4 9c9d 9c24 9d9c .......%.....$..
00000070: 249d a480 9d9c 259d 809c 9b80 9c9b 9c9c $.....%.........
00000080: 9f9c 9c9d 9ca4 9b80 259f 8025 9b80 259b ........%..%..%.
00000090: 80a4 9f80 a49d 80a4 ........
Try it online!
Prints 33
. This is a) because 33 is by far the easiest two-digit number to print in Incident, b) because I already had a program to print 33 handy, and all I needed to do was try to fit it into the given set of available bytes.
This program was harder to write than I expected (given that I'd already written it); 9 bytes is not a lot (the more the better with Incident, although it can work with very restricted sets if necessary), and working with character encoding issues is annoying. I started working with UTF-8, planning to change to Latin-1 later, but a) the program parses differently in UTF-8 (Incident looks at the raw bytes, so the encoding matters), b) I couldn't figure out what encoding @Razetime's currency symbols were in (euro isn't normally at 0x9C), and c) TIO apparently feeds UTF-8 to Incident so the program didn't work there directly, and I had to write my own wrapper in the TIO link above. A much more fruitful technique was to work with ASCII (abcde,.:;
), and tr
it into the set of available bytes at the end (Incident is tr
-invariant; consistently replacing one codepoint in the program with another unused codepoint makes no difference to the program's behaviour).
Explanation
Parsing the program
In the rest of this explanation, I'm going to represent the program in a more readable, equivalent, ASCII form (which is just a consistent replacement of the 9 available bytes):
cb,cc:dc.ca:ca.cb,bd.ce,bc,bc,ad:be,ab;ab.de:ad.ab;be;be;ad;
bd:ba:bb;aa:aa:de,aa;ac;ac.de.ba,ac:bb;bb,ba.bc,ce,ce,bd,ca,
dc.dc.cc;cc,cb.da;da.da.db;db,db
This program uses 17 different commands. The original program represented each command as a single byte:
lm3kklijhhdebbodbeedifgaaoaccofcggfhjjik33mml111222
but this uses 17 different bytes, and we only have 9 available. So instead, each of the commands is represented as a pair of letters from abcde
(i.e. the first five our our currency symbols). This would lead to a huge number of accidental mis-parses if I just wrote it out directly (in fact, Incident fails to parse a single token!), so additional characters drawn from .,:;
(i.e. the last four of our currency symbols) were inserted in between them in order to ensure that it recognised the correct pairs of bytes as tokens. (As a reminder, Incident tokenises the source by treating each substring of bytes that occurs exactly three times as a token, with a few adjustments for overlapping tokens and tokens that are subsets of each other.)
To translate the original program into the form with command pairs separated by additional characters, I used the Jelly program
O%38+10%25b€5ị“abcde”j”.
I then used simulated annealing to choose appropriate separating characters to make sure that none of the tokens ended up overlapping (usually these characters weren't part of the token, but in a few cases they became part of an adjacent token, without changing the behaviour of the program).
Program behaviour
cb, Call subroutine cb (which prints a 3)
cc: Goto label cccc (used to call cb a second time)
dc. Goto label dcdc (apparently unused?)
ca:ca. Jump target
cb, Entry/exit point for subroutine cb (which prints a 3)
bd. Call subroutine bd (which prints half a 3)
ce, Goto label cece
bc,bc, Jump target
ad: Call subroutine ad (which prints a 0 bit)
be, Goto label bebe
ab;ab. Jump target
de: Output a 0 bit (and jump to the centre of the program)
ad. Entry/exit point for subroutine ad (which prints a 0 bit)
ab; Goto label abab
be;be; Jump target
ad; Call subroutine ad (which prints a 0 bit)
bd: Entry/exit point for subroutine bd (which prints half a 3)
ba: Call subroutine ba (which prints a 1 bit)
bb; Goto label bbbb
CENTRE OF THE PROGRAM:
aa:aa:de,aa; After outputting a bit, jump back to where you were
ac;ac. Jump target
de. Output a 1 bit (and jump to the centre of the program)
ba, Entry/exit point for subroutine ba (which prints a 1 bit)
ac: Goto label acac
bb;bb, Jump target
ba. Call subroutine ba (which prints a 1 bit)
bc, Goto label bcbc
ce,ce, Jump target
bd, Call subroutine bd (which prints half a 3)
ca, Goto label caca (i.e. return from subroutine cb)
dc.dc. Jump target
cc;cc, Jump target
cb. Call subroutine cb (which prints a 3)
da;da.da. No-op to ensure "de" is in the centre of the program
db;db,db No-op to ensure "de" is in the centre of the program
This is pretty straightforward as programs go: we define a subroutine cb
to print 3
, and it does so in terms of a subroutine bd
which prints half a 3
(Incident prints a bit at a time, and the bit pattern of 3
is 11001100
in Incident's bit order, so to print half a 3
you just need to print 1100
). Unfortunately, the behaviour of an Incident command (except for unconditional jumps, which go from x
to xx
) depends on its position in the program, so a huge number of jumps are required in order to make the program's control flow run all the commands in the right order. The sequence in which the commands that actually do something must be given is fairly fixed (e.g. a subroutine must be called from exactly 2 locations, with the first location before it is defined, and the second location after it is defined; and I/O behaviour depends on which command is in the centre of the program), so because we can't reorder the commands to say which order we want to run them in, we reorder the control flow instead, putting jumps just before and after pretty much all of them.
I'm not completely sure why I put two different jump labels cccc
and dcdc
back when I originally wrote this program, but Incident is sufficiently hard to write that I'm not sure I want to change things now. (Perhaps it was in an attempt to get the centre of the program into the right place.)
Restriction
Time for a change of pace, given how unreadable the programs in this answer are. The next answer must use all 26 lowercase ASCII letters, plus the ASCII space character: abcdefghijklmnopqrstuvwxyz
, i.e. 0x61-0x7a, plus 0x20.
(Please try to keep the restrictions fairly reasonable from now on; one of the inspirations behind Incident was "escaping from tricky situations in answer-chaining puzzles", but now that it's been used, we won't have our get-out-of-jail card to free us from such situations if they happen again.)