The rotate google contest in 15 lines
The rotate example nico last week reported was funny to solve: No rotating needed! Read the complete problem description in nicos article or in the google code contest page. Here my complete python solution with file handling and solution printing.
- import sys
- from re import search
- fp = file(sys.argv[1])
- for case in range(1, 1+int(fp.next())):
- n, k = [int(x) for x in fp.next().split()]
- lines = [fp.next() for x in range(n)]
- #right-gravitation and joining to one line (delim is a line)
- s = "#".join(map(lambda x:"%%%ds"%n%(x.strip().replace(".","")), lines))
- result = 0
- #find one of the 4 variants: horiz, verti, slash, backslash for Blue
- reB = "(B.{%%d}){%d}B" % (k-1)
- if search(k*"B", s) or search(reB%(n-1), s) or search(reB%n, s) or search(reB%(n+1), s):
- result+=1
- #find one of the 4 variants: horiz, verti, slash, backslash for Red
- reR = "(R.{%%d}){%d}R" % (k-1)
- if search(k*"R", s) or search(reR%(n-1), s) or search(reR%n, s) or search(reR%(n+1), s):
- result= result+2
- print "Case #%d: %s" % (case, ["Neither", "Blue", "Red", "Both"][result])
There are 15 effective lines of code for the solution. And some lines are used for imports or reading from the input file (comments and spacer not counted) - cool?
handling the gravitation
To understand the code read the problem description in nicos article or in the google code contest page. I will describe now the two steps for the solution. First the play field have to sorted like a gravitation to the right. All dot character are handled like spaces and the capital letters goes to the right border.
We start with a n by n matrix:
- ..R ..R
- .R. -> ..R
- R.B .RB
To remove the dots simple replace it with nothing as a standard string manipulatin method. To fill it from the left use the common used string formating well know from printf.
- newLine = “%3s” % lin.replace(“.”, “”)
To do this with the length n use this obscure-looking multi step format string:
- newLine = “%%%ds” % n % line.replace(“.”, “”)
And to do this with a complete list of lines use a list comprehension (read more about functional programming in python).
- lines = map(lambda x:"%%%ds"%n%(x.replace(".","")), lines)
This is done in line 10 in the example (with joining to one string).
find the winner
Second part is to find the k=4 characters in a line:
- RBBBB
- _RBBB -> "RBBBB#_RBBB#__RBB#___RB"
- __RBB
- ___RB
I concat all lines to one string to find the four different directions with regular expressions: “RBBBB-_RBBB-__RBB-___RB”
- The horizontal line is easy:
/BBBB/
or with k:/B{4}/
- the vertical line can found by 4 B’s and n characters (one line up):
/B.{5}B.{5}B.{5}B/
or shorter:/(B.{5}){3}B/
- the backslash line is the same like the vertical line, only with n+1 spaces
- the slash line is the same like the vertical line, only with n-1 spaces
I prepared the regular pattern with k: reB = "(B.{%%d}){%d}B" % (k-1)
and used the multi step format string for the different pattern strings (see example above in line 15).
That’s all!
- Login to post comments
Comments
Solutions for the google code jam 2012 qualify round | unite (not verified) - Sun, 04/15/2012 - 22:17
[...] The rotate problem from the Round 1A 2010 from nico and my self [...]