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

Reply via email to