引き続き問題を解いていきます。
問題はプログラマ脳を鍛える数学パズルより。
今回の問題
問題
年月日をYYYYMMDDの8桁の整数で表したとき、これを2進数に変換して逆から並べ、さらに10進数に戻したとき、元の日付と同じ日付になるものを探してください。期間は、前回の東京オリンピック(1964年10月10日)から、次回の東京オリンピック(2020年7月24日)とします。
例)1966年7月13日
①YYYYMMDDのフォーマット→19669713
②2進数に変換→1001010111111111110101001
③2進数を逆から並べる→10010101111111111110101001
④逆から並べた2進数を10進数に戻す→19660713
1966年7月13日(最初の数)に戻る
実装手順
①対象の期間を1日おきループ出力する
②対象の日付を数値型に変換する
③10進数を2進数に変換する
④変換した2進数を反転させる
⑤反転した2進数を10進数に変換する
⑥対象の日付と④の10進数が一致するものを出力する
書いたPHPコードと出力結果
q07.php
<?php
$start = new Datetime('1964-10-10');
$end = new Datetime('2020-07-25');
$interval = new DateInterval('P1D');
$period = new DatePeriod($start, $interval, $end);
// ①対象の期間を1日おきループ出力する
foreach ($period as $date) {
// ②比較元の日付を数値型に変換
$original = (int)$date->format('Ymd');
// ③10進数から2進数に変換
$original_decbin = decbin($original);
// ④変換した2進数を反転させる
$original_decbin_reverse = strrev($original_decbin);
// ⑤反転した2進数を10進数に戻す
$original_decbin_reverse_bindec = bindec($original_decbin_reverse);
// ⑥比較元と比較対象が一致するものを出力する
if ($original === $original_decbin_reverse_bindec) {
echo $original;
echo '<br/>';
echo $original_decbin_reverse_bindec;
echo '<br/>';
}
}
// 結果
19660713
19660713
19660905
19660905
19770217
19770217
19950617
19950617
20020505
20020505
20130201
20130201
今回の学び
phpの日付処理はPHPで日付をループする方法と罠を参考にした。