6時だョ!!全員集合!!

Rails・JavaScrictを中心にアウトプットします。

2022年4月28日 アルゴリズムを自作して問題を解く

問題

1以上の整数nが与えられたとき、1からnまでの整数の内 7で割り切れない数の合計を出力するプログラムを示してください。

例えばnが7の場合は1, 2, 3, 4, 6, 7の合計を出力する。

関数型プログラミングと手続型プログラミングの違い

関数型プログラミング

過程ではなく、結果に重きを置いている。何をしたいかを書くだけ

手続型プログラミング

結果を得るための過程に重きを置いている

関数型は過程をメソッドに入れて、過程を抽象化している

手続型で解く

手続き型の場合、以下のようになりました。

const testNum = (n) => {
  let totalNum = 0;
    for (let i = 0; i <= n ; i++) {
      i % 7 !== 0 ? totalNum += i : totalNum - 7;
    }
  return totalNum;
}
testNum(7)

▼出力結果 15

手続き型の場合、何をやっているのか読み解きづらいです。

関数型で解く

https://paiza.io/projects/L5DLuSgZAyNYZUADmjXsOg?language=ruby

const testNum = (n) => {
  const num = [...Array(n).keys()].map(i => ++i)
             .filter(n => n % 7 !== 0)
             .reduce((accumulator, currentValue) => {
               return accumulator + currentValue;
              }, 0);
  return num;
}

console.log(testNum(5));

▼出力結果 15

  • ...Array(n)では引数に渡された数字の数だけundefinedが要素として生成されます。
    • [undefined, undefined,undefined,undefined, undefined,undefined, undefined]
  • 配列.keys()でインデックス番号の数字の配列を生成します。
    • 7の場合[0, 1, 2, 3, 4, 5, 6]となります。
  • 配列を1から始めたいため、mapで要素に1をプラスしています。
    • [1, 2, 3, 4, 5, 6, 7]となります。
  • 7で割り切れる数を省きたいため、配列のfilterメソッドを使用します。
    • [1, 2, 3, 4, 5, 6]となります。
  • あとは配列内の数値を足すだけです。reduceメソッドを使用します。

[...Array(3).keys()]のコード例

// undefinedを要素とする配列を、生成する

const array = [...Array(3)];

console.log(array); // => [ undefined, undefined, undefined ]
// Array(3).keys()の結果をスプレッド構文で展開する

const array = [...Array(3).keys()];

console.log(array); // => [ 0, 1, 2 ]

TypeScriptで書く場合

コンソール

const testNum = (n: number): number => {
  const num = [...Array(n).keys()].map(i => ++i)
             .filter(n => n % 7 !== 0)
             .reduce((accumulator, currentValue) => {
               return accumulator + currentValue;
              }, 0);
  return num;
};

console.log(testNum(7));

エイリアスで書いた場合(呼び出しシグネチャ)

type TestNum = (n: number) => number

const testNum: TestNum = (n) => {
  const num = [...Array(n).keys()].map(i => ++i)
                                  .filter(n => n % 5 !== 0)
                                  .reduce((accumulator, currentValue) => {
                                    return accumulator + currentValue;
                                  }, 0);
  return num;
}

console.log(testNum(5));