HackerRankとは
- 課題を通じてプログラミング言語を学習できるサイト
- 無料
- 扱っている言語は多数
- その中の30Days of Codeというカリキュラムに挑戦
背景
- Goの基本的な書き方を学ぶために始めます
- 初心者です
- 自分の解答やEditorialの内容を基に書きます
Day 1 Data Types
ポイント
- 標準入力から整数、浮動少数点数、文字列を取得する
メモ
- 標準入力の取得にはfmtパッケージのScanf関数が使える
- 引数にアドレスを指定することで、スペース区切りで順繰りに値を格納してくれる
入力
12
4.0
//標準入力取得用変数
var stdin_i uint64
var stdin_f float64
//標準入力から整数と浮動少数点数を取得
fmt.Scanf("%d\n%f\n", &stdin_i, &stdin_f)
参考
-
文字列をscanf関数で扱うとき
- C言語を扱っているが考え方は同じ
Day 2 Operators
ポイント
- 入力された数値から簡単な演算を行い、四捨五入した整数を出力する
メモ
- 出力時にフォーマットを指定できる
fmr.Printf()
を使用する - 主なフォーマット指定方法
-
%v
デフォルトのフォーマット -
%f
浮動小数点型の桁数を指定-
%4.2f
では、4が幅、2が桁数を表す- 幅には整数部と小数点も含まれる
- 0.3333333なら、0.33と表示される
-
-
%b
ビット表示
-
Day 3 Intro to Conditional Statements
ポイント
- 入力された整数の値に応じて条件分岐をif文で記載する
Day 4 Class vs. Instance
ポイント
- 新しく宣言した型にメソッドを定義する
メモ
- 新しい型を宣言するときは、
type
を使用する- 新しい型を導入することでコードが読みやすくなったり、エラーを防ぎやすくなることがある
type age int
- 構造体を使って複数の値を1つのグループにまとめて定義することもできる
type person struct {
age int
name string
}
- メソットを使うと、関数を型に割り当てることができる
// person型のageフィールドに1を加算するメソッド
func (p person) yearPasses() person {
p.age += 1
return p
}
-
ここでの
(p person)
は「レシーバ」と呼ばれる -
メソッドを呼び出すときはドッド表記を使う
p := person{age : 8}
p = p.yearPasses
fmt.Print(p.age) //9
Day 5 Loops
ポイント
- for文の書き方と標準出力(Day2参照)
メモ
- 単純に
int
と宣言すると、ハードウェアに依存して32ビットや64ビットになる - ただし、
int
、int32
、int64
はそれぞれ別の型 - 型が違うと代入も演算もできない
Day 6 Let's Review
ポイント
- 標準入力の文字列を偶数番目の要素と奇数番目の要素に分けて出力する
メモ
- ここでは改行区切りの標準入力をbufioのScannerで読み込む
- 標準入力の取得 :
std_in := bufio.NewScanner(os.Stdin)
- 一行読み込み :
std_in.Scan()
- 読み込んだ行を文字列として取り出す :
std_in.Text()
- 標準入力の取得 :
参考
Day 7 Arrays
ポイント
- 入力された整数の配列を逆の順序で出力する
Day 8 Dictionaries and Maps
ポイント
- 標準入力から名前と電話番号から成るMapを作成
- その後入力される名前がマップに存在するかを判定する
メモ
- 初期化する必要がない場合は、make関数で割り当てる
phoneBook := make(map[string] string)
- これは、Key、ValueがどちらもStringのMapを表す
- マップに値を設定するには以下のようにする
- phoneBook["sam"] = "99912222"
- mapにStringを渡すと、値とbool値の2つが返ってくる
- 存在する場合に処理を行うときは、以下のようなif文を書く
if number, ok := phoneBook["sam"]; ok{
[マップにKeyが存在した場合の処理]
}
Day 9 Recursion 3
ポイント
- 入力された自然数
n
からn!
を出力する
メモ
- 遅延実行の
defer
-
defer
によって指定されたアクションは、その関数からリターンされる前に必ず実行されることが保証される - ファイルのクローズなどに使える
-
Day 10 Binary Numbers
ポイント
- 入力された自然数を二進数に変換し、最大で"1"がいくつ連続しているかを出力する
メモ
-
fmt.Sprintf
は指定した書式に合わせて文字列を返す- 5の二進数を文字列で取得する場合は、
fmt.Sprintf("%b", 5)
と記載すればよい
- 5の二進数を文字列で取得する場合は、
- 文字列中の個々の文字にアクセスすることができるが、返ってくるのはUnicodeの符号位置になる
- 例えば、
s="101"
という文字列に対し、s[1]
を出力すると48
が出力される - これは0の符号位置が48のためである
- 文字そのものを表示するには書式指定子に
%c
を指定すればよい - 先ほどのSprintfを使って、
c=fmt.Sprintf("%c", s[1])
とすれば、c
は0になる
- 例えば、
Day 11 2D Arrays
ポイント
- 6×6の二次元配列から、3×3の大きさの砂時計型で切り取れる部分の和を計算し、最大値を出力する
Day 20 Sorting
ポイント
- 整数の配列をバブルソートで並び替える
Day 25 Running Time and Complexity
ポイント
- 入力された自然数が素数であるかを判定する
Day 26 Nested Logic
ポイント
- 入力された2つの日付を比較する
メモ
- 指定されたDate型の変数を作成するには
time.Date()
を指定する- 引数には、年、月、日、時、分、秒、ナノ秒、タイムゾーンを指定する
targetDate := time.Date(2001, 2, 3, 4, 5, 6, 0, time.Local)
- 2つの日付を比較する場合はTime型のBeforeメソッド、Afterメソッドを使う
if timeA.Before(timeB) {...}
Day 28 RegEx, Patterns, and Intro to Databases
ポイント
- 入力される名前とメールアドレスから成る文字列から、メールアドレスがgmailのユーザーの名前だけを抽出し、アルファベット順にソートして出力する
メモ
- メールアドレスがgmailかどうかは後方一致で判定する
- 後方一致には
strings.HasSuffix
関数を使用する if strings.HasSuffix(emailID, "@gmail.com"){...}
- 後方一致には
- Stringの並び替えであれば、
sort.Strings
関数が使えるsort.Strings(gmailUser)