【AtCoder】ABC201をPython3で解説

ABC201の解説。

https://atcoder.jp/contests/abc201

## A - Tiny Arithmetic Sequence 
### 解説
リストを適切にならびかえる、すなわち、1<=A1<=A2<=A3<=100。```sort()```を使い、昇順に並び替え。
A3-A2=A2-A1を計算し、正しければ、```'Yes'```を出力。

### コード

```python
A = list(map(int, input().split()))
A.sort()

if A[2]-A[1] == A[1]-A[0]:
    print('Yes')
else:
    print('No')
```

## B - Do you know the second highest mountain?
### 解説
2番目に高い山を出力する問題。
やり方は大きく2つ。

コード1は、とりあえずリストに入れて、タプルを```sort```で並び替えて、リストの2番目を出力するもの。

コード2は、1番目に高い山と2番目に高い山の値を保持しながら、最終的に2番目の値を出力するもの。

### コード1

```python
N = int(input())
data = []

for _ in range(N):
    S, T = input().split()
    T = int(T)
    # dataにタプルを追加
    data.append((T,S))
    
# 降順に並び替え
data.sort(reverse=True)
# 高さが2番目、つまり、data[1][1]を取り出す
print(data[1][1])
```

### コード2

```python
N = int(input())
top = 0
sec = 0
top_name = None
sec_name = None

for _ in range(N):
    S, T = map(str, input().split())
    T = int(T)
    
    # 1番高い山より値が大きいとき
    if T > top:
        # 1番目を2番目に代入
        sec_name, sec = top_name, top
        # 今の値を1番目に代入
        top_name, top = S, T
    # 2番目に高い山より値が大きいとき
    elif T > sec:
        # 今の値を2番目に代入
        sec_name, sec = S, T

print(sec_name)
```

## C - Secret Number
### 解説
`0000`から`9999`まで、10000通りの暗証番号を試す。

わかりやすいように、入力例`ooo???xxxx`で説明する。

まず、`'o'`と`'x'`の代わりに、`1`と`0`のリストを作成する。

```python
>> test_list: [0,0,0,0,0,0,0,0,0,0]
```

次に、4桁の数について検証する。
たとえば、forループがまわり、`now = 1230`の場合、`x = now % 10`、つまり、`x = 1230 % 10`で、`x`に`0`が代入される。
`test_list[0] = 1`より、次のようになる。

```python
>> test_list: [1,0,0,0,0,0,0,0,0,0]
```

そして、`now //= 10`で`now == 123`となる。
これを繰り返すと、

```python
>> test_list: [1,1,1,1,0,0,0,0,0,0]
```
となる。
実質的に、この２つを頭から1つ１つ見比べることで、正誤判定をする。

```python
S = 'ooo???xxxx'
test_list = [1,1,1,1,0,0,0,0,0,0]
```

続いて、`for j in range(10):`で0-9までの数を検証する。
もし、`S[j]`が`'o'`で、`test_list[j]`が`1`でなければ、`S`と`test_list`で正誤が一致しないため、そもそもこの暗証番号自体が存在しないこととなるので、`ok = False`となる。
同様に、`S[j]`が`'x'`で、`test_list[j]`が`0`でなければ、`S`と`test_list`で正誤が一致しないため、そもそもこの暗証番号自体が存在しないこととなるので、`ok = False`となる。

正誤の不一致がなければ、暗証番号としてありえる値なので、`cnt += 1`とカウントする。
0-9999までの番号を試し、最終的な`cnt`カウント数を出力する。

### コード（解説あり）

```python
S = input()
cnt = 0

# 0000-9999まで全探索
for i in range(10000):
    # 'o','x'の代わりに 1, 0のリストを作成
    test_list = [0]*10
    now = i

    # 4桁の数字を検証
    for _ in range(4):
        # 10で割った余り、つまり、1桁目を取り出す
        x = now % 10
        # '1','0'のリストで、(1桁目の値)番目のインデックスを'1'にする
        test_list[x] = 1
        # 桁を1つ落とす
        now //= 10

    ok = True

    # 0-9までの数字を試す
    for j in range(10):
        # 入力値が'o'で、探索値が'1'でなければ、False
        if S[j] == 'o' and test_list[j] != 1:
            ok = False
        # 入力値が'x'で、探索値が'0'でなければ、False
        elif S[j] == 'x' and test_list[j] != 0:
            ok = False

    # ありえない値がなければ暗証番号の1例としてカウント
    if ok:
        cnt += 1

print(cnt)
```

### コード（解説なし）

```python
S = input()
cnt = 0

for i in range(10000):
    test_list = [0]*10
    now = i

    for _ in range(4):
        x = now % 10
        test_list[x] = 1
        now //= 10

    ok = True

    for j in range(10):
        if S[j] == 'o' and test_list[j] != 1:
            ok = False
        elif S[j] == 'x' and test_list[j] != 0:
            ok = False

    if ok:
        cnt += 1

print(cnt)
```