7, 25 bytes (65 characters)
Try it online!
077 Initialize counter to 0 (an empty section)
17134200..77546635 Push the main loop onto the frame
Once the original code has finished executing, the frame is
The last section of this is the main loop, which will run repeatedly until it gets deleted. All of it except the last two commands is data and section separators, which push commands onto the frame to leave it as:
||6|| (main loop) |73426644|6734216644|6667553663||00137||54
3 outputs the last section (
54) and discards the last two bars. On the first iteration,
5 is interpreted as a switch to output format 5 ("US-TTY"), which converts each pair of commands to a character. The
4 following it does not form a group, so it is ignored. On future iterations, we are already in output format 5, so
54 is interpreted as a group meaning "input character". To do this, the character from STDIN is converted into its character code (or, on EOF,
-1), and 1 is added. Then, the last section (which is now the
00137) is repeated that many times. In summary:
- If the character is
00137 is repeated 49 times.
- If the character is
00137 is repeated 50 times.
- If there are no more characters,
00137 is repeated 0 times (i.e. deleted).
- If this was the first iteration,
00137 is left alone (i.e. repeated 1 time).
5 removes the last section (
00137 repeated some number of times) from the frame and executes it, resulting in this many sections containing
The main loop has now finished executing, so the last section (which is
6673 unless we reached EOF) runs.
66 concatenates the last three sections into one (and has some other effects that don't affect the number of sections), which
73 deletes. Thus, the last three sections are deleted, and this repeats until the last section is no longer
- If we reached EOF, nothing happens.
- If this is the first iteration or the character was
0, after removing the last three sections 0 or 16 times, there is just one copy left on the frame. This copy deletes itself and the two sections before it, leaving everything up to the main loop and the section after it.
- If the character was
1, after removing the last three sections 17 times, all 50 copies and the third section after the main loop (the EOF handler) have been deleted.
Now, the last section left on the frame runs. This could, depending on the inputted character, be any of the three sections after the main loop.
If this is the first iteration or the character was
0, the section just after the main loop,
73 deletes this section, and
4 swaps the main loop with the counter behind it. This counter keeps track of the number we want to output, stored as the number of
1s minus the number of
0s. This metric has the property that it is not changed by pacification (which changes some
1s, and sometimes inserts
7...6 around code).
2 duplicates the counter and
6 concatenates the two copies (after pacifying the second, which, as we saw, does not change the value it represents), so the value is doubled. If this was the first iteration, the counter was previously empty, and doubling it still results in an empty section. Then,
6 gets rid of the empty section inserted by
4 (and pacifies the counter again, leaving the value unchanged), and
44 swaps the counter back to its original position. This leaves two empty sections on the end of the frame, which are removed automatically, and the main loop runs again.
If the character was
1, the second section after the main loop (
6734216644) runs. This is just like the section before it (explained in the last paragraph), except for two extra commands: a
6 at the start, which joins the section with the previous one before
73 deletes it, and a
1 in the middle, which adds a
7 to the counter (increasing its value by 1) after it gets doubled.
If we reached EOF, the third section after the main loop (
666 joins the last four sections (everything after the counter) into one section, to be deleted by
7553 exits output format 5 by outputting
55 and deletes the section before it, leaving only
||6| (counter) on the frame.
66 pacifies the two sections and combines them, turning the
6 back into a
0 (and not changing the value of the counter). Finally, the last
3 outputs everything.
0 at the start enters output format 0 ("Numerical output"), and the rest of the section (i.e. the counter) is converted to a number by taking the number of
1s minus the number of
0s. This value, which is the input converted from binary, is output in decimal and the program terminates.