스도쿠 푸는 프로그램 입니다.

임창진의 이미지

lua 5.02 로 작성한 스도쿠 푸는 프로그램 입니다.
못푸는 문제도 있을수 있습니다.
따로 문제를 입력하는 방법은 없고 소스코드를 수정해서 입력해야 합니다.

44라인부터가 스도쿠의 문제를 표현한 부분입니다. 문제지의 빈칸은 space 번호가 있는칸은 해당번호를 넣으시면 됩니다.

local function newgetn(tbl)
    local n = 9
    local nilN = 0

    for i = 1,9 do
        if not tbl[i] then nilN = nilN + 1 end
    end

    return n - nilN
end


local function isEmpty(self)
    if self.dispNum ==  ' ' then
        return true
    else
        return false
    end
end

local function toString(self)
    return string.format("(%s,%s)=>[%s]",self.garo,self.sero,self.dispNum)
end

newCell = function(cellData)
    local tbl = {}
    local nomi = {'1','2','3','4','5','6','7','8','9'}

    tbl.sero = cellData[2]
    tbl.garo = cellData[1]
    tbl.blocknum = cellData[3]
    tbl.dispNum = cellData[4]
    tbl.isEmpty = isEmpty
    tbl.toString = toString

    tbl.nomi = nil
    if cellData[4] == ' ' then
        tbl.nomi = nomi
    end

    return tbl
end

board = {
    ['11']=newCell{1,1,1,' '} ,['21']=newCell{2,1,1,' '} ,['31']=newCell{3,1,1,'4'} ,['41']=newCell{4,1,2,' '} ,['51']=newCell{5,1,2,'5'} ,['61']=newCell{6,1,2,' '} ,['71']=newCell{7,1,3,' '} ,['81']=newCell{8,1,3,'6'} ,['91']=newCell{9,1,3,' '} ,
    ['12']=newCell{1,2,1,' '} ,['22']=newCell{2,2,1,'6'} ,['32']=newCell{3,2,1,' '} ,['42']=newCell{4,2,2,'1'} ,['52']=newCell{5,2,2,' '} ,['62']=newCell{6,2,2,' '} ,['72']=newCell{7,2,3,'8'} ,['82']=newCell{8,2,3,' '} ,['92']=newCell{9,2,3,'9'} ,
    ['13']=newCell{1,3,1,'3'} ,['23']=newCell{2,3,1,' '} ,['33']=newCell{3,3,1,' '} ,['43']=newCell{4,3,2,' '} ,['53']=newCell{5,3,2,' '} ,['63']=newCell{6,3,2,'7'} ,['73']=newCell{7,3,3,' '} ,['83']=newCell{8,3,3,' '} ,['93']=newCell{9,3,3,' '} ,
    ['14']=newCell{1,4,4,' '} ,['24']=newCell{2,4,4,'8'} ,['34']=newCell{3,4,4,' '} ,['44']=newCell{4,4,5,' '} ,['54']=newCell{5,4,5,' '} ,['64']=newCell{6,4,5,' '} ,['74']=newCell{7,4,6,'5'} ,['84']=newCell{8,4,6,' '} ,['94']=newCell{9,4,6,' '} ,
    ['15']=newCell{1,5,4,' '} ,['25']=newCell{2,5,4,' '} ,['35']=newCell{3,5,4,' '} ,['45']=newCell{4,5,5,'4'} ,['55']=newCell{5,5,5,' '} ,['65']=newCell{6,5,5,'3'} ,['75']=newCell{7,5,6,' '} ,['85']=newCell{8,5,6,' '} ,['95']=newCell{9,5,6,' '} ,
    ['16']=newCell{1,6,4,' '} ,['26']=newCell{2,6,4,' '} ,['36']=newCell{3,6,4,'6'} ,['46']=newCell{4,6,5,' '} ,['56']=newCell{5,6,5,' '} ,['66']=newCell{6,6,5,' '} ,['76']=newCell{7,6,6,' '} ,['86']=newCell{8,6,6,'7'} ,['96']=newCell{9,6,6,' '} ,
    ['17']=newCell{1,7,7,' '} ,['27']=newCell{2,7,7,' '} ,['37']=newCell{3,7,7,' '} ,['47']=newCell{4,7,8,'2'} ,['57']=newCell{5,7,8,' '} ,['67']=newCell{6,7,8,' '} ,['77']=newCell{7,7,9,' '} ,['87']=newCell{8,7,9,' '} ,['97']=newCell{9,7,9,'6'} ,
    ['18']=newCell{1,8,7,'1'} ,['28']=newCell{2,8,7,' '} ,['38']=newCell{3,8,7,'5'} ,['48']=newCell{4,8,8,' '} ,['58']=newCell{5,8,8,' '} ,['68']=newCell{6,8,8,'4'} ,['78']=newCell{7,8,9,' '} ,['88']=newCell{8,8,9,'3'} ,['98']=newCell{9,8,9,' '} ,
    ['19']=newCell{1,9,7,' '} ,['29']=newCell{2,9,7,'2'} ,['39']=newCell{3,9,7,' '} ,['49']=newCell{4,9,8,' '} ,['59']=newCell{5,9,8,'7'} ,['69']=newCell{6,9,8,' '} ,['79']=newCell{7,9,9,'1'} ,['89']=newCell{8,9,9,' '} ,['99']=newCell{9,9,9,' '} ,

    emptyCell=81
}


--~ count empty cell and print empty cell count
function board:calcEmpty()
    self.emptyCell = 0
    for sero = 1,9 do
    for garo = 1,9 do
        if self[sero..garo]:isEmpty()  then
            self.emptyCell = self.emptyCell + 1
        end
    end
    end
    print('emptyCell Count : ' .. self.emptyCell)
end



--~ garo(vertical line index) sero(horizontal line index) start from 1
--~ print nominees that can be placed at garo,sero location
function board:printNomi(garo,sero)
    print('can be placed ---------------------------------')

    if not self[garo..sero]:isEmpty() then
        print( self[garo..sero].dispNum .. ' is already founded!!!')
        return
    end

    local tc = self[garo..sero]
    for i = 1,9 do
        io.write((tc.nomi[i] or type(tc.nomi[i])) ..',')
    end
    print()
end

-- print all founded number and  not yet founded cell(space) of current board
function board:print()
    for sero=1,9 do
        for garo=1,9 do
            io.write( board[garo..sero].dispNum .. ',' )
        end
        print()
    end
end

--~ guess which number can be placed this garo,sero location
function board:guess(garo,sero)
    local tmpCell = self[garo..sero]
    local blockNum = tmpCell.blocknum

    if not tmpCell:isEmpty() then return end

    tmpCell.nomi = board:rmVertDup(garo,tmpCell.nomi)
    tmpCell.nomi = board:rmHoriDup(sero,tmpCell.nomi)
    tmpCell.nomi = board:rmBlockDup(blockNum,tmpCell.nomi)

    if newgetn(tmpCell.nomi) == 1 then
        io.write(tmpCell.garo ,',',tmpCell.sero ,'=******************=>')
        for i = 1,9 do
            if tmpCell.nomi[i] then
                tmpCell.dispNum = tmpCell.nomi[i]
                io.write(tmpCell.nomi[i] .. ' found \n')
            end
        end
    else
        for i=1,9 do
            if tmpCell.nomi[i] then
                local v = tmpCell.nomi[i]
                if not board:canBeOtherPlace(tmpCell,v) then
                    print('can\'t be ::::::::::::::::: ' .. v)
                    tmpCell.dispNum = v
                    break;
                end
            end
        end
    end
end

function table.containsv(tbl,v)
    for i = 1,9 do
        if tbl[i] == v then
            return true
        end
    end

    return false
end



function board:guessBlock(pBlockNum)
    local emptyNums = board:rmBlockDup(pBlockNum,{'1','2','3','4','5','6','7','8','9'})

    table.foreach(emptyNums,function (k,v)
        local canBePlacedCells = board:getCBPC(pBlockNum,v)

        local sGaro = getSameGaro(canBePlacedCells)
        if sGaro then
            board:cantBePlaceGaro(sGaro,v,pBlockNum)
        end

        local sSero = getSameSero(canBePlacedCells)
        if sSero then
            board:cantBePlaceSero(sSero,v,pBlockNum)
        end
    end)
end



function board:cantBePlaceGaro(garo,v,pBlockNum)
    for sero=1,9 do
        -- sero axis seearch
        if self[garo..sero]:isEmpty() and self[garo..sero].blocknum ~= pBlockNum then
            local nomi = self[garo..sero].nomi
            for i = 1,9 do
                if nomi[i] == v then
                    nomi[i] = nil
                end
            end
        end
    end
end


function board:cantBePlaceSero(sero,v,pBlockNum)
    for garo=1,9 do
		-- garo axis seearch
        if self[garo..sero]:isEmpty() and self[garo..sero].blocknum ~= pBlockNum then
            local nomi = self[garo..sero].nomi
            for i = 1,9 do
                if nomi[i] == v then
                    nomi[i] = nil
                end
            end
        end
    end
end




function getSameGaro(canBePlacedCells)
    local garo = '0'

    table.foreach(canBePlacedCells,function (k,cell)
        if garo ~= '0' and cell.garo ~= garo then
            garo = nil
        else
            garo = cell.garo
        end
--~         print (garo)
    end)

    return garo
end


function getSameSero(canBePlacedCells)
    local sero = '0'

    table.foreach(canBePlacedCells,function (k,cell)
        if sero ~= '0' and cell.sero ~= sero then
            sero = nil
        else
            sero = cell.sero
        end
--~         print (garo)
    end)

    return sero
end



function board:getCBPC(pBlockNum,v)
    local cbpcTbl = {}

    for sero=1,9 do
        for garo=1,9 do
            if self[garo..sero].blocknum == pBlockNum
                    and self[garo..sero]:isEmpty()
                    and table.containsv(self[garo..sero].nomi,v)  then
                table.insert(cbpcTbl,self[garo..sero])
            end
        end
    end

    return cbpcTbl
end

function board:canBeOtherPlace(tc,v)
    local pBlockNum = tc.blocknum
    for sero=1,9 do
        for garo=1,9 do
            local tmpCell = self[garo..sero]
            if tmpCell.blocknum == pBlockNum and tmpCell:isEmpty() and tmpCell ~= tc then
                if table.containsv(tmpCell.nomi , v) then return true end
            end
        end
    end

    return false
end


function board:rmVertDup(garo,nomi)
    for sero=1,9 do
        -- sero axis seearch
        if not self[garo..sero]:isEmpty() then
            for i = 1,9 do
                if nomi[i] == self[garo..sero].dispNum then
                    nomi[i] = nil
                end
            end
        end
    end

    return nomi
end

function board:rmHoriDup(sero,nomi)
    for garo=1,9 do
        -- garo axis seearch
        if not self[garo..sero]:isEmpty() then
            for i = 1,9 do
                if nomi[i] == self[garo..sero].dispNum then
                    nomi[i] = nil
                end
            end
        end
    end

    return nomi
end

function board:rmBlockDup(pBlockNum,nomi)
    for sero=1,9 do
        for garo=1,9 do
            if self[garo..sero].blocknum == pBlockNum and not self[garo..sero]:isEmpty() then
                for i = 1,9 do
                    if nomi[i] == self[garo..sero].dispNum then
                        nomi[i] = nil
                    end
                end
            end
        end
    end

    return nomi
end

while board.emptyCell > 0 do
    for sero=1,9 do
        for garo=1,9 do
            if board[garo..sero]:isEmpty() then
                board:guess(garo,sero)
            end
        end
    end

    for block=1,9 do
        board:guessBlock(block)
    end


    board:print();
    board:calcEmpty();
end


Forums: 
pynoos의 이미지

요즘 스도쿠에 빠져서 삽니다. 책도하나 사서 계속 풀고 있지요.. :)

내용과는 관계없이 반가와서 답글을 올려봅니다.

cppig1995의 이미지

조선일보 스도쿠 깨 볼까요?

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

익명 사용자의 이미지

임창진 wrote:
lua 5.02 로 작성한 스도쿠 푸는 프로그램 입니다.
못푸는 문제도 있을수 있습니다.
따로 문제를 입력하는 방법은 없고 소스코드를 수정해서 입력해야 합니다.

44라인부터가 스도쿠의 문제를 표현한 부분입니다. 문제지의 빈칸은 space 번호가 있는칸은 해당번호를 넣으시면 됩니다.

local function newgetn(tbl)
    local n = 9
    local nilN = 0

    for i = 1,9 do
        if not tbl[i] then nilN = nilN + 1 end
    end

    return n - nilN
end


local function isEmpty(self)
    if self.dispNum ==  ' ' then
        return true
    else
        return false
    end
end

local function toString(self)
    return string.format("(%s,%s)=>[%s]",self.garo,self.sero,self.dispNum)
end

newCell = function(cellData)
    local tbl = {}
    local nomi = {'1','2','3','4','5','6','7','8','9'}

    tbl.sero = cellData[2]
    tbl.garo = cellData[1]
    tbl.blocknum = cellData[3]
    tbl.dispNum = cellData[4]
    tbl.isEmpty = isEmpty
    tbl.toString = toString

    tbl.nomi = nil
    if cellData[4] == ' ' then
        tbl.nomi = nomi
    end

    return tbl
end

board = {
    ['11']=newCell{1,1,1,' '} ,['21']=newCell{2,1,1,' '} ,['31']=newCell{3,1,1,'4'} ,['41']=newCell{4,1,2,' '} ,['51']=newCell{5,1,2,'5'} ,['61']=newCell{6,1,2,' '} ,['71']=newCell{7,1,3,' '} ,['81']=newCell{8,1,3,'6'} ,['91']=newCell{9,1,3,' '} ,
    ['12']=newCell{1,2,1,' '} ,['22']=newCell{2,2,1,'6'} ,['32']=newCell{3,2,1,' '} ,['42']=newCell{4,2,2,'1'} ,['52']=newCell{5,2,2,' '} ,['62']=newCell{6,2,2,' '} ,['72']=newCell{7,2,3,'8'} ,['82']=newCell{8,2,3,' '} ,['92']=newCell{9,2,3,'9'} ,
    ['13']=newCell{1,3,1,'3'} ,['23']=newCell{2,3,1,' '} ,['33']=newCell{3,3,1,' '} ,['43']=newCell{4,3,2,' '} ,['53']=newCell{5,3,2,' '} ,['63']=newCell{6,3,2,'7'} ,['73']=newCell{7,3,3,' '} ,['83']=newCell{8,3,3,' '} ,['93']=newCell{9,3,3,' '} ,
    ['14']=newCell{1,4,4,' '} ,['24']=newCell{2,4,4,'8'} ,['34']=newCell{3,4,4,' '} ,['44']=newCell{1,9,' ',' '} ,['54']=newCell{' ',' ',' ',' '} ,['64']=newCell{' ',' ',' ',' '} ,['74']=newCell{' ',' ',' ',' '} ,['84']=newCell{' ',' ',2,' '} ,['94']=newCell{' ',' ',8,' '} ,
    ['15']=newCell{' ',' ',2,' '} ,['25']=newCell{' ',' ',1,' '} ,['35']=newCell{4,' ',' ',' '} ,['45']=newCell{' ',' ',5,'4'} ,['55']=newCell{5,5,5,' '} ,['65']=newCell{6,5,5,'3'} ,['75']=newCell{7,5,6,' '} ,['85']=newCell{8,5,6,' '} ,['95']=newCell{9,5,6,' '} ,
    ['16']=newCell{1,6,4,' '} ,['26']=newCell{2,6,4,' '} ,['36']=newCell{3,6,4,'6'} ,['46']=newCell{4,6,5,' '} ,['56']=newCell{5,6,5,' '} ,['66']=newCell{6,6,5,' '} ,['76']=newCell{7,6,6,' '} ,['86']=newCell{8,6,6,'7'} ,['96']=newCell{9,6,6,' '} ,
    ['17']=newCell{1,7,7,' '} ,['27']=newCell{2,7,7,' '} ,['37']=newCell{3,7,7,' '} ,['47']=newCell{4,7,8,'2'} ,['57']=newCell{5,7,8,' '} ,['67']=newCell{6,7,8,' '} ,['77']=newCell{7,7,9,' '} ,['87']=newCell{8,7,9,' '} ,['97']=newCell{9,7,9,'6'} ,
    ['18']=newCell{1,8,7,'1'} ,['28']=newCell{2,8,7,' '} ,['38']=newCell{3,8,7,'5'} ,['48']=newCell{4,8,8,' '} ,['58']=newCell{5,8,8,' '} ,['68']=newCell{6,8,8,'4'} ,['78']=newCell{7,8,9,' '} ,['88']=newCell{8,8,9,'3'} ,['98']=newCell{9,8,9,' '} ,
    ['19']=newCell{1,9,7,' '} ,['29']=newCell{2,9,7,'2'} ,['39']=newCell{3,9,7,' '} ,['49']=newCell{4,9,8,' '} ,['59']=newCell{5,9,8,'7'} ,['69']=newCell{6,9,8,' '} ,['79']=newCell{7,9,9,'1'} ,['89']=newCell{8,9,9,' '} ,['99']=newCell{9,9,9,' '} ,

    emptyCell=81
}


--~ count empty cell and print empty cell count
function board:calcEmpty()
    self.emptyCell = 0
    for sero = 1,9 do
    for garo = 1,9 do
        if self[sero..garo]:isEmpty()  then
            self.emptyCell = self.emptyCell + 1
        end
    end
    end
    print('emptyCell Count : ' .. self.emptyCell)
end



--~ garo(vertical line index) sero(horizontal line index) start from 1
--~ print nominees that can be placed at garo,sero location
function board:printNomi(garo,sero)
    print('can be placed ---------------------------------')

    if not self[garo..sero]:isEmpty() then
        print( self[garo..sero].dispNum .. ' is already founded!!!')
        return
    end

    local tc = self[garo..sero]
    for i = 1,9 do
        io.write((tc.nomi[i] or type(tc.nomi[i])) ..',')
    end
    print()
end

-- print all founded number and  not yet founded cell(space) of current board
function board:print()
    for sero=1,9 do
        for garo=1,9 do
            io.write( board[garo..sero].dispNum .. ',' )
        end
        print()
    end
end

--~ guess which number can be placed this garo,sero location
function board:guess(garo,sero)
    local tmpCell = self[garo..sero]
    local blockNum = tmpCell.blocknum

    if not tmpCell:isEmpty() then return end

    tmpCell.nomi = board:rmVertDup(garo,tmpCell.nomi)
    tmpCell.nomi = board:rmHoriDup(sero,tmpCell.nomi)
    tmpCell.nomi = board:rmBlockDup(blockNum,tmpCell.nomi)

    if newgetn(tmpCell.nomi) == 1 then
        io.write(tmpCell.garo ,',',tmpCell.sero ,'=******************=>')
        for i = 1,9 do
            if tmpCell.nomi[i] then
                tmpCell.dispNum = tmpCell.nomi[i]
                io.write(tmpCell.nomi[i] .. ' found \n')
            end
        end
    else
        for i=1,9 do
            if tmpCell.nomi[i] then
                local v = tmpCell.nomi[i]
                if not board:canBeOtherPlace(tmpCell,v) then
                    print('can\'t be ::::::::::::::::: ' .. v)
                    tmpCell.dispNum = v
                    break;
                end
            end
        end
    end
end

function table.containsv(tbl,v)
    for i = 1,9 do
        if tbl[i] == v then
            return true
        end
    end

    return false
end



function board:guessBlock(pBlockNum)
    local emptyNums = board:rmBlockDup(pBlockNum,{'1','2','3','4','5','6','7','8','9'})

    table.foreach(emptyNums,function (k,v)
        local canBePlacedCells = board:getCBPC(pBlockNum,v)

        local sGaro = getSameGaro(canBePlacedCells)
        if sGaro then
            board:cantBePlaceGaro(sGaro,v,pBlockNum)
        end

        local sSero = getSameSero(canBePlacedCells)
        if sSero then
            board:cantBePlaceSero(sSero,v,pBlockNum)
        end
    end)
end



function board:cantBePlaceGaro(garo,v,pBlockNum)
    for sero=1,9 do
        -- sero axis seearch
        if self[garo..sero]:isEmpty() and self[garo..sero].blocknum ~= pBlockNum then
            local nomi = self[garo..sero].nomi
            for i = 1,9 do
                if nomi[i] == v then
                    nomi[i] = nil
                end
            end
        end
    end
end


function board:cantBePlaceSero(sero,v,pBlockNum)
    for garo=1,9 do
		-- garo axis seearch
        if self[garo..sero]:isEmpty() and self[garo..sero].blocknum ~= pBlockNum then
            local nomi = self[garo..sero].nomi
            for i = 1,9 do
                if nomi[i] == v then
                    nomi[i] = nil
                end
            end
        end
    end
end




function getSameGaro(canBePlacedCells)
    local garo = '0'

    table.foreach(canBePlacedCells,function (k,cell)
        if garo ~= '0' and cell.garo ~= garo then
            garo = nil
        else
            garo = cell.garo
        end
--~         print (garo)
    end)

    return garo
end


function getSameSero(canBePlacedCells)
    local sero = '0'

    table.foreach(canBePlacedCells,function (k,cell)
        if sero ~= '0' and cell.sero ~= sero then
            sero = nil
        else
            sero = cell.sero
        end
--~         print (garo)
    end)

    return sero
end



function board:getCBPC(pBlockNum,v)
    local cbpcTbl = {}

    for sero=1,9 do
        for garo=1,9 do
            if self[garo..sero].blocknum == pBlockNum
                    and self[garo..sero]:isEmpty()
                    and table.containsv(self[garo..sero].nomi,v)  then
                table.insert(cbpcTbl,self[garo..sero])
            end
        end
    end

    return cbpcTbl
end

function board:canBeOtherPlace(tc,v)
    local pBlockNum = tc.blocknum
    for sero=1,9 do
        for garo=1,9 do
            local tmpCell = self[garo..sero]
            if tmpCell.blocknum == pBlockNum and tmpCell:isEmpty() and tmpCell ~= tc then
                if table.containsv(tmpCell.nomi , v) then return true end
            end
        end
    end

    return false
end


function board:rmVertDup(garo,nomi)
    for sero=1,9 do
        -- sero axis seearch
        if not self[garo..sero]:isEmpty() then
            for i = 1,9 do
                if nomi[i] == self[garo..sero].dispNum then
                    nomi[i] = nil
                end
            end
        end
    end

    return nomi
end

function board:rmHoriDup(sero,nomi)
    for garo=1,9 do
        -- garo axis seearch
        if not self[garo..sero]:isEmpty() then
            for i = 1,9 do
                if nomi[i] == self[garo..sero].dispNum then
                    nomi[i] = nil
                end
            end
        end
    end

    return nomi
end

function board:rmBlockDup(pBlockNum,nomi)
    for sero=1,9 do
        for garo=1,9 do
            if self[garo..sero].blocknum == pBlockNum and not self[garo..sero]:isEmpty() then
                for i = 1,9 do
                    if nomi[i] == self[garo..sero].dispNum then
                        nomi[i] = nil
                    end
                end
            end
        end
    end

    return nomi
end

while board.emptyCell > 0 do
    for sero=1,9 do
        for garo=1,9 do
            if board[garo..sero]:isEmpty() then
                board:guess(garo,sero)
            end
        end
    end

    for block=1,9 do
        board:guessBlock(block)
    end


    board:print();
    board:calcEmpty();
end


익명 사용자의 이미지

간단히 하기위해서 재귀를 이용해서 짜봤읍니다.
C로 코딩할려고 했는데 오랫동안 안쓰다가 다시 하려고 하니
안되는군요. 그래서 익숙한 Ada로...
효율성은 무시하고 ^^; . 그냥가능한 모든값을 대입해서 찾는 방식입니다.
그렇지만 그렇게 느리지는 않네요.
몇개를 테스트해봤는데 전부 거의 1초안에 답을 출력하는군요.
pc방인데 환경이 별로라서 대충해서 올려봅니다. 꼭 버그가 있을것
같은 기분이...

다른 스도쿠가 있는지는 모르겠지만 인터넷에서 찾아보니 전부
9x9의 형식이네요 그래서 이것도 마찬가지입니다.

with Ada.Text_IO;

procedure Sudoku is
	pragma Linker_Options("-s");

	package TIO renames Ada.Text_IO;

	subtype Sudoku_Index is Integer range -1..80;
	subtype Sudoku_Number is Character range '0'..'9';

	type Sudoku_Array is array(Sudoku_Index range 0..80) of Sudoku_Number;
	type Sudoku_Access is access Sudoku_Array;

	-- 다음 '0'의 첫번째 위치를 탐색.
	-- 그런장소가 없다면 -1을 리턴.
	function Search_Blank(
		Idx	: Sudoku_Index;
		Acs	: Sudoku_Access) return Sudoku_Index is
	begin
		for I in Idx..Acs'Last loop
			if Acs(I) = '0' then
				return I;
			end if;
		end loop;

		return -1;
	end Search_Blank;

	-- Num이 속한 행과 열 그리고 9 x 9의 행렬에서
	-- Num이 유효한지를 테스트.
	function Is_Valid(
		Num	: Sudoku_Number;
		Idx	: Sudoku_Index;
		Acs	: Sudoku_Access) return Boolean is
		
		I1, I2, I3	: Sudoku_Index;
	begin
 		-- Num이 위치한 같은 행의 첫번째 인덱스
		I1 := (Idx / 9) * 9;
 		-- Num이 위치한 같은 열의 첫번째 인덱스
		I2 := (Idx mod 9);
		-- Num이 속한 9 x 9배열의 왼쪽제일위의 인덱스
		I3 := ((Idx / 27) * 27) + (((Idx mod 9) / 3) * 3);

		for I in 0..8 loop
			if
				Acs(I1 + I) = Num or else
				Acs(I2 + (I * 9)) = Num or else
				Acs(I3 + ((I / 3) * 9) + (I mod 3)) = Num
			then
				return False;
			end if;
		end loop;

		return True;
	end Is_Valid;

	function Solve_Sudoku(
		Idx	: Sudoku_Index;
		Acs	: Sudoku_Access) return Boolean is

		I	: Sudoku_Index;
	begin
		I := Search_Blank(Idx, Acs);
		if I = -1 then
			return True;
		else
			for N in '0'..Sudoku_Number'Last loop
				if Is_Valid(N, I, Acs) then
					Acs(I) := N;
					if not (I + 1 in Sudoku_Index) then
						return True;
					elsif Solve_Sudoku(I + 1, Acs) then
						return True;
					end if;
				end if;
			end loop;
		end if;

 	              -- 현재의 함수에서의 테스트는 실패 원래의 값을 복구.
		-- 호출한 함수에서 아마 다른값을 시도할것. 
		Acs(I) := '0';
		return False;
	end Solve_Sudoku;

	procedure Put_Sudoku(Acs : in Sudoku_Access) is
	begin
		for I in Acs'Range loop
			if ((I mod 3) = 0) and not ((I mod 9) = 0) then
				TIO.Put(" ");
			elsif ((I mod 9) = 0) and not ((I mod 27) = 0)  then
				TIO.New_Line;
			elsif ((I mod 27) = 0) then
				TIO.New_Line(2);
			end if;
			TIO.Put(Acs(I));
		end loop;
		TIO.New_Line(2);
	end Put_Sudoku;

	procedure Get_Sudoku(Acs : in Sudoku_Access) is
		I	: Integer;
	begin
		I := 0;
		for J in Acs'Range loop
			if (J mod 9) = 0 then
				I := I + 1;
				TIO.Put("Line" & I'Img & " => ");
			end if;
			TIO.Get(Acs(J));
		end loop;
	end Get_Sudoku;

	Acs	: Sudoku_Access;
begin
	Acs := new Sudoku_Array;

	loop
		Get_Sudoku(Acs);
		TIO.New_Line;
		if Solve_Sudoku(Acs'First, Acs) then
			TIO.Put("Success!");
		else
			TIO.Put("Failure!");
		end if;
		Put_Sudoku(Acs);
	end loop;
end Sudoku;
익명 사용자의 이미지

이거 로그인이 안되어 있네요 쩝.....
혹시 위의 코드를 테스트 해보시려거든 ada컴파일러를 설치하시고
gnatmake sudoku 하시면 됩니다. 알아서 컴파일합니다.

입력은 그냥 한줄 9개의 문자를 공백없이 9번 입력하시면 됩니다.
300900200 Enter.
다음줄 입력...
요런식으로 ...

익명 사용자의 이미지

약간 수정합니다.
위의 Ada코드에서 Is_Valid 함수의 주석에 Num이 속한 9x9의 제일위의 인덱스가 아니라 3x3입니다.
그리고 Solve_Sudoku함수에서 for 루프문에 '0' 이아니라
'1'부터 시작입니다. 물론 상관이 없지만.....

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.