はじめに
こんにちは、野村です。
今回は、Javaを使っていくつかの数列を表示させてみます。
普通に書くのは面白くないので、ループ(forやwhile)を禁止してみました。
しかし、ソースがやたらと長くなるのは何とかならないものだろうか?
インストールと実行
インストール
環境はdebian9.2です。
とりあえず、現在のJavaのバージョンを表示してみたら
$ java -version openjdk version "1.8.0_151" OpenJDK Runtime Environment (build 1.8.0_151-8u151-b12-1~deb9u1-b12) OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode) $ javac -version bash: javac: コマンドが見つかりません
javacがなかった。
なので、default-jreとdefault-jdkをインストールしてみる。
$ sudo apt install default-jre $ sudo apt install default-jdk $ java -version openjdk version "1.8.0_151" OpenJDK Runtime Environment (build 1.8.0_151-8u151-b12-1~deb9u1-b12) OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode) $ javac -version javac 1.8.0_151
入りました。
実行
例えば、「sosu00.java」というファイルの場合、
ファイルをVimで開いて、コマンドモードに入って以下のコードを実行する。
:!javac %; java sosu00
素数
・1より大きい自然数で、正の約数が1と自分自身のみである数。
import java.util.stream.Stream;
import java.util.stream.IntStream;
import java.util.stream.Collectors;
import java.util.List;
public class sosu01{
private static List<Integer> sosu(List<Integer> b, int i){
int m = b.get(i);
if (m > Math.sqrt(b.get(b.size()-1))) return b;
return sosu(b.stream().filter(v -> (v%m!=0) || (v==m) )
.collect(Collectors.toList()), ++i);
}
private static void disp(List<Integer> a){
a.forEach(b->System.out.print(b+" "));
System.out.println();
}
public static void main(String[] args){
List<Integer> a = IntStream.range(2,100) // 100未満の素数を表示
.boxed().collect(Collectors.toList());
disp(sosu(a, 0));
}
}
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つの素数の組
import java.util.stream.Stream;
import java.util.stream.IntStream;
import java.util.ArrayList;
import java.util.List;
public class twin02{
private static Boolean chk(int a){
return IntStream.range(2,a).filter(v -> a%v==0).count() == 0;
}
private static List<int[]> loop(List<int[]> a, int f, int c, int i){
if (c<1) return a;
if (chk(i) && chk(i+f)){
int[] b = {i, i+f};
a.add(b);
--c;
}
return loop(a, f, c, i+1);
}
private static List<int[]> twin(int f, int c){
List<int[]> p = new ArrayList<int[]>();
return loop(p, f, c, 2);
}
private static void disp(List<int[]> a){
a.forEach(b->System.out.print("("+b[0]+","+b[1]+") "));
System.out.println();
}
public static void main(String[] args){
disp(twin(2,10)); // 双子素数を10組表示
disp(twin(4,10)); // いとこ素数を10組表示
disp(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)
幸運数
・ポーランドの数学者スタニスワフ・ウラムによって提案された数列。
・素数の性質を研究するために、素数に似たルールで導き出せる数列を考案したとのこと。
import java.util.stream.IntStream;
import java.util.stream.Collectors;
import java.util.List;
public class lucky00{
private static List<Integer> luc(List<Integer> a, int i){
a.add(0,0);
int s = a.get(i);
int l = a.size();
if (s<=l) {
List<Integer> m = IntStream.range(0,l).filter(v->v%s!=0)
.map(v->a.get(v)).boxed().collect(Collectors.toList());
return luc(m,i+1);
}
a.remove(0);
return a;
}
private static void disp(List<Integer> a){
a.forEach(b->System.out.print(b+" "));
System.out.println();
}
public static void main(String[] args){
List<Integer> a = IntStream.range(0,100).filter(v->v%2!=0)
.boxed().collect(Collectors.toList());
disp(luc(a,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 までのすべての整数の積。
import java.util.stream.IntStream;
public class fact00{
private static void disp(IntStream a){
a.forEach(b->System.out.print(b+" "));
System.out.println();
}
public static void main(String[] args){
IntStream a = IntStream.range(0,10).map(v->{ // 階乗を10個表示
return IntStream.range(1,v+1).reduce(1,(i,j)->i*j);
});
disp(a);
}
}
1 1 2 6 24 120 720 5040 40320 362880
フィボナッチ数
・フィボナッチ数:イタリアの数学者レオナルド・フィボナッチにちなんで名付けられた数
・リュカ数:フランスの数学者エドゥアール・リュカにちなんで名付けられた数
import java.util.stream.IntStream;
public class fibo00{
private static int loop(int a, int b, int c){
if (c==0) return a;
if (c==1) return b;
return loop(a,b,c-2)+loop(a,b,c-1);
}
private static IntStream fibo(int a, int b, int c){
return IntStream.range(0,c).map(v->loop(a,b,v));
}
private static void disp(IntStream a){
a.forEach(b->System.out.print(b+" "));
System.out.println();
}
public static void main(String[] args){
disp(fibo(0,1,10)); // フィボナッチ数を10個表示
disp(fibo(2,1,10)); // リュカ数を10個表示
}
}
0 1 1 2 3 5 8 13 21 34 2 1 3 4 7 11 18 29 47 76
パスカルの三角形
・二項展開における係数を三角形状に並べたもの。
import java.util.stream.IntStream;
import java.util.stream.Collectors;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
public class pas00{
private static List<Integer> pas(int a){
if (a==0) return new ArrayList<Integer>(Arrays.asList(1));
List<Integer> b = pas(a-1);
b.add(0,0);
b.add(b.size(),0);
return IntStream.range(1,b.size()).map(v->b.get(v-1)+b.get(v))
.boxed().collect(Collectors.toList());
}
private static void disp(List<Integer> a){
a.forEach(b->System.out.print(b+" "));
System.out.println();
}
public static void main(String[] args){
IntStream.range(0,10).forEach(v->disp(pas(v))); // パスカルの三角形を10段表示
}
}
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
最後に
以上、Javaを使っていくつかの数列を表示させてみました。
もっとソースを短く、わかりやすくできるはず。
Stream APIを勉強して書き直すかも。
というわけで、今回はこれにて。