PHP
アルゴリズム
競技プログラミング

プログラマ脳を鍛える数学パズル Q.7「日付の2進数変換」

More than 1 year has passed since last update.

引き続き問題を解いていきます。

問題はプログラマ脳を鍛える数学パズルより。


今回の問題


問題

年月日を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で日付をループする方法と罠を参考にした。