LeetCode daily #1550. Three Consecutive Odds

# 【LeetCode #1550】Three Consecutive Odds

## はじめに
今日の daily 問題はとっても簡単でした．なので，色々な解法で解いてみました．TypeScript で zip を実装もしてみました．
とても簡単なので，慣れていない言語で解いてみるのも良いかもですね．
朝のコーヒー替わりやティーブレイクに解いてみましょう．

## 問題概要
配列の中に 3 つ連続で奇数があるかどうかをチェックし，bool を返す
* あれば true
* なければ false

### 例
>**入力：** arr = [2, 6, 4, 1]
>**出力：** false

>**入力：** arr = [1, 2, 34, 3, 4, 5, 7, 23, 12]
>**出力：** true

### カテゴリ

問題難易度：easy
タグ：Array

## 解法①：素直に for ループ
単純に arr.length - 3 まで i を動かし，各 i で arr[i]・arr[i+1]・arr[i+2] をチェックする．
コード的には一番直感的で分かりやすいですね．
```python
class Solution:
    def threeConsecutiveOdds(self, arr: List[int]) -> bool:
        for i in range(len(arr)-2):
            if arr[i] % 2 == 1 and arr[i+1] % 2 == 1 and arr[i+2] % 2 == 1:
                return True
        return False
```


## 解法②：while でスキップを入れる
こちらも i 自体は arr.length - 3 まで動かします．
そして，arr[i+2]・arr[i+1]・arr[i] の順でチェックしていき，条件を満たさないところがあればその次の要素までスキップします．
```python
class Solution:
    def threeConsecutiveOdds(self, arr: List[int]) -> bool:
        i = 0
        while (i < len(arr)-2):
            if (arr[i+2] % 2 == 0):
                i += 3
            elif (arr[i+1] % 2 == 0):
                i += 2
            elif (arr[i] % 2 == 0):
                i += 1
            else:
                return True
        return False
```

## 解法③：ちょっと Pythonic
zip を使って，1 つずつ要素のズレた配列から要素を取り出し，チェックする方法です．
* arr[0:] = arr[0] から arr[末尾] までの要素
* arr[1:] = arr[1] から arr[末尾] まで要素
* arr[2:] = arr[2] から arr[末尾] までの要素

zip() は長さが違う配列の場合，最短のものが末尾まで至ったら終了するのでエラーも出ません．（zip_longest は別）

zip が若干 Python っぽいですかね．Rust などにもあるようですが．

これはこれで分かりやすいですね．

```python
class Solution:
    def threeConsecutiveOdds(self, arr: List[int]) -> bool:
        for n1, n2, n3 in zip(arr[0:], arr[1:], arr[2:]):
            if n1 % 2 == n2 % 2 == n3 % 2 == 1:
                return True
        return False
```

## まとめ
今日は easy 問題を解きました．
色々な解き方ができるので，LeetCode では，解いたら終わりではなく「他の解き方もできないか」を考えてみるとさらにスキルが伸びますね．
また，苦手な言語の練習で書いてみても良いかもしれません．
他にも解き方があればぜひ教えてください．

## おまけ
TypeScript です．

### 素直に for ループ
```typescript
function threeConsecutiveOdds(arr: number[]): boolean {
    for (let i: number = 0; i < arr.length-2; i++){
        if ((arr[i] % 2 == 1) && (arr[i+1] % 2 == 1) && (arr[i+2] % 2 == 1)){
            return true;
        }
    }
    return false;
};
```

### while ループ
```typescript
function threeConsecutiveOdds(arr: number[]): boolean {
    let i: number = 0;
    while (i < arr.length-2){
        if (arr[i+2] % 2 == 0){
            i += 3;
        } else if (arr[i+1] % 2 == 0){
            i += 2;
        } else if (arr[i] % 2 == 0){
            i += 1;
        } else {
            return true;
        }
    }
    return false;
};
```

### zip
TypeScrpt には zip がないので自作しないといけません．
また，速度は落ちますね．
```typescript
function zip<T>(...arrays: T[][]): T[][] {
  const minLen = Math.min(...arrays.map(arr => arr.length));
  const result: T[][] = [];

  for (let i = 0; i < minLen; i++) {
    result.push(arrays.map(arr => arr[i]));
  }

  return result;
}

function threeConsecutiveOdds(arr: number[]): boolean {
    const zipped = zip(arr.slice(0), arr.slice(1), arr.slice(2));
    for (const [n1, n2, n3] of zipped){
        if ((n1 % 2 == 1) && (n2 % 2 == 1) && (n3 % 2 == 1)){
            return true;
        }
    }
    return false;
};
```