只今、独学でプログラミング勉強中です。
「プログラマ脳を鍛える数学パズル」という本を始めましたが2問目で悩んでいます。
本にはPHPでの回答は載っていないのでご教授いただきたいです。
問題は、
1000〜9999のうち、数字の各桁の間に四則演算の演算子を入れて計算し、その計算結果が元の数の桁を逆から並べた数字と同じになるものを考えます。(演算子を入れない場所があってもOK。ただし最低でも1つは入れる)
数字の各桁の間に四則演算の演算子を入れる例:
1234 → 1+23-4 = 3
9876 → 987+6 = 789
100〜999の場合:
351 → 351 = 153
621 → 621 = 126
886 → 8*86 = 688
この問題をPHPでやってみました。
PHP
1// 演算子を配列に格納(※条件に必要となる演算子は「*」のみ) 2$op = array('*', ''); 3 4for ($num = 1000; $num <= 9999; $num++) { 5 // 数値を1文字ずつ分解して配列に格納 6 $num_arr = str_split($num); 7 8 for ($i = 0; $i < count($op); $i++) { 9 for ($j = 0; $j < count($op); $j++) { 10 for ($k = 0; $k < count($op); $k++) { 11 // 式を文字列で生成 12 $temp = $num_arr[0] . $op[$i] . $num_arr[1] . $op[$j] . $num_arr[2] . $op[$k] . $num_arr[3]; 13 // 文字列式を計算 14 $calc_res = eval("return {$temp};"); 15 16 if (mb_strlen($temp) >= 5 && strrev($num) == $calc_res) { // 演算子は最低でも1つは入れる=5桁以上 17 print $num . "\n"; 18 } 19 } 20 } 21 } 22}
PHP5では上記で動いていたのですが、これをPHP7で実行すると以下のようなエラーが出ました。
Parse error: Invalid numeric literal in (ファイル名): eval()'d code on line 1
文字列式に「00」など先頭が0で始まる数字が含まれてしまうことでエラーが出ているのだろうと思い、以下のようにしてみたところ、一応うまく動きました。
PHP
1// 演算子を配列に格納(※条件に必要となる演算子は「*」のみ) 2$op = array('*', ''); 3 4for ($num = 1000; $num <= 9999; $num++) { 5 // 数値を1文字ずつ分解して配列に格納 6 $num_arr = str_split($num); 7 8 for ($i = 0; $i < count($op); $i++) { 9 for ($j = 0; $j < count($op); $j++) { 10 for ($k = 0; $k < count($op); $k++) { 11 // 式を文字列で生成 12 $temp = $num_arr[0]. $op[$i]. $num_arr[1]. $op[$j]. $num_arr[2]. $op[$k]. $num_arr[3]; 13 14 // 生成された式を演算子で分解し、先頭が0の数字は0を除外する 15 $re_temp = ''; 16 $temp = explode('*', $temp); 17 foreach ($temp as $val) { 18 if ($val != '*') { 19 $val = intval($val); 20 } 21 $re_temp .= $val. '*'; 22 } 23 $re_temp = substr($re_temp, 0, -1); 24 25 // 文字列式を計算 26 $calc_res = eval("return {$re_temp};"); 27 28 if (mb_strlen($re_temp) >= 5 && strrev($num) == $calc_res) { // 演算子は最低でも1つは入れる=5桁以上 29 print $num . "\n"; 30 } 31 32 } 33 } 34 } 35}
答えは正しく出たのですが、必要になる演算子が「*」のみというのが前提のかなり強引な方法です。
もっと良い方法があれば教えていただきたいです。
ちなみに、eval関数を使用するのは避けて逆ポーランド記法などを使って実装すべきかもしれませんが、ここではそれはまた別の話とさせてください。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/05/22 02:28
退会済みユーザー
2020/05/22 02:51 編集
2020/05/25 08:07
退会済みユーザー
2020/05/25 08:16
2020/05/25 23:21