Google Code Jam Archive — Round 1C 2018 problems

Overview

The last of our Round 1s began with A Whole New Word; for those of you who know the song "A Whole New World", good luck getting it out of your heads! Lollipop Shop was another interactive problem with a somewhat intuitive solution; it also might have gotten you thinking about a certain 1950s song. Ant Stack was much harder than either of the previous two problems, but still approachable with enough thought and patience. It was easy to underestimate the limits of the second test set and time out!

This round was easier than 1B, and only 20 minutes into the contest, every problem had been solved by someone. Eryx was the first to snag a perfect score, after 35 minutes and 24 seconds. Full solutions to the first two problems generally sufficed to crack the top 1500.

That concludes Round 1 of Code Jam 2018! We will see our 1500 advancers from Round 1C, along with the combined 3000 advancers from Rounds 1A and 1B, in Round 2 in two weeks. 1000 of them will emerge with T-shirts and places in Round 3 and the Distributed Code Jam Online Round. For those of you who did not make it through the Round 1s, we encourage you to try again next year. Even making it through the Qual Round and giving Round 1 your all is a significant achievement!


Cast

A Whole New Word: Written and prepared by Jonathan Irvin Gunawan.

Lollipop Shop: Written and prepared by John Dethridge.

Ant Stack: Written by Pablo Heiber. Prepared by Kevin Tran.

Solutions and other problem preparation and review by Liang Bai, John Dethridge, Md Mahbubul Hasan, Robin Lee, Igor Naverniouk, Trung Thanh Nguyen, and Anqi (Joyce) Yang.

Analysis authors:

  • A Whole New Word: Jonathan Irvin Gunawan
  • Lollipop Shop: John Dethridge and Ian Tullis
  • Ant Stack: Jonathan Irvin Gunawan

A. A Whole New Word

Problem

Vincent and Desta are childhood friends. Today, Vincent is showing N distinct L-letter words to Desta by using some letter tiles. Each tile contains one uppercase English alphabet letter, and one number between 1 and L. A word consists of the letters spelled out by L tiles with numbers from 1 through L, in order. (Vincent's words are not necessarily real English words.)

For example, if Vincent has N = 3 words with L = 4, and the words are {CAKE, TORN, SHOW}, then Vincent must show the following to Desta:

C 1 A 2 K 3 E 4 T 1 O 2 R 3 N 4 S 1 H 2 O 3 W 4

Desta feels that creating words must be easy, and he wants to create a new word that obeys the rules above and is not one of Vincent's existing words. However, Desta does not have any tiles of his own, so he must use some of Vincent's tiles.

For instance, if Vincent has the words from the previous example, then Desta can make a new word such as CORN or SAKE or CHRE (Desta's words are also not necessarily real English words). Each of the example is illustrated in the following image:

C 1 O 2 R 3 N 4 S 1 A 2 K 3 E 4 C 1 H 2 R 3 E 4

Note that the three rows in the image above are independent. Desta only needs to make one new word.

However, in the above example, Desta cannot make WAKE, for example, because there is no W tile with a number 1. Nor can he make COO, since it is not the right length.

Notice that it may be impossible for Desta to make a new word. For example, if Vincent has only one word, then Desta cannot make anything new. Or, if Vincent has the words {AA, AB, BA, BB}, then any word that Desta can form is already present.

Help Desta to choose a word that he can show to Vincent using only the tiles used by Vincent, or indicate that it is impossible to do so.

Input

The first line of the input gives the number of test cases, T. T test cases follow. Each begins with one line with two integers N and L: the number of Vincent's words, and the length of each word. Then, N more lines follow. The i-th of these lines contains a string of L uppercase English letters representing the i-th of Vincent's words.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is a valid word to be chosen by Desta, or - (a single dash character of ASCII value 45) if there is no valid word to be chosen by Desta. If there is more than one valid word that Desta can make, you can output any of them.

Limits

1 ≤ T ≤ 100.
Time limit: 15 seconds per test set.
Memory limit: 1GB.
No two of Vincent's words are the same.

Test set 1 (Visible)

1 ≤ N ≤ 262.
1 ≤ L ≤ 2.

Test set 2 (Hidden)

1 ≤ N ≤ 2000.
1 ≤ L ≤ 10.

Sample

Sample Input
content_copy Copied!
5
4 1
A
B
C
D
4 2
WW
AA
SS
DD
4 2
AA
AB
BA
BB
3 4
CAKE
TORN
SHOW
5 7
HELPIAM
TRAPPED
INSIDEA
CODEJAM
FACTORY
Sample Output
content_copy Copied!
Case #1: -
Case #2: WA
Case #3: -
Case #4: CORN
Case #5: HOLIDAY

Note that the last two sample cases would not appear in test set 1.

In Sample Case #1, the only words that can be construted using the tiles used by Vincent are A, B, C, D. However, all of those words already appear in Vincent's list of words, so Desta is not allowed to choose them.

In Sample Case #2, there are 12 possible new words that Desta can make, one of which is WA.

Sample Case #3 was explained in the problem description above; there is no new word that Desta can make.

Sample Case #4 was explained in the problem description above; other answers such as SAKE are possible.

In Sample Case #5, other answers such as TRAPJAM are possible.

B. Lollipop Shop

Problem

You own a lollipop shop. At the start of the day, you make N lollipops, each of a single unique flavor, like huckleberry, cherry or lime. N customers come into the shop during the day, one at a time. Each customer gives you a list of which of your lollipop flavors they like. You can sell them one lollipop of any of those flavors, as long as you have not already sold someone else the same flavor earlier in the day (since there is only one lollipop of each flavor). If none of the flavors they like are still available, you cannot sell them a lollipop, and they leave your shop disappointed.

You do not know what each customer's flavor preferences are going to be until they arrive. Each customer decides if they like or dislike each flavor randomly, independently of whether they like any other flavor, or what flavors anyone else likes. However, your market studies have shown that some flavors may have a higher probability of being liked in general! For example, the lime flavor might have a 10% chance of being liked by any particular customer, whereas that chance might be 1% for the cherry flavor. These values are always chosen independently and uniformly at random from the interval [0.005, 0.1].

Obviously, you want to sell lollipops to as many of the N customers as possible! But, since you do not know what flavors your customers will ask for ahead of time, you cannot always make an optimal decision — sometimes you might sell a customer one flavor, and then later wish you had sold them another.

Suppose that you somehow knew all the customers' preferences in advance and could plan ahead; then there is some maximum number M of lollipops that you could possibly sell. You do not know the customers' preferences in advance, but we require you to sell a number of lollipops that is at least 90% of M for each input case.

Input and output

This problem is interactive, which means that the concepts of input and output are different than in standard Code Jam problems. You will interact with a separate process that both provides you with information and evaluates your responses. All information comes into your program via standard input; anything that you need to communicate should be sent via standard output. Remember that many programming languages buffer the output by default, so make sure your output actually goes out (for instance, by flushing the buffer) before blocking to wait for a response. See the FAQ for an explanation of what it means to flush the buffer. Anything your program sends through standard error is ignored, but it might consume some memory and be counted against your memory limit, so do not overflow it.

Initially, your program should read a single line containing a single integer T indicating the number of test cases. Then, you need to process T test cases.

For each test case, your program should read a single line with one integer N, the number of lollipops (which is the same as the number of customers).

Then, for each of the customers, your program should read a single line, which will contain space-separated integers. The first integer is D, the number of flavors that customer likes. Then, D integers follow, the ID numbers of those flavors, in strictly increasing order. Flavors have unique ID numbers in the range [0, N - 1]. Note that D might be zero for some or all customers.

After each of these lines, your program must write a single line to standard output, containing the ID number of one of the D flavors to sell to the customer, or -1 if no lollipop is to be sold to the customer. After you have written the Nth line for the test case, your program should terminate if it was the last test case; otherwise, it should start reading data for the next test case.

If your program gets something wrong (e.g., tries to sell a customer a flavor that was already sold, or tries to sell a customer a flavor they don't like, or uses the wrong output format, or outputs an out-of-bounds value), the judge will send -1 to your input stream and it will not send any other output after that. If your program continues to wait for the judge after receiving -1, your program will time out, resulting in a Time Limit Exceeded error. Notice that it is your responsibility to have your program exit in time to receive the appropriate verdict (Wrong Answer, Runtime Error, etc.) instead of a Time Limit Exceeded error. As usual, if the total time or memory is exceeded, or your program gets a runtime error, you will receive the appropriate verdict. Not selling enough lollipops for a test case will not cause you to get the -1 message.

You should not send additional information to the judge after processing all test cases. In other words, if your program keeps printing to standard output after the last test case, you will get a Wrong Answer judgment.

A note on judge behavior

At the start of each test case, the judge will determine all customers' preferences. That is, it will use a (hidden) list of probabilities Pi between 0.005 and 0.1, one for each flavor; each customer has a probability Pi of liking the i-th flavor. That is, the random variables indicating whether customer j likes flavor i are independent and identically distributed. These preferences are constant throughout the test and will not be modified e.g. in response to your choices.

Test set 1 (Visible)

T = 50.
N = 200.
0 ≤ DN.
Time limit (for the entire test set): 25 seconds.
Memory limit: 1GB.

Sample Interaction

Note that this sample interaction has smaller values of T and N than the real data. The local testing tool also uses smaller cases.

  t = readline_int()           // reads 10 into t
  n = readline_int()           // reads 4 into n (four customers & flavors)
  prefs = readline_int_list()  // reads 1 2 (customer only likes flavor 2)
  printline 2 to stdout        // sells this customer flavor 2
  flush stdout
  prefs = readline_int_list()  // reads 0 (customer likes nothing)
  printline -1 to stdout       // no flavor to sell to the customer!
  flush stdout
  prefs = readline_int_list()  // reads 1 2 (customer only likes flavor 2)
  printline -1 to stdout       // already used flavor 2, so no flavor to sell
  flush stdout
  prefs = readline_int_list()  // reads 2 1 3 (customer likes 1 and 3)
  printline 3 to stdout        // note: we could have also sold flavor 1
  flush stdout
  n = readline_int()           // (start of case 2) reads 1
  prefs = readline_int_list()  // reads 1 0
  printline -1 to stdout       // non-optimal but legal choice
  flush stdout
  n = readline_int()           // (start of case 3) reads 5
  prefs = readline_int_list()  // reads 2 1 3
  printline 1 to stdout
  flush stdout
  prefs = readline_int_list()  // reads 2 1 2
  printline 1 to stdout        // error -- tried to give same flavor twice!
  flush stdout
  prefs = readline_int_list()  // reads -1 (judge has given up on us)
  exit                         // exits to avoid an ambiguous TLE error

The pseudocode above demonstrates the following scenario.

  • In the first test case, the program sells a total of two lollipops. It would not have been possible to sell more than two, so the actual number sold is definitely at least 90% of the maximum possible number sold.
  • In the second test case, the program chooses (for the sake of demonstration here) not to sell the customer a lollipop, although it could have. It sells a total of 0 when it could have sold a total of 1. So, the program will not pass this test set, but note that this does not cause the judge to stop sending input.
  • In the third case, the program makes an error (again for the sake of demonstration) that causes the judge to stop sending input. The program recognizes this and terminates. The user will see a Wrong Answer judgment.

Testing Tool

You can use this testing tool to test locally or on our platform. To test locally, you will need to run the tool in parallel with your code; you can use our interactive runner for that. For more information, read the instructions in comments in that file, and also check out the Interactive Problems section of the FAQ.

Instructions for the testing tool are included in comments within the tool. We encourage you to add your own test cases. Please be advised that although the testing tool is intended to simulate the judging system, it is NOT the real judging system and might behave differently. If your code passes the testing tool but fails the real judge, please check the Coding section of the FAQ to make sure that you are using the same compiler as us.

Download testing tool

C. Ant Stack

Problem

Scott has an ant farm containing N ants. Each ant has a certain length and weight.

Today, as a challenge for the ants, Scott has placed some food at the top of the ant farm. The ants will try to reach it by arranging themselves into a vertical stack, with each ant in the stack directly holding the next on its back. In this way, each ant bears the weight of all ants above it. Scott's ants are very strong for their size and are able to carry up to 6 times their own weight. For example, an ant that weights 8 milligrams can carry two other ants weighing 24 milligrams each! Each ant also has a body length; the exact lengths are not important, except that they are all different.

  • The stack must be linear. Each ant except for the top ant must be directly below exactly one ant, and each ant except for the bottom ant must be directly above exactly one ant.
  • The lengths of the ants in the stack must be strictly decreasing from the bottom to the top of the stack; this ensures that each new ant that joins the stack will be able to climb up to the top.
  • For each ant, the sum of the weights of all the ants above it in the stack must be no more than 6 times the weight of that ant.

What is the maximum number of these ants that can form such a stack?

Input

The first line of the input gives the number of test cases, T. T test cases follow. Each begins with one line with an integer N: the number of ants in the colony. Then, a second line follows containing N integers W1, W2, ..., WN, where Wi is the weight in milligrams of the i-th ant. The ants are listed in strictly increasing order of length. Notice that no actual length values are given; only the order is important.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the maximum number of the given ants that can form a stack that obeys the rules above.

Limits

7 ≤ T ≤ 100.
Time limit: 15 seconds per test set.
Memory limit: 1GB.

Test set 1 (Visible)

For exactly 6 cases, N = 100; for the other T - 6 cases, 2 ≤ N ≤ 50.
1 ≤ Wi ≤ 1000, for all i.

Test set 2 (Hidden)

For exactly 6 cases, N = 105; for the other T - 6 cases, 2 ≤ N ≤ 500.
1 ≤ Wi ≤ 109, for all i.

Sample

Sample Input
content_copy Copied!
3
2
9 1
3
8 4 100
9
10 10 10 10 10 10 10 10 100
Sample Output
content_copy Copied!
Case #1: 1
Case #2: 3
Case #3: 8

In Sample Case #1, there are two ants. The first weighs 9 mg; the second weighs 1 mg, and is longer than the first ant. The first ant is strong enough to hold the second ant (since it can hold up to 9 × 6 mg), but it cannot, because the second ant is longer. The second ant is not strong enough to hold the first ant (since it can only hold up to 1 × 6 mg, which is less than 9 mg). So it is only possible to make a "stack" of one of the two ants.

In Sample Case #2, it is possible for all three ants to form a stack, with the third holding up the second, which holds up the first.

In Sample Case #3, the optimal solution has the ninth ant on the bottom, and then seven of the other ants above it.

Analysis — A. A Whole New Word

Test set 1

Since L ≤ 2, this test set can be solved using a complete search. First, we collect the letters that appear among the first characters of the input words in a set C1 and the letters that appear among the second characters of the input words in a set C2. Any candidate new word has the form c1c2, where c1 is in C1 and c2 is in C2. For each candidate new word, we check whether this word is in the input. We can output any candidate new word which does not appear in the input as our answer. If every candidate new word already appears in the input, the case is impossible.

Since there are only at most 262 different candidate words that we need to try, this solution will run very quickly.

Test set 2

In early rounds of Code Jam, a complete search will often work for the first test set, but will generally not work for subsequent test sets. This problem is an exception! Our approach above will work just fine for test set 2.

We can create sets C1, C2, ..., CL as in the solution above, and then use them to generate candidate words as before, one at a time. If we encounter a word that is not in the input, we can return it as our answer. If it turns out that there are exactly N candidate words (which implies that every word that could be generated is already in the input), the case is impossible. Otherwise, we can be sure that we will have found an answer by the time we generate and check the (N + 1)th candidate word, since there are only N words in the input list.

Test Data
info We recommend that you practice debugging solutions without looking at the test data.

Analysis — B. Lollipop Shop

This problem's acceptance condition is based on competitive analysis. The problem is a bit tough to test locally, even for an interactive problem. It is easy to generate a particular set of customer preferences, but determining the maximum possible number of lollipops we can sell requires bipartite matching. However, we do not necessarily need to do that; since there is only one test set, which is Visible, we have some room for experimentation and for small leaps of faith.

A solution that just picks random legal flavors is not good enough to pass, so we need a couple of insights:

  • Selling a lollipop, if possible, is never worse than not selling a lollipop. Assume that there is some good solution that involves not selling a lollipop now, and selling L lollipops in total later. Selling a lollipop now can only stop at most 1 lollipop from being sold later, so we can still sell L-1 more lollipops.
  • If we have a choice of lollipops to sell, the best we can do is sell a lollipop that has the lowest probability of being liked. Intuitively, this saves the flavors that are more likely to show up later. (This intuition can be proved mathematically.)
  • But we don't know the true probability for each flavor. The best estimate we can get for a flavor at any point is the number of customers that have liked that flavor so far, divided by the total number of customers seen so far.

Therefore, our best strategy is to always sell a lollipop if possible; whenever there are multiple flavors to choose from, we choose one of the flavors that we have seen the minimal number of times among previous customers' preferences. In problems like this, when we have to break a tie, we should do so at random just in case the problem setters have tried to anticipate and thwart particular strategies like always choosing the smallest ID number. (In this problem, it would have been impossible for the setters to penalize that, though!)

Notice that our solution would not work for an arbitrary list of probabilities, even with 200 customers. If every probability is 0.02, for example, our strategy loses its power (since all flavors are equally likely), and each flavor appears frequently enough to make our strategy do much worse than matching, but infrequently enough that we have very few chances to make the right choices. However, the problem guarantees that the probabilities are drawn randomly from the range [0.005, 0.1]. This should give us enough confidence that the probabilities will be different enough for our strategy to exploit.

The algorithm we have described can be shown to be at least as good as any other solution. But what if we had been less certain? In a problem with only Visible test sets, it is generally better to try (at the risk of a 4 minute penalty) than to spend more than 4 minutes worrying.

Analysis — C. Ant Stack

Test set 1

To solve this test set, we can use dynamic programming (DP). We define a function f(x, y) as the maximum number of ants that can form a stack (following the stack requirements given in the problem statement), in which we only consider ants from the first ant to the x-th ant, inclusive, and the sum of the ants' weight is not more than y.

We can compute the value of f(x, y) by considering two cases:

  • Suppose we don't put the x-th ant on the bottom of the stack. Then we can ignore the x-th ant, and so the value of f(x, y) from this case becomes f(x - 1, y).
  • Suppose we put the x-th ant on the bottom of the stack. Then we need to maximize the number of ants to be put on top of the x-th ant, which is the value of f(x - 1, min(6Wx, y - Wx)). Counting the x-th ant as well, the value of f(x, y) from this case becomes f(x - 1, min(6Wx, y - Wx)) + 1. Note that we only consider this case if y ≥ Wx.

Between the two cases (or only one case if y < Wx), we take the larger value as the value of f(x, y).

The answer for the problem is the value of f(N, ∞). Since there are O(N) possible values for x, O(max(W)) possible values for y, and O(1) iterations for each computation of f(x, y), this solution runs in O(N × max(W)) time.

There is also another solution involving another DP formulation f', where f'(x, y) only considers ants from the x-th ant to the N-th ant (instead of the first ant to the x-th ant).

Test set 2

To solve this test set, we need to find the value of K, the maximum possible answer to the problem. To have a stack with as many ants as possible, where the upper-bound of the ants' weight is fixed by a constant (i.e. 109 in this problem), we greedily put the lightest ant possible on the bottom of the stack. In other words, a stack with as many ants as possible will have ants with weights something like (1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 6, ...). We stop as soon as we need to add an ant with a weight more than 109. By creating a simple script, we can determine that the value of K is 139, much smaller than N.

Therefore, we can solve this test set with another DP formula. We define a function g(x, y) as the minimum sum of the weights of the ants that can form a stack of y ants where only the ants from the first ant to the x-th ant are considered, or ∞ if no such stack exists.

Again, we can compute the value of g(x, y) by considering two cases:

  • Suppose we don't put the x-th ant on the bottom of the stack. Then we can ignore the x-th ant, and so the value of g(x, y) from this case becomes g(x - 1, y).
  • Suppose we want to put the x-th ant on the bottom of the stack. We first need to check whether this is possible. We can compute the value of g(x - 1, y - 1), the minimum sum of the weights of the ants that can form a stack of y - 1 ants where only the ants from the first ant to the (x - 1)-th ant are considered. If g(x - 1, y - 1) ≤ 6Wx, then it is possible to put the x-th ant on the bottom of the stack. The value of g(x, y) from this case becomes g(x - 1, y - 1) + Wx.

Between the two cases (or only one case if g(x - 1, y - 1) > 6Wx), we take the smaller value as the value of g(x, y).

The answer for the problem is the largest possible value S where g(N, S) < ∞. Since there are O(N) possible values for x, O(K) possible values for y, and O(1) iterations for each computation of g(x, y), this solution runs in O(NK) time.

Test Data
info We recommend that you practice debugging solutions without looking at the test data.

Statistics — A. A Whole New Word

Statistics — B. Lollipop Shop

Statistics — C. Ant Stack