0
def dealHand(n):
    """
    Returns a random hand containing n lowercase letters.
    At least n/3 the letters in the hand should be VOWELS.

    Hands are represented as dictionaries. The keys are
    letters and the values are the number of times the
    particular letter is repeated in that hand.

    n: int >= 0
    returns: dictionary (string -> int)
    """

    hand={}
    numVowels = n / 3

    for i in range(numVowels):
        x = VOWELS[random.randrange(0, len(VOWELS))]
        hand[x] = hand.get(x, 0) + 1

    for i in range(numVowels, n):
        x = CONSONANTS[random.randrange(0,len(CONSONANTS))]
        hand[x] = hand.get(x, 0) + 1

    return hand

この関数は私が作成しなければならなかったワードゲームの一部であり、開始を支援するためにいくつかのヘルパー関数に含まれていました。私の問題は、返される文字があまりランダムではなく、次のような繰り返し文字がたくさんある a a c c b e e g j j m m m o o r t v y xことです。よりランダムな文字のセットを取得できるかどうか疑問に思っていますか?

4

3 に答える 3

1

「返される文字はあまりランダムではありません。繰り返し文字がたくさんあります」-真剣ですか?

繰り返しなしで n 文字を取得したい場合は、次のようなものを使用します。

from random import shuffle
alphabet = ['a', .., 'z']
shuffle(alphabet)
print(alphabet[:n])

n > len(alphabet) の場合、とにかく繰り返します。

于 2013-03-20T17:11:51.317 に答える
1

アルゴリズムのよりコンパクトな表現を次に示します。

from __future__ import division
from collections import Counter
import random
import string

VOWELS = "aeiou"
CONSONANTS = "".join(set(string.lowercase) - set(VOWELS))

def dealHand(n):
    numVowels = n // 3
    lettersets = [VOWELS] * numVowels + [CONSONANTS] * (n - numVowels)
    return Counter(c
        for letterset in lettersets
        for c in random.choice(letterset)
    )

十分にランダムに見えます。


その後、「文字を 2 回以内に表示したい場合、どうすればそれを達成できますか?」

まあ、あなたはこれを行うことができますが、私はこれをお勧めしません:

def dealHand2(n):
    while True:
        candidate = dealHand(n)
        if all(v <= 2 for v in candidate.values()):
            return candidate

これは、条件を満たす文字のセットが見つかるまで無限ループです。上映時間:未定。

于 2013-03-20T17:32:48.960 に答える
0

このバージョンでは、統計的に子音の 3 倍の母音が必要ですが、正確な数は保証されていません。

import collections
import random

VOWELS = 'aeiou'
CONSONANTS = 'bcdfghjklmnpqrstvwxyz'

def dealHand(n):
 letters = 3 * VOWELS + CONSONANTS 
 collections.Counter(random.sample(letters, n))
于 2013-03-20T18:16:56.363 に答える