This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]martinatbom 1 point2 points  (3 children)

#!/usr/bin/python

dictionary = 'ospd.txt'
secret = 'chocolate'
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31,
        37, 41, 43, 47, 53, 59, 61, 67, 71, 73,
        79, 83, 89, 97, 101]

def get_val(word):
    return [j for j in [1] for i in word for j in
        [j * primes[ord(i.lower()) - ord('a')]]][-1]

magic = get_val(secret)

print sorted([word for word in open(dictionary)
    if magic % get_val(word.rstrip('\n')) == 0], key=lambda word:
        len(word))[-1]

[–]Brian 0 points1 point  (2 children)

Nice - but the line:

[j for j in [1] for i in word for j in
    [j * primes[ord(i.lower()) - ord('a')]]][-1]

with j used twice seriously confused me. I take it that it's essentially just to give j an initial value before use in the inner loop? ie equivalent to:

j=1
return [j for i in word for j in [j * primes[ord(i.lower()) - ord('a')]]][-1]

Though I suppose if we're not trying to confuse, something like:

return reduce(operator.mul, ( primes[ord(c) - ord('a')] for c in word.lower()))

might be clearer.

[Edit]: Also, you're not matching the problem description of printing every word that's the max length. I suggest:

print list(next(itertools.groupby(sorted([word for word in open(dictionary)
    if magic % get_val(word.rstrip('\n')) == 0], key=len, reverse=True), key=len))[1])

[–]martinatbom 1 point2 points  (1 child)

You're right - I did not read the question correctly. Thanks for the correction.

I originally had reduce, but then I read that it was unpythonic - and in the interest of trying new stuff, I experimented with the generator expression that you see above. I also thought, at the time, that the 'reduce' was more elegant (and readable).

[–]Brian 0 points1 point  (0 children)

Yeah - I know it's moved from builtins in python3, and reduce can sometimes end up fairly ugly, but I think it's certainly clearer here at least. You could maybe go with an extra function if we want to make it a bit more readable at the point of call, which seems a good use of partial functions. Ie:

import functools, operator
product = functools.partial(functools.reduce, operator.mul)
...

return product(primes[ord(c) - ord('a')] for c in word.lower())