Jam 2013 Round 1B

Posted on 26th April 2015


As ever, links to: Official Contest Analysis and my code on GitHub.

I did this under timed conditions, and would have just qualified. A silly error was all which stood between B large and me...

Problem A, Osmos: Start with A and \( (x_i)_{i=1}^N \) integers. You can absorb one of the \( x_i \) if it's smaller than A, and then A grows by \( x_i \). Help Armin to be able to absorb all the numbers by adjusting the initial set:

  • You can add any new number;
  • You can remove a number.

What is the least number of moves to get a valid set?

  • Order so that \( x_1 \leq x_2 \leq \cdots \leq x_N \) as optimal case is to absorb from small to large.
  • If Armin is trying to absorb \( x_i \) but can't then A is too small, so add in a new number \( A-1 \). Maybe repeat this step a few times.
  • Now consider removing numbers: it only makes sense to remove the largest number (if you can't deal with a smaller number, then removing it just makes the next larger number ever harder to deal with!)
  • So compare removing the last k terms with how many "additions" these k would take up, and find the smallest overall number of moves.
  • My code actually checked if there was any k whereby removing k terms was better, removed them, and then iterated. I now don't see why this works...
  • Corner case: if A=1 initially, Armin can never absorb anything, and the optimal solution is just to remove all numbers.

Problem B, Falling Diamonds: The diamonds form this sort of triangular pattern:

*      *           *              - 
      * *         * *            - -
     * * *       * * *          * * -
                * * * *        * * * -
               * * * * *      * * * * *

The final picture shows one possible "half-way" point, with - marking slots to be filled in future. Each new diamond takes a 50/50 split at the top, and falls down one side.

  • So test if the coordinates X Y can ever be the centre of a diamond.
  • Work out which "layer" the Nth diamond will fall in. If X Y are in the a previous layer, the probability is 1.0; if X Y is in the next layer, it is 0.0
  • Otherwise, we have to work out or simulate the probability. Consider [a b] to indicate that the left pile contains a diamonds, the right b diamonds. With n = 0, 2, 4, 6, ... the layer height, then the transition probabilities are:
    • If a, b <= n then 50/50 chance of going to either [a+1 b] or [a b+1]
    • If a==n then move to [a b+1], and if b==n then move to [a+1 b]
  • A little paper analysis shows that you get a variant of Pascal's triangle (where later rows are "truncated"). Alternatively, just naively compute the probabilities, which is what I did. (Stupid mistake was not to notice that there are in general 2 ways to get to [a b] on the next step, so a dictionary is a better data structure than a list...)

Problem C, Garbled Email: I initially tried a DFS with pruning (aka backtracking) algorithm. This worked, but was too slow, even for the small case. So I cheated, and my Python code is just an implementation of the suggested route (elements of which you can see in my initial attempt!) which is a Dynamic Programming solution combined with cunning precalculation. (Don't walk the dictionary, but rather look up in it!)


Categories
Recent posts