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

カンパニーレ（ネフ社）という積み木パズルについて、pythonを使って組み合わせを全パターン計算をしました。
ただの趣味で調べただけなので、実用的な内容ではありません。
<img width="600px" alt="カンパニーレ　パーツ" src="https://image.jimcdn.com/app/cms/image/transf/dimension=455x1024:format=jpg/path/sb8991d0d3625399c/image/i0ab7bcb5d3b24782/version/1621566335/image.jpg">

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

#1. 考察をして、フローチャートを作成
考察の部分は別の記事で紹介していますので、<a href="https://patchwork-math.jimdofree.com/2021/05/19/%E7%A9%8D%E3%81%BF%E6%9C%A8%E3%83%91%E3%82%BA%E3%83%AB-%E3%82%AB%E3%83%B3%E3%83%91%E3%83%8B%E3%83%BC%E3%83%AC-%E3%83%8D%E3%83%95%E7%A4%BE-%E3%81%AE%E6%8F%83%E3%81%88%E6%96%B9/" rel="ugc">こちら</a>をご覧ください。
考察によって、以下のフローチャートを得ることができました。

<img width="600px" alt="カンパニーレ　フローチャート" src="https://image.jimcdn.com/app/cms/image/transf/none/path/sb8991d0d3625399c/image/iaf02a09cc428ab3d/version/1621572992/image.jpg">

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

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

#3. コード
```pyhton: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. 出力結果
茶と黄を追加して、同じ色ごとに並べ替えて、セルの色も変更した状態です。
<iframe src="https://docs.google.com/spreadsheets/d/e/2PACX-1vRLnHJIU2eImqbcx0EhD102RQTkNS9xKSziex_OyFFimTYYASdFcQLEptc_FsL1INjZScXLN6uvMf_W/pubhtml?gid=109089100&amp;single=true&amp;widget=true&amp;headers=false"　 width="600" height="450"></iframe>