この記事はpaizaのプログラミング問題をPowerShellで解いてみようという試みの記事です。
paizaのプログラミング問題とは?
ブラウザ上でコードを書いて実行できる、無料プログラミング練習問題集です。
- 難易度別に問題を選ぶ
- 問題文を読んで、解答コードを書く
- 提出するとテストケースが実行されて結果をわかる
- 正解・不正解だけではなく、解答コード例や解説も見ることができるので、プログラミングの習得から復習まで活用できます
こんな人におすすめ
- プログラミングスキルの腕試しをしたい方
- プログラミングのスキルアップしたい方
- 新しい言語にチャレンジをしたい方
- 通常は問題をc言語やJavaなどで解くのですがPowerShellで解いてみます。
問題
mod7占い (paizaランク S 相当)
あなたは今、「mod7占い」というサービスを始めようと考えています。
mod7占いとは、整数が書かれた複数のカードの中から3枚を選び、そこに書かれた整数の和が7で割り切れるかどうかで運勢を決めようというものです。 カードは必ず異なる3枚を選ぶ必要があり、全てのカードには全て異なる数字が書かれています。
占いというからには、7で割り切れる組み合わせはそれなりに少なくする必要があります。 そこで、適当な複数のカードに対して、カードに書かれた3つの整数を足した和が7で割り切れるような組合せがいくつあるかを計算するプログラムを作成してください。
入力
入力は以下のフォーマットで与えられます。
N
a_1
a_2
...
a_N
N は与えられるカードの枚数を表します。
a_i (1 ≦ i ≦ N) はi 枚目のカードに書かれた整数であり、改行区切りでN 個与えられます。
解き方
- カードを7で割った余りで分類します
- 各要素が0 ~ 6からなる 3つ組 (a, b, c) であって、足すと和が7で割り切れるようなものを求めます
- それぞれの3つ組に対して、7で割った余りが (a, b, c) となるようにカードを3枚選ぶ方法が何通りあるかを求めます。それらを足し合わせたものが答えです
コード
#件数の入力
$n=[int](read-host)
#カードの整数の分類
$a=@()
(0..7) | %{$a+=0}
for($i=0;$i -lt $n;$i++){
$num = [int](read-host)
$a[$num%7]+=1
}
#組み合わせの列挙
[int[][]]$mod7_combinations = @()
[int[]]$mod7_combination = @()
for($i =0;$i -lt 7;$i++) {
for($j =$i;$j -lt 7;$j++) {
for($k =$j;$k -lt 7;$k++) {
if((($i + $j + $k) % 7) -eq 0){
$mod7_combination=($i, $j, $k)
$mod7_combinations+=,@($mod7_combination)
#write-host $mod7_combination
}
}
}
}
function wari($moto,$waru){
$cnt=0
while($moto -ge $waru){
$moto= $moto - $waru
$cnt+=1
}
return $cnt
}
$ans = 0
foreach($ijk in $mod7_combinations) {
$i=[int]$ijk[0]
$j=[int]$ijk[1]
$k=[int]$ijk[2]
if($i -eq $j -and $j -eq $k){
$ans += $a[$i] * $($a[$i] - 1) * $(wari ($a[$i] - 2) 6)
} elseif($i -eq $j){
$ans += $a[$i] * $($a[$i] - 1) * $(wari $a[$k] 2)
} elseif($j -eq $k){
$ans += $a[$i] * $($a[$j]) * $(wari ($a[$j] - 1) 2)
} elseif($k -eq $i){
$ans += $($a[$k] - 1) * $a[$j] * $(wari $a[$k] 2)
} else {
$ans += $a[$i] * $a[$j] * $a[$k]
}
}
write-host $ans
Sランクの問題はムズイです。
問題の意味がちょっと、何それ?意味あるの?みたいな。
それが競技プログラミングなんでしょうけど
終わりに
noteにPowerShellのサンプルコードの記事を書いています。そっちも見てね
PowerShellまとめ