【理系大学生】yomiakiのラクガキ

徒然なるままによみあき

【プログラミング】JavaScript勉強記 ep5 ~素数を数えろ~

<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>勉強記 ep5 ~<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%C7%BF%F4">素数</a>を数えろ~

JavaScript勉強記 ep5 ~素数を数えろ~

youtu.be

素数が次々と表示されるというものを作りました。

落ち着けるかもしれません。

快眠の手助けとなるかもです。(多分…。)

 

素数(Prime Number)って?

2,3,5,7,11,13...のように「1と自分自身以外に約数を持たない数」のことをいいます。

しかし、1は例外で素数ではありません。これは、もし1が素数だと素因数分解したときの一意性が保てなくなるからです(…って数学ガールに書いてありました…。)

(例えば、12を素因数分解すると、12=(2^2)*3 ですが、もし1が素数となると、12=(1^2)*(2^2)*3 と表せられたり、12=(1^3)*(2^2)*3 と表せられたり, いろんなパターンが存在してしまうのでアカンというわけです。)

1のことも考えてあげると、素数は「約数の個数が2つのみの数」と言い換えられます。

 

コード

コードは次のようになっています。

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>素数を数えて落ち着くんだ</title>
<style>
body {
	background-color: #000;
	padding: 0px;
	margin: 0px;
	position:relative;
	width: 100vw;
	height:100vh;
}
#opening {
	color: #fff;
	font-size: 1em;
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
}
#prime {
	display : block;
	color: #fff;
	text-shadow: 0 0 30px #fff;
	background-color: #000;
	font-size: 1000%;
	opacity:1;
	position: absolute;
	top: 50%;
	left: 50%;
	transform-origin: center;
	transform: translate(-50%, -50%);
}
#button {
	display : none;
	border-radius : 5%;          /* 角丸       */
	font-size : 18pt;        /* 文字サイズ */
	text-align : center;      /* 文字位置   */
	cursor : pointer;     /* カーソル   */
	padding : 15px 35px;   /* 余白       */
	background : #000000;     /* 背景色     */
	color : #ffffff;     /* 文字色     */
	line-height : 1em;         /* 1行の高さ  */
	transition : .3s;         /* なめらか変化 */
	border : 2px solid #000000;    /* 枠の指定 */
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	opacity: 0;
	z-index: 1;
}
</style>
</head>

<body>
<div id="prime"></div>
<div id="opening">素数を数えて落ち着くんだ - プッチ神父</div>
<form>
<input type="button" value="素数を数える" id="button" onclick="myStart()">
</form>
</body>
<script>
//アニメーションのための要素の取得
const prime=document.querySelector("#prime");
const openig=document.querySelector("#opening");
const button=document.querySelector("#button");

//初期値定義
j=2;

//オープニングの動き
function myOpening(){
	//アニメーション
	opening.animate(
	[	{opacity:0},
		{opacity:1},
	 	{opacity:1},
		{opacity:1},
	 	{opacity:0}
	 ],
	{
		duration:3000,
		fill:"forwards",
	}
	);
	//アニメーション後の動き
	setTimeout(function(){
		document.getElementById("button").style.display= "block";
		button.animate(
	[	{opacity:0},
		{opacity:1}
	 ],
	{
		duration:3000,
		fill:"forwards",
	}
	);	
	},3500);
};	

//素数判定の関数
function primeNumberDetection(n) {
 if (n === 2) return true;
 for (let i = 2; i < n; i++) {
   if (n % i === 0) return false;
 }
 return true;
}

//カウントスタート
function myStart(){
	//スタートボタン無効化
	document.getElementById("button").disabled = true;
	
	//スタートボタンのアニメーション
	button.animate(
	[	{opacity:1},
		{opacity:0}
	 ],
	{
		duration:3000,
		fill:"forwards",
	}
	);
	
	//アニメーション後の動き
	setTimeout(mySet, 3500);
}	

//素数の代入
function mySet(){
	while(primeNumberDetection(j)==false){
		j++;
	};
	if(primeNumberDetection(j)==true){
	    document.getElementById("prime").innerHTML=j;
		j++;
	    fade();
	   };
	};

//素数のフェードインフェードアウト	
function fade(){
	//アニメーション
	prime.animate(
	[	{opacity:0,},
		{opacity:1,},
	 	{opacity:1,},
		{opacity:1,},
	 	{opacity:0,}
	 ],
	{
		duration:3000,
		fill:"forwards",
	}
	);
	
	//次の素数代入へ
	setTimeout(mySet, 3500);
	};

//開いたときに動かす
myOpening();
	
</script>
</html>

 

CSS

スタイルを最初のhead内に書いておきます。

position: absolute;
top: 50%;
left: 50%;
transform-origin: center;
transform: translate(-50%, -50%);

それぞれの要素が画面のど真ん中に来るように設定します。

buttonのCSSsubmitボタンをデザインするを用いてコピペしました。

 

HTML

空のprimeというidと「素数を数えて落ち着くんだ - プッチ神父」という名台詞(ジョジョまだ観てないから観たい…)をopeningのidに定めます。

スタートボタンのフォームをクリック時にmyStartが動くように作っておきます。

 

JavaScript

const prime=document.querySelector("#prime");
const openig=document.querySelector("#opening");
const button=document.querySelector("#button");

ここで最初に後々アニメーションをするために、それぞれの要素を取得しておきます。

j=2;

素数が代入される変数をjとして、最初の素数2を初期値としておきます。

 

関数myOpeningについて

ここでオープニングの動きを記述します。

opening.animate(
[ {opacity:0},
{opacity:1},
{opacity:1},
{opacity:1},
{opacity:0}
],
{
duration:3000,
fill:"forwards",
}
);

ここでopenigのテキストのフェードインフェードアウトをアニメーションします。

setTimeout(function(){
document.getElementById("button").style.display= "block" ;
button.animate(
[ {opacity:0},
{opacity:1}
],
{
duration:3000,
fill:"forwards",
}
);
},3500);

ここでアニメーション後の動きをsetTimeout関数を使って決めています。

document.getElementById("button").style.display= "block";

ここでスタートボタンを有効にします。

 

関数primeNumberDetection(n)について

ここで素数の判定を行います。

ある数nを判定しようとしたら、forループで2からn-1までの数で割っていって、割り切れるものがなければ、nは素数となるという仕組みです。

素数だとtrueを返して、素数でないとfalseを返します。

 

関数myStartについて

スタートボタンを押した後の動きを記述します。

document.getElementById("button").disabled = true;

ここでスタートボタンのクリックが無効化されます。

button.animate(
[ {opacity:1},
{opacity:0}
],
{
duration:3000,
fill:"forwards",
}
);

ここでスタートボタンがフェードアウトのアニメーションを記述しています。

setTimeout(mySet, 3500);

最後にアニメーションが終わった後の動きを記述します。

 

関数mySetについて

ここでは変数jに素数を代入する動きを記述してあります。jを2から増やしていって素数だったらinnerHTML関数でprimeを書き換え、次にfadeを動かします。

 

関数fadeについて

ほぼmyOpeningと同じことが書かれています。アニメーションが終わったときに、mySetを動かして、次の素数を表示するようにしています。

 

最後にページを開いたときにmyOpeningが実行されるように、

myOpening();

と記述しておきます。

 

やってみて

  • CSSJavaScriptの連携を実際に動かして確かめることができた。アニメーションなどjQuery勉強してもうちょい簡単に書いて実装できるようにしたい。
  • CSSの配置方法がわかるようになってきた。中央配置とかアンカーポイントがどことかでごっちゃになりそうだが、うまいことtransformのtranslateで対応できた。
  • 素数判定のアルゴリズムがわかった。大学2年の時のテストで急に素数判定のプログラム書けっていうのが出題されて、当時解けなかったが、いまならぶっ倒せる。

よみあきでした。