Created
June 15, 2011 07:24
-
-
Save kilburn/1026638 to your computer and use it in GitHub Desktop.
Script that answers the Ready For Zero challenges (https://www.readyforzero.com/challenge)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
def load_file(fname, slice=None, conversion=None, ignore=True): | |
"""Loads the specified file, returning a (sub)list of (converted) elements.""" | |
f = open(fname, 'r') | |
chars = ''.join([line.rstrip('\n') for line in f]) | |
f.close() | |
if slice: | |
chars = chars[slice] | |
if conversion: | |
original = chars | |
chars = [] | |
for c in original: | |
try: | |
chars.append(conversion(c)) | |
except (TypeError, ValueError): | |
if not ignore: | |
print "Warning: ignored input character '%c'" % c | |
return chars | |
print "Challenge 1:", | |
"""This implementation is an optimized case applicable when we look for sequences | |
that share either all of the characters, or all but one. | |
The advantadge is that it runs in linear time, whereas the caveat is that it uses more | |
memory than the simple quadratic algorithm for the problem. For instance, When the | |
sequences are of length 5 (S_LEN=5), we store 20chars (5 strings of 4chars) for each | |
sequence, instead of the 5chars saved by the quadratic algorithm. | |
The basic idea is to maintain S_LEN sets, where each sets[i] contains the subsequences | |
of S_LEN-1 characters seen until the moment, disregarding the character in position i. | |
To clarify, if we see these the following input: | |
aabbbb | |
And S_LEN=5, then we exctract two sequences: | |
aabbb abbbb | |
Then, after processing the first sequence, the sets are (x marks an ignored character): | |
sets[0] | xabbb = abbb | |
sets[1] | axbbb = abbb | |
sets[2] | aaxbb = aabb | |
sets[3] | aabxb = aabb | |
sets[4] | aabbx = aabb | |
When we process the second sequence, we will find a match in the i=1 set: | |
sets[0] | xbbbb = bbbb (it was not in sets[0] previously, so no match and its added) | |
sets[1] | axbbb = abbb (that is already in sets[1], match!) | |
""" | |
S_LEN = 5 | |
sets = [set() for i in xrange(S_LEN)] | |
chars = load_file('Challenge1.txt') | |
for i in xrange(len(chars) - S_LEN + 1): | |
sequence = chars[i:i+S_LEN] | |
for j in xrange(S_LEN): | |
subseq = sequence[0:j] + sequence[j+1:S_LEN] | |
if subseq in sets[j]: | |
print subseq | |
else: | |
sets[j].add(subseq) | |
print "Challenge 2:", | |
''' | |
This is as simple as summing those even characters that are | |
integers. | |
''' | |
numbers = load_file('Challenge2.txt', slice=slice(None,None,2), conversion=int) | |
print sum(numbers) | |
print "Challenge 3:", | |
''' | |
The smaller the factor, the larger the number of sub-sequences, | |
so we iterate over the factors in increasing order and stop when | |
the sequence can be properly partitioned. | |
''' | |
def factors(number): | |
"""Returns a list of all possible factors of number. | |
This function is very inefficient, and should be improved | |
in real-life code. | |
""" | |
return [i for i in xrange(2, number/2) if not number%i] | |
def partition(numbers, factor): | |
""" | |
Count the number of contiguous partitions that sum up to factor. | |
""" | |
sum = 0 | |
parts = 0 | |
for n in numbers: | |
sum += n | |
if (sum == factor): | |
parts += 1 | |
sum = 0 | |
elif (sum > factor): | |
return 0 | |
return parts | |
numbers = load_file('Challenge3.txt', conversion=int, ignore=False) | |
n_seq = 1 | |
for factor in factors(sum(numbers)): | |
n_seq = partition(numbers, factor) | |
if n_seq: | |
break; | |
print n_seq; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment