0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

積み木パズル カンパニーレ(ネフ社)の組み合わせを全パターン計算

Last updated at Posted at 2021-05-21

カンパニーレ(ネフ社)という積み木パズルについて、pythonを使って組み合わせを全パターン計算をしました。
ただの趣味で調べただけなので、実用的な内容ではありません。
カンパニーレ パーツ

手順

1.考察をして、フローチャートを作成
2.どのようにコーディングするか
3.コード
4.出力結果

1. 考察をして、フローチャートを作成

考察の部分は別の記事で紹介していますので、こちらをご覧ください。
考察によって、以下のフローチャートを得ることができました。

カンパニーレ フローチャート

Fのまっさらな状態から、すべての色の矢印を1つずつ使って、Fに戻るパターンの組み合わせを求めればよいことが分かります。

2. どのようにコーディングするか

最近atcoderで勉強した、DFS(深さ優先探索),BFS(幅優先探索)を使えば簡単にできるのではないかと思ったのですが、
同じ色の矢印は1回しか使えないという制約があり、いい方法が思いつきませんでした。
今回は「濃青","青","濃緑","緑","黄緑","濃赤","薄赤","橙"」の8色をどの順番で使うかでチェックする方法にしました。
濃赤、緑は特定の場合に2種類の積み方があるため、その場合分けも必要になりました。
Excelへの書き込みは初めてやったので、とても簡単な内容ですが勉強になりました。

3. コード

Campanile.py
from itertools import permutations

colorlist=["濃青","青","濃緑","緑","黄緑","濃赤","薄赤","橙"]#使用する積み木の色のリストです。
flowchart = [
    [-1, 3, 1,-1,-1,-1,-1,-1],
    [-1,-1, 0, 3, 2, 4, 1,-1],
    [-1,-1,-1, 3, 1, 4, 2, 3],
    [ 4,-1,-1,-1, 3, 1,-1,-1],
    [-1, 0,-1, 1, 4,-1,-1, 2]
    ]#[i][j]について、iはA~Eの状態を0~4で、jはcolorlistの順、flowchart[i][j]は積み木を重ねた後の状態を0~4で表している
answerset = set()

def arrow(color:"色",point:"A~Eの状態",green,red): #point:A~Eにcolor:積み木の色を使ったときに状態を求める
    
    if selectredgreen % 2 == 0 and color == "緑" and point == 4 :#緑①を使用しているかどうか
        green = "緑①"
    elif selectredgreen % 2 == 1 and color == "緑" and point == 4:
        green = "緑②"
        
    if selectredgreen <= 1 and color == "濃赤" and point == 3:
        red = "赤①"
    elif selectredgreen > 1 and color == "濃赤" and point == 3:
        red = "赤②"
    return flowchart[point][colorlist.index(color)],green,red 
    
for selectredgreen in range(4):#濃赤①②と緑①②の場合分け

    if selectredgreen % 2 == 0:
        flowchart[4][3] = 1
    else:
        flowchart[4][3] = 2
        
    if selectredgreen <= 1:
        flowchart[3][5] = 1
    else:
        flowchart[3][5] = 2
        
    for i in permutations(colorlist,8): #8色の色の順列
        point = 3 #最初の状態 茶色を入れたのみなので状態D
        flag = 0 #完成パターンであるかどうか
        green = 0
        red = 0
        for j in range(8):
            point,green,red = arrow(i[j],point,green,red)
            if point == -1:
                flag = 1
                break
        if flag == 0:
            answerset.add((i,green,red))

import openpyxl

book = openpyxl.load_workbook('data.xlsx')# ブックを取得

sheet = book['Sheet1']# シートを取得

DarkBlue    ='191970'# セルの背景色の設定
Blue        ='0000ff'
DarkGreen   ='006400'
Green       ='228b22'
Greenyellow ='adff2f'
DarkRed     ='8b0000'
Red         ='ffa07a'
Orange      ='ffa500'

fill = [
    openpyxl.styles.PatternFill(patternType='solid',fgColor=DarkBlue   , bgColor=DarkBlue   ),
    openpyxl.styles.PatternFill(patternType='solid',fgColor=Blue       , bgColor=Blue       ),
    openpyxl.styles.PatternFill(patternType='solid',fgColor=DarkGreen  , bgColor=DarkGreen  ),
    openpyxl.styles.PatternFill(patternType='solid',fgColor=Green      , bgColor=Green      ),
    openpyxl.styles.PatternFill(patternType='solid',fgColor=Greenyellow, bgColor=Greenyellow),
    openpyxl.styles.PatternFill(patternType='solid',fgColor=DarkRed    , bgColor=DarkRed    ),
    openpyxl.styles.PatternFill(patternType='solid',fgColor=Red        , bgColor=Red        ),
    openpyxl.styles.PatternFill(patternType='solid',fgColor=Orange     , bgColor=Orange     )
    ]

i = 1
for j in answerset:

    for k in range(8):
        
        sheet.cell(row=i, column=k+1).value = j[0][k]# セルへ書き込む
        sheet.cell(row=i, column=k+1).fill = fill[colorlist.index(j[0][k])]
    
    for l in range(1,3):
        
        sheet.cell(row=i, column=l+8).value = j[l]
        
    i += 1

book.save('data.xlsx')# 保存する

4. 出力結果

茶と黄を追加して、同じ色ごとに並べ替えて、セルの色も変更した状態です。

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?