Project Euler にチャレンジ:Problem 51 PHPでの解答

← Problem 50  Problem 52 →
<?php
// 8個素数になるためには、少なくとも2以下から始まらなければいけない。2,3,4,5,6,7,8,9
// 1の位は連続する数にはならない。
// 置き換えて素数になる数を8つ以上にするためには、置き換える数は3の倍数である必要がある。
// 最小は1111から

$i = 1111;

while(true)
{
	// 一桁目を除く残りの桁から、0,1,2 のいずれかで、同じ数が3つある。
	// 4つ、5つある場合はどれか3つを抽出する必要があるが、なんとなく考慮しなくても解ける気がする。
	$tmp = substr($i,0,-1);
	$tmp0 = substr_count($tmp,"0");
	$tmp1 = substr_count($tmp,"1");
	$tmp2 = substr_count($tmp,"2");
	if($tmp0 == 3 or $tmp1 == 3 or $tmp2 == 3)
	{
		$count = 1;
		// 同じ数が3つある場合に素数かどうかチェック
		if(check_prime($i))
		{
			if($tmp0 == 3)
			{
				$j = 0;
			}
			else if($tmp1 == 3)
			{
				$j = 1;
			}
			else
			{
				$j = 2;
			}
			$k = $j + 1;
			while($k <= 9)
			{
				$num = str_replace($j,$k,$tmp).substr($i,-1);
				if(check_prime($num))
				{
					$count++;
				}
				if($k - $count > 1)
				{
					break;
				}
				$k++;
			}
		}
		if($count == 8)
		{
			break;
		}
	}
	$i += 2;
}

echo $i."\n";

function check_prime($num)
{
        $flag = true;
        if($num % 2 != 0)
        {
                // 素数チェック
                $sqrt = sqrt($num);
                for($i = 3 ;$i <= $sqrt ; $i+=2)
                {
                        if($num % $i == 0)
                        {
                                $flag = false;
                                break;
                        }
                }
        }
        else
        {
                $flag = false;
        }
        return $flag;
}

?>
問題文