2

私はプロジェクトオイラーの問題22に取り組んでいます:

names.txt(右クリックして[リンク/ターゲットに名前を付けて保存...])を使用して、5000を超える名を含む46Kテキストファイルをアルファベット順に並べ替えます。次に、各名前のアルファベットの値を計算し、この値にリスト内のアルファベットの位置を掛けて、名前のスコアを取得します。

たとえば、リストをアルファベット順に並べ替えると、3 + 15 + 12 + 9 + 14=53の価値があるCOLINがリストの938番目の名前になります。したがって、COLINは938×53=49714のスコアを取得します。

ファイル内のすべての名前スコアの合計はいくつですか?

http://projecteuler.net/problem=22

以下のコードをコンパイルすると、 871196077という答えが返されます。正解は871198282である必要があります。

インポート時間

def euler_22():

## Creates a sorted list of the names in Py_Euler_22.txt
names = open('Py_Euler_22.txt', 'r')
names = names.read()
names = names.split('","')
names[0] = names[0][1:]
names[-1] = names[-1][:-2]
names = sorted(names)

## Creates a dictionary: letter -> value
value_letters = {}
start = ord("A")
for i in range(0, 26):
    value_letters[chr(start+i)] = i+1

result = 0

for i in range(1, len(names)+1):
    name = names[i-1] 
    sum_letters = 0
    for letter in name:
        sum_letters += value_letters[letter]*i 
        # = value of the letter multiplied with the name position
    result += sum_letters
return result

tstart = time.time()print euler_22()print "実行時間:" + str(time.time()-tstart)

同様の解決策でプログラムを見つけようとしましたが、オプションを制限するPythonしか知りません。私は、プログラムなしで答えを得ることができ、それらすべてが機能する、より単純なテキストファイルを使用してプログラムを実行しました。問題の答えをグーグルで検索しましたが、不足している点が見つからないため、それも役に立ちませんでした。

私は初心者なので、問題を正しく解決するのに役立つ、プログラムとPythonに関するヒントだけでなく、それらに関するヒントを本当にいただければ幸いです。

どうもありがとう!

4

3 に答える 3

3

誤って 1 つの名前を壊してしまいました。

これはあなたqnamesのコードが生成する名前のソートされたリストであり、sorted_names私のものです:

>>> for a,b in zip(qnames, sorted_names):
...     if a != b:
...         print a, b
... 
ALONS ALONSO

楽しみのために: ワンライナー - ネストされたリスト内包表記、avast ye!

print sum ( [ (pos+1) * nv for pos, nv in enumerate([ sum ( [ ord(char) - 64 for char in name ] ) for name in sorted([name.strip('"') for name in open('names.txt','r').readline().split(",")]) ]) ] )

またはより読みやすい:

print sum (
    [(pos+1) * nv for pos, nv in
        enumerate([ sum ([ ord(char) - 64 for char in name ] ) for name in
            sorted([name.strip('"') for name in
                open('names.txt','r').readline().split(",")]) ]) ] )

ブラック マジックは、ASCIIAは integer 65、ASCIIBは integer66などであるということです。ord(char) - 64つまり、 の「文字値」が得られますchar


編集2:

あなたの娯楽のために私が1行に詰め込んだ、人間が読める完全なソリューション.

with open('names.txt','r') as f:
    data = f.readline();

names = [name.strip('"') for name in data.split(",")]
sorted_names = sorted(names)
name_values = [ sum ( [ ord(char) - 64 for char in name ] ) for name in sorted_names ]
name_position_values = [ (pos+1) * nv for pos, nv in enumerate(name_values) ]
total_sum = sum(name_position_values)

# debug output
from pprint import pprint
#position, word value, position * word value, word
pprint(zip(xrange(1,len(names)+1),name_values,name_position_values,sorted_names))

[x for x in list_of_xes]ループの代わりにリスト内包表記を多用していること、および のsum()代わりに関数を使用していることに注意してくださいfor x in xes: sum += x

ここには他にもいくつかのトリックがありますが、ここで得られる教訓は、リスト内包表記とリストを処理する関数を使用すると、コードがはるかに単純で読みやすくなるということです。


編集3:

機能は「pprint.pprint()かわいいprint()」です。デバッグに最適です。


編集4:

コード ゴルフ バージョン (142 文字):

print sum([(p+1)*v for p,v in enumerate([sum(map(ord,n))-64*len(n) for n in sorted([n[1:-1] for n in open('names.txt').read().split(",")])])])
于 2012-05-08T06:57:03.867 に答える
1

コードをクロスチェックしたところ、最後の単語の最後の文字をうっかり切り取ってしまったようです。最後の単語から引用符を取り除くには、次を使用します。

names[-1] = names[-1][:-1]
于 2012-05-08T06:51:52.073 に答える
0

ファイルの内容をリストに変換するときに名前からすべての引用符を一度に削除しようとするのではなく、リストを処理するときにそれらを削除します。

# Project Euler Problem 22
# Name Scores

def score(name):
    total = 0

    for char in name:
        total += (ord(char) - 64) # scale so A = 1, B = 2...

    return total

def main():
    # Open the names file for reading
    infile = open('names.txt', 'r')

    # Read the entire contents of the file
    file_contents = infile.read()

    # Close the file
    infile.close()

    # Convert file contents to a list of quoted names and sort them
    list_of_names = file_contents.split(',')
    list_of_names.sort()

    position = 1
    total = 0
    for name in list_of_names:
        name = name.strip('"') # strip the quotes from names individually
        total += score(name) * position
        position += 1

    print(total)

if __name__ == "__main__":
    main()
于 2012-08-04T15:43:03.140 に答える