Post History
dc, 3 unique bytes, 138 bytes This challenge is pretty easy if you aim for just 4 unique bytes. For example, you could push the stack depth repeatedly to get ascending integers, set the precision ...
Answer
#1: Initial revision
# dc, 3 unique bytes, 138 bytes This challenge is pretty easy if you aim for just 4 unique bytes. For example, you could push the stack depth repeatedly to get ascending integers, set the precision to something positive, divide and then print. ```dc zzzzk/p ``` And surely it can't go any lower, right? After all, we have to increase the precision (`k`), print (`p`, `n`, `f`), do a floating-point operation (`v`, `^`, `/`, `.`), and still get a number from somewhere... Luckily though, there is actually a narrow path forward thanks to `a` and `x`. `a` pops a number off the stack, casts it to a `long`, and pushes its LSB back as a single-character string. Using `x` we can then execute that string as a command. This leaves us to choose a third command which should give us some helpful numbers that we can feed into `a`. The only options that can give us a range of numbers are `z` as well as the hex digits `A` through `F`. I haven't found a way to tame `z`, since it buries every intermediate result you get, so let's just see what useful characters we can get if we choose one of the hex digits. | Program | Resulting character | |---|---| | `AAa` | `n` | | `AAAAa` | `f` | | `AAAAAAa` | `F` | | `CCCa` | `4` | | `DDDDa` | `k` | | `FFFFFFa` | `i` | At first, this might not look too promising, but if we choose `F` as our third command, we can use the `i` to change the input base to 15 and basically get a reroll on our commands. 🤞 | Program | Resulting character | |---|---|---| | `FxFFFFFFaxFFFFFa` | `/` | | `FxFFFFFFaxFFFFFFFa` | `?` | The `?` doesn't help us, since we don't get any input, the `/` however is game-changing. By carefully placing the right constants on the stack before and after the base change we can later use `/` to efficiently calculate the ASCII value of any command. We use this to first set the precision to 15 and then sum, divide and print three pre-placed `F`s (as in `F k F F F + / n`) to do the actual calculation. Finally, here is an annotated version of the complete program: ```dc F F F # three 15s for calculating 0.5 FFFFFFFFFFFFF # "+" numerator FFFFFF # "+" denominator 1 F # argument for k FFFFFFFFFFF # "k" numerator FFFFF # "k" denominator 1 F # argument for i FFFFFFax # execute "i" to switch base FFFFFax # "k" division 1 F # "k" denominator 2 FFFFFax # "k" division 2 ax # execute "k" to set precedence FFFFFax # "+" division 1 F # "+" denominator 2 FFFFFax # "+" division 2 ax # execute "+" to add two 15s FFFFFax # divide 15 by 30 FFFFFFFFFFFF # "n" numerator 1 FFF # "n" denominator 1 FFFFFax # "n" division 1 FFFF # "n" denominator 2 FFFFFax # "n" division 2 ax # execute "n" to print the result ``` We can get rid of any whitespace by placing `x`s between constants since they act as no-ops on numbers. ```dc FxFxFxFFFFFFFFFFFFFxFFFFFFxFxFFFFFFFFFFFxFFFFFxFxFFFFFFaxFFFFFaxFxFFFFFaxaxFFFFFaxFxFFFFFaxaxFFFFFaxFFFFFFFFFFFFxFFFxFFFFFaxFFFFxFFFFFaxax ``` [Try it online!](https://tio.run/##S0n@/9@tAgyRQQWMqsAQhIslVsAoGAOfCJo5yOIIxf//AwA "dc – Try It Online")