Swiftで100マス計算を実装してみた
まず、実装したソースは以下のようになりました。
let col = [1,2,3,4,5,6,7,8,9,10] let row = [1,2,3,4,5,6,7,8,9,10] class Answer { let col: [Int] let row: [Int] let ans: [[Int]] init(col: [Int], row: [Int], ans: [[Int]]) { self.col = col; self.row = row; self.ans = ans; } } func hyakumasu(_ a:((_ x: Int,_ y: Int) -> Int), _ col: [Int], _ row: [Int]) -> Answer { return Answer(col: col, row: row, ans: col.map { (i) -> [Int] in row.map{ (j) -> Int in a(i, j) }}) } func showAns(_ ans: Answer) { let colAns = ans.ans.map{col -> String in col.map{ (a) -> String in ansFormat(a)}.reduce("", + ) } print(ansFormat(0) + ans.col.map{(a) -> String in ansFormat(a)}.reduce("", + )) for (a1, a2) in Zip2Sequence(_sequence1: ans.row, _sequence2: colAns) { print(ansFormat(a1) + a2) } } func ansFormat(_ ans: Int) -> String { return spaceSeq(4 - ans.description.count) + ans.description } func spaceSeq(_ x:Int) -> String { return [String](repeating: " ", count: x).reduce("", +) } showAns(hyakumasu(+, col, row)) print("") showAns(hyakumasu(*, col, row))
各処理について
計算結果を保持するためのクラスは以下のように定義しています。
class Answer { let col: [Int] let row: [Int] let ans: [[Int]] init(col: [Int], row: [Int], ans: [[Int]]) { self.col = col; self.row = row; self.ans = ans; } }
計算は以下の処理で行なっています。
func hyakumasu(_ a:((_ x: Int,_ y: Int) -> Int), _ col: [Int], _ row: [Int]) -> Answer { return Answer(col: col, row: row, ans: col.map { (i) -> [Int] in row.map{ (j) -> Int in a(i, j) }}) }
[Int]型の各行と列の要素同士に対して引数で受け取った(( x: Int, y: Int) -> Int)型の関数を適用するのは以下の処理になります。(( x: Int, y: Int) -> Int)型はInt型の引数を2つ受け取りInt型を返す関数になります。
col.map { (i) -> [Int] in row.map{ (j) -> Int in a(i, j) }})
それから計算結果をAnswer型にして返しています。
計算結果の各項目について、4文字詰でフォーマットして表示するため以下の関数を定義して4文字に足りない分はスペースを詰めて表示が崩れないようにしています。
func ansFormat(_ ans: Int) -> String { return spaceSeq(4 - ans.description.count) + ans.description } func spaceSeq(_ x:Int) -> String { return [String](repeating: " ", count: x).reduce("", +) }
計算結果の表示には以下の関数を使用しています。
func showAns(_ ans: Answer) { let colAns = ans.ans.map{col -> String in col.map{ (a) -> String in ansFormat(a)}.reduce("", + ) } print(ansFormat(0) + ans.col.map{(a) -> String in ansFormat(a)}.reduce("", + )) for (a1, a2) in Zip2Sequence(_sequence1: ans.row, _sequence2: colAns) { print(ansFormat(a1) + a2) } }
colAnsには計算結果のInt型の配列に対してフォーマットをかけて行毎で連結させて[String]にしたものをセットしています。
let colAns = ans.ans.map{col -> String in col.map{ (a) -> String in ansFormat(a)}.reduce("", + ) }
print(ansFormat(0) + ans.col.map{(a) -> String in ansFormat(a)}.reduce("", + ))
の部分では入力行の配列にフォーマットをかけておいて先頭に0を付与したものを表示しています。
for (a1, a2) in Zip2Sequence(_sequence1: ans.row, _sequence2: colAns) { print(ansFormat(a1) + a2) }
の部分では各列と列毎の計算結果をフォーマットしたものを連結して表示するようにしています。
計算をするときは以下のように適用する関数と行、列の関数を引数として渡しています。
showAns(hyakumasu(+, col, row)) print("") showAns(hyakumasu(*, col, row))
結果として以下のように計算結果が表示されるのが確認できます。
0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 11 2 3 4 5 6 7 8 9 10 11 12 3 4 5 6 7 8 9 10 11 12 13 4 5 6 7 8 9 10 11 12 13 14 5 6 7 8 9 10 11 12 13 14 15 6 7 8 9 10 11 12 13 14 15 16 7 8 9 10 11 12 13 14 15 16 17 8 9 10 11 12 13 14 15 16 17 18 9 10 11 12 13 14 15 16 17 18 19 10 11 12 13 14 15 16 17 18 19 20 0 1 2 3 4 5 6 7 8 9 10 1 1 2 3 4 5 6 7 8 9 10 2 2 4 6 8 10 12 14 16 18 20 3 3 6 9 12 15 18 21 24 27 30 4 4 8 12 16 20 24 28 32 36 40 5 5 10 15 20 25 30 35 40 45 50 6 6 12 18 24 30 36 42 48 54 60 7 7 14 21 28 35 42 49 56 63 70 8 8 16 24 32 40 48 56 64 72 80 9 9 18 27 36 45 54 63 72 81 90 10 10 20 30 40 50 60 70 80 90 100