題目:
(5 級) ISBN-10 Validation
ISBN-10 標示為 10 個數字,前面的九個數字範圍從 0 到 9,最後一個數字可以為 0 到 9 或者字母 "X" (用來代表 10)。
有效的 ISBN-10,每個數字的總和與其位置的乘積必須等於零 (模除 11)。
例如,ISBN-10:1112223339 是有效的,因為:
(((1*1)+(1*2)+(1*3)+(2*4)+(2*5)+(2*6)+(3*7)+(3*8)+(3*9)+(9*10)) % 11) == 0
範例:
validISBN10('1112223339') => true
validISBN10('1234554321') => true
validISBN10('1234512345') => false
Ruby 解法:
def validISBN10(isbn)
# 先檢查 isbn 是否有 10 位 digits
return false if isbn.size != 10
# 再檢查是否符合 isbn-10 的規則
return false if not isbn.match(/^\d{9,10}[X]?$/)
# 如果符合的話就把 isbn 轉成陣列
# 並把每個 character 轉成整數,"X" 轉成 10
arr = isbn.split("")
.map { |char| char == "X" ? 10 : char.to_i }
# 把陣列中的每個數字乘上該位置數字
1.upto(10) do |n|
arr[n-1] = arr[n-1] * n
end
# 最後回傳陣列的總和模除 11 後是否為 0
arr.sum % 11 == 0
end
JavaScript 解法:
function validISBN10(isbn) {
// 先檢查 isbn 是否有 10 位 digits
if (isbn.length !== 10) return false;
// 再檢查是否符合 isbn-10 的規則
if (isbn.match(/^\d{9,10}[X]?$/)) {
// 如果符合的話就把 isbn 轉成陣列
let arr = isbn.split("");
// 如果最後一個 character 是 "X" 的話就轉成 10
if (arr[9] === "X") arr[9] = 10;
// 把陣列中的每個數字乘上該位置數字
for (let i = 1; i <= 10; i++) {
arr[i-1] = parseInt(arr[i-1]) * i;
}
// 最後回傳陣列的總和模除 11 後是否為 0
return arr.reduce((sum, n) => {return sum += n;}, 0) % 11 === 0
} else {
// 如果沒有符合 isbn-10 的規則則回傳 false
return false;
}
}
心得:
就這樣完賽了,還記得最初開始刷題是因為看到龍哥的 自學程式,你應該知道的四件事情(一)我該學什麼程式語言?
那個時候還處在自學階段,沒有系統沒有目標,光是 8 級的題目就讓我需要苦思好幾天。
這次鐵人賽最大的挑戰是在兩種語言間切換,而且 Ruby 和 JavaScrip 的語法又相差甚遠,經常 Ruby 題目寫完了,卻卡在 JavaScrip 沒有提供一樣好用的方法。或是語法寫錯了卻沒發現,怎麼跑題目都不過的情況也很常見。
一個月寫下來,其中有挫折有壓力,寫到一半被我放棄的題目也不少。
雖然進步不多,但每天都告訴自己,要比昨天多往前走一點點。