# Busy busy busy!

Just stopped by quickly to say that may not be able to post during this week… finishing projects at work, so, that means long hours and a tight schedule. But I’ll be fine. I sincerely hope there’s pizza for dinner. 🙂 baba

# Difficult CodeJam problem and Free Software Documentary

Well, it’s been a tough weekend. Many new things were installed at home, lots of drilling and weightlifting (oh my arms…) but feels nicer after all. 🙂 More places for the kittens to hide.

That said, I’m evolving on Africa 2010 CodeJam D problem, but as soon as I get closer to solving, another challenge appears. This time, I’m having trouble finding an heuristic to determine the right choice to make, of all the results. Perhaps I’m still getting many results and not comparing correctly to the “solved group” list. I’ll for sure find out eventually.

Also, watched InProprietario, a brazilian documentary on free software (lots of Stallman) and, beside being very crude on effects, they used some nice movie references to cleverly show some software concepts. If you can understand portuguese and would like to know more about Free Software, I highly recommend it. 🙂

# Code Jam 2010 Africa – Problem C

Whoa, that was a tough problem. Ironically it’s called Qualification Round:

You’ve just advanced from the Qualification Round of Google Code Jam Africa 2010, and you want to know how many of your fellow contestants advanced with you. To give yourself a challenge, you’ve decided only to look at how many people solved each problem.

The Qualification Round consisted of P problems; the ith problem was fully solved by Scontestants. Contestants had to solve C problems in order to advance to the next round. Your job is to figure out, using only that information, the maximum number of contestants who could have advanced.

Well, at first it seems pretty simple, but there is quite some math involved. The first case of the example input is easy to solve, but the second will most likely get you scratching your head thinking “where the #\$%* that number came from” (at least I did). 🙂 Well the secret is that you should not look at the inputs as they are, but instead, find the maximum amount of solved problem combinations there are.

I studied a bit but still could not solve it, and surrendered by checking the contest analysis. It was quite complicated to understand, until they wrote about a clever solution from the winning candidate: it consisted in lowering the possible scores to max at the division of the scores by the amount of needed problems. Just do it (don’t ask why) until there are no scores over the result of that division. That same result will be the answer. Creepy! Python code time:

```for case in range(1,int(raw_input())+1):          # For all test cases
info = map(int, raw_input().split(" "))       # Get test case information
problems = info[0]                            # Fetch number of problems
needed = info[1]                              # Fetch number of needed problems to pass
results = info[2:]                            # Fetch results for each problem

qualified = 0                                 # Initialize our results

if (problems == needed):                      # For this case, we can expect
results.sort()                            # as many contestants as the
qualified = results[len(results)-needed]  # least solved problem

else:                                         # For this case, we use a solution
out = False                               # similar to the winning one
while not out:
out = True
qualified = sum(results)/needed       # Reduce the number of possible qualifiers
for i in range(len(results)):         # And for all results
if results[i] > qualified:        # Limit their values to the current qualifiers
results[i] = qualified
out = False                   # Until they all "match" the qualifiers number

print "Case #%d: %s" % (case, str(qualified)) # Report results
```

Interestingly enough, this code is smaller than the last, and solves a more complicated problem (at least in my opinion). I don’t think I could have done a better job on this one. 🙂 That’s the beauty in learning!

# CodeJam Quickie: 2010 Africa – Problem B

Howdy! This time, problems started getting more and more complex, and that’s good, because I like the challenge! The next problem is Get to Work:

You work for a company that has E employees working in town T. There are N towns in the area where the employees live. You want to ensure that everyone will be able to make it to work. Some of the employees are drivers and can drive P passengers. A capacity of `P == 1` indicates that the driver can only transport themselves to work. You want to ensure that everyone will be able to make it to work and you would like to minimize the number of cars on the road.

You want to calculate the number of cars on the road, with these requirements:

• Every employee can get to town T.
• The only way an employee may travel between towns is in a car belonging to an employee.
• Employees can only take rides from other employees that live in the same town.
• The minimum number of cars is used.

Find whether it is possible for everyone to make it to work, and if it is, how many cars will end up driving to the office.

Whoa, that’s way more complex than the other problems, but still, not that hard! What we need to do is: check who are drivers and passengers for each town (since they can only help same town buddies), if the total capacity of cars from a town is inferior to the number of passengers, the problem cannot be solved and so, reported as “IMPOSSIBLE”. If we can carry everyone, start filling the cars from the “minivan” (can carry more passengers) to the “mini cooper”. 😀 That way we can make sure there are fewer cars on the road.

Some rough, but commented, and validated (!) python code follows:

```for case in range(1,int(raw_input())+1):                  # For all test cases
town_len, office = map(int, raw_input().split(" "))   # Get amount of towns and office

carriers = [[] for x in xrange(town_len)]             # Create new lists for every town
capacities = town_len * [0]                           # Initialize "capacity of transportation"
payload = town_len * [0]                              # Initialize "cargo" for each town

for i in range(int(raw_input())):                     # Get and go through employee list
town, capacity = map(int, raw_input().split(" ")) # Get the current employee info
if town == office:                                # If employee is from office town
continue                                      #   No need to commute, ignore

town -= 1                                         # Adjust "town" to zero-based index
payload[town] += 1                                # Employee needs to commute, count

if capacity != 0:                                 # If employee has a car
capacities[town] += capacity                  # Add to our capacities for the town
carriers[town].append(capacity)               # Append its car capacity

resultStr = ""                                        # Create our result string

for i in range(town_len):                             # For all towns
if capacities[i] < payload[i]:                    # If we can't carry everyone
resultStr = "IMPOSSIBLE "                     #   declare it impossible, give up
break;

carriers[i].sort()                                # Sort and reverse the car list
carriers[i].reverse()
for car in carriers[i]:                           # So we can start from the bigger ones
break                                     #  we're done for this town

payload[i] -= car                             # Else, fill a car, report as being used
cars += 1

resultStr += str(cars)+" "                        # Add this town filled vehicles

print "Case #%d: %s" % (case, resultStr[:-1])         # Report results, remove last space
```

As the last problem, the same can be told about this code. There are many ways to improve its performance, but this way it can already solve the large inputs in an instant. Bitbangers apart, it solves the problem and everybody gets happy. Also, I think it is quite clear to understand, even more with the comments. 🙂 Bye!

# CodeJam Quickie: 2010 Africa – Problem A

Hey there! So, another day, another problem! This time, it is called Odd Man Out, and it is quite simple to “get”:

You are hosting a party with `G` guests and notice that there is an odd number of guests! When planning the party you deliberately invited only couples and gave each couple a unique number `C` on their invitation. You would like to single out whoever came alone by asking all of the guests for their invitation numbers.

Well, just get the number that’s not duplicated! There are many ways to do this, be it counting the occurrences of every member of the list and finding the “odd man”, or the way I did, which is basically some push and pop into a new list. Python code follows:

```for case in range(1,int(raw_input())+1):        # For all test cases
raw_input()                                 # Discard the guest list size
guests = raw_input().split(" ")             # Get the list of guest IDs

guestList = []                              # Create an empty guest list

for guest in guests:                        # For all guests
if guestList.count(guest) > 0:          # If it's already on the final list
guestList.remove(guest)             #    if is a couple, remove
else:                                   # If it's not in the list yet

print "Case #%d: %s" % (case, guestList[0]) # Reports results
```

Needless to say, I bet there are many ways to improve this algorithm, but for this problem it performs decently, so no worries (unless you’re a hardcore bit banger). 🙂 See you tomorrow!

# CodeJam Quickie: 2010 Africa – Qualification C

Whoa! Keeping up with the Africa 2010 contest, enter the Qualification C problem: T9 Spelling! It was a very fun problem and says:

The Latin alphabet contains 26 characters and telephones only have ten digits on the keypad. We would like to make it easier to write a message to your friend using a sequence of keypresses to indicate the desired characters. The letters are mapped onto the digits as shown below. To insert the character `B` for instance, the program would press `22`. In order to insert two characters in sequence from the same key, the user must pause before pressing the key a second time. The space character `' '` should be printed to indicate a pause. For example, `2 2` indicates `AA` whereas `22` indicates `B`.

Reminds me of those days of texting through that old indestructible Nokias! Anyway, it’s not hard to do, but requires some data disposition. I chose to create a map to lists containing keys and the amount of keystrokes for every letter (including space, which would be 0), in order to simply match letters and print the sequence right along. Also, to know when to pause, I would check the last printed character before, so I can print a space and then the sequence.

Python code followsas usual:

```# Build a map with the number to write and its repetition count
t9 = {
"a" : ["2", 1], "b" : ["2", 2], "c": ["2", 3],
"d" : ["3", 1], "e" : ["3", 2], "f": ["3", 3],
"g" : ["4", 1], "h" : ["4", 2], "i": ["4", 3],
"j" : ["5", 1], "k" : ["5", 2], "l": ["5", 3],
"m" : ["6", 1], "n" : ["6", 2], "o": ["6", 3],
"p" : ["7", 1], "q" : ["7", 2], "r": ["7", 3], "s": ["7", 4],
"t" : ["8", 1], "u" : ["8", 2], "v": ["8", 3],
"w" : ["9", 1], "x" : ["9", 2], "y": ["9", 3], "z": ["9", 4],
" " : ["0", 1],
}

for case in range(1,int(raw_input())+1): # For all test cases
message = raw_input()                # Get the list of words