はじめに
個人的に好きなアルゴリズム学習サイト「CodeWars」の問題をシェア。
週1くらいのペースで、全10回を目指す予定。今回が第10回です!
今回は(主観ですが)Rubyの特徴を活かせる問題です。
オススメ問題
問題
与えられた数値の「タワー」を作ります。
3 => [
" * ",
" *** ",
"*****"
]
6 => [
" * ",
" *** ",
" ***** ",
" ******* ",
" ********* ",
"***********"
]
難易度
分類は 6kyu です。
アルゴリズム問題として手応えがあるレベル。
オススメの回答
「評価が高い回答」の中から、学びの多い回答をピックアップしてご紹介。
丁寧な回答
export const towerBuilder = (nFloors: number): string[] => {
let result = [];
for (let i = 1; i <= nFloors; i++) {
result.push(buildFloor(i, nFloors));
}
return result;
};
// build i'th floor for a tower of size n floors
function buildFloor(i: number, n: number): string {
let middleSection = "*".repeat(2 * i - 1);
let sideSection = " ".repeat(n - i);
let floor = sideSection + middleSection + sideSection;
return floor;
}
buildFloor
関数が「それぞれの列」を作ります。
2 * i - 1
/ n - 1
はそれぞれ、その列の*
と
の数を計算するアルゴリズムです。
このbuildFloor
関数を各列分ごとに呼び出し、arrayに追加して完成です。
丁寧な手続き型の回答です。
テクい回答
export const towerBuilder = (nFloors: number): string[] => {
return Array.from({ length: nFloors }, (_, index) => {
const spaces = " ".repeat(nFloors - 1 - index);
return `${spaces}${"*".repeat(index * 2 + 1)}${spaces}`;
});
};
Array.from
を使用し、ひとまとまりで書かれたコードです。
引数の_
は、「その部分を使用しない」ことを明示しています。
length: nFloor
が肝です。
擬似的に「lengthは5」と設定することで、lengthが5の配列であるとある種騙して、コードを成り立たせています。
ダックタイピングの一例と言えるでしょう。
おわりに
以上、CodeWarsオススメ問題でした。
オススメ問題・解法など、ぜひコメントお待ちしております!