LoginSignup
3
2

More than 5 years have passed since last update.

プログラマ脳を鍛える数学パズル Q.3「カードを裏返せ」

Last updated at Posted at 2018-04-28

前回記事に引き続き問題を解いていく。
問題はプログラマ脳を鍛える数学パズルより。

今回の問題

1~100までの番号が書かれた100枚のカードが順番に並べられています。最初、すべてのカードは裏返しの状態で置かれています。ある人が2番のカードが表を向くようになります。
次に、別の人が、3番のカードから2枚おきにカードを裏返していきます。また、別の人が、4番のカードから3番おきに、カードを裏返していきます。
このようにn番目のカードからn-1枚おきにカードを裏返す操作を、どのカードの向きも変わらなくなるまで続けたとします。
問題
カードの向きが変わらなくなったとき、裏向きになっているカードの番号をすべて求めてください。

実装手順

①1から100までのカードの配列を作成する。それぞれの番号に表裏の情報を付与する(今回はtrue, falseとする)。
②めくるカード(問題でいう「n」)のループ文を作成する。問題文の通り2から100までにする。
③実際にめくるカードを決めるループ文を作成する。
④めくるカードが表(true)の時は裏(false)に、裏の時は表にする条件文を書く
⑤結果を出力する

書いたPHPコードと出力結果

q03.php
<?php

$cards = [];

// ①表裏の情報を持つ1から100までのカード配列を作成する
for ($i = 1; $i <= 101; $i++) {
  array_push($cards, 'false');
  // 添字の番号とカード番号を合わせたいので、101枚作成して添字0のカードを削除する
  unset($cards[0]);
}

// ②nをループさせる
for ($number = 2; $number <= 100; $number++) {
  // ③nをn間隔でループさせてめくるカードを決める
  for ($i = $number; $i <= 100; $i += $number) {
    // ④めくるカードが表(true)の時は裏(false)に、裏の時は表にする
    if ($cards[$i] === 'true') {
      $cards[$i] = '';
      // 参照渡しをする
      $cards[$i] .= 'false';
    } elseif ($cards[$i] === 'false') {
      $cards[$i] = '';
      $cards[$i] .= 'true';
    }
  }
}

// ⑤結果を出力する
foreach ($cards as $key => $value) {
  if ($value === 'false') {
    echo $key;
    echo '<br/>';
  }
}

// 結果
1
4
9
16
25
36
49
64
81
100

できた~~:joy:
平方数が並んでいるのが何か大きな力を感じます

今回の学び

  • ループ文の中で配列の値を置換し出力する際に手間取ったが、「参照渡し」という概念があることを知った。
  • カードの表裏の状態を、カードの値とは別に持っておくと操作しやすい
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2