Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(Un)folding a sheet of paper according to a pattern and giving the order of the layers

Last Friday, in a French programming contest, we were given a paper folding problem which was as follows:

Given a square sheet of paper and a folding pattern, write a function "fold(pattern)" that will give the order of the layers that will result from the cumulative folding (in half) of the sheet in respect of the pattern."

That may not be very clear, so let me explain a bit (having a square sheet of paper handy might help to understand, if you're willing to go that far to help me out).

Suppose that we have a square sheet of paper which we draw a N*N grid on and then number all its inner squares. Given a pattern "LTRB", we would fold this paper vertically in half and put the resulting left part on to the right part. Then, we would fold it horizontally and put the top part onto the bottom part. Then, we would fold it vertically again and put the right part onto the left part. Finally, we would fold it horizontally and put the bottom part on the top part. This leaves us with a sheet of paper that is the size of one square and N^2 layers. The expected answer is the resulting order of each original square.

For example, if we have a draw a 2*2 grid on a square sheet of paper and then number each inner square from 1 to 4 (top left to bottom right, horizontally), and given the pattern "LT", we would have this happening:

fold("LT"):

 1 | 2   L  1,2  T
---|--- ==> --- ==> 2,1,3,4
 3 | 4      3,4

and with a "RB" pattern, for example:

fold("RB"): 

 1 | 2   R  2,1  B
---|--- ==> --- ==> 3,4,2,1
 3 | 4      4,3

As you would have probably guessed, it basically boils down to a recursive transformation of an N*N matrix. This was the easy part, and here is my solution:

http://ideone.com/QaXGq

Now comes the interesting part.

  • Write a function unfold(order) that will, for a given resulting layer ordering, give the pattern that produced this ordering. Note that unfold(fold("LRTB")) => "LRTB"

And then my brain stopped working for a while and I didn't have the time (2 hours left from 4 hours total) to come up with a fast enough solution.

My initial ideas were:

  1. Try to brute force it. Because we know the length of the input is N^2, we can create an initial matrix and try all possible folding until we reach the same order as the input. O(4^N) complexity, not viable.

  2. Brute force reverse. Start from the input, and try all unfolding possibilities until we reach a correct initial state. A little bit better, but still too slow.

  3. ???

Anyone has an idea?

like image 549
Serkan Eryilmaz Avatar asked May 07 '12 16:05

Serkan Eryilmaz


1 Answers

At each step you only need to know the first element and the last element of your list. If the first element should be on the left of the last one, then the folding direction was left (idem with right, top and bottom).

like image 96
Thomash Avatar answered Nov 04 '22 21:11

Thomash