各行の最後にハード リターンを含め、それぞれ 60 文字の長さの 3 行のテキスト (本質的にはジブリっぽい) を生成する必要があります。行は、さまざまな長さ (通常は 1 ~ 8 文字) の単語の辞書から生成されます。単語を複数回使用することはできず、単語はスペースで区切る必要があります。これは本質的にビンパッキングの問題だと思います。
私がこれまでに取ったアプローチは、長さによってグループ化された単語の hashMap を作成することです。次に、ランダムな長さを選択し、その長さの単語をマップから取り出して、現在生成している行の末尾に追加します。スペースまたはハード リターンを考慮します。約半分の時間は機能しますが、残りの半分の時間は無限ループに陥り、プログラムがクラッシュします。
私が直面している 1 つの問題は次のとおりです。行にランダムな単語を追加すると、特定の長さの単語のグループが枯渇する可能性があります。これは、辞書内の各長さの単語数が必ずしも同じであるとは限らないためです。たとえば、長さ 1 の単語は 1 つしかない場合があります。その長さの任意の単語が利用可能です。
以下は、私がこれまでに持っているものをまとめたものです。私は ActionScript で作業していますが、どの言語でもこの問題についての洞察をいただければ幸いです。よろしくお願いします。
dictionary // map of words with word lengths as keys and arrays of corresponding words as values
lengths // array of word lengths, sorted numerically
min = lengths[0] // minimum word length
max = lengths[lengths.length - 1] // maximum word length
line = ""
while ( line.length < 60 ) {
len = lengths[round( rand() * ( lengths.length - 1 ) )]
if ( dictionary[len] != null && dictionary[len].length > 0 ) {
diff = 60 - line.length // number of characters needed to complete the line
if ( line.length + len + 1 == 60 ) {
// this word will complete the line exactly
line += dictionary[len].splice(0, 1) + "\n"
}
else if ( min + max + 2 >= diff ) {
// find the two word lengths that will complete the line
// ==> this is where I'm having trouble
}
else if ( line.length + len + 1 < 60 - max ) {
// this word will fit safely, so just add it
line += dictionary[len].splice(0, 1) + " "
}
if ( dictionary[len].length == 0 ) {
// delete any empty arrays and update min and max lengths accordingly
dictionary[len] = null
delete dictionary[len]
i = lengths.indexOf( len )
if ( i >= 0 ) {
// words of this length have been depleted, so
// update lengths array to ensure that next random
// length is valid
lengths.splice( i, 1 )
}
if ( lengths.indexOf( min ) == -1 ) {
// update the min
min = lengths[0]
}
if ( lengths.indexOf( max ) == -1 ) {
// update the max
max = lengths[lengths.length - 1]
}
}
}
}