1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Posted at

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

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

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

一番通りの繁華街(paizaランク:B相当)

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です。

if map[i][j] == "#":
    continue

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

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

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

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

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

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

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

ギャングのアジト(paizaランク:B相当)

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をスキップです。

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

以上です。

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

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」「コード」の種別を判別したい
  • 正答結果の画面から、再度自分のコードを見る動線がほしい

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

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?