こんにちは!じゃいごテックのあつしです。
今回はpaiza クラス・構造体メニュー から静的メンバという問題を解説します。
この問題集はクラスの静的メンバ(クラス変数)や継承に関する5個のSTEP問題(C~B級)とFINAL問題(B級)で構成されていて、STEP問題を解いて行けばFINAL問題も解けるはず!となっています。
この問題集はボリュームがありますので前半と後半で記事を分けます。
前半はコンストラクタ(initializeメソッド)とインスタンス変数の更新に関する問題です。
STEP問題を解いてみる(前半)
簡単な解説は付けていますが、難しいと感じたら下記の記事も参考にしてみて下さい。
STEP1: クラスの作成 (paizaランク C 相当)
STEP1 は指定されたインスタンス変数とインスタンスメソッドを持つクラスを定義し、入力されたデータでインスタンスメソッドを実行する問題です。
※ STEP2でコンストラクタを実装するので今回はゲッターとセッターを定義します。
Employeeクラス
- インスタンス変数
- 社員番号 @number : Integer (外部からの更新を許可)
- 名前 @name : String (外部からの更新を許可)
- インスタンスメソッド
- getnum : @number を返す
- getname : @name を返す
解答例
INPUT1 = <<~"EOS" 3 make 1 nana getnum 1 getname 1 EOS OUTPUT1 = <<~"EOS" 1 nana EOS INPUT2 = <<~"EOS" 7 make 2742 mako getnum 1 make 2782 taisei getname 2 make 31 megumi getname 1 getname 3 EOS OUTPUT2 = <<~"EOS" 2742 taisei mako megumi EOS class Employee # クラス外から @number, @name の更新を許可 attr_writer :number, :name def getnum @number end def getname @name end end def solve(input_data) # 入力データ受け取り _, *requests = input_data.split("\n") employees = [] result = [] requests.each do |request| method, number, name = request.split number = number.to_i case method when "make" # インスタンス化してデータを入力する employee = Employee.new employee.number = number employee.name = name # employee を employees に push する employees << employee when "getnum", "getname" # getnum 又は getname でデータを参照して result に push する result << employees[number - 1].public_send(method) end end # 処理結果を改行で連結し末尾に改行を加える result.join("\n") << "\n" end puts solve(STDIN.read) # [参考 確認用コード] # p solve(INPUT1) # > "1\nnana\n" # > p solve(INPUT1) == OUTPUT1 # > true # p solve(INPUT2) # > "2742\ntaisei\nmako\nmegumi\n" # > p solve(INPUT2) == OUTPUT2 # true
解答例: solveメソッドの処理内容
n件
の命令を受け取り、半角区切りで分割して配列requests
に格納します。配列requests
の先頭から順に命令の1個目の要素を調べます。"make"
ならEmployeeクラス
のインスタンスを生成します。インスタンス変数@number
にnumber
を代入します。インスタンス変数@name
にname
を代入します。インスタンスemployee
を配列employees
にpush
します。
"getnum"
か"getname"
ならpublic_sendメソッド
で該当メソッドを実行し、結果をresult
にpush
します。
- 処理結果を改行で連結して末尾に改行を加えて返します。
STEP2: コンストラクタ (paizaランク C 相当)
STEP2 は指定されたインスタンス変数とインスタンスメソッドを持つクラスを定義し、入力されたデータでインスタンスメソッドを実行する問題です。
※ STEP1と同じ問題ですが、コンストラクタ(initializeメソッド)でインスタンス変数を初期化します。
Employeeクラス
- インスタンス変数
- 社員番号 @number : Integer
- 名前 @name : String
- initializeメソッド(引数:number, name)
- @numberをnumberで初期化する
- @nameをnameで初期化する
- インスタンスメソッド
- getnum : @number を返す
- getname : @name を返す
解答例
INPUT1 = <<~"EOS" 3 make 1 nana getnum 1 getname 1 EOS OUTPUT1 = <<~"EOS" 1 nana EOS INPUT2 = <<~"EOS" 7 make 2742 mako getnum 1 make 2782 taisei getname 2 make 31 megumi getname 1 getname 3 EOS OUTPUT2 = <<~"EOS" 2742 taisei mako megumi EOS class Employee # インスタンス変数の初期化 def initialize(number, name) @number = number @name = name end def getnum @number end def getname @name end end def solve(input_data) # 入力データ受け取り _, *requests = input_data.split("\n") employees = [] result = [] requests.each do |request| method, number, name = request.split number = number.to_i case method when "make" # 引数に number, name を与えてインスタンス化して # employees に push する employees << Employee.new(number, name) when "getnum", "getname" # getnum 又は getname を呼び出して result に push する result << employees[number - 1].public_send(method) end end # 処理結果を改行で連結し末尾に改行を加える result.join("\n") << "\n" end puts solve(STDIN.read) # [参考 確認用コード] # p solve(INPUT1) # > "1\nnana\n" # p solve(INPUT1) == OUTPUT1 # > true # p solve(INPUT2) # > "2742\ntaisei\nmako\nmegumi\n" # p solve(INPUT2) == OUTPUT2 # > true
解答例: solveメソッドの処理内容
n件
の命令を受け取り、半角区切りで分割して配列requests
に格納します。配列requests
の先頭から順に命令の1個目の要素を調べます。"make"
なら続くパラメータ(number, name)を引数に与えてEmployeeクラス
のインスタンスを生成します。インスタンスemployee
を配列employees
にpush
します。
"getnum"
か"getname"
ならpublic_sendメソッド
で該当メソッドを実行し、結果をresult
にpush
します。
- 処理結果を改行で連結して末尾に改行を加えて返します。
STEP3: クラスのメンバの更新 (paizaランク C 相当)
STEP3 は指定されたインスタンス変数とインスタンスメソッドを持つクラスを定義し、入力されたデータでインスタンスメソッドを実行してインスタンス変数を更新する問題です。
※ メソッドが増えますがSTEP1, STEP2と同じような問題です。
Employeeクラス
- インスタンス変数
- 社員番号 @number : Integer
- 名前 @name : String
- initializeメソッド(引数: number, name)
- @numberをnumberで初期化する
- @nameをnameで初期化する
- インスタンスメソッド
- getnum : @number を返す
- getname : @name を返す
- change_num(引数: number) : @numberをnumberで更新する
- change_name(引数: name) : @nameをnameで更新する
解答例
INPUT1 = <<~"EOS" 4 make 3 nana getnum 1 change_num 1 5 getnum 1 EOS OUTPUT1 = <<~"EOS" 3 5 EOS INPUT2 = <<~"EOS" 12 make 2742 makoto getnum 1 make 2782 taro getname 1 getname 2 change_num 2 9927 change_name 1 mako getnum 2 make 31 meu change_name 3 meumeu getnum 3 getname 1 EOS OUTPUT2 = <<~"EOS" 2742 makoto taro 9927 31 mako EOS class Employee def initialize(number, name) @number = number @name = name end def getnum @number end def getname @name end def change_num(number) @number = number end def change_name(name) @name = name end end def solve(input_data) # 入力データ受け取り _, *requests = input_data.split("\n") employees = [] result = [] requests.each do |request| method, number, param = request.split number = number.to_i case method when "make" # 引数に number, name を与えてインスタンス化して # employees に push する employees << Employee.new(number, param) when "change_num" # 引数に整数にした param を与えて change_num を実行 employees[number - 1].change_num(param.to_i) when "change_name" # 引数に param を与えて change_name を実行 employees[number - 1].change_name(param) when "getnum", "getname" # getnum 又は getname でデータを参照して result に push する result << employees[number - 1].public_send(method) end end # 処理結果を改行で連結し末尾に改行を加える result.join("\n") << "\n" end puts solve(STDIN.read) # [参考 確認用コード] # p solve(INPUT1) # > "3\n5\n" # p solve(INPUT1) == OUTPUT1 # > true # p solve(INPUT2) # > "2742\nmakoto\ntaro\n9927\n31\nmako\n" # p solve(INPUT2) == OUTPUT2 # > true
解答例: solveメソッドの処理内容
n件
の命令を受け取り、半角スペースで分割して配列requests
に格納します。配列requests
の先頭から順に命令の1個目の要素を調べます。"make"
なら続くパラメータ(number, name
)を引数に与えてEmployeeクラス
のインスタンスを生成します。インスタンスemployee
を配列employees
にpush
します。
"change_num"
なら引数に整数にしたparamを
与えてchange_numメソッド
を実行します。"change_name"
なら引数にparam
を与えてchange_nameメソッド
を実行します。"getnum"
か"getname"
ならpublic_sendメソッド
で該当メソッドを実行し、結果をresult
にpush
します。
- 処理結果を改行で連結して末尾に改行を加えて返します。
今回のまとめ
前半はクラスの基礎的な問題を解きました。
- クラスの定義
- インスタンス変数(ゲッター・セッター)
- initializeメソッド(コンストラクタ)
- インスタンスメソッド
前半は復習的な問題でした。
後半は継承や特異メソッド(クラスメソッド)を扱います!