paizaラーニング レベルアップ問題集 Aランクレベルアップメニュー JavaScript 規則的な数列の和

規則的な数列の和 (paizaランク C 相当)

https://paiza.jp/works/mondai/a_rank_level_up_problems/a_rank_calculation_exchange_700

普通にループで足し算を行うとタイムオーバーになります。
規則性を見つけて、場合分けをします。
```javascript
//タイムアウト
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//N 要素目から K 要素目まで
const [N, K] = lines[0].split(" ").map(Number);
//Aの要素番号を３で割ったとき、
//余り１ならばAの要素は１、余り２ならばAの要素は０、余り３ならばAの要素は−１
//N要素目からK要素目までの和Sは
let S = 0;
for (let i = N; i <= K; i++) {
    if (i % 3 === 1) {
        S += 1;
    } else if (i % 3 === 0) {
        S -= 1;
    }
}
console.log(S);
```

# 解答例
Aの規則性を見つけます。
Aの要素は、1,0,-1の３つが繰り返されています。
AのN要素目スタート、K要素目のまでの和をSとすると、以下のような規則が見つかります。

// N 要素目が１スタート → N%3=1の時
K=1 S=1 K%3= 1
K=2 S=1 K%3= 2
K=3 S=0 K%3= 0 

// N 要素目が０スタート → N%3=2の時
K=2 S=0 K%3= 2
K=3 S=-1 K%3= 0
K=4 S=0 K%3= 1

// N 要素目がー１スタート → N%3=0の時
K=3 S=-1 K%3= 0
K=4 S=0 K%3= 1
K=5 S=0 K%3= 2

```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [N, K] = lines[0].split(" ").map(Number);

if (N % 3 === 1) {
    if (K % 3 === 1) {
        console.log(1);
    } else if (K % 3 === 2) {
        console.log(1);
    } else if (K % 3 === 0) {
        console.log(0);
    }    
} else if (N % 3 === 2) {
    if (K % 3 === 1) {
        console.log(0);
    } else if (K % 3 === 2) {
        console.log(0);
    } else if (K % 3 === 0) {
        console.log(-1);
    }    
} else if (N % 3 === 0) {
    if (K % 3 === 1) {
        console.log(0);
    } else if (K % 3 === 2) {
        console.log(0);
    } else if (K % 3 === 0) {
        console.log(-1);
    }    
}
```
# 解答例(C++の場合とRuby の場合参考)
上の解答例のコードを見ると、出力値が共通しているところがあるので、まとめます。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [N, K] = lines[0].split(" ").map(Number);

if (N % 3 === 1) {
   if (K % 3 === 0) {
        console.log(0);
    } else {
        console.log(1); 
    }  
} else if (N % 3 === 2) {
    if (K % 3 === 0) {
        console.log(-1);
    } else {
        console.log(0);
    }   
} else if (N % 3 === 0) {
    if (K % 3 === 0) {
        console.log(-1);
    } else if (K % 3 === 2) {
        console.log(0);
    }   
}
```

# 解答例(Python3の場合参考)
改めて規則性をみてみます。
AのN要素目スタート、K要素目のまでの和をSとします。

// N 要素目が１スタート → N%3=1の時
K=1 S=1 K%3= 1
K=2 S=1 K%3= 2
K=3 S=0 K%3= 0 

// N 要素目が０スタート → N%3=2の時
K=2 S=0 K%3= 2
K=3 S=-1 K%3= 0
K=4 S=0 K%3= 1

// N 要素目がー１スタート → N%3=0の時
K=3 S=-1 K%3= 0
K=4 S=0 K%3= 1
K=5 S=0 K%3= 2

S=0が多いので、初期値を0として、0以外の値になったときに代入し直します。
以下の解答では和Sをresultとしています。

```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//N 要素目から K 要素目まで
const [n, k] = lines[0].split(" ").map(Number);
//和
let result = 0;

//nが-１から始まる時
if (n % 3 === 0) {
    //kが-1ならば
    if (k % 3 === 0) {
        //和は-1
        result = -1;
    }
//nが1から始まる時    
} else if (n % 3 === 1) {
    //kが1か0ならば
    if (k % 3 !== 0) {
        result = 1;
    }
//nが0から始まる時      
} else {
    if (k % 3 === 0) {
        result = -1;
    }
}
//和を出力
console.log(result);
```