電脳少女プログラミング2088を一部やったけど、あんまピンときてない


電脳少女プログラミング2088を一部やったけど、あんまピンときてない。

この「あんまピンときてない」は、「自分の解答にピンときてない」の意です。

試行錯誤した問題をピックアップして、以下に記載します。


# 一番通りの繁華街（paizaランク：B相当）

```python
number = int(input())
map = []
for i in range(number):
    map.append(input())
area = 0
#print(number)
#for i in range(number):
#    print(map[i])
for i in range(number-1):
    for j in range(number-1):
#        print(i,j)
        if map[i][j] == "#":
            continue
        for k in range(number):
#            print(i,j,k)
            if i+k+1 > number-1 or j+k+1 > number-1:
                continue
#            print(i+k+1, j+k+1)
            if map[i+k+1][j] == "." and map[i][j+k+1] == "." and map[i+k+1][j+k+1] == ".":
                area += 1
print(area)
```

この手のプログラミングコンテスト的なやつに慣れていないので、毎回入力の受け取りを調べることになります。
でも、今回は普通にStringとして受けとればよかったので、書くことは少なくてすんなり書けました。

さて、肝心の回答部分です。

最大N=50ということなので、普通にループさせても問題なさそうだと感じて、真っ当に総当たりをしました。
始点(i,j)に対して、1<=kを足して、四隅を検査する総当たりです。

まず、始点(i,j)が建物でなければ（#だったら）、continueです。
                
```python
if map[i][j] == "#":
    continue
```

ふつうに足していると座標がはみ出るので、はみ出る座標は刈り取ります。
このへんは真面目に考えておらず、実行してランタイムエラーを確認しながら、適当に足したり引いたりしました。
なんとも不真面目です。

```python
for k in range(number):
    if i+k+1 > number-1 or j+k+1 > number-1:
        continue
```

後は四隅の検査です。
始点は検査済みなので、残りの三隅を検査します。

```python
if map[i+k+1][j] == "." and map[i][j+k+1] == "." and map[i+k+1][j+k+1] == ".":
    area += 1
```

と、まあこんな感じでチェックは通りましたが、冒頭で書いたとおり、あまりピンときてません。

座標ものは特に苦手としているため、適当になんちゃってマジックナンバーを足したり引いたりしています。

他の方の回答も見ながら、もう少し理解を深めたいところです。


# ギャングのアジト（paizaランク：B相当）

```python
import math
number = int(input())
pixels = []
for i in range(number):
    pixels.append(list(map(int, input().split())))
flag = True
#for i in range(number):
#    print(pixels[i])
for i in range(number):
    for j in range(number):
        if 1 == (number % 2)  and j == math.floor(number/2):
            #print(i,j)
            continue
        if not (pixels[i][j] == pixels[i][number - j - 1]) :
            #print(i, j, pixels[i][j], pixels[i][number - j - 1])
            flag = False
            break
    if(flag == False):
        break
if flag == True:
    print("Yes")
else:
    print("No")
```

これも戦略はほぼ総当たりの検査です。

必要ないけれど、全面を検査していますが、線対称を確認しているので、本来は半分だけ検査すればいいですね。

真ん中は無条件で検査が通るので、continueします。
Nが奇数だったら、真ん中の列jをスキップです。

```python
for i in range(number):
    for j in range(number):
        if 1 == (number % 2)  and j == math.floor(number/2):
            #print(i,j)
            continue
```

後は、線対称の位置が同じかどうかを検査します。

```python
if not (pixels[i][j] == pixels[i][number - j - 1]) :
    #print(i, j, pixels[i][j], pixels[i][number - j - 1])
    flag = False
    break
```

以上です。

で、対称をチェックしているだけなので、半分検査すればよいですから、

```python
for i in range(math.floor(number/2)):
    for j in range(math.floor(number/2)):
        if not (pixels[i][j] == pixels[i][number - j - 1]) :
            #print(i, j, pixels[i][j], pixels[i][number - j - 1])
            flag = False
            break
    if(flag == False):
        break
```

こうでもよさそうです。


# 終わりに

ひとまずこんな感じでした。

ひさしぶりにプログラミング問題をやりましたが、やっぱり楽しいですね。
特殊な三進数問題が解けていないので、皆さんの回答で勉強したい次第です。

また、ゲームのコンセプトそのものはそんなに興味がないのですが、UI的に以下の改善が欲しいなと思いました。

- チャレンジする問題をマップ上だけではなく、リスト上の一覧でも確認したい
- クリア済みの問題の「SQL」「コード」の種別を判別したい
- 正答結果の画面から、再度自分のコードを見る動線がほしい

以上です。
ここまで読んでいただきありがとうございました。