PHP7を使っていろんな数列を書き出してみる

はじめに

こんにちは、野村です。

今回は、PHP7を使っていくつかの数列を書き出してみます。

PHPって、こういった用途にはあまり適してないイメージがあったけど、いろいろできるようになってました。

インストール

管理ユーザになって以下のコマンドを実行。

# apt install php-cli

「apt install php」では、apacheなど不要なものまでインストールされてしまう。
今回はスクリプトを走らせるだけでいいので「php-cli」をインストールしました。

素数

・1より大きい自然数で、正の約数が1と自分自身のみである数。

<?php
function sosu($a){
  $s = $a[0];
  if ($s>sqrt(end($a))) return $a;
  $b = array_values(array_filter($a, function($v)use($s){
    return $v%$s!=0;
  }));
  return array_merge(array($s),sosu($b));
}

echo join(",",sosu(range(2,100-1))); // 100未満の素数を表示
2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97

双子素数

・双子素数:差が2である2つの素数の組
・いとこ素数:差が4である2つの素数の組
・セクシー素数:差が6である2つの素数の組

<?php
function disp($a, $f){
  foreach ($a as $v) printf("(%d,%d) ",$v-$f, $v);
  echo "\n";
}

function twin($f, $c){
  $loop = function($a, $j)use(&$loop, $f){
    $k = array_filter($a, function($x)use($j){return $j%$x==0;});
    if (count($k)==0){
      $a[] = $j;
      $h = $j-$f;
      $g = array_filter($a, function($x)use($h){return $x==$h;});
      if (count($g)>0) return $a;
    }
    return $loop($a,$j+1);
  };
  $r = array_reduce(range(0,$c-1), function($m,$n)use(&$loop){
    $x = $loop($m[0], end($m[0])+1);
    return array($x, array_merge($m[1],array(end($x))));
  }, array(array(2),array()));
  disp($r[1], $f);
}

twin(2,10); // 双子素数を10組表示
twin(4,10); // いとこ素数を10組表示
twin(6,10); // セクシー素数を10組表示
(3,5) (5,7) (11,13) (17,19) (29,31) (41,43) (59,61) (71,73) (101,103) (107,109)
(3,7) (7,11) (13,17) (19,23) (37,41) (43,47) (67,71) (79,83) (97,101) (103,107)
(5,11) (7,13) (11,17) (13,19) (17,23) (23,29) (31,37) (37,43) (41,47) (47,53)

幸運数

・ポーランドの数学者スタニスワフ・ウラムによって提案された数列。
・素数の性質を研究するために、素数に似たルールで導き出せる数列を考案したとのこと。

<?php
function luc($a, $n){
  $c = array_merge(array(0),$a);
  $g = $c[$n];
  $b = array_values(array_filter($c, function($k)use($g){
    return $k%$g!=0;}, ARRAY_FILTER_USE_KEY));
  return ($b[$n]<count($b)+1) ? luc($b,$n+1) : $b;
}

// 100未満の幸運数を表示
echo join(",",luc(array_values(array_filter(range(0,100-1)
 ,function($v){return $v%2!=0;})),2));
1,3,7,9,13,15,21,25,31,33,37,43,49,51,63,67,69,73,75,79,87,93,99

階乗

・1 から n までのすべての整数の積。

<?php
$fact = function($v){
  if ($v<1) return 1;
  return array_product(range(1,$v));
};
$a = range(0,10-1); // 階乗を10個表示
echo join(",", array_map($fact, $a));
1,1,2,6,24,120,720,5040,40320,362880

フィボナッチ数

・フィボナッチ数:イタリアの数学者レオナルド・フィボナッチにちなんで名付けられた数
・リュカ数:フランスの数学者エドゥアール・リュカにちなんで名付けられた数

<?php
function fibo($a,$b,$c){
  if ($c==0) return $a;
  if ($c==1) return $b;
  return fibo($a,$b,$c-2)+fibo($a,$b,$c-1);
}

function disp($a,$b,$c){
  echo join(",",array_map(function($v)use($a,$b){
    return fibo($a,$b,$v);
  },range(0,$c-1)));
  echo "\n";
}
disp(0,1,10); // フィボナッチ数を10個表示
disp(2,1,10); // リュカ数を10個表示
0,1,1,2,3,5,8,13,21,34
2,1,3,4,7,11,18,29,47,76

パスカルの三角形

・二項展開における係数を三角形状に並べたもの。

<?php
function pas($a){
  if ($a==0) return array(1);
  $b = pas($a-1);
  $c = array_merge(array(0),$b);
  $d = array_merge($b,array(0));
  return array_map(function($x,$y){return $x+$y;},$c,$d);
}

foreach(range(0,10-1) as $v){ // パスカルの三角形を10段表示
  echo join(",",pas($v));
  echo "\n";
}
1
1,1
1,2,1
1,3,3,1
1,4,6,4,1
1,5,10,10,5,1
1,6,15,20,15,6,1
1,7,21,35,35,21,7,1
1,8,28,56,70,56,28,8,1
1,9,36,84,126,126,84,36,9,1

終わりに

以上、PHP7でいくつかの数列を書き出してみました。

PHPを触ったのは数年ぶり。
随分と進化してる印象です。

PHPを書いているとつい変数に$を付け忘れてしまう。
以前はそんなことなかったのにな。

というわけで今回はこれにて。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

野村 野村のプロフィール
メインPCはWindows10のVirtualBox上のFreeBSD。Linux/Unixの小ネタを求めて日々右往左往してたりする。