Number Place(数独)とSwift 3 (3)

backtrack

グラフは、再帰的関数dropNum(index: Int)が呼ばれたときのindexの値を示しています。初期状態では、52個の埋めるべき空白があることに注意して下さい。

    func dropNum(index: Int) {
        var place = emptyPlaces[index]
        for num in 1...9 {
            if isSafeForNum(place: place, num: num) {
                table[place.row][place.col] = num
                putCount += 1
                if putCount == nplaces { return }
                dropNum(index: index+1)
                if putCount != nplaces {
                    place = emptyPlaces[index]
                    table[place.row][place.col] = 0
                    putCount -= 1
                }
            }
        }
    }

あなたは以下の95行をコピー・ペーストして、IBM Swift Sandboxというサイトで、このプログラムを試してみることができます。

backtrack2

struct Place {
    var row: Int = -1
    var col: Int = -1
}

class NumBoard {
    var table       = [[Int]]()
    var emptyPlaces = [Place]()
    var place       = Place()
    let nplaces : Int
    var putCount: Int

    init() {
        table = [[7,0,3, 0,0,0, 0,0,0],
                 [0,5,1, 3,7,0, 4,0,0],
                 [6,0,0, 0,1,0, 0,2,0],
                 [0,0,4, 6,0,0, 0,0,0],
                 [0,0,0, 0,0,7, 0,8,0],
                 [5,0,0, 2,3,1, 9,0,0],
                 [3,0,0, 0,2,4, 0,9,1],
                 [0,0,0, 0,0,0, 8,4,0],
                 [0,0,7, 0,9,0, 2,0,0]]
        for rr in 0...8 {
            for cc in 0...8 {
                if table[rr][cc] == 0 {
                    place.row = rr
                    place.col = cc
                    emptyPlaces.append(place)
                 }
            }
        }
        putCount = 0
        nplaces  = emptyPlaces.count
        myprint(table: table)
        print("nplaces = \(nplaces)")
    }

    func myprint(table: [[Int]]) {
        print("-----------------")
        for rr in 0...8 {
            for cc in 0...8 {
                if table[rr][cc] == 0 {
                    print(".", terminator: " ")
                } else {
                    print(table[rr][cc], terminator: " ")
                }
            }
            print("")
        }
        print("-----------------")
    }
    
    func isSafeForNum(place: Place, num: Int) -> Bool {
        for rr in 0...8 {
            if num == table[rr][place.col] { return false }
        }
        for cc in 0...8 {
            if num == table[place.row][cc] { return false }
        }
        let rowBase = (place.row / 3) * 3
        let colBase = (place.col / 3) * 3
        for rr in 0...2 {
            for cc in 0...2 {
                if num == table[rowBase+rr][colBase+cc] { return false }
            }
        }
        return true
    }

    func dropNum(index: Int) {
        var place = emptyPlaces[index]
        for num in 1...9 {
            if isSafeForNum(place: place, num: num) {
                table[place.row][place.col] = num
                putCount += 1
                if putCount == nplaces { return }
                dropNum(index: index+1)
                if putCount != nplaces {
                    place = emptyPlaces[index]
                    table[place.row][place.col] = 0
                    putCount -= 1
                }
            }
        }
    }

    func play() {
        dropNum(index: 0)
        myprint(table: table)
    }
}

// main program
let myboard = NumBoard()
myboard.play()

Number Place(数独)とSwift 3 (2)

numberplace2

プログラムは常にシンプルであるべきなのですが、まだその段階に達していません。

struct Place {
    var row: Int = -1
    var col: Int = -1
}

class NumBoard {
    var table       = [[Int]]()
    var emptyPlaces = [Place]()
    var place       = Place()
    let nplaces : Int
    var putCount: Int

    init() {
        table = [[7,0,3, 0,0,0, 0,0,0],
                 [0,5,1, 3,7,0, 4,0,0],
                 [6,0,0, 0,1,0, 0,2,0],
                 [0,0,4, 6,0,0, 0,0,0],
                 [0,0,0, 0,0,7, 0,8,0],
                 [5,0,0, 2,3,1, 9,0,0],
                 [3,0,0, 0,2,4, 0,9,1],
                 [0,0,0, 0,0,0, 8,4,0],
                 [0,0,7, 0,9,0, 2,0,0]]

        for rr in 0...8 {
            for cc in 0...8 {
                if table[rr][cc] == 0 {
                    place.row = rr
                    place.col = cc
                    emptyPlaces.append(place)
                 }
            }
        }
        putCount = 0
        nplaces = emptyPlaces.count
        myprint(table: table)
    }

    func myprint(table: [[Int]]) {
        print("-----------------")
        for rr in 0...8 {
            for cc in 0...8 {
                print(table[rr][cc], terminator: " ")
            }
            print("")
        }
        print("-----------------")
    }
    
    func isSafeForNum(place: Place, num: Int) -> Bool {
        for rr in 0...8 {
            if num == table[rr][place.col] { return false }
        }
        for cc in 0...8 {
            if num == table[place.row][cc] { return false }
        }
        let rowBase = (place.row / 3) * 3
        let colBase = (place.col / 3) * 3
        for rr in 0...2 {
            for cc in 0...2 {
                if num == table[rowBase+rr][colBase+cc] { return false }
            }
        }
        return true
    }

    func dropNum(index: Int) {
        /* could be better */
    }

    func play() {
        dropNum(index: 0)
        myprint(table: table)
    }
}

let myboard = NumBoard()
myboard.play()

ところで、あなたは以下のような行が気に入らないかもしれません。

let rowBase = (place.row / 3) * 3
let colBase = (place.col / 3) * 3
  for rr in 0...2 {
    for cc in 0...2 {
      if num == table[rowBase+rr][colBase+cc] { return false }
    }
  }

私の意見では、この方がずっと目に優しいと思います。3blockSizeに、そして、2blockSize-1に置き換えるよりは。

日は上り、日は沈む

Swift 3で、Number Placeを解くプログラムを書こうとしていたら、音楽が聞こえてきて私の集中力を奪いました。

Sunrise, sunset
Sunrise, sunset
Swiftly fly the years
One season following another
Laden with happiness and tears

swift3

プログラムは未だ完成していません。

Gmsh

gmsh

Gmshは、3次元の有限要素メッシュジェネレータです。

Gmshのフォーマットから、ElmerSolverのメッシュフォーマットに変換するのにElmerGridが用いられます。

% ElmerGrid 14 2 mesh.msh -autoclean

elmer4

solver input fileの一部です:

Equation 1
  Name = "Equation 1"
  Active Solvers(1) = 1
End

Material 1
  Name = "Aluminium (generic)"
  Heat expansion Coefficient = 23.1e-6
  Heat Conductivity = 237.0
  Sound speed = 5000.0
  Heat Capacity = 897.0
  Mesh Poisson ratio = 0.35
  Density = 2700.0
  Poisson ratio = 0.35
  Youngs modulus = 70.0e9
End

Boundary Condition 1
  Target Boundaries(1) = 1 
  Name = "BoundaryCondition 1"
  Temperature = 100.0
End

Boundary Condition 2
  Target Boundaries(1) = 2 
  Name = "BoundaryCondition 2"
  Temperature = 200.0
End

Boundary Condition 3
  Target Boundaries(1) = 3 
  Name = "BoundaryCondition 3"
  Temperature = 300.0
End

Elmer

elmer

Elmerは、オープンソースの物理シミュレーションソフトウェアです。

図は片端を固定された弾性梁を示しています。