Another Person
Another Person

Reputation: 1

why is Julia looking for a function with a different argument type when I've defined all parameters and variables

I'm trying to write a short Julia program to solve the n queens problem - where you try place n queens on an nxn chess board such that they don't attack each other - I am new to Julia and I don't understand why the error "MethodError: no method matching check(::Int64, ::Int64, ::Int64, ::BitMatrix)" is given when check is defined with argument types for the variable types desired.

I've tried to detail the variable types more within the function and prior to passing the values, but it still tries to find a method with different data types.

code listed below

solve(1, 6, falses(6, 6))
display(board)



function check(row::Int16, column::Int16, n::Int16, board::BitMatrix)
    left::Int16 = 0
    checkLeft::Bool = true
    right::Int16 = 0
    checkRight::Bool = true
    for j::Int16 = row:-1:1
        if left==column-1
            checkLeft = false
        else
            left+=1
        end
        if right==n-column
            checkRight = false
        else
            right+=1
        end
        if board[j,column]||(board[j,column-left]&&checkLeft)||(board[j,column+right]&&checkRight)
            return true
        end
    end
    return false
end

function solve(row::Int16, n::Int16, board::BitMatrix)
    column::Int16 = 1
    if row>=n
        return true
    end
    for column = 1:n
        if check(row, column, n, board)
            board[row,column] = true
            if solve(row+1, n, board)
                return true
            end
            board[row,column] = false
        else
            column+=1
        end
    end
    return false
end

Upvotes: 0

Views: 53

Answers (1)

xlxs4
xlxs4

Reputation: 183

You mean you get MethodError: no method matching solve(::Int64, ::Int64, ::BitMatrix). solve is erroring, not check. For the fastest fix, just replace all Int16 to Int:


    function check(row::Int, column::Int, n::Int, board::BitMatrix)
        left::Int = 0
        checkLeft::Bool = true
        right::Int = 0
        checkRight::Bool = true
        for j::Int = row:-1:1
            if left==column-1
                checkLeft = false
            else
                left+=1
            end
            if right==n-column
                checkRight = false
            else
                right+=1
            end
            if board[j,column]||(board[j,column-left]&&checkLeft)||(board[j,column+right]&&checkRight)
                return true
            end
        end
        return false
    end
    
    function solve(row::Int, n::Int, board::BitMatrix)
        column::Int = 1
        if row>=n
            return true
        end
        for column = 1:n
            if check(row, column, n, board)
                board[row,column] = true
                if solve(row+1, n, board)
                    return true
                end
                board[row,column] = false
            else
                column+=1
            end
        end
        return false
    end
    
    solve(1, 6, falses(6, 6))

This code runs. The problem is that in your function call solve(1, 6, falses(6, 6)), these are Ints, which I'm guessing in your system default to Int64 (docs).

In general, there's usually no need to specify the types of the function arguments explicitly. This is a common Julia antipattern and has been documented and discussed multiple times. For an example, read this Discourse thread.


Edit: to be extra clear, you can simply have:


    function check(row, column, n, board)
        left = 0
        checkLeft = true
        right = 0
        checkRight = true
        for j = row:-1:1
            if left == column - 1
                checkLeft = false
            else
                left += 1
            end
            if right == n - column
                checkRight = false
            else
                right += 1
            end
            if board[j, column] ||
               (board[j, column-left] && checkLeft) ||
               (board[j, column+right] && checkRight)
                return true
            end
        end
        return false
    end
    
    function solve(row, n, board)
        column = 1
        if row >= n
            return true
        end
        for column = 1:n
            if check(row, column, n, board)
                board[row, column] = true
                if solve(row + 1, n, board)
                    return true
                end
                board[row, column] = false
            else
                column += 1
            end
        end
        return false
    end
    
    solve(1, 6, falses(6, 6))

with no impact on performance whatsoever. Refer to https://docs.julialang.org/en/v1/manual/methods/#man-method-specializations.

Upvotes: 1

Related Questions