Intro
One of my favorite competitive programming tasks (IOI 2011). You don’t have to actually write any code — just come up with a way to do the task. Suitable for a) people familiar with binary, or b) programmers, or c) people who kinda liked math in school.
Problem statement for non-programmers (rephrased)
-
Jaxon has an N byte file, which he wants to send to Lachlan. They both know how big the file is.
-
They don’t have internet (b/c Australia) so they are going to use parrots. Each parrot can memorize a single byte. Bytes are just whole numbers from 0 to 255.
-
However, parrots don’t necessarily arrive in the same order they departed. So if the file is [1,2,3], Jaxon can’t just take three parrots and teach them the numbers 1, 2, 3 — because the parrots might arrive in the opposite order 3, 2, 1 (or in any other order). He’ll need to be cleverer.
-
Naturally Jaxon will have to use more parrots than N. It’s alright. We love you anyway, Jaxon. Would be nice to use as few parrots as possible though. Are you listening, Jaxon. Listen to me.
If it’s unclear, you can read the full original statement here. I got rid of some extra cases because I don’t like them.
Problem statement for programmers
Write an encoder and decoder for messages (arrays of bytes). Your decoder will be given the length of the original message.
encode(msg: uint8[]): uint8[]
decode(n: int, data: uint8[]): uint8[]
The decoder must be able to correctly decode the message even if the data is randomly shuffled after encoding. That is, decode(length(msg), random_shuffle(encode(msg))) == msg
for all msg
.
Levels of difficulty
-
ONE BROWNIE POINT: the file is N \leq 16 bytes long, and Jaxon can use at most 10 \times N parrots. Doesn’t have to be optimal.
-
TWO BROWNIE POINTS: the file is N \leq 32 bytes long, and Jaxon can use at most 10 \times N parrots. Also doesn’t have to be optimal.
-
RED VELVET CAKE: come up with the optimal solution that works for any N. Optimal means “minimize the maximum number of parrots you’d possibly need”.
Solution for N = 2 (read if you didn’t get the task)
You can always use three parrots to send a two-byte file. Here’s how:
If the file is [A, B], you just teach two parrots A and one parrot B. This works because:
Even if the parrots get shuffled on their way to Lachlan, he can look at which byte is more common and he’ll know it was the first byte of the file.