ソースコード
今回の連載 python/pypy/codonのソースコードディレクトリはこちら
https://github.com/suzukiiichiro/N-Queens/tree/master/10Bit_Python
インストールなどの構築はこちら
Nクイーン問題(66) Python-codonで高速化
https://suzukiiichiro.github.io/posts/2025-03-05-01-n-queens-suzuki/
carryChain(キャリーチェーン)について
キャリーチェーンはN27の解を発見したドレスデン大学の研究者が編み出したアルゴリズムです。
Jeffサマーズがミラーとビットマップの組み合わせでN23を発見し、電気通信大学がサマーズのアルゴリズムを並列処理しN24を発見、プロアクティブが対称解除法でN25を発見し、N27でキャリーチェーンによりドレスデン大学が世界一となりました。
まず最初に対称解除法の実行結果を見てみましょう。
## 対象解除法
# <> 06Bash_symmetry.sh 対象解除法
# N: Total Unique hh:mm:ss
# 4: 2 1 0:00:00
# 5: 10 2 0:00:00
# 6: 4 1 0:00:00
# 7: 40 6 0:00:00
# 8: 92 12 0:00:00
# 9: 352 46 0:00:00
# 10: 724 92 0:00:02
# 11: 2680 341 0:00:05
# 12: 14200 1787 0:00:26
# 13: 73712 9233 0:02:28
# 14: 365596 45752 0:14:18
# 15: 2279184 285053 1:23:34
N25で、1時間23分かかっています。
Bashだからこその遅さです。CプログラムではN17までは1秒かかりません。
とはいえ、アルゴリズムやロジックを深く知るためには、プログラムのシンタックスに悩むドデカ級のプログラム言語よりも、身近なBash言語のほうが直感的でよいのです。
UNIXを開発したAT&Tベル研究所では、開発者はBashでプロトタイプを作り、その後プログラマがCに移植します。
新しい開発、革新的なロジックを研究することにBashは多くの現場で活躍してきました。CやJavaは、知恵を導入するまえに、構文(シンタックス)の複雑さに気を奪われ、書いた気になる、作った気になる言語と言われています。
では、N27を叩き出したドレスデン大学のソースをBashに移植して、高速化、最適化したソースの実行結果を見てみます。
# キャリーチェーン
# <> 07Bash_carryChain.sh
# N: Total Unique hh:mm:ss
# 4: 2 1 0:00:00
# 5: 10 2 0:00:00
# 6: 4 1 0:00:00
# 7: 40 6 0:00:01
# 8: 92 12 0:00:02
# 9: 352 46 0:00:12
# 10: 724 92 0:00:44
# 11: 2680 341 0:02:39
# 12: 14200 1788 0:08:35
# 13: 73712 9237 0:27:05
# 14: 365596 45771 1:30:40
# 15: 2279184 285095 5:59:03
おそい。。。。
遅すぎますね。大丈夫なのでしょうか。
実際、とてつもなく遅いのですが、キャリーチェーンとは
1.対称解除とは比較にならないほど遅い
2.対称解除とは比較にならないほどメモリ消費量が小さい
3.対称解除と比べ、Nが小さいときに遅いが、Nが大きくなるに従って対称解除のスピードに追いつき、N17で対称解除を追い抜き安定して実行を継続する。
4.一方で対称解除は、Nが小さいときは快調だが、Nが大きくなるに従って、board配列を中心にメモリ消費量が爆発的に肥大し、N17以降、高い確率でバースト、システムは停止する。
ということで、キャリーチェーンは、遅いけど安定的に処理し続けるアルゴリズムなのです。
さらに、次の章で紹介する並列処理に極めて高い親和性があるアルゴリズムです。
キャリーチェーン ロジック解説
まず、NQ()を実行するとcarryChain()を呼び出します。
carrychain()は、チェーンの初期化を行うinitChain()と、チェーンのビルドを行う buildChain()を実行します。
チェーンの初期化を行う initChain()は以下の2行のクイーンが配置できるすべてをブルートフォースで導き出します。ここではクイーンの効きは考慮しません。
1行目の配置を pres_a配列に、2行目の配列をpres_b配列に保存します。
initChain()
+-+-+-+-+-+-+-+
|Q|Q|Q|Q|Q|Q|Q|
+-+-+-+-+-+-+-+
|Q|Q|Q|Q|Q|Q|Q|
+-+-+-+-+-+-+-+
| | | | | | | |
+-+-+-+-+-+-+-+
| | | | | | | |
+-+-+-+-+-+-+-+
| | | | | | | |
+-+-+-+-+-+-+-+
| | | | | | | |
+-+-+-+-+-+-+-+
| | | | | | | |
+-+-+-+-+-+-+-+
次にbuildChain()は、上2行に配置します。
buildChain()では配置のたびに placement()を呼び出し、クイーンの効きに問題がないかをチェックします。
ざっくりいうと上1行目のクイーンはミラーのロジックにより、Nの半分しか配置しません。上2行目はNすべてを配置候補とします。
buildChain()
+-+-+-+-+-+-+-+
| | | | | | |Q| ←
+-+-+-+-+-+-+-+
| | | | |Q|x|x| ←
+-+-+-+-+-+-+-+
| | | | | | | |
+-+-+-+-+-+-+-+
| | | | | | | |
+-+-+-+-+-+-+-+
| | | | | | | |
+-+-+-+-+-+-+-+
| | | | | | | |
+-+-+-+-+-+-+-+
| | | | | | | |
+-+-+-+-+-+-+-+
上2行に配置できたら、左2列を作成します。
↓↓
+-+-+-+-+-+-+-+
|x|x| | | | |Q|
+-+-+-+-+-+-+-+
|x|x|x|x|Q|x|x|
+-+-+-+-+-+-+-+
|Q|x|x|x|x|x|x|
+-+-+-+-+-+-+-+
|x|x|x|x|x| |x|
+-+-+-+-+-+-+-+
|x|x|x|x|x|x|x|
+-+-+-+-+-+-+-+
|x|Q|x|x|x|x|x|
+-+-+-+-+-+-+-+
|x|x|x|Q|x|x|x|
+-+-+-+-+-+-+-+
左2列が完成したら、下2行を作成します。
クイーンの配置の都度、placement()が呼び出され、クイーンの効きをチェックします。
+-+-+-+-+-+-+-+
|x|x|x|x|x|x|Q|
+-+-+-+-+-+-+-+
|x|x| | |Q|x|x|
+-+-+-+-+-+-+-+
|Q|x| |x|x| |x|
+-+-+-+-+-+-+-+
|x|x|x|x|x| |x|
+-+-+-+-+-+-+-+
|x|x|x|x|x|x|x|
+-+-+-+-+-+-+-+
|x|Q|x|x|x|x|x| ←
+-+-+-+-+-+-+-+
|x|x|x|Q|x|x|x| ←
+-+-+-+-+-+-+-+
すでに配置されている場合はそれを許可し、配置したことにします。
下2行を作成したら、右2列を作成します。
+-+-+-+-+-+-+-+
|x|x|x|x|x|x|Q|
+-+-+-+-+-+-+-+
|x|x| |x|Q|x|x|
+-+-+-+-+-+-+-+
|Q|x| |x|x|x|x|
+-+-+-+-+-+-+-+
|x|x|x|x|x|Q|x|
+-+-+-+-+-+-+-+
|x|x|x|x|x|x|x|
+-+-+-+-+-+-+-+
|x|Q|x|x|x|x|x|
+-+-+-+-+-+-+-+
|x|x|x|Q|x|x|x|
+-+-+-+-+-+-+-+
↑↑
配置が終わりました。
配置が終わったら、carryChainSymmetry()を呼び出して、対称解除法を実行します。
これまでのsymmetry.shでは1行目のクイーンが角にあるか、ないかで分岐し、クイーンの配置がすべて完了したら対称解除を行ってきました。ようするに処理の最終局面で対称解除を行ってきたわけです。
ですので、ボード情報をboard配列に入れて90度回転を繰り返してきました。この処理はbit処理でなかった(僕がどうやってよいか分からなかった)ため、負荷も高くなってしまいました。
盤面のクイーンの配置すべてを格納したboard配列をまるっと90度回転、さらに90度回転、さらにさらに90度回転と繰り返して、COUNT2,COUNT4,COUNT8のユニーク解を導き出していました。
キャリーチェーンは、盤面の外枠2行2列のみにクイーンを配置します。理由は「対称解除は2行2列に配置されていれば可能」だからです。
まず、2行2列を配置し、対称解除を行い、COUNT2,COUNT4,COUNT8のいずれかである場合にかぎって、内側にクイーンの配置処理に入ります。
すごいですね! 新しいです。
最初に対称解除を行うことができるから、最初からbit処理可能です。そして最後までbit処理で完結できます。
これまでやってきた枝刈りのロジックは、ドレスデン大学のソースにはありませんでしたが、追記しておきました。期待大!ですね。
ですが、激しく遅いのです。残念です。
とはいえ世界一となったこのロジックはただものではありません。極めて優れたロジックで、パッと見だめでもじつはイケてるプログラムなのです。
ノードレイヤーに一工夫入れたキャリーチェーンは確かに遅いのですが、後継の「コンステレーション」では、これまで最速だったビット版対象解除法よりも良い結果を導くことに成功します。お楽しみに
from datetime import datetime
import copy
# pypyを使うときは以下を活かしてcodon部分をコメントアウト
import pypyjit
# pypyjit.set_param('max_unroll_recursion=-1')
# pypy では ThreadPool/ProcessPoolが動きます
#
# from threading import Thread
# from multiprocessing import Pool as ThreadPool
# import concurrent
# from concurrent.futures import ThreadPoolExecutor
# from concurrent.futures import ProcessPoolExecutor
#
class NQueens17:
def __init__(self):
pass
def carryChain(self,size:int)->int:
def process(size:int,sym:int,B:list[int])->int:
def solve(row:int,left:int,down:int,right:int)->int:
total:int=0
if not down+1:
return 1
while row&1:
row>>=1
left<<=1
right>>=1
row>>=1 # 1行下に移動する
bitmap:int=~(left|down|right)
while bitmap!=0:
bit=-bitmap&bitmap
total+=solve(row,(left|bit)<<1,down|bit,(right|bit)>>1)
bitmap^=bit
return total
return sym*solve(B[0]>>2,B[1]>>4,(((B[2]>>2|~0<<size-4)+1)<<size-5)-1,B[3]>>4<<size-5) # sym 0:COUNT2 1:COUNT4 2:COUNT8
def Symmetry(size:int,n:int,w:int,s:int,e:int,B:list[int],B4:list[int])->int:
# 前計算
ww=(size-2) * (size-1)-1-w
w2=(size-2) * (size-1)-1
# 対角線上の反転が小さいかどうか確認する
if s==ww and n<(w2-e): return 0
# 垂直方向の中心に対する反転が小さいかを確認
if e==ww and n>(w2-n): return 0
# 斜め下方向への反転が小さいかをチェックする
if n==ww and e>(w2-s): return 0
# 【枝刈り】1行目が角の場合
if not B4[0]: return process(size,8,B) # COUNT8
# n,e,s==w の場合は最小値を確認
if s==w:
if n!=w or e!=w: return 0
return process(size,2,B) # COUNT2
# e==w は180度回転して同じ
if e==w and n>=s:
if n>s: return 0
return process(size,4,B) # COUNT4
# その他の場合
return process(size,8,B) # COUNT8
def placement(size:int,dimx:int,dimy:int,B:list[int],B4:list[int])->int:
if B4[dimx]==dimy: return 1
if B4[0]:
if ( B4[0]!=-1 and ((dimx<B4[0] or dimx>=size-B4[0]) and (dimy==0 or dimy==size-1)) ) or ((dimx==size-1) and (dimy<=B4[0] or dimy>=size-B4[0])): return 0
elif (B4[1]!=-1) and (B4[1]>=dimx and dimy==1): return 0
if ((B[0]&(1<<dimx)) or B[1]&(1<<(size-1-dimx+dimy))) or (B[2]&(1<<dimy)) or (B[3]&(1<<(dimx+dimy))): return 0
B[0]|=1<<dimx
B[1]|=1<<(size-1-dimx+dimy)
B[2]|=1<<dimy
B[3]|=1<<(dimx+dimy)
B4[dimx]=dimy
return 1
def buildChain(size:int,pres_a:list[int],pres_b:list[int])->int:
def deepcopy(lst:list[int])->list:
return [deepcopy(item) if isinstance(item,list) else item for item in lst]
total:int=0
B:list[int]=[0,0,0,0]
B4:list[int]=[-1]*size # Bの初期化
sizeE:int=size-1
sizeEE:int=size-2
range_size:int=(size//2)*(size-3)+1
for w in range(range_size):
wB,wB4=deepcopy(B),deepcopy(B4)
# 1.0行目と1行目にクイーンを配置
if not placement(size,0,pres_a[w],wB,wB4) or not placement(size,1,pres_b[w],wB,wB4): continue
# 2.90度回転
wMirror=set(range(w,(sizeEE)*(sizeE)-w,1))
for n in wMirror:
nB,nB4=deepcopy(wB),deepcopy(wB4)
if not placement(size,pres_a[n],sizeE,nB,nB4) or not placement(size,pres_b[n],sizeEE,nB,nB4): continue
# 3.90度回転
for e in wMirror:
eB,eB4=deepcopy(nB),deepcopy(nB4)
if not placement(size,sizeE,sizeE-pres_a[e],eB,eB4) or not placement(size,sizeEE,sizeE-pres_b[e],eB,eB4): continue
# 4.90度回転
for s in wMirror:
sB,sB4=deepcopy(eB),deepcopy(eB4)
if not placement(size,sizeE-pres_a[s],0,sB,sB4) or not placement(size,sizeE-pres_b[s],1,sB,sB4): continue
# 対象解除法
total+=Symmetry(size,n,w,s,e,sB,sB4)
return total
def initChain(size:int,pres_a:list[int],pres_b:list[int])->None:
idx:int=0
for a in range(size):
for b in range(size):
# if (a>=b and (a-b)<=1) or (b>a and (b-a<=1)):
if abs(a-b)<=1: continue
# pres_a[idx]=a
# pres_b[idx]=b
pres_a[idx],pres_b[idx]=a,b
idx+=1
pres_a:list[int]=[0]*930
pres_b:list[int]=[0]*930
initChain(size,pres_a,pres_b)
return buildChain(size,pres_a,pres_b)
class NQueens17_carryChain():
def main(self)->None:
nmin:int=5
nmax:int=18
print(" N: Total Unique hh:mm:ss.ms")
for size in range(nmin,nmax):
start_time=datetime.now()
NQ=NQueens17()
total:int=NQ.carryChain(size)
time_elapsed=datetime.now()-start_time
text=str(time_elapsed)[:-3]
print(f"{size:2d}:{total:13d}{0:13d}{text:>20s}")
""" メイン実行部分 """
if __name__=="__main__":
NQueens17_carryChain().main()
実行結果
CentOS$ codon build -release 15Python_carryChain.py && ./15Python_carryChain
N: Total Unique hh:mm:ss.ms
5: 10 0 0:00:00.000
6: 4 0 0:00:00.000
7: 40 0 0:00:00.000
8: 92 0 0:00:00.003
9: 352 0 0:00:00.012
10: 724 0 0:00:00.042
11: 2680 0 0:00:00.130
12: 14200 0 0:00:00.406
13: 73712 0 0:00:01.111
14: 365596 0 0:00:02.901
15: 2279184 0 0:00:07.301
16: 14772512 0 0:00:19.571
17: 95815104 0 0:01:14.466
ソースコード
今回の連載 python/pypy/codonのソースコードディレクトリはこちら
https://github.com/suzukiiichiro/N-Queens/tree/master/10Bit_Python
Nクイーン問題 過去記事アーカイブ
【過去記事アーカイブ】Nクイーン問題 過去記事一覧
https://suzukiiichiro.github.io/search/?keyword=Nクイーン問題
【Github】エイト・クイーンのソース置き場 BashもJavaもPythonも!
https://github.com/suzukiiichiro/N-Queens
Nクイーン問題(81)Python-codonで高速化 15Python_carryChain
https://suzukiiichiro.github.io/posts/2025-03-11-05-n-queens-suzuki/
Nクイーン問題(80)Python-並列処理で高速化 14Python_NodeLayer_symmetry_ProcessPool
https://suzukiiichiro.github.io/posts/2025-03-11-04-n-queens-suzuki/
Nクイーン問題(79)Python-codonで高速化 13Python_NodeLayer_symmetry
https://suzukiiichiro.github.io/posts/2025-03-11-03-n-queens-suzuki/
Nクイーン問題(78)Python-codonで高速化 12Python_NodeLayer_mirror
https://suzukiiichiro.github.io/posts/2025-03-11-02-n-queens-suzuki/
Nクイーン問題(77)Python-codonで高速化 11Python_NodeLayer
https://suzukiiichiro.github.io/posts/2025-03-11-01-n-queens-suzuki/
Nクイーン問題(76)Python-並列処理で高速化 10Python_bit_symmetry_ProcessPool
https://suzukiiichiro.github.io/posts/2025-03-10-05-n-queens-suzuki/
Nクイーン問題(75)Python-並列処理で高速化 09Python_bit_symmetry_ThreadPool
https://suzukiiichiro.github.io/posts/2025-03-10-04-n-queens-suzuki/
Nクイーン問題(74)Python-codonで高速化 08Python_bit_symmetry
https://suzukiiichiro.github.io/posts/2025-03-10-03-n-queens-suzuki/
Nクイーン問題(73)Python-codonで高速化 07Python_bit_mirror
https://suzukiiichiro.github.io/posts/2025-03-10-02-n-queens-suzuki/
Nクイーン問題(72)Python-codonで高速化 06Python_bit_backTrack
https://suzukiiichiro.github.io/posts/2025-03-10-01-n-queens-suzuki/
Nクイーン問題(71)Python-codonで高速化 05Python_optimize
https://suzukiiichiro.github.io/posts/2025-03-07-01-n-queens-suzuki/
Nクイーン問題(70)Python-codonで高速化 04Python_symmetry
https://suzukiiichiro.github.io/posts/2025-03-06-02-n-queens-suzuki/
Nクイーン問題(69)Python-codonで高速化 03Python_backTracking
https://suzukiiichiro.github.io/posts/2025-03-06-01-n-queens-suzuki/
Nクイーン問題(68)Python-codonで高速化 02Python_postFlag
https://suzukiiichiro.github.io/posts/2025-03-05-03-n-queens-suzuki/
Nクイーン問題(67)Python-codonで高速化 01Python_bluteForce
https://suzukiiichiro.github.io/posts/2025-03-05-02-n-queens-suzuki/
Nクイーン問題(66)Python-codonで高速化
https://suzukiiichiro.github.io/posts/2025-03-05-01-n-queens-suzuki/
Nクイーン問題(65) N25を解決!事実上の日本一に
https://suzukiiichiro.github.io/posts/2024-04-25-01-n-queens-suzuki/
Nクイーン問題(64)第七章 並列処理 キャリーチェーン NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-05-n-queens-suzuki/
Nクイーン問題(63)第七章 並列処理 キャリーチェーン NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-05-n-queens-suzuki/
Nクイーン問題(62)第七章 並列処理 対称解除法 ビットボード NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-04-n-queens-suzuki/
Nクイーン問題(61)第七章 並列処理 対称解除法 ノードレイヤー NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-03-n-queens-suzuki/
Nクイーン問題(60)第七章 並列処理 ミラー NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-02-n-queens-suzuki/
Nクイーン問題(59)第七章 並列処理 ビットマップ NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-01-n-queens-suzuki/
Nクイーン問題(58)第六章 並列処理 pthread C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-09-n-queens-suzuki/
Nクイーン問題(57)第八章 キャリーチェーン C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-08-n-queens-suzuki/
Nクイーン問題(56)第八章 ミラー C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-06-n-queens-suzuki/
Nクイーン問題(55)第八章 ビットマップ C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-05-n-queens-suzuki/
Nクイーン問題(54)第八章 ビットマップ C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-04-n-queens-suzuki/
Nクイーン問題(53)第八章 配置フラグ C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-03-n-queens-suzuki/
Nクイーン問題(52)第八章 バックトラック C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-02-n-queens-suzuki/
Nクイーン問題(51)第八章 ブルートフォース C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-01-n-queens-suzuki/
Nクイーン問題(50)第七章 マルチプロセス Python編
https://suzukiiichiro.github.io/posts/2023-06-21-04-n-queens-suzuki/
Nクイーン問題(49)第七章 マルチスレッド Python編
https://suzukiiichiro.github.io/posts/2023-06-21-03-n-queens-suzuki/
Nクイーン問題(48)第七章 シングルスレッド Python編
https://suzukiiichiro.github.io/posts/2023-06-21-02-n-queens-suzuki/
Nクイーン問題(47)第七章 クラス Python編
https://suzukiiichiro.github.io/posts/2023-06-21-01-n-queens-suzuki/
Nクイーン問題(46)第七章 ステップNの実装 Python編
https://suzukiiichiro.github.io/posts/2023-06-16-02-n-queens-suzuki/
Nクイーン問題(45)第七章 キャリーチェーン Python編
https://suzukiiichiro.github.io/posts/2023-06-16-01-n-queens-suzuki/
Nクイーン問題(44)第七章 対象解除法 Python編
https://suzukiiichiro.github.io/posts/2023-06-14-02-n-queens-suzuki/
Nクイーン問題(43)第七章 ミラー Python編
https://suzukiiichiro.github.io/posts/2023-06-14-01-n-queens-suzuki/
Nクイーン問題(42)第七章 ビットマップ Python編
https://suzukiiichiro.github.io/posts/2023-06-13-05-n-queens-suzuki/
Nクイーン問題(41)第七章 配置フラグ Python編
https://suzukiiichiro.github.io/posts/2023-06-13-04-n-queens-suzuki/
Nクイーン問題(40)第七章 バックトラック Python編
https://suzukiiichiro.github.io/posts/2023-06-13-03-n-queens-suzuki/
Nクイーン問題(39)第七章 バックトラック準備編 Python編
https://suzukiiichiro.github.io/posts/2023-06-13-02-n-queens-suzuki/
Nクイーン問題(38)第七章 ブルートフォース Python編
https://suzukiiichiro.github.io/posts/2023-06-13-01-n-queens-suzuki/
Nクイーン問題(37)第六章 C言語移植 その17 pthread並列処理完成
https://suzukiiichiro.github.io/posts/2023-05-30-17-n-queens-suzuki/
Nクイーン問題(36)第六章 C言語移植 その16 pthreadの実装
https://suzukiiichiro.github.io/posts/2023-05-30-16-n-queens-suzuki/
Nクイーン問題(35)第六章 C言語移植 その15 pthread実装直前版完成
https://suzukiiichiro.github.io/posts/2023-05-30-15-n-queens-suzuki/
Nクイーン問題(34)第六章 C言語移植 その14
https://suzukiiichiro.github.io/posts/2023-05-30-14-n-queens-suzuki/
Nクイーン問題(33)第六章 C言語移植 その13
https://suzukiiichiro.github.io/posts/2023-05-30-13-n-queens-suzuki/
Nクイーン問題(32)第六章 C言語移植 その12
https://suzukiiichiro.github.io/posts/2023-05-30-12-n-queens-suzuki/
Nクイーン問題(31)第六章 C言語移植 その11
https://suzukiiichiro.github.io/posts/2023-05-30-11-n-queens-suzuki/
Nクイーン問題(30)第六章 C言語移植 その10
https://suzukiiichiro.github.io/posts/2023-05-30-10-n-queens-suzuki/
Nクイーン問題(29)第六章 C言語移植 その9
https://suzukiiichiro.github.io/posts/2023-05-30-09-n-queens-suzuki/
Nクイーン問題(28)第六章 C言語移植 その8
https://suzukiiichiro.github.io/posts/2023-05-30-08-n-queens-suzuki/
Nクイーン問題(27)第六章 C言語移植 その7
https://suzukiiichiro.github.io/posts/2023-05-30-07-n-queens-suzuki/
Nクイーン問題(26)第六章 C言語移植 その6
https://suzukiiichiro.github.io/posts/2023-05-30-06-n-queens-suzuki/
Nクイーン問題(25)第六章 C言語移植 その5
https://suzukiiichiro.github.io/posts/2023-05-30-05-n-queens-suzuki/
Nクイーン問題(24)第六章 C言語移植 その4
https://suzukiiichiro.github.io/posts/2023-05-30-04-n-queens-suzuki/
Nクイーン問題(23)第六章 C言語移植 その3
https://suzukiiichiro.github.io/posts/2023-05-30-03-n-queens-suzuki/
Nクイーン問題(22)第六章 C言語移植 その2
https://suzukiiichiro.github.io/posts/2023-05-30-02-n-queens-suzuki/
Nクイーン問題(21)第六章 C言語移植 その1
N-Queens問://suzukiiichiro.github.io/posts/2023-05-30-01-n-queens-suzuki/
Nクイーン問題(20)第五章 並列処理
https://suzukiiichiro.github.io/posts/2023-05-23-02-n-queens-suzuki/
Nクイーン問題(19)第五章 キャリーチェーン
https://suzukiiichiro.github.io/posts/2023-05-23-01-n-queens-suzuki/
Nクイーン問題(18)第四章 エイト・クイーンノスタルジー
https://suzukiiichiro.github.io/posts/2023-04-25-01-n-queens-suzuki/
Nクイーン問題(17)第四章 偉人のソースを読む「N24を発見 Jeff Somers」
https://suzukiiichiro.github.io/posts/2023-04-21-01-n-queens-suzuki/
Nクイーン問題(16)第三章 対象解除法 ソース解説
https://suzukiiichiro.github.io/posts/2023-04-18-01-n-queens-suzuki/
Nクイーン問題(15)第三章 対象解除法 ロジック解説
https://suzukiiichiro.github.io/posts/2023-04-13-02-nqueens-suzuki/
Nクイーン問題(14)第三章 ミラー
https://suzukiiichiro.github.io/posts/2023-04-13-01-nqueens-suzuki/
Nクイーン問題(13)第三章 ビットマップ
https://suzukiiichiro.github.io/posts/2023-04-05-01-nqueens-suzuki/
Nクイーン問題(12)第二章 まとめ
https://suzukiiichiro.github.io/posts/2023-03-17-02-n-queens-suzuki/
Nクイーン問題(11)第二章 配置フラグの再帰・非再帰
https://suzukiiichiro.github.io/posts/2023-03-17-01-n-queens-suzuki/
Nクイーン問題(10)第二章 バックトラックの再帰・非再帰
https://suzukiiichiro.github.io/posts/2023-03-16-01-n-queens-suzuki/
Nクイーン問題(9)第二章 ブルートフォースの再帰・非再帰
https://suzukiiichiro.github.io/posts/2023-03-14-01-n-queens-suzuki/
Nクイーン問題(8)第一章 まとめ
https://suzukiiichiro.github.io/posts/2023-03-09-01-n-queens-suzuki/
Nクイーン問題(7)第一章 ブルートフォース再び
https://suzukiiichiro.github.io/posts/2023-03-08-01-n-queens-suzuki/
Nクイーン問題(6)第一章 配置フラグ
https://suzukiiichiro.github.io/posts/2023-03-07-01-n-queens-suzuki/
Nクイーン問題(5)第一章 進捗表示テーブルの作成
https://suzukiiichiro.github.io/posts/2023-03-06-01-n-queens-suzuki/
Nクイーン問題(4)第一章 バックトラック
https://suzukiiichiro.github.io/posts/2023-02-21-01-n-queens-suzuki/
Nクイーン問題(3)第一章 バックトラック準備編
https://suzukiiichiro.github.io/posts/2023-02-14-03-n-queens-suzuki/
Nクイーン問題(2)第一章 ブルートフォース
https://suzukiiichiro.github.io/posts/2023-02-14-02-n-queens-suzuki/
Nクイーン問題(1)第一章 エイトクイーンについて
https://suzukiiichiro.github.io/posts/2023-02-14-01-n-queens-suzuki/