こんにちは、ナナオです。
前回に引き続き競プロを実施していきたいと思います。
今回の問題は以下です。
デフォルト引数 | レベルアップ問題集 | プログラミング学習サイト【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())
}
}
まぁ競プロのコードにしては長いですが、業務コード感があって僕は割と好きです。
実装に時間はかかりましたが。。
ということで今回はこれで👍