各位觀眾!!!!!
不好意思讓大家久等啦~~~~ (醒醒,沒有人在等吧)
本系列的正片終於要開始啦XD
但怕耽誤到大家時間,
開始前還是有幾個溫馨小提醒要跟大家說個:
好,前言到這結束,就讓我們正式進入主題吧!
(※溫馨提醒:下面很落落長, 沒時間的人可以用 Ctrl + F 搜尋 [快速回顧] 就好XD)
(對不起應該只有這一篇會一堆前言QQ 大家忍耐一下QQ)
之前文章有提過我出身於資管系,
不知道資訊科系相關的夥伴們跟我經驗像不像,
就是人生第一次學的程式語言就是 C 語言,
然後人生第一次程式語言期中考試一定有數學題?
是的,我一直都記得,
當年我的 C 語言期中考題是質數XD(說來慚愧,我當年的 C 是低空飛過的orz 謝謝老師當年不殺之恩QQ)
因為我們都不是完全的程式新手了,
拜託複習寫程式起手式請不要從 Hello World 開始XD
我們是要練習寫程式的思考邏輯跟感覺,
因此我覺得用數學題目來當開頭難易度正好!
既不會簡單到像 Hello World 一樣,
又不會難到要你馬上進入指標之類的。(其實 C 語言的指標概念我從以前到現在沒弄懂過orz)
正好我記得今年的 3 月 20 日有一則新聞:
https://news.cts.com.tw/cts/life/202003/202003201994343.html
今天是「超級整除日」! 本世紀僅有9天
今天除了是二十四節氣中的「春分」,也是「超級整除日」,意思就是今天的日期「20200320」剛好都是數字1、2、3、4、5、6、7、8、9、10的倍數,而這樣特別的日子,過了今天,下一次可就得等到5年後囉!
沒錯,所以現在就讓我們就用程式找出本世紀的「超級整除日」有哪些吧!
這邊我是用 JavaScript 實作,
如同我前兩天的文章提到的,
因為我後來幾乎都在寫 JavaScript,所以對它的語法最熟,
當然看到的夥伴們也可以用其他語言挑戰這是絕對沒有問題的!
例如:Python, Perl...... All OK, if you like, and you can!!!!!!!
首先我們要準備的材料(?)有:
相信有在寫的人就知道,JavaScript 起手式就是要有 .html 檔跟 .js 檔XD
我在這個挑戰開始以前真的完全沒有偷打開 Visual Studio Code 寫程式,
就真的是如實將我復健的過程一一寫下來XD
真的可以把本系列文章當記錄片看的概念XD
準備好了就讓我們開始吧XD
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>超級整除日</title>
</head>
<body>
<script src="js/FullDivided.js"></script>
</body>
</html>
console.log("HIHI");
確定 html 有顯示 console log 就可以往下個步驟進行。
3. 然後因為真的是久違的寫程式,
對自己的記性實在沒太大把握,
知道這個題目一定會用到迴圈,
於是用簡單的語法搭配 console 看看自己的記性有沒有問題XD
for ( let i=0;i<3;i++){
console.log(`我是${i}`);
}
(PS. ${i}
為 JavaScript ES6 寫法,有興趣的可以 Google 個~)
let cnt = 0; // 整除次數
let basicNum = 20200320;
for ( let i=1; i<=10; i++ ){
// console.log(`我是${i}`);
if ( basicNum%i == 0 ){
cnt++;
}
}
console.log(`被整除次數為 ${cnt}`);
(我知道以上這幾句程式應該會有很多路過的大大看不過去XD
但這是復健,請大家再耐心等待個XD)
if ( cnt == 10 ){
console.log(`${basicNum} 是超級整除數!`);
}
let cnt;
// let basicNum = 20200320;
for ( let basicNum=20250101; basicNum<=20251231; basicNum++ ){
cnt = 0;
for ( let j=1; j<=10; j++ ){
if ( basicNum%j == 0 ){
cnt++;
}
}
if ( cnt == 10 ){
console.log(`${basicNum} 是超級整除數!`);
}
}
到這裡找出 20250720 是超級整除數,
這邊我有稍微暫停調整一下程式,
例如裡面的迴圈改由 10 開始,遞減到 2,
因為如果一開始就不能被 10 整除,
表示該數字一定不可能是超級整除數了XD
因此不能被 10 整除,
就可以不用再繼續往下執行,
用 break bypass掉內層迴圈再回到外層迴圈一開始繼續往下做)
let cnt; // 整除次數
// let basicNum = 20200320;
let execTimes = 0; // 計算次數(只是比較效能用)
for ( let basicNum=20250101; basicNum<=20251231; basicNum++ ){
cnt = 1;
for ( let j=10; j>=2; j-- ){
if ( basicNum%j != 0 ){
break;
}
cnt++;
execTimes++;
}
if ( cnt == 10 ){
console.log(`${basicNum} 是超級整除數!`);
}
}
console.log(`計算次數為 ${execTimes}`);
let cnt; // 整除次數
// let basicNum = 20200320;
let execTimes = 0; // 計算次數(只是比較效能用)
for ( let basicNum=20010101; basicNum<=21001231; basicNum++ ){
cnt = 1;
for ( let j=10; j>=2; j-- ){
if ( basicNum%j != 0 ){
break;
}
cnt++;
execTimes++;
}
if ( cnt == 10 ){
console.log(`${basicNum} 是超級整除數!`);
}
}
console.log(`計算次數為 ${execTimes}`);
結果跑出了我意想不到的結果:
不是說本世紀只有 9 個超級整除日嗎?為什麼跑出一堆?
看到這裡相信聰明的你一定知道發生什麼事了!
所以連 20018880 這種不為正常日期的數字都被算出來了......=口=
-先寫年月日字串連在一起
(PS. 這邊不判斷大月小月,太麻煩了,而且 31 也不會被 10 整除,所以可以忽略不計XD)
let dateStr = "";
for ( let year=2001; year<=2001; year++ ){
for ( let month=1; month<=12; month++ ){
for ( let date=1; date<=31; date++ ){
dateStr = `${year}${month}${date}`;
console.log(`dateStr: ${dateStr}`);
}
}
}
-因為要計算 記得將字串轉數字
let dateStr = "";
for ( let year=2001; year<=2100; year++ ){
for ( let month=1; month<=12; month++ ){
month = month.toString(); // 將月份數字轉字串
if ( month.length == 1 ){ month = "0"+month; } // 月如果只有1碼要補0
for ( let date=1; date<=30; date++ ){
date = date.toString(); // 將日子數字轉字串
if ( date.length == 1 ){ date = "0"+date; } // 日如果只有1碼要補0
dateStr = `${year}${month}${date}`; // 將年月日用字串的方式串在一起
basicNum = parseInt(dateStr); // 最後再將組出來的日期字串轉數字型態
}
}
}
-再把上述組出來的日期數字跟先前寫好的超級整除數判斷邏輯組起來,大功告成!
let cnt; // 整除次數
let basicNum = 20200320;
let dateStr = ""; // 日期字串
for ( let year=2001; year<=2100; year++ ){
for ( let month=1; month<=12; month++ ){
month = month.toString(); // 將月份數字轉字串
if ( month.length == 1 ){ month = "0"+month; } // 月如果只有1碼要補0
for ( let date=1; date<=30; date++ ){
if ( date % 10 != 0 ){
continue; // 如果 date 不能被 10 整除就直接跳過後面不做回到迴圈開始處
}
date = date.toString(); // 將日子數字轉字串
if ( date.length == 1 ){ date = "0"+date; } // 日如果只有1碼要補0
dateStr = `${year}${month}${date}`; // 將年月日用字串的方式串在一起
basicNum = parseInt(dateStr); // 最後再將組出來的日期字串轉數字型態
cnt = 1;
for ( let j=10; j>=2; j-- ){ // 1可以整除任何數,所以直接從2開始
if ( basicNum%j != 0 ){
break;
}
cnt++;
}
if ( cnt == 10 ){
console.log(`${basicNum} 是超級整除數!`);
}
}
}
}
耶~~~~~~ 我終於成功用程式找出本世紀 9 個超級整除日了~~~~~~(灑花)
我知道上面太落落長,因此這邊讓我們快速 review 一下本日重點XD
[後記]
後續應該還可以再 tune 一下程式,
但我沒時間了先這樣XD
(前幾天都可以保持第2名交文章的......今天變成本團最晚交的QQ)
在 JavaScript 比較值的時候,請愛用 ===
instead of ==
,比較不會遇到意想不到的 bug XD
供參考的比較表:https://dorey.github.io/JavaScript-Equality-Table/