CodilityのLesson2をGoで解いてみた(続き)
概要
オンラインコーディングの試験であるCodilityのLesson2を自分なりに解いてみました。(続き) CyclicRotation coding task - Learn to Code - Codility
前提
以下の条件で配列が生成される
- 要素: N個
- シフト数: K回
- 要素は配列の終端に達した後、シフトすると先頭に移動する
func Solution(A []int, K int) []int
は 配列を取得すると、K回シフトさせた配列を返します。
アルゴリズムを組み立てる際の情報
- NとKの範囲は[0..100]
- 要素の整数範囲は[−1,000..1,000]
Sample Data
data1
A = [3, 8, 9, 7, 6]
K = 3
data2
A = [0, 0, 0]
K = 1
data3
A = [1, 2, 3, 4]
K = 4
Code
package main import ( "fmt" ) func main() { // 問題文の仮定リスト intList := []int{3, 8, 9, 7, 6} fmt.Println(`before:`, intList) fmt.Println(`rotated:`, Solution(intList, 3)) fmt.Println(``) intList = []int{0, 0, 0} fmt.Println(`before:`, intList) fmt.Println(`rotated:`, Solution(intList, 1)) fmt.Println(``) intList = []int{1, 2, 3, 4} fmt.Println(`before:`, intList) fmt.Println(`rotated:`, Solution(intList, 4)) fmt.Println(``) } // Solution の概要 // arg1: A []int [−1,000..1,000]の範囲の値をもつ[0..100]の要素数で構成された配列 // arg2: K int [0..100]の範囲をもつ数値 // return: arg1 を arg2 右側にシフトさせた配列 func Solution(A []int, K int) []int { // 要素数が0,もしくは1の場合シフトさせても結果が変わらないので // 早期リターンする if len(A) == 0 { return A } else if len(A) == 1 { return A } // 取り出した数値を確保する領域 var popInt = 0 // K回分要素を右にシフトさせる // 厳密には要素を取り出して、取り出す前の要素と取り出した要素を結合する for index := 0; index < K; index++ { // 終端から要素を取り出す popInt = A[len(A)-1] // 終端を取り除いた要素を作成 A = A[:len(A)-1] // 要素を先頭に追加した配列を結合して作成 A = append([]int{popInt}, A...) } return A }
結果 before: [3 8 9 7 6] rotated: [9 7 6 3 8] before: [0 0 0] rotated: [0 0 0] before: [1 2 3 4] rotated: [1 2 3 4]
解説
あまり書くことがありませんが、強いて言えば論理演算子を使わないことですかね。
論理演算子を使うと、頭の中でパターンを想定しなければなりませんが条件式が一つの時と比べて 考えることが多くなりバグを生む可能性が高くなります。
しょうもないヒューマンエラーを生んで悩む可能性を孕むよりは、多少の美しさは捨てるべきだと思っています。
美しさ = 可読性ではないですからね。