I want to convert this Word Search algo from Python to Nim.
Hit several errors. Need help!
I have commented those sections that hit error.
**Python:**
#-------------------------------------------------------------------------------
# Name: WordSearch-2.py
# Purpose: Find word in a grid of letters in any directions.
#-------------------------------------------------------------------------------
# Function to find word in grid of letters.
# Not a perfect algo, it miss "Thailand" and
# the solution doesn't follow the order of the clues.
def solve(puzzle, clues):
puzzle = puzzle.replace(' ','')
length = puzzle.index('\n')+1
# Make a list of tuples containing each letter and its row and column.
letters = [(letter, divmod(index, length))
for index, letter in enumerate(puzzle)]
# Reorder the list to represent each reading direction,
# and add them all to a dictionary.
lines = {}
offsets = {'down':0, 'left down':-1, 'right down':1}
for direction, offset in offsets.items():
lines[direction] = []
for i in range(length):
for j in range(i, len(letters), length + offset):
lines[direction].append(letters[j])
#print(f"lines[dir]={lines[direction]},
letters[j]={letters[j]}")
lines[direction].append('\n')
lines['right'] = letters
lines['left'] = [i for i in reversed(letters)]
lines['up'] = [i for i in reversed(lines['down'])]
lines['left up'] = [i for i in reversed(lines['right down'])]
lines['right up'] = [i for i in reversed(lines['left down'])]
# Make strings from the letters, find the words in them and retrieve
# their original locations.
nc = 0
for direction, tup in lines.items():
string = ''.join([i[0] for i in tup])
for word in clues:
if word.upper() in string:
nc = nc + 1
location = tup[string.index(word.upper())][1]
print(f"{word.upper()}: row[{location[0]+1:02}]
col[{chr(ord('a')+location[1])}] {direction}")
if (nc%5) == 0 and nc<len(clues):
print("-"*35)
# Function to print the grid of letters with row numbers & column letters.
def print_grid(puzzle):
print()
g = puzzle.replace(" ","")
w = g.find("\n")+1
for r, row in enumerate(g.split('\n'), start=1):
# Print top column letters heading.
if r == 1:
print(" ", end='')
print("".join("%s " % chr(ord('a')+m) for m in range(len(row))))
print(" +", end='')
print("-"*(2*len(row)+1), end='')
print("+")
# Print row numbers heading.
print("%02d|" % r, end=' ')
for c, l in enumerate(row, start=1):
print("%s" % l, end=' ')
print("|%02d" % r)
# Print bottom column letters heading.
print(" +", end='')
print("-"*(2*len(row)+1), end='')
print("+")
print(" ", end='')
print("".join("%s " % chr(ord('a')+m) for m in range(len(row))))
# Function to find word in grid of letters.
# A better algo, that is able to find start & end of word;
# the solution is in order of the clues, and didn't missed "Thailand".
def find_word(puzzle, word):
print("%s:" % word.upper())
g = puzzle.replace(" ","")
w = g.find("\n")+1
L = len(word)
res = []
for i in range(len(g)):
for j in (-w-1, -w, -w+1, -1, 1, w-1, w, w+1):
for x in (i, i+(L-1)*j):
if g[i::j][:L] == word.upper():
res.append((x//w+1, x%w+1))
print(" --> ".join("Row[%02d] Col[%s]" % (t[0], chr(ord('a')+t[1]-1))
for t in res))
if __name__ == '__main__':
# Define the puzzle.
puzzle = """I U W S S W E D E N F Q S M V R P B
B M I D F I N D I A H I S P W Y Y L
H T E N I G E R I A I O N V A M C P
Y Y H X R L E B E T G R J L O I A A
H N X A I U E Z F R A N C E A E N N
V R O T I C S N B E L G I U M N A A
N F R R Y L O S G I C V M N V E D M
W N X F W V A I I L T O Z I H A A A
G H A N A A M N X A A A F B K I N B
G R E E C E Y A D A D N L Z U D F Z
T P K P Q J A P A N T Q D Y D L V I
V K A M E R I C A D C H I N A B C X"""
clues = ["Belgium", "Greece", "Canada", "Japan", "England",
"Italy", "France", "Panama", "India", "Mexico",
"Norway", "Spain", "China", "Thailand", "Sweden",
"Ghana", "Russia", "Finland", "Nigeria", "America"]
# Init g_highlight.
g_highlight = [False for l in (puzzle.replace(" ",""))]
# Print the grid.
print_grid(puzzle)
# Find the words.
print("")
print("="*40)
solve(puzzle, clues)
print("="*40)
# Another algo to find words.
print("")
print("="*40)
nw = 0
for word in clues:
nw = nw + 1
find_word(puzzle, word)
if (nw%5) == 0 and nw<len(clues):
print("-"*35)
else:
if nw!=len(clues):
print()
print("="*40)
print()
Run
**Nim:**
#-------------------------------------------------------------------------------
# Name: WordSearch.nim
# Purpose: Find word in a grid of letters in any directions.
#-------------------------------------------------------------------------------
import strutils, std/strformat, std/enumerate, std/sugar, std/tables
# Implement print("="*20) for nim-lang.
let zero = ""
proc `+`(a, b: string): string =
a & b
proc `*`[T](a: T, b: int): T =
result = zero
for i in 0 .. b-1:
result = result + a # calls `+` from above proc `+`.
# Implement divmod for nim-lang.
proc divmod(a, b: int): (int, int) =
let res = a div b # integer division
let rem = a mod b # integer modulo operation
return (res, rem)
# Procedure to print the grid of letters with row numbers & column letters.
proc print_grid(puzzle: string) =
var lastRow: string
let newGrid = puzzle.replace(" ","")
for i, row in enumerate(1, newGrid.split('\n')):
# Print top column letters heading.
if i == 1:
write(stdout, " ")
for m in 0 ..< len(row):
write(stdout, fmt"{chr(ord('a')+m)} ")
echo()
write(stdout, " +")
write(stdout, "-"*(2*len(row)+1))
echo("+")
# Print row numbers heading.
write(stdout, fmt"{i:02}| ")
for m in row:
write(stdout, fmt"{m} ")
echo(fmt"|{i:02}")
# row is out of scope after the for-loop in Nim.
# Need a var lastRow to store the last value.
lastRow = row
# Print bottom column letters heading.
write(stdout, " +")
write(stdout, "-"*(2*len(lastRow)+1))
echo("+")
write(stdout, " ")
for m in 0 ..< len(lastRow):
write(stdout, fmt"{chr(ord('a')+m)} ")
echo()
# Procedure to find word in grid of letters.
proc solve_puzzle(puzzle: string; clues: seq) =
let newGrid = puzzle.replace(" ","")
let length = newGrid.find('\n')+1
##echo(fmt"length = {length}")
# Make a list of tuples containing each letter and its row and column.
let letters = collect(newSeq):
for index, letter in enumerate(newGrid): (letter, divmod(index,
length))
##echo(fmt"letters = {letters}")
# Reorder the list to represent each reading direction,
# and add them all to a dictionary.
var lines = initTable[string, seq]()
let offsets = {"down": 0, "left down": -1, "right down": 1}.toTable
##echo(fmt"offsets = {offsets}")
# Test printing the dictionary/table 'offsets' items.
for dirn, offset in offsets.pairs():
echo(fmt"dirn = {dirn}, offset = {offset}")
#[
#!!! Hit error here !!!
for direction, offset in offsets.pairs():
lines[direction] = @[] # Empty seq.
for i in 0 ..< length:
for j in countup(i, len(letters), length+offset):
lines[direction].add(letters[j]) ## nim(84, 33) Error:
type mismatch: got <seq[string], (char, (int, int))> but expected one of: proc
add[T](x: var seq[T]; y: openArray[T])
lines[direction].add('\n')
lines["right"] = letters
lines["left"] = collect(newSeq):
for i in reversed(letters): i
lines["up"] = collect(newSeq):
for i in reversed(lines["down"]): i
lines["left up"] = collect(newSeq):
for i in reversed(lines["right down"]): i
lines["right up"] = collect(newSeq):
for i in reversed(lines["left down"]): i
# Make strings from the letters, find the words in them and retrieve
# their original locations.
var nc = 0
var myStr = ""
for direction, tup in lines.items():
myStr = collect(newSeq):
for i in tup: join("", i[0])
for word in clues:
if word.upper() in myStr:
nc = nc + 1
var location = tup[myStr.index(word.upper())][1]
echo(fmt"{word.upper()}: row[{location[0]+1:02}]
col[{chr(ord('a')+location[1])}] {direction}")
if (nc%5) == 0 and nc<len(clues):
echo("-"*35)
#]#
# Function to find word in grid of letters.
proc solve_puzzle(puzzle: string; word: string) =
echo(fmt"{word}:")
let newGrid = puzzle.replace(" ","")
let w = newGrid.find("\n")+1
let L = len(word)
#[
#!!! Hit error here !!!
var res = @[] # nim(120, 15) Error: cannot infer the type of the
sequence
for i in 0 ..< len(g):
for j in (-w-1, -w, -w+1, -1, 1, w-1, w, w+1):
for x in i ..< i+(L-1)*j:
if g[i::j][:L] == word.upper(): # nim(124, 25) Error:
expected: ']', but got: '::'
res.append((x//w+1, x%w+1))
for t in res:
echo(" --> ".join("Row[t[0]:02] Col[{chr(ord('a')+t[1]-1)}]"))
#]#
when is_main_module:
# Define the puzzle.
let puzzle = """I U W S S W E D E N F Q S M V R P B
B M I D F I N D I A H I S P W Y Y L
H T E N I G E R I A I O N V A M C P
Y Y H X R L E B E T G R J L O I A A
H N X A I U E Z F R A N C E A E N N
V R O T I C S N B E L G I U M N A A
N F R R Y L O S G I C V M N V E D M
W N X F W V A I I L T O Z I H A A A
G H A N A A M N X A A A F B K I N B
G R E E C E Y A D A D N L Z U D F Z
T P K P Q J A P A N T Q D Y D L V I
V K A M E R I C A D C H I N A B C X"""
let clues = @["Belgium", "Greece", "Canada", "Japan", "England",
"Italy", "France", "Panama", "India", "Mexico",
"Norway", "Spain", "China", "Thailand", "Sweden",
"Ghana", "Russia", "Finland", "Nigeria", "America"]
# Print the grid.
print_grid(puzzle)
# Find the words.
echo()
echo("="*40)
solve_puzzle(puzzle, clues)
echo("="*40)
Run