Brainf*ck Loop Problem

19

I have a problem for a cyber club that asks you to print:

ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$#"!

Using Brainf**k in 29 bytes or less without using the ',' character.

I have a working code:

++++++++++[>++++++>+++++++++<<-]>-->.<[>-.<-]

However my loop is too long, sending me 16 bytes over the limit.

Is there a more efficient way to set the second and third cell to 58 and 90 so I can run my second loop? Or is there a better way to do this all together that I am just not seeing?

Nick Rod

Posted 2016-08-27T14:55:27.433

Reputation: 301

1As for your question, while it only saves four bytes, it's actually better to generate 59 and 90 and change the -. to .-, dropping the >.<. – Martin Ender – 2016-08-27T15:05:22.150

I got +[--->++<]>++++[.-] for 19 bytes but it prints the control chars as well... – Timtech – 2016-08-27T18:52:39.830

@MartinEnder Yeah sorry about that, I saw your comment on the other post and found this group which seemed much more appropriate, I will delete the one on SO since it didn't generate many answers. – Nick Rod – 2016-08-28T04:57:35.233

2I'm honestly curious what this "cyber club" is, because boy they must have some really good golfers! – Sp3000 – 2016-08-28T11:40:42.217

Answers

23

27 24 bytes

++[<++[++<]>>>+]<[-<-.>]

Spent a whole day basically writing up a brute forcer and watching the results come in. Now I can get back to doing some actual work... Another day of brute forcing later...

Try it online!

The component ++[<++[++<]>>>+] initialises the tape to

[130, 0, 0, 0, 91, 59, 0]
                       ^

which is just perfect for what we need!

Sp3000

Posted 2016-08-27T14:55:27.433

Reputation: 58 729

8Wizardry. (∩`-´)⊃━☆゚.*・。゚ – primo – 2016-08-28T10:57:32.210

@primo To be fair I have no idea what's going on structure-wise in the first half, and I think the fact that you're able to come up with your own algorithms/techniques is amazing :) – Sp3000 – 2016-08-28T11:21:10.940

Tape at the end of each loop: http://codepad.org/ZoJUlQ8M. It's not at all intuitive that it would terminate at the values that it does, or even at all ;)

– primo – 2016-08-28T11:40:35.367

1An alternative 24: +[[>++<<]>->+>+]<[-<-.>] – primo – 2018-05-03T11:19:08.257

15

30 bytes

-<-[>+>-[---<]>]>++>+[---<.->]

Try it online!

85 and 171 are fairly easy to generate in brainfuck (modular inverses of 3 and -3). 85 is pretty close to 90, and 171 is pretty close to 177 (59·3), which is used here. With a bit of hackery, I'm able to produce 88 and 176 instead.

Still one byte short of the target, though.

Other suggestions

In general, it's shorter to iterate over a list, multiplying by a constant, rather than the other way. This is especially true for 3 or more values. For example, this:

++++++++++[>++++++>+++++++++<<-]

can be written as:

+>++++[+++++[>++++++++++<-]<]>

There were only two inner values, so it's not much of an improvement in this case. In fact, just refactoring is one byte shorter:

+++++[>++++++[>++>+++<<-]<-]>

Multiplying 30 by 2 and 3, rather than 10 by 6 and 9. With Martin Büttner's suggestion, this is already down to 38 bytes, without much change to the original:

+++++[>++++++[>++>+++<<-]<-]>>-[>.-<-]

primo

Posted 2016-08-27T14:55:27.433

Reputation: 30 891

I never would have thought about multiplying up the 58 and iterating by a larger number, that's much more efficient. – Nick Rod – 2016-08-28T05:13:26.090

4

34 bytes

Saved you 11 bytes, but still 5 bytes too long...

+[--->++<]>++++<+[--------->.-<]>.

I've spent hours already, hopefully someone can improve on this.

Timtech

Posted 2016-08-27T14:55:27.433

Reputation: 12 038