質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

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

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Q&A

解決済

3回答

944閲覧

python数値の求め方

zeitaku_fire

総合スコア26

Python 3.x

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

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

0グッド

0クリップ

投稿2018/06/19 04:08

編集2018/06/19 05:26

皆様からのご指摘ありがとうございます。
ルールを明確に伝えられてなくて、本当にすいません・・・・。
ルールがわからなければ、回答できない。・・・おっしゃるとおりだと思います。

『ルール』
・縦の合計が、必ず34
・数字が重複することはありません。
1~16の数字が必ず1個入ります。
・入力データの数字はランダムで形成されます。
・入力データには、0が必ず2個形成されます ※0が形成される場所もランダムです
横もしくは縦に続けて0が配置される可能性もございます。
・縦に0が2個入る場合は、出力する数字はどちらでもかまいません。
下記の場合、1 2 3 4 でも、1 2 11 4でも正となります。

『ケース3.入力データ』
8  7  6  5
1  2  0  4
16 15 14 13
9 10  0 12

『3.出力結果 パターン1』
8  7  6  5
1  2  3  4
16 15 14 13
9 10 11 12

『3.出力結果 パターン2』
8  7  6  5
1  2 11  4
16 15 14 13
9 10  3 12

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

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

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

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

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

hayataka2049

2018/06/19 04:16

入力の内容に関わらず常に同じ出力を出せば良いようにも解釈できますが、そういう訳ではありませんか?
fuzzball

2018/06/19 04:39

出力に0が残ってもいいのでしょうか?
hayataka2049

2018/06/19 04:46

縦の列に出現する0の回数は1以下ですか?
zeitaku_fire

2018/06/19 04:49

ご連絡ありがとうございます。出力する際には、0を適切な値に修正し出さなければいけないため、0は残ってはいけません。私の考えていることは、入力データをリストとして取り出し、リストの値(0の部分)を修正して、出力したいと考えております。プログラミングの勉強を始めたばかりで、拙いご質問となってしまい、申しわけございません。
fuzzball

2018/06/19 04:59

ケース3の場合に複数の解がありますが、出力はいずれか一つでかまわないのでしょうか?
zeitaku_fire

2018/06/19 05:01

ご回答ありがとうございます。縦の列に0の回数が2というケースもありますが、回答頂きました、「zipでlistを転置する方法」参考にさせて頂きます!
hayataka2049

2018/06/19 05:04

たとえばケース3では3,11で埋めることを意図しているのでしょうが、これが7,7とかでも構いませんか?
zeitaku_fire

2018/06/19 05:04

fuzzballさま、ご認識のとおりです。「1 2 11 4」もしくは、「1 2 3 4」のどちらであってもかまいません。
R.Shigemori

2018/06/19 05:09

たいしたことではありませんが、ケース3はもうひとつくらいルールがないと答えが無数に存在してしまいます。例示は3,11ですが11,3でもよく、7,7や10,4でもルールに沿っています
zeitaku_fire

2018/06/19 05:09

hayatakaさま、条件を明確に伝えておらず申し訳ございません。ご認識のとおり、3、11である必要がございます。
hayataka2049

2018/06/19 05:12

「7,7でも別に良い」って認識だったんだけどな・・・3,11である必要があるなら、R.Shigemoriさんの仰る通り他にルールが必要なので、明文化してください。どんなルールなのか見当がつかない(というかいろいろ考えられる)ので、方針が示せません
fuzzball

2018/06/19 05:13

ようするに、1〜16の数字が一つずつあるってことかな‥。
zeitaku_fire

2018/06/19 05:28

皆様ご指摘ありがとうございます。 質問本文を一新させました。
guest

回答3

0

ベストアンサー

縦の合計が、必ず34
・数字が重複することはありません。
1~16の数字が必ず1個入ります。
・入力データには、0が必ず2個形成されます ※0が形成される場所もランダムです

より、入力データから、2つの値が0になってしまった と考えます。
そこで、その数値と位置を特定します。
あとはその2つの数値を0の代わりに埋めてみて、縦計が34であるほうを採用すればよいです。
2つの数値しかないので探索パターンは2×1=2回でよいです。
ちなみに、仮に3個が0になった場合なら3×2×1=6回になります。

Python

1import numpy as np 2import itertools 3 4""" 5条件を満たす行列を生成。テストデータ作成用 6for one in itertools.permutations(range(1,17)): 7 a = np.array(one).reshape(4,4) 8 if all(a.sum( axis=0) == 34): 9 print(a) 10""" 11 12# 15と14が0に置き換わったデータ例 13l =[[ 1, 2, 3, 4], 14 [ 8, 7, 6, 5], 15 [ 9,10,11,12], 16 [16, 0, 0,13]] 17 18# 8と9が0に置き換わったデータ例 19l = [[ 1, 2, 3, 4], 20 [ 5, 0,10,11], 21 [16,15,14,13], 22 [12, 0, 7, 6]] 23 24# 8,12,14,15が0に置き換わったデータ例 25l =[[ 1, 2, 3, 4], 26 [ 0, 7, 6, 5], 27 [ 9,10,11, 0], 28 [16, 0, 0,13]] 29 30a = np.array(l) 31print(a) 32 33# 0になった値を特定 34s = set(range(1,17)) - set(a.flatten()) 35print(s) # {8,9} 36 37# 0の位置を特定 38ps = np.where( a == 0) 39print(ps) # (array([1, 3], dtype=int64), array([1, 1], dtype=int64)) 40 41# あとは 各パターンにおいて、各列計すべて34であるものを採用する 42# 縦に0が並んでいれば複数のケースで条件を満たすので、最初のほうでよい。 43for vals in itertools.permutations(s): # (8,9), (9,8) 44 print(vals) 45 # 0を数値で埋める 46 tmp = a.copy() 47 for i in range(len(s)): 48 tmp[ps[0][i],ps[1][i]] = vals[i] 49 50 # 条件を満たす 51 if all(tmp.sum( axis=0) == 34): 52 print(tmp) 53 break

投稿2018/06/19 06:22

編集2018/06/19 08:54
can110

総合スコア38262

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

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

zeitaku_fire

2018/06/19 07:55

ありがとうございます。 質問があいまいだったため、大変お手数おかけいたしました。
can110

2018/06/19 08:59

問題が整理できれば、比較的素直に解ける問題かと思います。 なお、0の個数が2以外の場合も考慮して回答を修正しました。
guest

0

ケース1とケース2、一要素ずつmax()で大きい方を残すようにするのはいかがでしょう?

ケース1 1  2  3  4 8  7  6  5 9 10 11 12 16 0  0 13 ケース2 1  2  3  0 8  0  6  5 9 10 11 12 16 15 14 13 出力にあったっての計算 max(1, 1)  max(2, 2) ...(あと省略) max(8, 8)  max(7, 0) ...(あと省略) max(9, 9)  max(10, 10) ...(あと省略) max(16, 16) max(0, 15) ...(あと省略)

投稿2018/06/19 04:21

YouheiSakurai

総合スコア6142

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

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

0

問題の定義通り、縦に加算した値を見ていくのでは駄目ですか? 

とりあえず縦に複数の0は出現しないと想定。

python

1data = [[8,7,6,5], 2 [1,0,3,4], 3 [16,15,14,13], 4 [9,10,0,12]] 5 6result = [] 7for col in zip(*data): 8 if sum(col) == 34: 9 result.append(col) 10 else: 11 tmp = list(col) 12 tmp[tmp.index(0)] = 34 - sum(col) 13 result.append(tmp) 14 15print(list(map(list, zip(*result)))) 16# => [[8, 7, 6, 5], [1, 2, 3, 4], [16, 15, 14, 13], [9, 10, 11, 12]]

zipでlistを転置する方法を利用しています。参考:
Python標準で転置行列

追記

作ってみました。上のコードを多少書き換えただけ。ヘンなデータが入ってきたときのことはまったく考えていません。

python

1data1 = [[8,7,6,5], 2 [1,0,3,4], 3 [16,15,14,13], 4 [9,10,0,12]] 5 6data2 = [[8,7,6,5], 7 [1,2,0,4], 8 [16,15,14,13], 9 [9,10,0,12]] 10 11def f(data): 12 result = [] 13 for col in zip(*data): 14 if sum(col) == 34: 15 result.append(col) 16 else: 17 if col.count(0) == 1: 18 # 一列に0が1つのとき 19 tmp = list(col) 20 tmp[tmp.index(0)] = 34 - sum(col) 21 result.append(tmp) 22 else: 23 # 一列に2つあるとき 24 fillvals = [i for i in range(1, 17) if i not in sum(data, [])] 25 result.append([fillvals.pop() if e == 0 else e for e in col]) 26 27 return list(map(list, zip(*result))) 28 29print(f(data1)) 30print(f(data2)) 31""" => 32[[8, 7, 6, 5], [1, 2, 3, 4], [16, 15, 14, 13], [9, 10, 11, 12]] 33[[8, 7, 6, 5], [1, 2, 11, 4], [16, 15, 14, 13], [9, 10, 3, 12]] 34"""

投稿2018/06/19 04:54

編集2018/06/19 05:44
hayataka2049

総合スコア30933

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問