Code: Select all

```
def permutations(letters) {
def powerset = powerset(letters)
def res = []
powerset.each {
def list = it.split("") - "" as List
res << list.permutations().collect { it.join("") }
}
return res.flatten()
}
def powerset(letters) {
def size = 2 ** letters.size()
def res = []
for (int i=0;i<size;i++) {
def tmp = ""
for (int j=0;j<letters.size();j++) {
if ( (i & (1<<j)) > 0) {
tmp += letters[j]
}
}
res << tmp
}
return res - ""
}
```

* a, b, c

* ab, ba

* ac ,ca

* bc, cb

* abc,acb,bca, etc..

across the board.

Code: Select all

```
def putWord(word, board, x, y) {
if (board[y][x] != ASTERISK) return null
//println "tryword: $word x/y $x $y"
def clone = clone(board)
def putat = x
for(int i=0;i<word.size();i++) {
while(putat < 14 && clone[y][putat] != "*") {
putat++
}
if (putat > 14) {
//putting the whole word would exceed board bounds
return clone
}
clone[y][putat] = word[i]
putat++
}
return clone
}
```

if you want to put the word "xyz" at position 0,0 you need to skip over the letter a and then continue putting the word so it looks like

if the starting location doesn't contain the * character you just return as a word can't start there.

Code: Select all

```
def isValidWords(board, dict) {
def words = []
for (def line : board) {
def wl = line.join("")
def st = new StringTokenizer(wl, "*")
while(st.hasMoreElements()) {
def nt = st.nextToken()
if (nt.size() > 1) words<<nt
}
}
for (String w : words) {
if (!dict.containsKey(w)) return false
}
return true
}
```

Code: Select all

```
[
[* * * * *],
[* * * * *]
...
]
```

Code: Select all

```
def connected(board) {
//dumpboard(board)
def startx, starty
outer:
for(int i=0;i<15;i++) {
for(int j=0;j<15;j++) {
if (board[i][j] != ASTERISK) {
startx = j
starty = i
break outer
}
}
}
def clone = clone(board)
floodfill(clone, startx, starty)
for(int i=0;i<15;i++) for(int j=0;j<15;j++) if (clone[i][j] != ASTERISK && clone[i][j] != BANG) return false
return true
//return clone.flatten().findAll { it != ASTERISK && it != BANG }.size() == 0
}
def floodfill(board, x, y) {
board[y][x] = BANG
if (y < 14 && board[y+1][x] != ASTERISK && board[y+1][x] != BANG) {
floodfill(board, x, y+1)
}
if (y > 0 && board[y-1][x] != ASTERISK && board[y-1][x] != BANG) {
floodfill(board, x, y-1)
}
if (x < 14 && board[y][x+1] != ASTERISK && board[y][x+1] != BANG) {
floodfill(board, x+1, y)
}
if (x>0 && board[y][x-1] != ASTERISK && board[y][x-1] != BANG) {
floodfill(board, x-1, y)
}
//dumpboard(board)
}
```

The first iteration of the script ran on a single thread and would take about 6 to 7 minutes to calculate 13699 words. But it's a great candidate for parallelization which is very simple with groovy. With 6 threads it completes in about 2 minutes which is quite acceptable.