🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

3回答

231閲覧

プログラムの拡張性を高めるための改善点、何が良くなかったのでしょうか

malia

総合スコア9

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2019/10/02 05:52

編集2019/10/02 06:22

独学のずぶの素人です。
この問題の結果だけ求めるプログラムを書いたのですが、後になって結果がどの数値から求められたのか
気になり改良しようとしたのですが面倒になりやめました
最初からどのように書いていれば拡張性が高いプログラムを作ることが出来たのでしょうか?

'''
「格子内の最大の積」

08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48

上の 20×20 の格子のうち, 上下左右斜めのいずれかの方向で連続する4つの数字の積のうち最大のものはいくつか?
'''

python

1import numpy as np 2 3def right( a, row, column ): 4 tmp = 1 5 for i in range( 4 ): 6 tmp *= a[ row ][ column + i ] 7 return tmp 8 9def under( a, row, column ): 10 tmp = 1 11 for i in range( 4 ): 12 tmp *= a[ row + i ][ column ] 13 return tmp 14 15def bottom_right( a, row, column ): 16 tmp = 1 17 for i in range( 4 ): 18 tmp *= a[ row + i ][ column + i ] 19 return tmp 20 21def upper_right( a, row, column ): 22 tmp = 1 23 for i in range( 4 ): 24 tmp *= a[ row - i ][ column + i ] 25 return tmp 26 27standard_value = 20 28 29a = np.loadtxt('11.txt', delimiter = ' ') 30tmp = 0 31 32for row in range( standard_value ): 33 for column in range( standard_value ): 34 if standard_value-4 >= column: 35 tmp = right( a, row, column ) if tmp < right( a, row, column ) else tmp 36 37 if standard_value-4 >= row: 38 tmp = bottom_right( a, row, column ) if tmp < bottom_right( a, row, column ) else tmp 39 elif row >= 3: 40 tmp = upper_right( a, row, column ) if tmp < upper_right( a, row, column ) else tmp 41 if standard_value-4 >= row: 42 tmp = under( a, row, column ) if tmp < under( a, row, column ) else tmp 43print( int(tmp) ) 44 45#51267216

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coco_bauer

2019/10/02 06:13

解こうとする問題の内容を、質問の中に正しく簡潔に記載してください。 ・「上の 20×20 の格子のうち, 斜めに並んだ4つの数字が赤くマークされている」と書かれていますが、『赤くマークされた4つの数字』は何を意味するのですか? 何かに使うのですか? ・「上の 20×20 の格子のうち, 上下左右斜めのいずれかの方向で連続する4つの数字の積のうち最大のものはいくつか?」 と書かれていますが、”上下左右斜めのいずれかの方向で連続する”というのは、隣り合う数字が「上下左右斜めのいずれかの位置にあれば良い」という意味ですか、それとも「4つの数字は、上下左右斜めのいずれかの方向に直線的に並んでいる」という意味ですか?
malia

2019/10/02 06:25

失礼致しました、修正致しました。 ・赤マーク(それらの数字の積は 26 × 63 × 78 × 14 = 1788696 となる.)というのは環境の違いで反映できなかった箇所です、削除しました。 ・上下左右斜めのいずれかの方向に直線的に並んでいるという意味です。
t_obara

2019/10/02 07:37

どのような点で面倒に感じたのでしょうか。その面倒くささがヒントになるかと思います。
guest

回答3

0

ベストアンサー

シンプルに書くのが一番かなと思います。
最初は

Python

1 2values = [ 3[ 8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8], 4[49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 4, 56, 62, 0], 5[81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 3, 49, 13, 36, 65], 6[52, 70, 95, 23, 4, 60, 11, 42, 69, 24, 68, 56, 1, 32, 56, 71, 37, 2, 36, 91], 7[22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80], 8[24, 47, 32, 60, 99, 3, 45, 2, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50], 9[32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70], 10[67, 26, 20, 68, 2, 62, 12, 20, 95, 63, 94, 39, 63, 8, 40, 91, 66, 49, 94, 21], 11[24, 55, 58, 5, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72], 12[21, 36, 23, 9, 75, 0, 76, 44, 20, 45, 35, 14, 0, 61, 33, 97, 34, 31, 33, 95], 13[78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 3, 80, 4, 62, 16, 14, 9, 53, 56, 92], 14[16, 39, 5, 42, 96, 35, 31, 47, 55, 58, 88, 24, 0, 17, 54, 24, 36, 29, 85, 57], 15[86, 56, 0, 48, 35, 71, 89, 7, 5, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58], 16[19, 80, 81, 68, 5, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 4, 89, 55, 40], 17[ 4, 52, 8, 83, 97, 35, 99, 16, 7, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66], 18[88, 36, 68, 87, 57, 62, 20, 72, 3, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69], 19[ 4, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 8, 46, 29, 32, 40, 62, 76, 36], 20[20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 4, 36, 16], 21[20, 73, 35, 29, 78, 31, 90, 1, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 5, 54], 22[ 1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48], 23] 24 25standard_value = 20 26NUMBERS=4 27a = 0 28 29for base_y in range(standard_value): 30 for base_x in range(standard_value): 31 tmp = [ 1, 1, 1, 1 ] 32 for i in range(NUMBERS): 33 if (base_x+NUMBERS <= standard_value): 34 tmp[0] *= values[base_y][base_x+i] 35 else: 36 tmp[0] = 0 37 38 if (base_y+NUMBERS <= standard_value): 39 tmp[1] *= values[base_y+i][base_x] 40 else: 41 tmp[1] = 0 42 43 if (base_y+NUMBERS <= standard_value) and (base_x+NUMBERS <= standard_value): 44 tmp[2] *= values[base_y+i][base_x+i] 45 tmp[3] *= values[base_y+i][base_x+NUMBERS-(i+1)] 46 else: 47 tmp[2] = 0 48 tmp[3] = 0 49 50 a = max(a, max(tmp)) 51 52print(a) 53

と書いて数値もみたいなら

Python

1 2 3values = [ 4# 略 5] 6 7standard_value = 20 8NUMBERS=4 9a = 0 10 11max_x = max_y = max_dir = -1 12 13for base_y in range(standard_value): 14 for base_x in range(standard_value): 15 tmp = [ 1, 1, 1, 1 ] 16 for i in range(NUMBERS): 17 if (base_x+NUMBERS <= standard_value): 18 tmp[0] *= values[base_y][base_x+i] 19 else: 20 tmp[0] = 0 21 22 if (base_y+NUMBERS <= standard_value): 23 tmp[1] *= values[base_y+i][base_x] 24 else: 25 tmp[1] = 0 26 27 if (base_y+NUMBERS <= standard_value) and (base_x+NUMBERS <= standard_value): 28 tmp[2] *= values[base_y+i][base_x+i] 29 tmp[3] *= values[base_y+i][base_x+NUMBERS-(i+1)] 30 else: 31 tmp[2] = 0 32 tmp[3] = 0 33 34 tmp_a = max(tmp) 35 if a < tmp_a: 36 max_x = base_x 37 max_y = base_y 38 max_dir = tmp.index(tmp_a) 39 a = tmp_a 40 41if max_dir == 0: 42 print([values[max_y][max_x+i] for i in range(NUMBERS)]) 43elif max_dir == 1: 44 print([values[max_y+i][max_x] for i in range(NUMBERS)]) 45elif max_dir == 2: 46 print([values[max_y+i][max_x+i] for i in range(NUMBERS)]) 47elif max_dir == 3: 48 print([values[max_y+i][max_x+(NUMBERS-(i+1))] for i in range(NUMBERS)]) 49 50print(a)

投稿2019/10/02 12:29

編集2019/10/02 14:13
nomuken

総合スコア1627

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

malia

2019/10/02 16:01

すごいです
guest

0

right, under, bottom_right, upper_right がほとんど同じ処理をしているので、以下のように追加引数dirでどの方向に計算するのかを渡すようにしてまとめるのはどうでしょうか。
4つの数字の積と一緒に、4つの数字と方向、開始地点も返すようにしています。

python

1import numpy as np 2 3from functools import reduce 4from operator import mul 5 6def calc_product(a, row, column, dir): 7 dx, dy = {'right': (1, 0), 'under': (0, 1), 'bottom_right': (1, 1), 'upper_right': (1, -1)}[dir] 8 numbers = [a[row + dy * i][column + dx * i] for i in range(4)] 9 return reduce(mul, numbers), numbers, dir, f'row={row}, col={column}' 10 11standard_value = 20 12 13a = np.loadtxt('11.txt', delimiter = ' ', dtype=int) 14answer = [] 15 16for row in range( standard_value ): 17 for column in range( standard_value ): 18 if standard_value-4 >= column: 19 answer.append(calc_product(a, row, column, 'right')) 20 if standard_value-4 >= row: 21 answer.append(calc_product(a, row, column, 'bottom_right')) 22 elif row >= 3: 23 answer.append(calc_product(a, row, column, 'upper_right')) 24 if standard_value-4 >= row: 25 answer.append(calc_product(a, row, column, 'under')) 26 27print(sorted(answer)[-1])

結果が最大となるデータがどこから得られたものなのかについては、20x20の格子なので手抜きをして全てのデータを保持しておいてソートして答えを出すようにしました。

なお、元のソースにはバグがあります。
答えが最大になるのは、row=15, col=3から右上方向の 87 * 97 * 94 * 89 = 70600674 だと思います。

投稿2019/10/02 10:50

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

そこまでおかしな書き方には見えないですが、強いていえばもう少し適切な名前があるかと思います。
色々な考え方があるのでベストとは言わないですが、少なくとも今よりベターかなと思うものをいくつか

・standard_value -> grid_size など(さらにwidthとheightに分けた方が、正方形以外の問題も対応できる)
・right/under などの関数名を calc_right_dir などもう少し関数名で説明する
・最後に出力する tmp という変数名は max_value など(関数内の tmp はスコープが小さいのでOK)

その他、色々な意見や書き方があるかと思います。
変数名の付け方や読みやすいコードなどは下記の書籍が参考になります。
リーダブルコード

ただ、コードを書く力と同じくらい、コードを読む力も大事になります。
これくらいの量であれば諦めずにスラスラ読めるようになった方が良いです!

(一応、最低限のコードの一例を掲載します)

a = np.loadtxt('11.txt', delimiter = ' ') tmp = 0 direction = "" key_row = 0 key_col = 0 for row in range( standard_value ): for column in range( standard_value ): if standard_value-4 >= column: right_value = right( a, row, column ) if tmp < right_value: tmp = right_value direction = "right" key_row = row key_col = column if standard_value-4 >= row: bottom_right_value = bottom_right( a, row, column ) if tmp < bottom_right_value: tmp = bottom_right_value direction = "bottom_right" key_row = row key_col = column elif row >= 3: upper_right_value = upper_right( a, row, column ) if tmp < upper_right_value: tmp = upper_right_value direction = "upper_right" key_row = row key_col = column if standard_value-4 >= row: under_value = under( a, row, column ) if tmp < under_value: tmp = under_value direction = "under" key_row = row key_col = column print( int(tmp) ) print( "column: %d / row: %d (value: %d), direction: %s" % (key_col+1, key_row+1, a[key_col][key_row], direction) )

投稿2019/10/02 07:17

Kapustin

総合スコア1186

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問