paizaの練習問題を解く RPG Go編
こんにちは、ナナオです。 前回に引き続き競プロを実施していきたいと思います。 今回の問題は以下です。 RPG | レベルアップ問題集 | プログラミング学習サイト【paizaラーニング】 実装 以下のように実装しました。 package main import "fmt" type Hero struct { l int h int a int d int s int c int f int } func main(){ var n, k int fmt.Scan(&n, &k) heroes := make([]Hero, n) for i := 0; i < n; i++ { fmt.Scan( &heroes[i].l, &heroes[i].h, &heroes[i].a, &heroes[i].d, &heroes[i].s, &heroes[i].c, &heroes[i].f, ) } for i := 0; i < k; i++ { var e string var j int fmt.Scan(&j, &e) switch e { case "levelup": var h, a, d, s, c, f int fmt.Scan(&h, &a, &d, &s, &c, &f) heroes[j - 1].l++ heroes[j - 1].h += h heroes[j - 1].a += a heroes[j - 1].d += d heroes[j - 1].s += s heroes[j - 1].c += c heroes[j - 1].f += f case "muscle_training": var h, a int fmt.Scan(&h, &a) heroes[j - 1].h += h heroes[j - 1].a += a case "running": var d, s int fmt.Scan(&d, &s) heroes[j - 1].d += d heroes[j - 1].s += s case "study": var c int fmt.Scan(&c) heroes[j - 1].c += c case "pray": var f int fmt.Scan(&f) heroes[j - 1].f += f } } for i := 0; i < n; i++ { fmt.Println( heroes[i].l, heroes[i].h, heroes[i].a, heroes[i].d, heroes[i].s, heroes[i].c, heroes[i].f, ) } } 条件分岐とかがちょっと長いですが、まぁ一つ構造体作ってあげればすぐ実装できました。 ...
paizaの練習問題を解く 出口のない迷路 Go編
こんにちは、ナナオです。 前回に引き続き競プロを実施していきたいと思います。 今回の問題は以下です。 出口のない迷路 | レベルアップ問題集 | プログラミング学習サイト【paizaラーニング】 実装 実装は以下の通りです。 package main import "fmt" type Location struct { Str string First int Second int } func main(){ var n, k, s int fmt.Scan(&n, &k, &s) var locs []Location for i := 0; i < n; i++ { var fst, scd int var str string fmt.Scan(&str, &fst, &scd) locs = append(locs, Location { Str: str, First: fst, Second: scd, }) } r := locs[s - 1].Str for i := 0; i < k; i++ { var m int fmt.Scan(&m) if m == 1 { s = locs[s - 1].First } else { s = locs[s - 1].Second } r += locs[s - 1].Str } fmt.Println(r) } 構造体で1番目、2番目の地点管理を行いました。たぶんこういうことでしょう。 解説を見たらfirst, secondという定義ではなく、roadという配列を構造体に定義していました。確かにそっちの方が実態に即しているか… ということで今回はこれで👍
paizaの練習問題を解く 静的メンバ Go編
こんにちは、ナナオです。 前回に引き続き競プロを実施していきたいと思います。 今回の問題は以下です。 静的メンバ | レベルアップ問題集 | プログラミング学習サイト【paizaラーニング】 実装 前回のデフォルト値と同じく、Goには静的メンバのような機能はありません。 ということで、普通に変数を定義してあげます。 package main import "fmt" // OrderAlCohol関数に対するデフォルト値設定のためのOptions構造体を定義 type OrderAlCoholOptions struct { Amount int } type OrderAlCoholOption func(*OrderAlCoholOptions) func Amount(amount int) OrderAlCoholOption { return func(opts *OrderAlCoholOptions) { opts.Amount = amount } } type Customer interface { OrderAlCohol(opts ...OrderAlCoholOption) OrderSoftdrink(amount int) OrderFood(amount int) GetTotalAmount() int } type Children struct { TotalAmount int } func (c *Children) OrderAlCohol(opts ...OrderAlCoholOption) { return } func (c *Children) OrderSoftdrink(amount int) { c.TotalAmount += amount } func (c *Children) OrderFood(amount int) { c.TotalAmount += amount } func (c *Children) GetTotalAmount() int { return c.TotalAmount } type Adult struct { Children HasOrderedAlcohol bool } func (a *Adult) OrderAlCohol(opts ...OrderAlCoholOption) { defaultOpts := &OrderAlCoholOptions { Amount: 500, } for _, opt := range opts { opt(defaultOpts) } a.TotalAmount += defaultOpts.Amount a.HasOrderedAlcohol = true } func (a *Adult) OrderSoftdrink(amount int) { a.TotalAmount += amount } func (a *Adult) OrderFood(amount int) { if a.HasOrderedAlcohol { a.TotalAmount += amount - 200 } else { a.TotalAmount += amount } } func main(){ var n, k int fmt.Scan(&n, &k) var c []Customer for i := 0; i < n; i++ { var age int fmt.Scan(&age) if age >= 20 { c = append(c, &Adult{ Children: Children{TotalAmount: 0}, HasOrderedAlcohol: false, }) } else { c = append(c, &Children{TotalAmount: 0}) } } // 退店した人の数 cnt := 0 for i := 0; i < k; i++ { var s, amount int var o string fmt.Scan(&s, &o) if o == "alcohol" { fmt.Scan(&amount) c[s - 1].OrderAlCohol(Amount(amount)) } else if o == "softdrink" { fmt.Scan(&amount) c[s - 1].OrderSoftdrink(amount) } else if o == "food" { fmt.Scan(&amount) c[s - 1].OrderFood(amount) } else if o == "0" { c[s - 1].OrderAlCohol() } else if o == "A" { fmt.Println(c[s - 1].GetTotalAmount()) cnt++ } } fmt.Println(cnt) } Goで静的メンバのような挙動をしたい場合、パッケージ変数を使うのがよいようです。 ...
paizaの練習問題を解く デフォルト引数 Go編
こんにちは、ナナオです。 前回に引き続き競プロを実施していきたいと思います。 今回の問題は以下です。 デフォルト引数 | レベルアップ問題集 | プログラミング学習サイト【paizaラーニング】 実装 Goにはデフォルト引数を設定するような機能はありません。 ということで以下のブログを参考にしながら実装します。 【Golang】関数でデフォルト引数を実現させる方法 | Functional Options Pattern | しーまんブログ 具体的にはFunctional Options Patternというのを使うのが一般的なようです。 package main import "fmt" // OrderAlCohol関数に対するデフォルト値設定のためのOptions構造体を定義 type OrderAlCoholOptions struct { Amount int } type OrderAlCoholOption func(*OrderAlCoholOptions) func Amount(amount int) OrderAlCoholOption { return func(opts *OrderAlCoholOptions) { opts.Amount = amount } } type Customer interface { OrderAlCohol(opts ...OrderAlCoholOption) OrderSoftdrink(amount int) OrderFood(amount int) GetTotalAmount() int } type Children struct { TotalAmount int } func (c *Children) OrderAlCohol(opts ...OrderAlCoholOption) { return } func (c *Children) OrderSoftdrink(amount int) { c.TotalAmount += amount } func (c *Children) OrderFood(amount int) { c.TotalAmount += amount } func (c *Children) GetTotalAmount() int { return c.TotalAmount } type Adult struct { Children HasOrderedAlcohol bool } func (a *Adult) OrderAlCohol(opts ...OrderAlCoholOption) { defaultOpts := &OrderAlCoholOptions { Amount: 500, } for _, opt := range opts { opt(defaultOpts) } a.TotalAmount += defaultOpts.Amount a.HasOrderedAlcohol = true } func (a *Adult) OrderSoftdrink(amount int) { a.TotalAmount += amount } func (a *Adult) OrderFood(amount int) { if a.HasOrderedAlcohol { a.TotalAmount += amount - 200 } else { a.TotalAmount += amount } } func main(){ var n, k int fmt.Scan(&n, &k) var c []Customer for i := 0; i < n; i++ { var age int fmt.Scan(&age) if age >= 20 { c = append(c, &Adult{ Children: Children{TotalAmount: 0}, HasOrderedAlcohol: false, }) } else { c = append(c, &Children{TotalAmount: 0}) } } for i := 0; i < k; i++ { var s, amount int var o string fmt.Scan(&s, &o) if o == "alcohol" { fmt.Scan(&amount) c[s - 1].OrderAlCohol(Amount(amount)) } else if o == "softdrink" { fmt.Scan(&amount) c[s - 1].OrderSoftdrink(amount) } else if o == "food" { fmt.Scan(&amount) c[s - 1].OrderFood(amount) } else if o == "0" { c[s - 1].OrderAlCohol() } } for i := 0; i < n; i++ { fmt.Println(c[i].GetTotalAmount()) } } まぁ競プロのコードにしては長いですが、業務コード感があって僕は割と好きです。 ...
paizaの練習問題を解く クラスの継承 Go編
こんにちは、ナナオです。 前回に引き続き競プロを実施していきたいと思います。 今回の問題は以下です。 クラスの継承 | レベルアップ問題集 | プログラミング学習サイト【paizaラーニング】 実装 以下のように実装しました。 package main import "fmt" type Customer interface { OrderAlCohol(amount int) OrderSoftdrink(amount int) OrderFood(amount int) GetTotalAmount() int } type Children struct { TotalAmount int } func (c *Children) OrderAlCohol(amount int) { return } func (c *Children) OrderSoftdrink(amount int) { c.TotalAmount += amount } func (c *Children) OrderFood(amount int) { c.TotalAmount += amount } func (c *Children) GetTotalAmount() int { return c.TotalAmount } type Adult struct { Children HasOrderedAlcohol bool } func (a *Adult) OrderAlCohol(amount int) { a.TotalAmount += amount a.HasOrderedAlcohol = true } func (a *Adult) OrderSoftdrink(amount int) { a.TotalAmount += amount } func (a *Adult) OrderFood(amount int) { if a.HasOrderedAlcohol { a.TotalAmount += amount - 200 } else { a.TotalAmount += amount } } func main(){ var n, k int fmt.Scan(&n, &k) var c []Customer for i := 0; i < n; i++ { var age int fmt.Scan(&age) if age >= 20 { c = append(c, &Adult{ Children: Children{TotalAmount: 0}, HasOrderedAlcohol: false, }) } else { c = append(c, &Children{TotalAmount: 0}) } } for i := 0; i < k; i++ { var s, amount int var o string fmt.Scan(&s, &o, &amount) if o == "alcohol" { c[s - 1].OrderAlCohol(amount) } else if o == "softdrink" { c[s - 1].OrderSoftdrink(amount) } else if o == "food" { c[s - 1].OrderFood(amount) } } for i := 0; i < n; i++ { fmt.Println(c[i].GetTotalAmount()) } } Goの場合継承が通じないのでインターフェースを定義することで解決しました。 ...
paizaの練習問題を解く クラスのメンバの更新 Go編
こんにちは、ナナオです。 前回に引き続き競プロを実施していきたいと思います。 今回の問題は以下です。 クラスのメンバの更新 | レベルアップ問題集 | プログラミング学習サイト【paizaラーニング】 実装 以下のように実装しました。 package main import "fmt" type Emplpyee struct { number int name string } func NewEmployee(number int, name string) *Emplpyee { return &Emplpyee{ number: number, name: name, } } func (e Emplpyee) GetNum() int { return e.number } func (e Emplpyee) GetName() string { return e.name } func (e *Emplpyee) ChangeNum(number int) { e.number = number } func (e *Emplpyee) ChangeName(name string) { e.name = name } func main(){ var n int fmt.Scan(&n) var es []Emplpyee for i := 0; i < n; i++ { var cmd string fmt.Scan(&cmd) if cmd == "make" { var number int var name string fmt.Scan(&number, &name) es = append(es, *NewEmployee(number, name)) } else if cmd == "getnum" { var j int fmt.Scan(&j) fmt.Println(es[j - 1].GetNum()) } else if cmd == "getname" { var j int fmt.Scan(&j) fmt.Println(es[j - 1].GetName()) } else if cmd == "change_num" { var j, num int fmt.Scan(&j, &num) es[j - 1].ChangeNum(num) } else if cmd == "change_name" { var j int var name string fmt.Scan(&j, &name) es[j - 1].ChangeName(name) } } } 前回のコードにセッターを追加しました。 ...
paizaの練習問題を解く コンストラクタ Go編
こんにちは、ナナオです。 前回に引き続き競プロを実施していきたいと思います。 今回の問題は以下です。 コンストラクタ | レベルアップ問題集 | プログラミング学習サイト【paizaラーニング】 実装 以下のように実装しました。 package main import "fmt" type Emplpyee struct { number int name string } func NewEmployee(number int, name string) *Emplpyee { return &Emplpyee{ number: number, name: name, } } func (e Emplpyee) GetNum() int { return e.number } func (e Emplpyee) GetName() string { return e.name } func main(){ var n int fmt.Scan(&n) var es []Emplpyee for i := 0; i < n; i++ { var cmd string fmt.Scan(&cmd) if cmd == "make" { var number int var name string fmt.Scan(&number, &name) es = append(es, *NewEmployee(number, name)) } else if cmd == "getnum" { var j int fmt.Scan(&j) fmt.Println(es[j - 1].GetNum()) } else if cmd == "getname" { var j int fmt.Scan(&j) fmt.Println(es[j - 1].GetName()) } } } 前回と少し異なるのは、コンストラクタ(NewEmployee)を実装したところです。 ...
paizaの練習問題を解く クラスの作成 Go編
こんにちは、ナナオです。 前回に引き続き競プロを実施していきたいと思います。 今回の問題は以下です。 クラスの作成 | レベルアップ問題集 | プログラミング学習サイト【paizaラーニング】 実装 以下のように実装しました。 package main import "fmt" type Employee struct { number int name string } func (e Employee) GetNumber() int { return e.number } func (e Employee) GetName() string { return e.name } func main(){ var n int fmt.Scan(&n) var es []Employee for i := 0; i < n; i++ { var c string fmt.Scan(&c) if c == "make" { var e Employee fmt.Scan(&e.number, &e.name) es = append(es, e) } else if c == "getname" { var ind int fmt.Scan(&ind) fmt.Println(es[ind - 1].GetName()) } else if c == "getnum" { var ind int fmt.Scan(&ind) fmt.Println(es[ind - 1].GetNumber()) } } } ゲッターを実装するだけなので簡単ですね。 ということで今回はこれで👍
paizaの練習問題を解く 構造体の更新 Go編
こんにちは、ナナオです。 前回に引き続き競プロを実施していきたいと思います。 今回の問題は以下です。 構造体の更新 | レベルアップ問題集 | プログラミング学習サイト【paizaラーニング】 実装 以下のように実装しました。 package main import "fmt" type User struct { nickname string old int birth string state string } func (u *User) ChangeName(nickname string) { u.nickname = nickname } func (u User) Printf() { fmt.Printf("%s %d %s %s\n", u.nickname, u.old, u.birth, u.state) } func main(){ var n, k int fmt.Scan(&n, &k) u := make([]User, n) for i := 0; i < n; i++ { fmt.Scan(&u[i].nickname, &u[i].old, &u[i].birth, &u[i].state) } for i := 0; i < k; i++ { var m int var nn string fmt.Scan(&m, &nn) u[m - 1].ChangeName(nn) } for i := 0; i < n; i++ { u[i].Printf() } } goのセッター実装は初めてだったのでよくわかりませんでしたが、ポインタレシーバをつければいいだけでしたね。 ということで今回はこれで👍
paizaの練習問題を解く 構造体の整列 Go編
こんにちは、ナナオです。 前回に引き続き競プロを実施していきたいと思います。 今回の問題は以下です。 構造体の整列 | レベルアップ問題集 | プログラミング学習サイト【paizaラーニング】 実装 以下のように実装しました。 package main import ( "fmt" "sort" ) type User struct { nickname string old int birth string state string } func (u User) Printf() { fmt.Printf("%s %d %s %s\n", u.nickname, u.old, u.birth, u.state) } func main(){ var n int fmt.Scan(&n) u := make([]User, n) for i := 0; i < n; i++ { fmt.Scan(&u[i].nickname, &u[i].old, &u[i].birth, &u[i].state) } sort.Slice(u, func(i, j int) bool { return u[i].old < u[j].old }) for _, v := range u { v.Printf() } } sortパッケージを使うと楽に実装できますね。 ということで今回はこれで👍