この記事はpaizaのプログラミング問題をPowerShellで解いてみようという試みの記事です。
paizaのプログラミング問題とは?
ブラウザ上でコードを書いて実行できる、無料プログラミング練習問題集です。
- 難易度別に問題を選ぶ
- 問題文を読んで、解答コードを書く
- 提出するとテストケースが実行されて結果をわかる
正解・不正解だけではなく、解答コード例や解説も見ることができるので、プログラミングの習得から復習まで活用できます
こんな人におすすめ
- プログラミングスキルの腕試しをしたい方
- プログラミングのスキルアップしたい方
- 新しい言語にチャレンジをしたい方
通常は問題をc言語やJavaなどで解くのですがこの記事ではPowerShellで解いてみます。
問題
本の整理 (paizaランク A 相当)
あなたはパイザ図書館で働く図書館員です。
パイザ図書館には N 冊の蔵書があります。この蔵書はすべて 1 段からなる本棚で管理されています。そして、それぞれの本には 1 から N までの相異なる整数の ID がついています。本棚の本は ID 順に並んでいます。
しかし、ある日、あなたが蔵書の点検をしていると、本棚の本がバラバラに並べられていることに気づきました。
そこで、あなたは、次のルールに従って本を並び替えることにしました。
次の手順を N 回繰り返す。
- i (1 ≦ i ≦ N) 回目の手順では、まず本棚の左から i 番目の位置に立つ。
- 左から i 番目の位置にある本から、本棚の右端にある本までのうち、最も ID が小さい本の位置を歩きながら見つける。この位置を j とする。
- i = j なら、何もしない。 i ≠ j なら、i 番目の本と j 番目の本を入れ替える。
本を取り出して入れ替えるのには時間がかかります。そこで、このルールに従って本を整理するときに、何回本を入れ替える必要があるのかを計算してください。
解き方:
問題文にあるようにn回ループしてi番目の本を順に交換して交換回数を出力します。
コード:
# 本の初期位置入力
$n = [int](read-host)
$shelf = @()
foreach($i in (read-host).split()){
$shelf+=([int]($i)-1)
}
# 各本の位置を記録する配列を用意
$pos = @()
(1..$n) | %{$pos+=-1}
(0..($n-1)) | %{$pos[$shelf[$_]]=$_}
# 解答用変数 本の交換回数
$swapcnt = 0
# 本を並び替える
(0..($n-1)) | %{
# 既に正しい位置にある本はスキップ
if($shelf[$_] -ne $_){
# 交換回数カウントアップ
$swapcnt += 1
# i番目の本と現在の位置の本を交換
$shelf[$pos[$_]] = $shelf[$_]
$pos[$shelf[$_]] = $pos[$_]
}
}
write-host $swapcnt
コードの説明:
- 標準入力から本の初期位置を読み込む:
$n = [int](read-host)
$shelf = @()
foreach($i in (read-host).split()){
$shelf+=([int]($i)-1)
}
配列shelf に入力値を格納する際にプログラム内で扱いやすいように本のID を -1 しています。
- 標準入力から本の初期位置を読み込む:
# 各本の位置を記録する配列を用意
$pos = @()
(1..$n) | %{$pos+=-1}
(0..($n-1)) | %{$pos[$shelf[$_]]=$_}
計算用の配列posを用意して初期値をセットします。
(1..n)と書くとn回ループ、ループ変数は$_
- 本の交換回数を保存する変数を用意
# 解答用変数 本の交換回数
$swapcnt = 0
- 本を並び替える
# 本を並び替える
(0..($n-1)) | %{
# 既に正しい位置にある本はスキップ
if($shelf[$_] -ne $_){
# 交換回数カウントアップ
$swapcnt += 1
# i番目の本と現在の位置の本を交換
$shelf[$pos[$_]] = $shelf[$_]
$pos[$shelf[$_]] = $pos[$_]
}
}
本の位置が正しい場合はスキップ、違う場合は位置交換を行い、交換回数をカウントアップしていきます。
- 解答の出力
write-host $swapcnt
終わりに
noteにPowerShellのサンプルコードの記事を書いています。そっちも見てね
PowerShellまとめ