スクラブルの文字の袋から単語を描画しない確率


27

タイルがあり、それぞれに文字が書かれたバッグがあるとします。あり文字'A'、とタイル 'B'で、というように、と 'ワイルドカード'タイルは、(私たちが持っている)。単語数が有限の辞書があるとします。交換せずにバッグからタイルを選びます。選択されたタイルが与えられた場合、辞書からゼロ語を形成できる確率をどのように計算(または推定)しますか?nnAnBnn=nA+nB++nZ+nkk

Scrabble(TM)に慣れていない人には、ワイルドカード文字を使用して任意の文字と一致させることができます。したがって、単語[ BOOT ]は、タイル 'B'、 '*'、 'O'、 'T'で 'スペル'できます。

問題の規模を理解するために、は7のように小さく、は約100で、辞書にはサイズ以下の約100,000語が含まれています。knk

編集:「単語を形成する」とは、長さが以下の単語を意味します。したがって、単語[ A ]が辞書にある場合、バッグから単一の 'A'を描画するだけで、 '単語を形成しました'。辞書に長さ1の単語があると仮定できる場合、ワイルドカードの問題は根本的に単純化されます。存在する場合、ワイルドカードの描画は自動的に長さ1の単語に一致するため、ワイルドカードがない場合に集中できます。したがって、より滑りやすい形式の問題には、辞書に1文字の単語がありません。k

また、バッグから文字が描画される順序は重要ではないことを明示的に述べる必要があります。単語の「正しい」順序で文字を描く必要はありません。


「交換せずに kタイル選ぶ」べきではないでしょうか?非常に興味深い質問です。

おっとっと。確かにそうすべきです。
shabbychef

私が覚えている限り、スクラブルは1文字の単語を許可していないので、少なくとも問題のその部分は解決されています;)
ニコ

1
@nicoの良い点ですが、これはゲーム中期専用だと思います。1文字の単語は、文字を再生する必要がないか、ボード上の任意の場所に1つの文字を配置することができますが、どちらも明らかに受け入れられません。しかし、私は最初の動きを考えていました。実際、スクラブルに精通している人にとっては、「最初のプレーヤーが合格しなければならない確率はいくらですか?」と質問を簡潔に述べることができます。
みすぼらしいシェフ

@nicoその説明をありがとう。理論的には、2文字の組み合わせをすべて単語として含む辞書にも同様の問題があります。その場合、2文字以上の手に単語が自動的に含まれます。ゲーム中盤に関する@shabbychefのコメントは、元の質問がScrabbleのほとんどとは無関係であることを示しています。ハンド。これにより、単語を作成できる可能性が大幅に高まります。
whuber

回答:


14

これは、このスレッドで@vqvが投稿した素晴らしい作品に関する(長い!)コメントです。それは最終的な答えを得ることを目指しています。彼は辞書を単純化するという大変な仕事をしました。残っているのは、それを最大限に活用することです。彼の結果は、ブルートフォースソリューションが実行可能あることを示唆してます。すべての後に、ワイルドカードを含む、ある最大で 1は7つの文字で作ることができ、そしてそれは彼ら未満の1/10000のように見えるの言葉-万人の周りに、たとえば-意志有効な単語が含まれていない。 277=10,460,353,203

最初のステップは、ワイルドカード文字「?」で最小辞書を拡張することです。22文字は2文字の単語で表示されます(c、q、v、zを除くすべて)。これらの22文字にワイルドカードを追加して、これらを辞書に追加します:{a ?, b ?, d ?, ...、y?}が今です。辞書に表示されます。最後に、「??」を追加します 辞書に。結果の繰り返しを削除すると、342個の最小単語が含まれます。

非常に少ない量のエンコードを実際に使用するエレガントな方法は、この問題を代数的なもの見なすことです。単語は、文字の順序付けられていないセットと見なされ、単なる単項式です。たとえば、「spats」は単項式です。したがって、辞書は単項式のコレクションです。のように見えますaps2t

{a2,ab,ad,...,ozψ,wxψ,ψ2}

(混乱を避けるために、ワイルドカード文字にを記述しました)。ψ

ラックに有効な単語が含まれるのは、その単語がラックを分割する場合のみです。

より抽象的でありながら非常に強力な方法は、辞書が多項式環R = Z [ a b z ψ ]で理想的な生成し、有効な語を持つラックが商でゼロになることです。R / Iを鳴らしますが、有効な語のないラックは商でゼロ以外のままです。Rのすべてのラックの合計を形成し、この商リングで計算する場合、単語のないラックの数は商の異なる単項式の数に等しくなります。IR=Z[a,b,,z,ψ]R/IR

さらに、のすべてのラックの合計は簡単に表現できます。してみましょうα = A + B + + Z + ψは、アルファベットのすべての文字の合計であること。 α 7は、各ラックのための1つの単項式を含有します。(追加のボーナスとして、その係数は各ラックの形成方法の数をカウントするため、必要に応じて確率を計算できます。)Rα=a+b++z+ψα7

(これがどのように機能するかを見るための)簡単な例として、(a)ワイルドカードを使用せず、(b)「a」から「x」までのすべての文字を単語と見なすと仮定します。次に、単語を形成できない唯一の可能なラックは、完全にyとzで構成されている必要があります。我々計算によって生成された理想を法{ B C ··· X }従って一度に1つのステップ:α=(a+b+c++x+y+z)7{a,b,c,,x}

α0=1α1=a+b+c++x+y+zy+zmodIα2(y+z)(a+b++y+z)(y+z)2modIα7(y+z)6(a+b++y+z)(y+z)7modI.

最終的な回答、から非単語ラックを取得する可能性を読み取ることができます。7 y z 6 + z 7:各係数は、対応するラックを描画できる方法をカウントします。例えば、2 Yの5 Zだ描画する21(7 ^ 26のうちの可能な)方法があるため、係数Yy7+7y6z+21y5z2+35y4z3+35y3z4+21y2z5+7yz6+z7は21です。y2z5

基本的な計算から、これが正解であることは明らかです。全体のポイントは、この手順が辞書の内容に関係なく機能するということです。

各段階で理想を法とするべき乗を減らすと、計算が減少することに注意してください。これが、このアプローチで明らかになった近道です。(例の終わり。)

多項式代数システムはこれらの計算を実装します。例えば、ここにMathematicaコードがあります:

alphabet =  a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + 
            p + q + r + s + t + u + v + w + x + y + z + \[Psi];
dictionary = {a^2, a b, a d, a e, ..., w z \[Psi], \[Psi]^2};
next[pp_] := PolynomialMod[pp alphabet, dictionary];
nonwords = Nest[next, 1, 7];
Length[nonwords]

(辞書は@vqvのmin.dictから簡単に構築できます。必要に応じて直接指定できるほど短いことを示す行をここに入れます。)

出力-計算の10分を要する- (577958.あるNBで私は辞書を調製する際に小さなミスを犯したと私は私が今あることを望むものを反映するテキストを編集した577940.を得ていた、このメッセージの以前のバージョン正しい結果です!)私は予想していた数百万個弱でしたが、規模は同じです。

そのようなラックを取得する可能性を計算するには、ラックを引き出す方法の数を考慮する必要があります。私たちは一例で見たように、これは中にその係数に等しい。このようなラックを描画する可能性は、これらすべての係数の合計です。すべての文字を1に設定すると簡単に見つかります。α7

nonwords /. (# -> 1) & /@ (List @@ alphabet)

答えは1066056120に等しく、有効な単語を形成できないラックを引き出す確率は10.1914%になります(すべての文字が同じ可能性がある場合)。

文字の確率が異なる場合は、各文字を描かれる可能性に置き換えてください。

tiles = {9, 2, 2, 4, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1, 6, 4, 6, 
         4, 2, 2, 1, 2, 1, 2};
chances = tiles / (Plus @@ tiles);
nonwords /. (Transpose[{List @@ alphabet, chances}] /. {a_, b_} -> a -> b)

出力は1.079877553303%で、正確な答えです(ただし、近似モデルを使用し、置換を使用して描画します)。背中を見て、それが仕事をするためのデータ(アルファベット、辞書、およびアルファベット周波数)を入力する4本のラインを取り、わずか3行:次のパワー取る方法を説明しモジュロIを、再帰的に7電源を取る、と置き換え手紙の確率。αI


+1辞書に結合してから最小化するのは賢い考えです。代数は私を超えていますが、超幾何ではなく多項確率を計算しているように感じます。だから、確率は、サンプリングするためであるの交換。1.08%の回答が、0.4%の見積もりよりもはるかに大きい理由は、これで説明できると思います。交換せずにサンプリングを処理するアプローチを変更する方法はありますか?
vqv

2
@vqvはい。単語のない50万台程度のラックのリストができたので、(最後の2行のコードを変更することで)簡単に各ラックの確率を計算し(交換なし)、超幾何学的結果を取得します。正確な答えは349870667877/80678106432000 = 0.43366%です。N = 100Kトライアルでは、SEは0.021%なので、答えは0.38%から0.49%(両側99%CI)の間にあるはずです。私たちの答えが同意してくれてうれしいです!
whuber

@whuber Words With Friends(WWF)タイル分布を使用して計算を実行できますか?私の推定0.4%は、WWFの辞書とWWFタイルの分布に基づいています。WWFレキシコンでスクラブルタイルディストリビューションを使用していると思います。
vqv

おっとっと。正確な答えは、実際には349870675899です(辞書にエラーがあるため8022オフでした)。幸いなことに、実際的な違いはありません。
whuber

@vqv私はさまざまなタイルの分布に精通していません。私はあなたのコードから私のものを直接コピーしました(そして私はあなたの辞書を使いました):-)。あなたがで配布を意味する場合osxreality.com/2010/01/01/...、私は入手1.15444パーセントを、(交換で)0.43366パーセント(交換なし)を。2番目の数字は、8番目の有効数字のスクラブル周波数と実際には異なります。
whuber

14

Scrabbleおよびその変形で有効な単語を含まないラックを描くのは非常に困難です。以下は、最初の7タイルラックに有効な単語が含まれていない確率を推定するために書いたRプログラムです。モンテカルロアプローチとWords With Friendsレキシコンを使用します(公式のScrabbleレキシコンが簡単な形式で見つかりませんでした)。各トライアルでは、7タイルラックを描画し、ラックに有効な単語が含まれているかどうかを確認します。

最小限の言葉

ラックに有効な単語が含まれているかどうかを確認するためにレキシコン全体をスキャンする必要はありません。最小限の単語で構成される 最小限の辞書をスキャンするだけです。単語がサブセットとして他の単語を含まない場合、単語は最小です。たとえば、「em」は最小限の単語です。「空」ではありません。この点は、ラックに単語xが含まれている場合、xのサブセットも含まれている必要があるということです。言い換えると、最小限の単語が含まれていない場合、ラックには単語が含まれていません。幸いなことに、レキシコンのほとんどの単語は最小限ではないため、削除できます。順列に相当する単語をマージすることもできます。Words With Friendsのレキシコンを172,820から201の最小単語に減らすことができました。

ワイルドカードは、ラックや単語を文字の分布として扱うことで簡単に処理できます。ある分布から他の分布を引くことにより、ラックに単語が含まれているかどうかを確認します。これにより、ラックにない各文字の数がわかります。これらの数の合計がある場合ワイルドカードの数は、その単語は、ラックにあります。

モンテカルロアプローチの唯一の問題は、興味のあるイベントが非常にまれであることです。したがって、十分に小さな標準誤差で推定値を得るには、多くの試行が必要です。私は(一番下に貼り付けられた)私のプログラムを実行した 試練となった最初のラックが有効な単語が含まれていないことを0.004の推定確率を。その推定の推定標準誤差は0.0002です。辞書をダウンロードするなど、Mac Proで実行するのに数分かかりました。N=100000

誰かが効率的な正確なアルゴリズムを思い付くことができるかどうかに興味があります。包含/除外に基づく単純なアプローチは、組み合わせ爆発を伴う可能性があるようです。

包含除外

これは悪い解決策だと思いますが、とにかく不完全なスケッチです。原則として、計算を行うプログラムを作成できますが、仕様は曲がりくねります。

計算する確率は 右側の確率内部イベントは、イベントの和集合である: P K ラック-tile単語を含んでいる= P X M { K ラック-tileに含まれる  Xを} M

P(k-tile rack does not contain a word)=1P(k-tile rack contains a word).
P(k-tile rack contains a word)=P(xM{k-tile rack contains x}),
Mは最小限の辞書です。包含/除外式を使用して拡張できます。上記のイベントのすべての可能な交差点を考慮する必要があります。レッツのパワーセット表すMすなわち、すべての可能なサブセットの集合Mを。それから P(M)MM
P(k-tile rack contains a word=PバツM{k-タイルラックに含まれるもの バツ}=j=1|M|1j1SPM|S|=jPバツS{k-タイルラックに含まれるもの バツ}

最後に指定するのは、上の最後の行で確率を計算する方法です。多変量超幾何が含まれます。
ラック内のすべての単語含まれている場合であるSを。これは、ワイルドカードのために対処するのが苦痛です。条件付けにより、次の各ケースを考慮する必要があります:ラックにワイルドカードが含まれていない、ラックにワイルドカードが1つ含まれている、ラックにワイルドカードが2つ含まれている、...

バツS{k-タイルラックに含まれるもの バツ}
S

それから

PバツS{k-タイルラックに含まれるもの バツ}=w=0nPバツS{k-タイルラックに含まれるもの バツ}|k-タイルラックに含まれるもの w ワイルドカード×Pk-タイルラックに含まれるもの w ワイルドカード

2|M|2|M|3.2×1060

考えられるすべてのラックをスキャンする

最小単語の可能なサブセットよりも可能なラックが少ないため、これは計算が簡単だと思います。可能な集合を連続的に減らすk-単語が含まれていないラックのセットを取得するまで、タイルラック。Scrabble(またはWords with Friends)の場合、可能な7タイルラックの数は数百億です。可能性のある単語を含まないものの数を数えるには、数十行のRコードで実行できるはずです。しかし、考えられるすべてのラックを列挙するだけでなく、もっとうまくやれるはずだと思います。たとえば、「aa」は最小限の単語です。これにより、複数の「a」を含むすべてのラックがすぐに削除されます。他の言葉で繰り返すことができます。最新のコンピューターでは、メモリーは問題になりません。7タイルのスクラブルラックに必要なストレージは7バイト未満です。最悪の場合、可能なすべてのラックを格納するために数ギガバイトを使用しますが、それも良い考えだとは思いません。誰かがこれについてもっと考えたいかもしれません。

モンテカルロRプログラム

# 
#  scrabble.R
#  
#  Created by Vincent Vu on 2011-01-07.
#  Copyright 2011 Vincent Vu. All rights reserved.
# 

# The Words With Friends lexicon
# http://code.google.com/p/dotnetperls-controls/downloads/detail?name=enable1.txt&can=2&q=
url <- 'http://dotnetperls-controls.googlecode.com/files/enable1.txt'
lexicon <- scan(url, what=character())

# Words With Friends
letters <- c(unlist(strsplit('abcdefghijklmnopqrstuvwxyz', NULL)), '?')
tiles <- c(9, 2, 2, 5, 13, 2, 3, 4, 8, 1, 1, 4, 2, 5, 8, 2, 1, 6, 5, 7, 4, 
           2, 2, 1, 2, 1, 2)
names(tiles) <- letters

# Scrabble
# tiles <- c(9, 2, 2, 4, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1, 6, 4, 6, 4, 
#            2, 2, 1, 2, 1, 2)


# Reduce to permutation equivalent words
sort.letters.in.words <- function(x) {
  sapply(lapply(strsplit(x, NULL), sort), paste, collapse='')
}

min.dict <- unique(sort.letters.in.words(lexicon))
min.dict.length <- nchar(min.dict)

# Find all minimal words of length k by elimination
# This is held constant across iterations:
#   All words in min.dict contain no other words of length k or smaller
k <- 1
while(k < max(min.dict.length))
{
  # List all k-letter words in min.dict
  k.letter.words <- min.dict[min.dict.length == k]

  # Find words in min.dict of length > k that contain a k-letter word
  for(w in k.letter.words)
  {
    # Create a regexp pattern
    makepattern <- function(x) {
      paste('.*', paste(unlist(strsplit(x, NULL)), '.*', sep='', collapse=''), 
            sep='')
    }
    p <- paste('.*', 
               paste(unlist(strsplit(w, NULL)), 
                     '.*', sep='', collapse=''), 
               sep='')

    # Eliminate words of length > k that are not minimal
    eliminate <- grepl(p, min.dict) & min.dict.length > k
    min.dict <- min.dict[!eliminate]
    min.dict.length <- min.dict.length[!eliminate]
  }
  k <- k + 1
}

# Converts a word into a letter distribution
letter.dist <- function(w, l=letters) {
  d <- lapply(strsplit(w, NULL), factor, levels=l)
  names(d) <- w
  d <- lapply(d, table)
  return(d)
}

# Sample N racks of k tiles
N <- 1e5
k <- 7
rack <- replicate(N,
                  paste(sample(names(tiles), size=k, prob=tiles), 
                        collapse=''))

contains.word <- function(rack.dist, lex.dist)
{
  # For each word in the lexicon, subtract the rack distribution from the 
  # letter distribution of the word.  Positive results correspond to the 
  # number of each letter that the rack is missing.
  y <- sweep(lex.dist, 1, rack.dist)

  # If the total number of missing letters is smaller than the number of 
  # wildcards in the rack, then the rack contains that word
  any(colSums(pmax(y,0)) <= rack.dist[names(rack.dist) == '?'])
}

# Convert rack and min.dict into letter distributions
min.dict.dist <- letter.dist(min.dict)
min.dict.dist <- do.call(cbind, min.dict.dist)
rack.dist <- letter.dist(rack, l=letters)

# Determine if each rack contains a valid word
x <- sapply(rack.dist, contains.word, lex.dist=min.dict.dist)

message("Estimate (and SE) of probability of no words based on ", 
        N, " trials:")
message(signif(1-mean(x)), " (", signif(sd(x) / sqrt(N)), ")")

うわー、とてもいいフォローアップ。
マットパーカー

201語に短縮されたことに少し驚いています。最初に再生される単語については、ハウスルールは「I」と「A」を単語として受け入れます。これにより、最小単語数がさらに減少する可能性があります。私は誰かが包含/除外分析を
破り

@shabbychef辞書に1文字の単語はありません。ほとんどの最小単語は2文字と3文字の単語です。最小語長の完全な分布は次のとおりです。2:73、3:86、4:31、5:9、6:2。6文字の単語は、GLYCYLとSYZYGYです。
vqv

@shabbychef正確な包含/除外アプローチのスケッチを含めるように回答を更新しました。毛深いよりも悪い。
vqv

すごい仕事!1つの文として(十分なバックグラウンドを持つ人に)提示できるこの質問が、モンテカルロ、包含/除外、DAG、探索木、多項式代数をもたらし、シミュレーションが@の理論によって確認されることを気に入っていますうわー 乾杯!
みすぼらしいシェフ

7

1k

2番目の理由は、MCが実際に実行可能であるということです。あなたはそれを正しくしなければなりません。前のパラグラフは手がかりを提供します。単語をランダムに生成して検索するだけではありません。代わりに、最初に辞書を分析し、その構造を活用します。

k1

k次に、元の辞書の単語のソートされた代表から構築されたツリーで、このソートされた「単語」を探します。これは、{stop、post、pots、opts、spot}などのソート等価なすべての単語セットをマージするため、実際には元のツリーよりも小さくなります。実際、英語の辞書では、「so」が最初に見つかるため、このクラスの単語には到達しません。これを実際に見てみましょう。ソートされたマルチセットは「opst」です。「o」は文字{o、p、...、z}のみを含むすべての単語に分岐し、「p」は最大{o、p、...、z}のみを含むすべての単語に分岐します。 1つの「o」、最後に「s」が「so」の葉に分岐します。(もっともらしい候補「o」、「op」、「

ワイルドカードを処理するには修正が必要です。プログラマーにタイプを聞かせて、それについて考えてみましょう。辞書のサイズは増加しません(実際には減少します)。ツリーの走査は少し遅くなりますが、基本的な方法で変更することはありません。英語( "a"、 "i")のような1文字の単語を含む辞書では、複雑さはありません。ワイルドカードが存在するということは、単語を形成できることを意味します。(これは、元の質問が見た目ほど面白くないかもしれないことを示唆しています。)

要するに、単一の辞書検索には(a)ソートが必要です。k-文字マルチセットおよび(b)以下のトラバース k木の端。実行時間はOkログk。ソートされた順序でランダムなマルチセットを巧みに生成する場合(これを行うためのいくつかの効率的な方法を考えることができます)、実行時間はOk。これに反復回数を掛けて、合計実行時間を取得します。

実際のスクラブルセットと数百万回の反復で数秒でこの研究を実行できると思います。


@whuberツリーはすてきなアイデアです(そのアイデアに賛成です)が、多くのメモリを必要としませんか?辞書の多様性に依存すると思いますが、かなり多様な辞書には多くのツリーが必要になると思います。たとえば、「b」ツリーは、「a」ではなく「b」で始まるすべての単語ではなく、それらに「a」があります。同様に、「c」ツリーは、「a」と「b」はないが「c」はある単語の文字「c」で始まります。私が提案した直接的なアプローチは、辞書内のすべての単語を一度だけ走査する必要があるため、より簡単に思えます。

1
@Srikant:ツリーは、最初から辞書全体をキャッシュするよりもはるかに少ないRAMで済みます。とにかく、数メガバイトのRAMを本当に心配していますか?ところで、ツリーは1つだけで、多くはありません。それらはすべて空の単語に根ざしています。私が理解しているように、あなたのアプローチは、繰り返しごとに辞書の複数の検索(最大7!)を必要とし、@ shabbychefの恐怖として実行不可能にします。「単語を形成できるかどうかを確認する」と書かれている、念頭に置いているアルゴリズムについて詳しく説明できれば助かります。これにより、多くの重要な詳細が隠されます。
whuber

@whuber:コメントを投稿した後、ツリーが1つしかないことに気付きました。私のアプローチを登録してください-私のモンテカルロ提案はあいまいであり、あなたの答えはこの設定で実際にモンテカルロを実装する方法を急いでいることに同意します。実際には、直接アプローチ(私の回答を参照)は、ツリーで数千回の反復を必要とするモンテカルロとは異なり、辞書での1回限りの操作を必要とするため、実際にはより単純になる可能性があります。アプローチの相対的なメリットについて疑問に思います。

@Srikantあなたの直接的なアプローチについてコメントすることは控えました。辞書構造、つまり単語間のサブセットの関係を考慮していないようです。たとえば、すべての可能な1文字の単語を含むすべての辞書に対して、式は0の正解を取得しますか?
whuber

@whuberうーん良い点。おそらく、私は間違った質問に答えています!

2

モンテカルロアプローチ

迅速で汚いアプローチは、モンテカルロ研究を行うことです。ドローk タイル m 回との各引き分け kタイルは、単語を形成できるかどうかを確認します。単語を形成できる回数を示しますmw。望ましい確率は次のとおりです。

1mwm

直接的なアプローチ

辞書内の単語の数を S。させてts 私たちが形成できる方法の数である s番目ワード。に必要な文字数をs番目 言葉によって示される mambmz (つまり、 s番目 言葉のニーズ ma「a」の文字数など)。すべてのタイルで形成できる単語の数を示しますN

N=nk

そして

ts=namanbmbnzmz

(ワイルドカードタイルの影響を含めることは少し複雑です。この問題は今のところ延期します。)

したがって、望ましい確率は次のとおりです。

1stsN

迅速で汚れたアプローチはそれほど速くないかもしれません!辞書には100,000個の単語が含まれている可能性があり、指定されたタイルの一致の検索はコーディング障害になる可能性があります。
みすぼらしいシェフ

@shabbychefこれは、スペルチェッカーに適した方法です。たとえば、n3labs.com / pdf / lexicon-squeeze.pdfを参照してください

@shabbychef Reg monte-carlo-辞書がソートされている場合、一致はかなり速いはずです。いずれにせよ、前に概説した直接的なアプローチには欠陥がありました。それを私が直した。私の以前のソリューションの問題は、同じ単語を複数の方法で形成できることでした(たとえば、 'bat'、 'b * t'など)。

1
@shabbychefさらに反省すると、モンテカルロアプローチが機能しないことに同意します。1つの問題は、kタイルで実際に形成できる単語を把握する必要があることです。2番目の問題は、kタイルで複数の単語を形成できることです。k個のタイルからこれらの組み合わせを計算することは、おそらくそれほど簡単ではありません。

1
@Srikantありがとう。あなたの式は、単語を形成するためにすべてのk文字を使用する必要があると仮定しているようですが、私はそれがOPが求めているものだとは思いません。(とにかくScrabbleのプレイ方法ではありません。)その暗黙の仮定では、正しい軌道に乗っていますが、アルゴリズムを変更する必要があります。相互に置換されている辞書の単語の計算を繰り返さないでください。たとえば、式でt_ {stop}とt_ {post}の両方を減算することはできません。(これは実装が簡単な変更です。)
whuber
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.