Probabilité de dessiner un mot donné à partir d'un sac de lettres en Scrabble

18

Supposons que vous ayez un sac avec n tuiles, chacune avec une lettre dessus. Il y a tuiles avec la lettre 'A', avec 'B', et ainsi de suite, et 'wildcard' tuiles (nous avons ). Supposons que vous disposiez d'un dictionnaire avec un nombre fini de mots.n n = n A + n B + + n Z + n nUNEnBnn=nUNE+nB++nZ+n

Vous choisissez tuiles du sac sans remplacement.k

Comment calculeriez-vous (ou estimeriez-vous) la probabilité que vous puissiez former un mot donné, de longueur l (avec 1 < l = < k ) à partir du dictionnaire étant donné les k tuiles sélectionnées?

Pour ceux qui ne connaissent pas Scrabble (TM), le caractère générique peut être utilisé pour correspondre à n'importe quelle lettre. Ainsi, le mot «BOOT» pourrait être «orthographié» avec les tuiles «B», «*», «O», «T». L'ordre dans lequel les lettres sont dessinées n'a pas d'importance.

Suggestion: afin de simplifier la rédaction des réponses, il serait peut-être préférable de simplement répondre à la question: quelle est la probabilité d'avoir le mot `` BOOT '' parmi vos mouvements possibles après avoir tiré 7 lettres d'un nouveau sac.

(l'introduction du problème a été copiée à partir de cette question similaire )

Sébastien
la source
Je vous conseille d'aborder un cas plus simple, comme celui sans caractères génériques.
Glen_b -Reinstate Monica
@Glen_b Je suis d'accord. Comme mon but final est d'ordonner les mots par probabilité, je pense que l'ignorance des caractères génériques est une approximation acceptable. Cependant, je n'ai toujours pas les compétences nécessaires pour construire une formule pour résoudre ce problème plus simple
Sébastien
1
Si vous voulez commencer encore plus simplement, calculez la probabilité de choisir «B», puis «O», puis «O», puis «T». Après cela, calculez la probabilité de choisir les lettres dans n'importe quel ordre. Après cela, tenez compte du fait que vous avez sept essais. Ensuite, prenez en compte les caractères génériques.
Jerry Schirmer
1
Un moyen facile de résoudre ce problème serait d'utiliser une approximation de Monte Carlo. Cela suffirait-il?
Rasmus Bååth
1
Parlez-vous de former des mots avec uniquement les lettres que vous choisissez, ou de prendre en considération les lettres déjà choisies et les mots déjà placés au tableau?
samthebrand

Réponses:

12

Une formule est demandée. Malheureusement, la situation est si compliquée qu'il semble que toute formule ne soit qu'un moyen détourné d'énumérer toutes les possibilités. Au lieu de cela, cette réponse propose un algorithme qui (a) équivaut à une formule impliquant des sommes de produits de coefficients binomiaux et (b) peut être porté sur de nombreuses plates-formes.


Pour obtenir une telle formule, divisez les possibilités en groupes mutuellement disjoints de deux manières: selon le nombre de lettres absentes du mot sélectionnées dans le rack (que ce soit ) et selon le nombre de caractères génériques (blancs) sélectionnés ( que ce soit w ). Lorsqu'il y a r = 7 tuiles dans le rack, N tuiles disponibles, M tuiles disponibles avec des lettres absentes du mot et W = 2 blancs disponibles, le nombre de choix possibles donné par ( m , w ) estmwr=7NMW=2(m,w)

(Mm)(Ww)(NMWrmw)

car les choix de lettres non vierges, de blancs et de lettres de mots sont indépendants et conditionnels à (m,w,r).

Cela réduit le problème de trouver le nombre de façons d'épeler un mot lors de la sélection uniquement à partir des tuiles représentant les lettres du mot, étant donné que blancs sont disponibles et que les tuiles r - m - w seront sélectionnées. La situation est désordonnée et aucune formule fermée ne semble disponible. Par exemple, avec w = 0 espaces et m = 3 lettres hors mot sont dessinées, il restera précisément quatre lettres pour épeler "boot" qui ont été tirées des tuiles "b", "o" et "t" . Étant donné qu'il y a 2 "b", 8 "o" et 6wrmww=0m=3286"t" dans le jeu de tuiles Scrabble, il y a des probabilités positives de dessiner (multisets) "bboo", "bbot", "bbtt", "booo", "boot", "bott", "bttt", "oooo "," ooot "," oott "," ottt "et" tttt ", mais un seul de ces sorts" boot ". Et c'était le cas facile! Par exemple, en supposant que le rack contient cinq tuiles choisies au hasard parmi les tuiles "o", "b" et "t", ainsi que les deux blancs, il existe de nombreuses autres façons d'épeler "boot" - et non de l'épeler. Par exemple, "boot" peut être orthographié à partir de "__boott" et "__bbttt", mais pas de "__ttttt".

Ce comptage - le cœur du problème - peut être géré de manière récursive. Je vais le décrire avec un exemple. Supposons que nous souhaitons compter les façons d'orthographier "boot" avec une tuile vide et quatre autres tuiles de la collection de tuiles "b", "o" et "t" (d'où les deux tuiles restantes montrent des lettres non vides pas en { "b", "o", "t"}). Considérez la première lettre, "b":

  1. Un "b" peut être tracé chemins à partir des deux tuiles "b" disponibles. Cela réduit le problème de compter le nombre de façons d'épeler le suffixe "oot" en utilisant les deux blancs et seulement trois autres tuiles de la collection de tuiles "o" et "t".(21)

  2. Un blanc peut être désigné comme un "b". Cela réduit le problème de compter le nombre de façons d'orthographe "oot" en utilisant le blanc restant et seulement trois autres tuiles de la collection de tuiles "o" et "t".

En général, les étapes (1) et (2) - qui sont disjointes et contribuent donc de manière additive aux calculs de probabilité - peuvent être implémentées en boucle sur le nombre possible de blancs qui pourraient être utilisés pour la première lettre. Le problème réduit est résolu récursivement. Le cas de base se produit quand il reste une lettre, qu'il y a un certain nombre de tuiles avec cette lettre disponible et qu'il peut aussi y avoir des blancs dans le rack. Il suffit de s'assurer que le nombre de blancs dans le rack plus le nombre de tuiles disponibles sera suffisant pour obtenir la quantité souhaitée de cette dernière lettre.

Voici le Rcode de l'étape récursive. rackest généralement égal à , est un tableau de décomptes des lettres (comme ), est une structure similaire donnant le nombre de tuiles disponibles avec ces lettres, et est le nombre de blancs supposés se produire dans le rack.7wordc(b=1, o=2, t=1)alphabetwild

f <- function(rack, word, alphabet, wild) {
  if (length(word) == 1) {
    return(ifelse(word > rack+wild, 0, choose(alphabet, rack)))
  }
  n <- word[1]
  if (n <= 0) return(0)
  m <- alphabet[1]
  x <- sapply(max(0, n-wild):min(m, rack), 
              function(i) {
                choose(m, i) * f(rack-i, word[-1], alphabet[-1], wild-max(0, n-i))
              })
  return(sum(x))
}

Une interface pour cette fonction spécifie les tuiles Scrabble standard, convertit un mot donné en sa structure de données multiset et effectue la double somme sur et w . Voici où les coefficients binomiaux ( Mmw et ( W(Mm) sont calculés et multipliés.(Ww)

scrabble <- function(sword, n.wild=2, rack=7, 
              alphabet=c(a=9,b=2,c=2,d=4,e=12,f=2,g=3,h=2,i=9,j=1,k=1,l=4,m=2,
                         n=6,o=8,p=2,q=1,r=6,s=4,t=6,u=4,v=2,w=2,x=1,y=2,z=1),
              N=sum(alphabet)+n.wild) {
  word = sort(table(strsplit(sword, NULL))) # Sorting speeds things a little
  a <- sapply(names(word), function(s) alphabet[s])
  names(a) <- names(word)
  x <- sapply(0:n.wild, function(w) {
    sapply(sum(word):rack-w, 
           function(i) {
             f(i, word, a, wild=w) *
               choose(n.wild, w) * choose(N-n.wild-sum(a), rack-w-i)
           })
  })
  return(list(numerator = sum(x), denominator = choose(N, rack),
              value=sum(x) / choose(N, rack)))
}

Essayons cette solution et chronométrons au fur et à mesure. Le test suivant utilise les mêmes entrées que celles utilisées dans les simulations de @Rasmus Bååth :

system.time(x <- sapply(c("boot", "red", "axe", "zoology"), scrabble))

Cette machine signale un temps total écoulé de seconde: relativement rapide. Les resultats?0.05

> x
            boot        red         axe         zoology     
numerator   114327888   1249373480  823897928   11840       
denominator 16007560800 16007560800 16007560800 16007560800 
value       0.007142118 0.07804896  0.0514693   7.396505e-07

La probabilité pour « démarrage » de est exactement égale à la valeur 2.381.831 / 333490850 obtenu dans mon autre réponse (qui utilise une méthode similaire , mais des canapés dans un cadre plus puissant nécessitant une plate - forme de calcul algèbre symbolique). Les probabilités pour les quatre mots sont assez proches des simulations de Baath (qui ne pouvait attendre de donner une valeur exacte pour « Zoology » en raison de sa faible probabilité de 11 840 / 16007560800 , qui est inférieur à un sur un million).114327888/160075608002381831/33349085011840/16007560800,

whuber
la source
Solution cool et élégante! Et beaucoup plus rapide que le mien ... :)
Rasmus Bååth
1
Ceci est une excellente réponse, merci. J'aurais eu du mal à coder votre algorithme, donc le code prêt à l'emploi est le bienvenu. Je ne savais pas, Rmais j'ai quand même réussi à utiliser vos fonctions en moins d'une heure de travail, de sorte que le script prenne des entrées à partir d'un fichier de dictionnaire de 20 000 mots et écrive les résultats dans un fichier .csv. (cela a pris moins de 10 minutes sur un Core i5 de milieu de gamme)
Sébastien
16

Les réponses à la question référencée s'appliquent ici directement: créez un dictionnaire composé uniquement du mot cible (et de ses éventuelles orthographes génériques), calculez les chances qu'un rack aléatoire ne puisse pas former la cible et soustrayez-le de . Ce calcul est rapide.1

Les simulations (illustrées à la fin) prennent en charge les réponses calculées.


Détails

Comme dans la réponse précédente, Mathematica est utilisé pour effectuer les calculs.

  1. Spécifiez le problème: le mot (ou les mots, si vous le souhaitez), les lettres, leur nombre et la taille du rack. Parce que toutes les lettres qui ne sont pas dans le mot agissent de la même manière, cela accélère considérablement le calcul pour les remplacer toutes par un seul symbole représentant "toute lettre qui ne se trouve pas dans le mot".χ

    word = {b, o, o, t};
    letters = {b, o, t, \[Chi], \[Psi]};
    tileCounts = {2, 8, 6, 82, 2};
    rack = 7;
  2. Créez un dictionnaire de ce mot (ou de ces mots) et augmentez-le pour inclure toutes les orthographes génériques possibles.

    dict[words_, nWild_Integer] := Module[{wildcard, w},
       wildcard = {xx___, _, yy___} -> {xx, \[Psi], yy};
       w = Nest[Flatten[ReplaceList[#, wildcard] & /@ #, 1] &, words, nWild];
       Union[Times @@@ Join[w, Times @@@ words]]];
    dictionary = dict[{word}, 2]

    {bo2t,bo2ψ,botψ,o2tψ,boψ2,o2ψ2,btψ2,otψ2}

  3. Calculez les non mots:

    alphabet = Plus @@ letters;
    nonwords = Nest[PolynomialMod[# alphabet, dictionary] &, 1, rack]

    b7+7b6o+21b5o2++7χψ6+ψ7

    (Il y a non-mots dans ce cas.)185

  4. Calculez les chances. Pour l'échantillonnage avec remplacement, substituez simplement le nombre de tuiles aux variables:

    chances = (Transpose[{letters, tileCounts/(Plus @@ tileCounts)}] /. {a_, b_} -> a -> b);
    q = nonwords /. chances;
    1 - q

    20726341339062500000

    Cette valeur est d'environ 0.00756036.

    Pour l'échantillonnage sans remplacement, utilisez des puissances factorielles plutôt que des puissances:

    multiplicities = MapThread[Rule, {letters, tileCounts}];
    chance[m_] :=  (ReplaceRepeated[m , Power[xx_, n_] -> FactorialPower[xx, n]] 
                   /. multiplicities);
    histor = chance /@ MonomialList[nonwords];
    q0 = Plus @@ histor  / FactorialPower[Total[tiles], nn];
    1 - q0

    2381831333490850

    Cette valeur est d'environ Les calculs ont été pratiquement instantanés.0.00714212.


Résultats de la simulation

106 itérations avec remplacement:

simulation = RandomChoice[tiles -> letters, {10^6, 7}];
u = Tally[Times @@@ simulation];
(p = Total[Cases[Join[{PolynomialMod[u[[All, 1]], dictionary]}\[Transpose], 
       u, 2], {0, _, a_} :> a]] / Length[simulation] ) // N

0.007438

Comparez-le à la valeur calculée par rapport à son erreur standard:

(p - (1 - q)) / Sqrt[q (1 - q) / Length[simulation]] // N

1.41259

L'accord est bon, soutenant fortement le résultat calculé.

106

tilesAll = Flatten[MapThread[ConstantArray[#1, #2] &, {letters, tiles}] ]
    (p - (1 - q)) / Sqrt[q (1 - q) / Length[simulation]] // N;
simulation = Table[RandomSample[tilesAll, 7], {i, 1, 10^6}];
u = Tally[Times @@@ simulation];
(p0 = Total[Cases[Join[{PolynomialMod[u[[All, 1]], dictionary]}\[Transpose], 
       u, 2], {0, _, a_} :> a]] / Length[simulation] ) // N

0.00717

Faites la comparaison:

(p0 - (1 - q0)) / Sqrt[q0 (1 - q0) / Length[simulation]] // N

0.331106

L'accord dans cette simulation était excellent.

12

whuber
la source
13

Il s'agit donc d'une solution Monte Carlo , c'est-à-dire que nous allons simuler le dessin des carreaux un million de fois, puis nous allons calculer combien de ces dessins simulés nous ont permis de former le mot donné. J'ai écrit la solution en R, mais vous pouvez utiliser n'importe quel autre langage de programmation, par exemple Python ou Ruby.

Je vais d'abord décrire comment simuler un tirage. Définissons d'abord les fréquences des tuiles.

# The tile frequency used in English Scrabble, using "_" for blank.
tile_freq <- c(2, 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)
tile_names <- as.factor(c("_", letters))
tiles <- rep(tile_names, tile_freq)
## [1] _ _ a a a a a a a a a b b c c d d d d e e e e e e
## [26] e e e e e e f f g g g h h i i i i i i i i i j k l
## [51] l l l m m n n n n n n o o o o o o o o p p q r r r
## [76] r r r s s s s t t t t t t u u u u v v w w x y y z
## 27 Levels: _ a b c d e f g h i j k l m n o p q r ... z

Encodez ensuite le mot comme vecteur de décompte des lettres.

word <- "boot"
# A vector of the counts of the letters in the word
word_vector <- table( factor(strsplit(word, "")[[1]], levels=tile_names))
## _ 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 
## 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 1 0 0 0 0 0 0 

Maintenant, dessinez un échantillon de sept tuiles et encodez-les de la même manière que le mot.

tile_sample <- table(sample(tiles, size=7))
## _ 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 
## 1 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 1 0 1 0 0 0 

Enfin, calculez les lettres manquantes ...

missing <- word_vector - tile_sample
missing <- ifelse(missing < 0, 0, missing)
## _ 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 
## 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 

... et additionnez le nombre de lettres manquantes et soustrayez le nombre de blancs disponibles. Si le résultat est nul ou inférieur, nous avons réussi à épeler le mot.

sum(missing) - tile_sample["blank"] <= 0
## FALSE

Dans ce cas particulier, nous ne l'avons pas pensé ... Il nous suffit maintenant de répéter cela plusieurs fois et de calculer le pourcentage de tirages réussis. Tout cela se fait par la fonction R suivante:

word_prob <- function(word, reps = 50000) {
  tile_freq <- c(2, 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)
  tile_names <- as.factor(c("_", letters))
  tiles <- rep(tile_names, tile_freq)
  word_vector <- table( factor(strsplit(word, "")[[1]], levels=tile_names))
  successful_draws <- replicate(reps, {
    tile_sample <- table(sample(tiles, size=7))
    missing <- word_vector - tile_sample
    missing <- ifelse(missing < 0, 0, missing)
    sum(missing) - tile_sample["_"] <= 0
  })
  mean(successful_draws)
}

Voici repsle nombre de tirages simulés. Maintenant, nous pouvons l'essayer sur un certain nombre de mots différents.

> word_prob("boot")
[1] 0.0072
> word_prob("red")
[1] 0.07716
> word_prob("axe")
[1] 0.05088
> word_prob("zoology")
[1] 2e-05
Rasmus Bååth
la source
J'obtiens des réponses différentes. Il est difficile de dire pourquoi ils ne sont pas d'accord, étant donné la complexité de votre code de simulation, mais je commencerais à rechercher la cause lors de notre traitement des caractères génériques.
whuber
2
Je crois que cela samplen'agit pas comme vous semblez l'attendre. Par exemple, qu'advient-il de votre code si le jeu est modifié pour permettre un rack de 28 tuiles? Passez size=7à size=28pour le savoir.
whuber
2
@whuber Vous avez raison, merci de l'avoir signalé! Maintenant, cela fonctionne et donne la même réponse que votre code!
Rasmus Bååth
Merci pour ce beau travail. En effet, une approche Monte Carlo convient parfaitement. Cependant, principalement pour des raisons de performances, j'ai choisi d'utiliser l'algorithme de calcul exact fourni par whuber.
Sébastien
7

For the word "BOOT" with no wildcards:

p0=(nb1)(no2)(nt1)(n43)(n7)
With wildcards, it becomes more tedious. Let pk indicate the probability of being able to play "BOOT" with k wildcards:
p0=(nb1)(no2)(nt1)(n43)(n7)p1=p0+(n1)(no2)(nt1)(n43)(n7)+(nb1)(no1)(n1)(nt1)(n43)(n7)+(nb1)(no2)(n1)(n43)(n7)=p0+(n1)(n43)(n7)((no2)(nt1)+(nb1)(no1)(nt1)+(nb1)(no2))p2=p1+(n2)(n43)(n7)((nb1)(no1)+(nb1)(nt1)+(no2)+(no1)(nt1))p3=p2+(n3)(n43)(n7)((nb1)+(no1)+(nt1))p4=p3+(n4)(n43)(n7)pi=p4,i4
clintonmonk
la source
The idea is correct (although it would help to explain why and to explain the notation, especially concerning exactly what "n" means: whether it counts all other letters or all other letters and the wildcards), but the treatment of wildcards is incomplete. Without any explanation and without any worked examples, it is difficult to determine whether your formulas are correct so we must consider them unreliable. Generally, it is possible to write down a formula for the probability in terms of sums of products of binomial coefficients.
whuber
1
There are mistakes in the calculation of p0: it assumes exactly 1 "b", 2 "o"s, and 1 "t" will be chosen; and then it assumes the choice of the other three letters will be independent of those choices, which it is not. Assuming n=100 is the total number of tiles, the resulting value is larger than it should be (it equals 8/25850.0031). The same mistake is propagated into the calculations of the wildcard probabilities.
whuber
-1

Meh.

γc=b0xcln(x)r=0(c+y1)(c+α)r(c+β)r(c+1)r(c+γ)rxr+

+b0xcr=0(c+γ1)(c+α)r(c+β)r(c+1)r(c+γ)r(1c+γ1+

+k=0r1(1c+α+κ+1c+β+κ+1c+1+κ1c+γ+κ))xr

=b0xcr=0(c+γ1)(c+α)r(c+β)r(c+1)r(c+γ)r(ln x+1c+γ1+

+k=0r1(1c+α+κ+1c+β+κ1c+1+κ1c+γ+κ))xr
.

It's been a while since I looked at how I built my project. And my math may be entirely incorrect below, or correct. I may have it backwards. Honestly, I forget. BUT! Using only binomial combination, without taking into account blank tiles which throws the entire thing out of whack. The simple combination solution without wild.

I asked these questions myself, and built my own scrabble words probability dictionary because of it. You don't need a dictionary of possible words pulled out, only the math behind it and available letters based on letters in tile bag. The array of English rules is below. I spent weeks developing the math just to answer this question for all English words that can be used in a game, including words that can not be used in a game. It may all be incorrect.

The probability of drawing a given word from a bag of letters in Scrabble, requires how many letters are available in the bag, for each letter ( A-Z ) and, whether we're using the wild card as an addition to the math. The blank tiles are included in this math - assuming 100 tiles, 2 of which are blank. Also, how many tiles are available differs based on language of the game, and game rules from around the world. English scrabble differs from Arabic scrabble, obviously. Just alter the available letters, and the math should do the work.

If anyone finds errors, I will be sure to update and resolve them.

Boot: The probability of Boot in a game of scrabble is 0.000386% which is a chance of 67 out of 173,758 hands as shown on the word page for boot.

English Tiles

all is the array of letters in the bag. count is the array of available tiles for that letter, and point is the point value of the letter.

// All arranged by letter, number of letters in scrabble game, and point for the letter.
$all = array("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");
    $count = array("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");
$point = array("1", "3", "3", "2", "1", "4", "2", "4", "1", "8", "5", "1", "3", "1", "1", "3", "10", "1", "1", "1", "1", "4", "4", "8", "4", "10");

There are 100 tiles in an English scrabble game (i.e., the sum of $count). It does not matter how the tiles are pulled, so it's not a permutation.

The Math I Used Determine how many letters are in the word and what letters are in the word, how many of those letters are available in the tile bag ( count for each letter, unique and allchars ). Binomial coefficient of each, divided by binomial coefficient of length word.

Determine the binomial combinations available

let C(n,r) be binomial coefficient: n!/[n!(n-r)!], or 0 if r > n

Foreach letter, what is the binomial coefficient.

There is 1 "B". There are 2 available, a 2% chance of pulling the b.
There is 2 "O". There are 8 available, a 8% chance of pulling the o.
There is 1 "T". There are 6 available, a 6% chance of pulling the t.
BOOT is a 4 letter word, being taken from a 100 tile set with blanks, 98 without.

n = 98. The number of tiles without blank in the English set

B=(21)=2!2!(21)!
O=(82)=8!8!(82)!
T=(61)=6!6!(61)!

B×O×T divided by the binomial coefficient of tilecount 98!98!(98length)!

James Cordeiro
la source
It's hard to evaluate your solution without knowing what n and r refer to in the final formula. How do you handle the effect of the blank tiles? That's what makes this a difficult problem. Regardless, it would be interesting to see a demonstration that the value of 38248840160075608000.00239 is incorrect: this was obtained using the R solution I posted. Try this one-second R simulation: let <- c(rep("b", 2), rep("o", 8), rep("t", 6), rep("_", 84)); boot <- function(x) sum(x=="b")>=1 && sum(x=="o")>=2 && sum(x=="t")>=1; mean(replicate(1e5, boot(sample(let, 7))))
whuber
Re the edit: one obvious error is that your calculation does not account for the number of blanks at all. As far as I can tell from your formulas, if that number were to change (from 2 to 50, say) then your answer would not change. That's obviously wrong. Another problem you face is to explain how your answer can conflict with three other answers already posted, which use three completely different techniques yet agree with one another (and disagree with yours).
whuber
If combinations - the math is binomial coefficients. So, let x be the count of blank tiles. The only math that changes, is n! - is there blanks used, or not. If so, add the count of blank to n! since blank allows 2 more options of every letter possible (n+x)! - if not, leave n! as is. Yes? No? If blanks are not used depending on language rule set in this case English, n! = 98 or 100 with. Each letter without blank is C(n,r), else with blank C((n+x),r). In the array, blank is there - but I forgot to put blank in the math. So just change n to work with blanks. Yes?
James Cordeiro
No, your reasoning is invalid. I invite you to try out your formulas with smaller numbers so you can see where they go wrong.
whuber
What do you mean by smaller numbers - whuber? Give me an example. Are you saying pulling boot from a set of 10 letters instead, 1 b, 2 o, 1 t's with a 1 blank in the set and 5 other letters. Or something completely different. I'm no math major, but it seems we've become poker players. We're now calculating poker odds with scrabble tiles that don't have suits.
James Cordeiro