この記事はpaizaのプログラミング問題をPowerShellで解いてみようという試みの記事です。
paizaのプログラミング問題とは?
ブラウザ上でコードを書いて実行できる、無料プログラミング練習問題集です。
- 難易度別に問題を選ぶ
- 問題文を読んで、解答コードを書く
- 提出するとテストケースが実行されて結果をわかる
正解・不正解だけではなく、解答コード例や解説も見ることができるので、プログラミングの習得から復習まで活用できます
こんな人におすすめ
- プログラミングスキルの腕試しをしたい方
- プログラミングのスキルアップしたい方
- 新しい言語にチャレンジをしたい方
通常は問題をc言語やJavaなどで解くのですがPowerShellで解いてみます。
問題
長テーブルのうなぎ屋 (paizaランク B 相当)
問題:
東京の下町に長テーブルで有名な老舗うなぎ屋がありました。
そのうなぎ屋にはとても大きい長テーブルがあり、テーブルの周りにn個の座席が配置されています。
座席には、時計回りに1, 2, …, nと番号が振られています。
座席はテーブルの周りに配置されているので、座席番号nの座席と1の座席は隣接しています。
今、m個のグループの人達が座席に順番に座りに来ます。i番目(1≦i≦m)のグループの人数をa_i人とします。
彼らは、長テーブルに並んだ座席の内、ある連続するa_i個の座席に一斉に座ろうとします。
ただしお客さんは江戸っ子なので、それら座席のうち、いずれか一つでも既に先客に座られている座席があった場合、
一人も座らずにグループ全員で怒って帰ってしまいます。江戸っ子は気が早いんでぃ。
入力では、i番目のグループが座ろうとする連続した座席の位置は、整数b_iにより指定されます。
i番目のグループは、座席番号b_iの座席を始点として、そこから時計回りにa_i個分の座席に座ろうとします。
最後のグループが座りに来た後、無事に長テーブルの座席に着席出来ている人数を出力するプログラムを作成してください。
入力: 入力はm+1行から成ります。
1行目にはn(座席数)とm(グループ数)が半角スペース区切りで入力されます。
i+1行目(1≦i≦m)には2個の整数a_i(グループの人数)とb_i(着席開始座席番号)が半角スペース区切りで入力されます。
入力値最終行の末尾に改行が1つ入ります。
文字列は標準入力から渡されます
出力:
最後のグループが座りに来た後、無事に座席に着席出来ている人数を1行で出力してください。
解き方:
- 空席状況を管理する変数 (配列がよいでしょう) を用意し、すべて空席としてマーク
- グループが来店する度に、そのグループが座れるかどうかを判定
- 座席が円状になり最初の席と最後の席が隣り合っていることに注意
コード:
# 入力を標準入力から読み取る
$n,$m = (read-host).split()
$n = [int]$n
$m = [int]$m
# 座席の使用状況を管理する配列 すべて空席としてマーク(Falseは空いている、Trueは埋まっている)
$seats = @()
(1..$n) | %{$seats += $False}
# 座れた人数のカウンター
$seated_count = 0
# 来店グループの処理
(0..($m-1)) | %{
$a, $b = (read-host).split()
$a=[int]$a
$b=[int]$b
$b -= 1 # 座席番号を0始まりに変換
# グループが座ろうとする座席の範囲を計算
$can_seat = $True
(0..($a - 1)) | %{
if( $seats[($b + $_) % $n] -eq $True){
$can_seat = $False
}
}
# 座れる場合、座席をTrue(埋まっている)に更新
if($can_seat -eq $True) {
(0..($a - 1)) | %{ $seats[($b + $_) % $n] = $True}
$seated_count += $a
}
}
write-host "$seated_count"
コードの説明:
1.標準入力から読み込む:
$n,$m = (read-host).split()
$n = [int]$n
$m = [int]$m
- read-hostを使って標準入力から文字列を読み込み変数に格納します
2.文字列を比較:
$seats = @()
(1..$n) | %{$seats += $False}
- 座席の使用状況を管理する配列をすべて空席としてマーク
(Falseは空いている、Trueは埋まっている)
3.座れた人数のカウンター
$seated_count = 0
- 座れた人数のカウントを用意。回答用
3.来店グループの処理
(0..($m-1)) | %{
$a, $b = (read-host).split()
$a=[int]$a
$b=[int]$b
$b -= 1 # 座席番号を0始まりに変換
# グループが座ろうとする座席の範囲を計算
$can_seat = $True
(0..($a - 1)) | %{
if( $seats[($b + $_) % $n] -eq $True){
$can_seat = $False
}
}
# 座れる場合、座席をTrue(埋まっている)に更新
if($can_seat -eq $True) {
(0..($a - 1)) | %{ $seats[($b + $_) % $n] = $True}
$seated_count += $a
}
}
write-host "$seated_count"
- 来店グループをread-hostで受け取ります
- 後で処理しやすいように座席番号を-1します
- グループが座れるかどうかを判定
- 座れる場合は座席を埋めます。席数分をseated_countに+します
4.結果を出力
write-host "$seated_count"
終わりに
noteにPowerShellのサンプルコードの記事を書いています。そっちも見てね
PowerShellまとめ