Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pycon JP 2018 python_お絵描きパズルのロジックまとめ.pdf

J-Ogu
September 06, 2018

Pycon JP 2018 python_お絵描きパズルのロジックまとめ.pdf

J-Ogu

September 06, 2018
Tweet

More Decks by J-Ogu

Other Decks in Programming

Transcript

  1. 処理1 確定マスの塗りつぶし 処理5 端から確定マスを見つける 処理2 端が確定した際の処理 処理6 指示の最大数と同じ連続した塗り 処理3 届かないマスの確定処理

    処理7 端から指示 +1のマスが塗られていたら 処理9 端から 「1」 と 「2」 の連続した塗り指示の確定処理 処理4 「×」 のマスで分割して処理1〜3を実行 処理8 端から 「1」 の連続した塗り指示の確定処理 処理10 連続された塗りから対象の指示数字を特定する お絵描きロジックの解き方まとめ
  2. pythonの内部処理 ・3つのパターンがある numpyで配列計算 全てのリストを加算 リストの数と一致した 箇所は塗り確定 [1, 1, 1, 1,

    1, 1, 1, 1, 0, 0] [0, 1, 1, 1, 1, 1, 1, 1, 1, 0] [0, 0, 1, 1, 1, 1, 1, 1, 1, 1] [1, 2, 3, 3, 3, 3, 3, 3, 2, 1] [□,□,▪,▪,▪,▪,▪,▪,□,□] 処理1 確定マスの塗りつぶし 3つのパターンがある 全てのパターンで 塗られているマスは確定 8 処理1 確定マスの塗りつぶし
  3. 8 処理1 確定マスの塗りつぶし 3つのパターンがある 全てのパターンで 塗られているマスは確定 pythonの内部処理 ・3つのパターンがある numpyで配列計算 全てのリストを加算

    リストの数と一致した 箇所は塗り確定 [1, 1, 1, 1, 1, 1, 1, 1, 0, 0] [0, 1, 1, 1, 1, 1, 1, 1, 1, 0] [0, 0, 1, 1, 1, 1, 1, 1, 1, 1] [1, 2, 3, 3, 3, 3, 3, 3, 2, 1] [□,□,▪,▪,▪,▪,▪,▪,□,□] import itertools n_list = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] n_vals = [8] NLISTLEN = len(n_list) # 隙間の数を埋める処理 interval_len = len(n_vals) + 1 sum_range_num = int(NLISTLEN - sum(np.array(n_vals))) # 左右のどちらかが 「0」 になることを見越して処理量を減らすための処理 range_num = sum_range_num - interval_len + 3 interval = [list(b) for b in list(itertools.product(range(range_num+1), repeat = interval_len)) if sum(b) == sum_range_num and (0 not in b[1:-1] or len(b) <= 2)] ## interval = [0,2],[1,1],[2,0] patarn = np.zeros(NLISTLEN) for iv_val in interval: new_list = np.zeros(0) for w,n_value in enumerate(n_vals): new_list = np.append(new_list, np.zeros(int(iv_val[w]))) new_list = np.append(new_list, np.ones(int(n_value))) new_list = np.append(new_list, np.zeros(NLISTLEN - len(new_list))) patarn = patarn+new_list ## patarn = [1,2,3,3,3,3,3,3,2,1] bunkatsu = np.array([ 1 if val==len(interval) or n_list[nums[i]] == 1 else 0 for i,val in enumerate(patarn)]) ## interval = [0,0,1,1,1,1,1,1,0,0] = [□,□,▪,▪,▪,▪,▪,▪,□,□] bunkatsu = np.array([-1 if val==0 else bunkatsu[i] for i,val in enumerate(patarn)]) n_list[nums[0]:nums[-1]+1] = bunkatsu 「itertools」 を使ってみた 処理1 確定マスの塗りつぶし
  4. 処理1 確定マスの塗りつぶし 3つのパターンがある 全てのパターンで 塗られているマスは確定 6,2 処理1 確定マスの塗りつぶし import itertools

    n_list = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] n_vals = [6,2] NLISTLEN = len(n_list) # 隙間の数を埋める処理 interval_len = len(n_vals) + 1 sum_range_num = int(NLISTLEN - sum(np.array(n_vals))) # 左右のどちらかが 「0」 になることを見越して処理量を減らすための処理 range_num = sum_range_num - interval_len + 3 interval = [list(b) for b in list(itertools.product(range(range_num+1), repeat = interval_len)) if sum(b) == sum_range_num and (0 not in b[1:-1] or len(b) <= 2)] ## interval = [0,1,1],[0,2,0],[1,1,0] patarn = np.zeros(NLISTLEN) for iv_val in interval: new_list = np.zeros(0) for w,n_value in enumerate(n_vals): new_list = np.append(new_list, np.zeros(int(iv_val[w]))) new_list = np.append(new_list, np.ones(int(n_value))) new_list = np.append(new_list, np.zeros(NLISTLEN - len(new_list))) patarn = patarn+new_list ## patarn = [2,3,3,3,3,3,1,1,3,2] bunkatsu = np.array([ 1 if val==len(interval) or n_list[nums[i]] == 1 else 0 for i,val in enumerate(patarn)]) ## interval = [0,1,1,1,1,1,0,0,1,0] = [□,▪,▪,▪,▪,▪,□,□,▪,□] bunkatsu = np.array([-1 if val==0 else bunkatsu[i] for i,val in enumerate(patarn)]) n_list[nums[0]:nums[-1]+1] = bunkatsu 「itertools」 を使ってみた
  5. 処理1 確定マスの塗りつぶし 処理1 確定マスの塗りつぶし import itertools n_list = [0, 0,

    0, 0, 0, 0, 0, 0, 0, 0] n_vals = [6,2] NLISTLEN = len(n_list) # 隙間の数を埋める処理 interval_len = len(n_vals) + 1 sum_range_num = int(NLISTLEN - sum(np.array(n_vals))) # 左右のどちらかが 「0」 になることを見越して処理量を減らすための処理 range_num = sum_range_num - interval_len + 3 interval = [list(b) for b in list(itertools.product(range(range_num+1), repeat = interval_len)) if sum(b) == sum_range_num and (0 not in b[1:-1] or len(b) <= 2)] ## interval = [0,1,1],[0,2,0],[1,1,0] patarn = np.zeros(NLISTLEN) for iv_val in interval: new_list = np.zeros(0) for w,n_value in enumerate(n_vals): new_list = np.append(new_list, np.zeros(int(iv_val[w]))) new_list = np.append(new_list, np.ones(int(n_value))) new_list = np.append(new_list, np.zeros(NLISTLEN - len(new_list))) patarn = patarn+new_list ## patarn = [2,3,3,3,3,3,1,1,3,2] bunkatsu = np.array([ 1 if val==len(interval) or n_list[nums[i]] == 1 else 0 for i,val in enumerate(patarn)]) ## interval = [0,1,1,1,1,1,0,0,1,0] = [□,▪,▪,▪,▪,▪,□,□,▪,□] bunkatsu = np.array([-1 if val==0 else bunkatsu[i] for i,val in enumerate(patarn)]) n_list[nums[0]:nums[-1]+1] = bunkatsu 「itertools」 を使ってみた 6,2 3つのパターンがある 全てのパターンで 塗られているマスは確定 pythonの内部処理 ・3つのパターンがある numpyで配列計算 全てのリストを加算 リストの数と一致した 箇所は塗り確定 [1, 1, 1, 1, 1, 1, 0, 1, 1, 0] [1, 1, 1, 1, 1, 1, 0, 0, 1, 1] [0, 1, 1, 1, 1, 1, 1, 0, 1, 1] [2, 3, 3, 3, 3, 3, 1, 1, 3, 2] [□,▪,▪,▪,▪,▪,□,□,▪,□]
  6. 処理1 確定マスの塗りつぶし 処理1 確定マスの塗りつぶし import itertools n_list = [0, 0,

    0, 0, 0, 0, 0, 0, 0, 0] n_vals = [6,2] # 隙間の数を埋める処理 リファクト後の処理 for n,val in enumerate(n_vals): af = sum(n_vals[n:]) + len(n_vals[n:]) - 1 bf = sum(n_vals[:n+1]) + len(n_vals[:n+1]) - 1 if not list(n_list[-af:bf]):continue n_list[-af:bf] = 1 if len(n_list) == sum(n_vals) + len(n_vals) - 1: for n,val in enumerate(n_vals[:-1]): n_list[sum(n_vals[:n+1]) + len(n_vals[:n+1]) - 1] = -1 n_list[nums[0]:nums[-1]+1] = bunkatsu import itertools n_list = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] n_vals = [6,2] NLISTLEN = len(n_list) # 隙間の数を埋める処理 interval_len = len(n_vals) + 1 sum_range_num = int(NLISTLEN - sum(np.array(n_vals))) # 左右のどちらかが 「0」 になることを見越して処理量を減らすための処理 range_num = sum_range_num - interval_len + 3 interval = [list(b) for b in list(itertools.product(range(range_num+1), repeat = interval_len)) if sum(b) == sum_range_num and (0 not in b[1:-1] or len(b) <= 2)] ## interval = [0,1,1],[0,2,0],[1,1,0] patarn = np.zeros(NLISTLEN) for iv_val in interval: new_list = np.zeros(0) for w,n_value in enumerate(n_vals): new_list = np.append(new_list, np.zeros(int(iv_val[w]))) new_list = np.append(new_list, np.ones(int(n_value))) new_list = np.append(new_list, np.zeros(NLISTLEN - len(new_list))) patarn = patarn+new_list ## patarn = [2,3,3,3,3,3,1,1,3,2] bunkatsu = np.array([ 1 if val==len(interval) or n_list[nums[i]] == 1 else 0 for i,val in enumerate(patarn)]) ## interval = [0,1,1,1,1,1,0,0,1,0] = [□,▪,▪,▪,▪,▪,□,□,▪,□] bunkatsu = np.array([-1 if val==0 else bunkatsu[i] for i,val in enumerate(patarn)]) n_list[nums[0]:nums[-1]+1] = bunkatsu 処理1のリファクタリング(別の考え方) 6,2 3つのパターンがある 全てのパターンで 塗られているマスは確定 6,2 6,2 6,2 6,2 左から詰めて 「6」 の配置 右から詰めて 「2」 の配置 右から詰めて 「6」 の配置 左から詰めて 「2」 の配置 左から詰めた際の一番右ののマスから 右から詰めた際の一番左マスまでは確定 左から詰めた際の一番右ののマスから 右から詰めた際の一番左マスまでは確定 「itertools」 を使った解き方
  7. この時点では確定できるマスはありません 処理2 端が確定した際の処理 3,2 処理2 端が確定した際の処理 縦を進める際に確定マスができた 塗りマスの確定ができる × n_list

    = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0] n_vals = [3,2] # 前方から処理 if n_list[0] == 1.0: n_list[0:n_vals[0]] = 1 n_list[n_vals[0]:n_vals[0]+1] = -1 # 後方から処理 if n_list[-1] == 1.0: n_list[-n_vals[-1]:len(n_list)] = 1 n_list[-n_vals[-1] -1:-n_vals[-1]] = -1 ## n_list = [1,1,1,-1,0,0,0,0,0,0] Pythonコード
  8. 可能性は3パターンしかない ×のマスは塗られることはない × × × × × 処理3 届かないマスの確定処理 3

    処理3 届かないマスの確定処理 n_list = [0, 0, 0, 1, 0, 0, 0, 0, 0, 0] n_vals = [3] if not 1 in n_list: return n_list leftNumm = int(np.where(n_list == 1)[0][0])+int(n_vals[0]) if leftNumm < len(n_list): n_list[leftNumm:len(n_list)] = -1 # 反転してもう一度 n_list = n_list[::-1] leftNumm = int(np.where(n_list == 1)[0][0])+int(n_vals[0]) if leftNumm < len(n_list): n_list[leftNumm:len(n_list)] = -1 # 反転してもとに戻す n_list = n_list[::-1] ## n_list = [-1,0,0,1,0,0,-1,-1,-1,-1] Pythonコード
  9. リストを[×]の箇所で分割する 1,3 1 分割したリストごとに処理1〜3を実行 1,3 1 処理4 「×」 のマスで分割して処理1〜3を実行 ×

    × 1,3,1 × 1,3,1 処理4 「×」 のマスで分割して処理1〜3を実行 このロジックで注意すること
  10. リストを[×]の箇所で分割する 1,3 1 分割したリストごとに処理1〜3を実行 1,3 1 処理4 「×」 のマスで分割して処理1〜3を実行 ×

    × 1,3,1 × 1,3,1 処理4 「×」 のマスで分割して処理1〜3を実行 このロジックで注意すること リストを[×]の箇所で分割する
  11. リストを[×]の箇所で分割する 1,3 1 分割したリストごとに処理1〜3を実行 1,3 1 処理4 「×」 のマスで分割して処理1〜3を実行 ×

    × 1,3,1 × 1,3,1 処理4 「×」 のマスで分割して処理1〜3を実行 このロジックで注意すること リストを[×]の箇所で分割する このように処理してしまった × × 1,3,1 0
  12. リストを[×]の箇所で分割する 1,3 1 分割したリストごとに処理1〜3を実行 1,3 1 処理4 「×」 のマスで分割して処理1〜3を実行 ×

    × 1,3,1 × 1,3,1 処理4 「×」 のマスで分割して処理1〜3を実行 このロジックで注意すること リストを[×]の箇所で分割する このように処理してしまった この場合可能性は2パターン存在した × × × × × × 1,3,1 1,3,1 1,3 0 1 0
  13. リストを[×]の箇所で分割する 1,3 1 分割したリストごとに処理1〜3を実行 1,3 1 処理4 「×」 のマスで分割して処理1〜3を実行 ×

    × 1,3,1 × 1,3,1 処理4 「×」 のマスで分割して処理1〜3を実行 このロジックで注意すること リストを[×]の箇所で分割する このように処理してしまった この場合可能性は2パターン存在した × × × × × × 1,3,1 1,3,1 1,3 0 1 0 複数の可能性がある場合は 処理4を実行してはいけない
  14. リストを[×]の箇所で分割する 1,3 1 分割したリストごとに処理1〜3を実行 1,3 1 処理4 「×」 のマスで分割して処理1〜3を実行 ×

    × 1,3,1 処理4 「×」 のマスで分割して処理1〜3を実行 このロジックで注意すること × 1,3,1 リストを[×]の箇所で分割する このように処理してしまった × × 1,3,1 0 複数の可能性がある場合は 処理4を実行してはいけない n_list = [0, 0, 0, 0, 0, 0, -1, -1, 0, 0] n_vals = [1,3,1] bunkatsu_list = [] # 塗り指示が分割されたリスト nums_list = [] # 塗り指示の戻る場所のリスト # ×(-1)で分割する m_list = np.where(n_list == -1)[0] bf = 0 for m,val in enumerate(m_list): if bf == val:bf = val+1;continue; bunkatsu_list.append(np.array(n_list[bf:val])) nums_list.append(np.array(range(bf,val))) bf = val+1 ## bunkatsu_list = [[0, 0, 0, 0, 0, 0],[0, 0]] ## nums_list = [[0, 1, 2, 3, 4, 5],[8, 9]] ######################################## ## 「bunkatsu_list」 の全てが 「1」 の値はリストから削除 ######################################## while True: if not bunkatsu_list: return nums_list, bunkatsu_list, n_vals if 0 not in bunkatsu_list[0]: bunkatsu_list = bunkatsu_list[1:] nums_list = nums_list[1:] n_vals = n_vals[1:] continue if 0 not in bunkatsu_list[-1]: bunkatsu_list = bunkatsu_list[:-1] nums_list = nums_list[:-1] n_vals = n_vals[:-1] continue break Pythonコード m_list: n_listを 「×」 (-1)で     区切ったindexのリスト n_list = [0, 0, 0, 0, 0, 0, -1, -1, 0, 0] m_list = np.where(n_list == -1)[0] m_list = [6,7]
  15. 処理5 端から確定マスを見つける 処理5 端から確定マスを見つける 5,3,1 15 塗られているマスは 「5」 の一部であることは確定 必ず左から3マス目が塗られてそれが

    「5」 であるパターン 塗られていたマスから 「5」 マス目までの塗りが確定 n_list = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] n_vals = [5,3,1] # 端から塗り数値内に1がある場合は端から数値までの間で塗り確定が発生 if n_list[0] == 0 and 1 in n_list[0:n_vals[0]+1]: nuri_index = np.where(n_list == 1)[0] n_list[nuri_index[0]:n_vals[0]] = 1 # ここで塗っている nuri_index = np.where(n_list == 1)[0] other_index = np.where(n_list != 1)[0] nuriend = [val for n,val in enumerate(other_index) if nuri_index[0] < val] if nuriend and n_vals: if nuriend[0] > n_vals[0]: n_list[:nuriend[0] - n_vals[0]] = -1 Pythonコード
  16. 処理6 指示の最大数と同じ連続した塗り 処理6 指示の最大数と同じ連続した塗り 1,3,2,1 15 3つ連続された塗りの 両端は塗られないことが確定 × ×

    n_list = [0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0] n_vals = [1,3,2,1] def one_index_list(oi_list, oiNum): cklist = [] add_list = [] one_index = np.where(oi_list == 1)[0] for o,ival in enumerate(one_index): if add_list: if add_list[-1]+1 != ival: cklist.append(add_list) add_list = [] if len(cklist) == oiNum: return cklist add_list.append(ival) else: if add_list: cklist.append(add_list) return cklist max_num = max(n_vals) one_index = one_index_list(bunkatsu, 100) for o,o_index in enumerate(one_index): if len(o_index) == max_num: if o_index[0] != 0: bunkatsu[o_index[0]-1] = -1 if o_index[-1] < len(nums)-1: bunkatsu[o_index[-1]+1] = -1 Pythonコード
  17. 処理7 端から指示 +1のマスが塗られていたら 処理7 端から指示 +1のマスが塗られていたら 5,1 × × 5,1

    5,1 5,1 この塗られているマスは5の一部になる なぜなら... そして 「5」 の一部が確定したなら
  18. 処理8 「1」 の連続した塗り指示の確定処理 × 1,1,1,1,3,2 20 × × × ×

    1,1,1,1,3,2 端から塗り指示の 「1」 が4つ連続している 仮に左端から詰めて並んでいた場合 処理8 塗り指示の端から 「1」 の連続した塗り指示の確定処理
  19. 処理8 「1」 の連続した塗り指示の確定処理 × 1,1,1,1,3,2 20 × × × ×

    1,1,1,1,3,2 × 1,1,1,1,3,2 端から塗り指示の 「1」 が4つ連続している 仮に左端から詰めて並んでいた場合 左から8マスまでは必ず塗り指示 「1」 の一部であることが確定 処理8 塗り指示の端から 「1」 の連続した塗り指示の確定処理
  20. 処理8 「1」 の連続した塗り指示の確定処理 × 1,1,1,1,3,2 20 × × × ×

    1,1,1,1,3,2 × 1,1,1,1,3,2 × × × × × × 1,1,1,1,3,2 端から塗り指示の 「1」 が4つ連続している 仮に左端から詰めて並んでいた場合 左から8マスまでは必ず塗り指示 「1」 の一部であることが確定 8マスいないの塗られているマスの前後は 「×」 が確定 処理8 塗り指示の端から 「1」 の連続した塗り指示の確定処理
  21. 処理8 「1」 の連続した塗り指示の確定処理 × 1,1,1,1,3,2 20 × × × ×

    1,1,1,1,3,2 × 1,1,1,1,3,2 × × × × × × 1,1,1,1,3,2 端から塗り指示の 「1」 が4つ連続している 仮に左端から詰めて並んでいた場合 左から8マスまでは必ず塗り指示 「1」 の一部であることが確定 8マスいないの塗られているマスの前後は 「×」 が確定 n_list = [0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 1] n_vals = [1,1,1,1,3,2] # 塗り指示の 「1」 の連続した処理。 塗りの両端を[-1]で確定 for n,val in enumerate(n_vals): # 連続しなくなった時点までを処理する if val != 1: break; if n > 1: for l,val in enumerate(n_list[0:sumlen(n_vals[:n])+1]): if val == 1: n_list[l -1] = -1 n_list[l+1] = -1 Pythonコード 処理8 塗り指示の端から 「1」 の連続した塗り指示の確定処理
  22. 処理9 塗り指示の端から 「1」 と 「2」 の連続した塗り指示の確定処理 1,2,1,1,1,5 20 × ×

    × × 1,2,1,1,1,5 × × × × × 1,2,1,1,1,5 塗りの 「2」 である可能性が2パターン存在するため 塗りの前後を 「×」 にする処理はできない 処理9 塗り指示の端から 「1」 と 「2」 の連続した塗り指示の確定処理
  23. 処理9 塗り指示の端から 「1」 と 「2」 の連続した塗り指示の確定処理 1,2,1,1,1,5 20 × ×

    × × 1,2,1,1,1,5 1,2,1,1,1,5 × × × × × 1,2,1,1,1,5 塗りの 「2」 である可能性が2パターン存在するため 塗りの前後を 「×」 にする処理はできない しかし、 塗り指示の 「1」 と 「2」 の届く範囲内の [▪,□,▪]組み合わせに対しては真ん中の 「×」 が確定できる 処理9 塗り指示の端から 「1」 と 「2」 の連続した塗り指示の確定処理
  24. 処理9 塗り指示の端から 「1」 と 「2」 の連続した塗り指示の確定処理 1,2,1,1,1,5 20 × ×

    × × 1,2,1,1,1,5 1,2,1,1,1,5 × 1,2,1,1,1,5 × × × × × 1,2,1,1,1,5 塗りの 「2」 である可能性が2パターン存在するため 塗りの前後を 「×」 にする処理はできない しかし、 塗り指示の 「1」 と 「2」 の届く範囲内の [▪,□,▪]組み合わせに対しては真ん中の 「×」 が確定できる こうなる 処理9 塗り指示の端から 「1」 と 「2」 の連続した塗り指示の確定処理
  25. n_list = [0, 0, 1, 0, 0, 1, 0, 1,

    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] n_vals = [1,1,1,1,3,2] # 塗り指示の 「1,2」 の連続した処理。 [1, 0, 1]の[0]を[-1]で確定できる for n,val in enumerate(n_vals): # 連続しなくなった時点までを処理する if not (1 <= val <= 2): break; if n > 1: for l,val in enumerate(n_list[0:sumlen(n_vals[:o])+1]): if list(n_list[ l: l+3]) == [1,0,1]: copy_n_list[ l: l+3] = [1,-1,1] Pythonコード 処理9 塗り指示の端から 「1」 と 「2」 の連続した塗り指示の確定処理 1,2,1,1,1,5 20 × × × × 1,2,1,1,1,5 1,2,1,1,1,5 × 1,2,1,1,1,5 × × × × × 1,2,1,1,1,5 塗りの 「2」 である可能性が2パターン存在するため 塗りの前後を 「×」 にする処理はできない しかし、 塗り指示の 「1」 と 「2」 の届く範囲内の [▪,□,▪]組み合わせに対しては真ん中の 「×」 が確定できる こうなる 処理9 塗り指示の端から 「1」 と 「2」 の連続した塗り指示の確定処理
  26. 処理10 塗り指示の数と塗りを持つ分割リストの数が一致したらできる処理 × × × 2,2,3 2,2,3 20 まずは 「×」

    で分割してみる 処理10 塗り指示の数と塗りを持つ分割リストの数が一致したらできる処理
  27. 処理10 塗り指示の数と塗りを持つ分割リストの数が一致したらできる処理 × × × 2,2,3 2,2,3 2 2 3

    0 20 まずは 「×」 で分割してみる 指示の数字が3つ、 塗りマスを含む分割したリストの数が3つ なのでこうなる 処理10 塗り指示の数と塗りを持つ分割リストの数が一致したらできる処理
  28. 処理10 塗り指示の数と塗りを持つ分割リストの数が一致したらできる処理 × × × 2,2,3 × × × ×

    × × × × × × 2,2,3 × × × × × × × 2,2,3 2 2 2 2 3 3 0 0 20 まずは 「×」 で分割してみる 指示の数字が3つ、 塗りマスを含む分割したリストの数が3つ なのでこうなる それぞれのリストに今まで実装した全てのロジックを当てる 処理10 塗り指示の数と塗りを持つ分割リストの数が一致したらできる処理
  29. 処理11 連続された塗りから対象の指示数字を特定する × × 2,11,1,5,1,1 × × × × ×

    × × × × 2,11,1,5,1,1 32 今回はロジックの説明の前に答えを明かすと 処理11 連続された塗りから対象の指示数字を特定する
  30. 処理11 連続された塗りから対象の指示数字を特定する × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 32 連続された塗りに注目。

    「5」 以上の数字が対象。 ここでは 「11」 もしくは 「5」 処理11 連続された塗りから対象の指示数字を特定する
  31. 処理11 連続された塗りから対象の指示数字を特定する × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 × ×

    2,11,1,5,1,1 × × 2,11,1 32 連続された塗りに注目。 「5」 以上の数字が対象。 ここでは 「11」 もしくは 「5」 「5」 である可能性を考えてみる 1,1 成り立たないので 「5」 では ないことが確定 処理11 連続された塗りから対象の指示数字を特定する
  32. 処理11 連続された塗りから対象の指示数字を特定する × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 × ×

    2,11,1,5,1,1 × × 2 32 連続された塗りに注目。 「5」 以上の数字が対象。 ここでは 「11」 もしくは 「5」 「11」 である可能性を考えてみる 1,5,1,1 どうやら成り立ちそうだ 処理11 連続された塗りから対象の指示数字を特定する
  33. 処理11 連続された塗りから対象の指示数字を特定する × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 × ×

    2,11,1,5,1,1 × × 2,11,1,5,1,1 × × × × 2 2 32 連続された塗りに注目。 「5」 以上の数字が対象。 ここでは 「11」 もしくは 「5」 「11」 である可能性を考えてみる 「11」 を無理やり前後にずらしてみて成り立った場合は複数の可能性が考えられるの場合は中止 1,5,1,1 1,5,1,1 処理11 連続された塗りから対象の指示数字を特定する
  34. このマスは 「2」 と 「11」 両方になり得る可能性がある 処理11 連続された塗りから対象の指示数字を特定する × × 2,11,1,5,1,1

    × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 × × × × 2 2 32 連続された塗りに注目。 「5」 以上の数字が対象。 ここでは 「11」 もしくは 「5」 「11」 である可能性を考えてみる 「11」 を無理やり前後にずらしてみて成り立った場合は複数の可能性が考えられるの場合は中止 1,5,1,1 1,5,1,1 処理11 連続された塗りから対象の指示数字を特定する
  35. 処理11 連続された塗りから対象の指示数字を特定する × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 32 連続された塗りに注目。

    「5」 以上の数字が対象。 ここでは 「11」 もしくは 「5」 処理11 連続された塗りから対象の指示数字を特定する
  36. 処理11 連続された塗りから対象の指示数字を特定する × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 32 連続された塗りに注目。

    「5」 以上の数字が対象。 ここでは 「11」 もしくは 「5」 × × 2,11,1,5,1,1 2 1,5,1,1 「11」 である可能性を考えてみる × × 成り立たないので 「11」 では ないことが確定 処理11 連続された塗りから対象の指示数字を特定する
  37. 処理11 連続された塗りから対象の指示数字を特定する × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 32 連続された塗りに注目。

    「5」 以上の数字が対象。 ここでは 「11」 もしくは 「5」 × × 2,11,1,5,1,1 2,11,1 1,1 「5」 である可能性を考えてみる × × どうやら成り立ちそうだ 処理11 連続された塗りから対象の指示数字を特定する
  38. × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 前後にずらしてチェックしてもそのほかの可能性はなさそうなので 「5」 の一部であることが確定 処理11

    連続された塗りから対象の指示数字を特定する × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 32 連続された塗りに注目。 「5」 以上の数字が対象。 ここでは 「11」 もしくは 「5」 × × 2,11,1,5,1,1 2,11,1 1,1 「5」 である可能性を考えてみる × × 処理11 連続された塗りから対象の指示数字を特定する
  39. 処理11 連続された塗りから対象の指示数字を特定する × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 前後にずらしてチェックしてもそのほかの可能性はなさそうなので 「5」

    の一部であることが確定 × × 2,11,1,5,1,1 32 × × 2,11,1,5,1,1 リストを分割して全てのロジックを当てる 処理を当てるとこうなる × × 2,11,1 1,1 × × × × × × × × × × 2,11,1 1,1 処理11 連続された塗りから対象の指示数字を特定する
  40. 処理11 連続された塗りから対象の指示数字を特定する × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 前後にずらしてチェックしてもそのほかの可能性はなさそうなので 「5」

    の一部であることが確定 × × 2,11,1,5,1,1 32 × × 2,11,1,5,1,1 × × × × × × × × × × 2,11,1,5,1,1 リストを分割して全てのロジックを当てる 処理を当てるとこうなる 元のリストに値を戻す × × 2,11,1 1,1 × × × × × × × × × × 2,11,1 1,1 処理11 連続された塗りから対象の指示数字を特定する
  41. 処理11 連続された塗りから対象の指示数字を特定する × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 前後にずらしてチェックしてもそのほかの可能性はなさそうなので 「5」

    の一部であることが確定 × × 2,11,1,5,1,1 32 × × 2,11,1,5,1,1 × × × × × × × × × × 2,11,1,5,1,1 × × × × × × × × × × 2,11,1,5,1,1 × × × × × × × × × × 2,11,1,5,1,1 リストを分割して全てのロジックを当てる 処理を当てるとこうなる 元のリストに値を戻す 「5」 の処理は確定できないので 「5」 が届く範囲のマスは元に戻す × × 2,11,1 1,1 × × × × × × × × × × 2,11,1 1,1 処理11 連続された塗りから対象の指示数字を特定する
  42. 処理11 連続された塗りから対象の指示数字を特定する × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 前後にずらしてチェックしてもそのほかの可能性はなさそうなので 「5」

    の一部であることが確定 × × 2,11,1,5,1,1 32 × × × × × × × × × × 2,11,1,5,1,1 × × × × × × × × × 2,11,1,5,1,1 × × × × × × × × × × 2,11,1,5,1,1 「5」 の処理は確定できないので 「5」 が届く範囲のマスは元に戻す ここまで確定 処理11 連続された塗りから対象の指示数字を特定する
  43. 処理11 連続された塗りから対象の指示数字を特定する × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 前後にずらしてチェックしてもそのほかの可能性はなさそうなので 「5」

    の一部であることが確定 × × 2,11,1,5,1,1 32 × × × × × × × × × × 2,11,1,5,1,1 × × × × × × × × × 2,11,1,5,1,1 1,5 1,5 × × × × × × × × × × 2,11,1,5,1,1 「5」 の処理は確定できないので 「5」 が届く範囲のマスは元に戻す ここまで確定 最後に残りの処理 処理11 連続された塗りから対象の指示数字を特定する
  44. 処理11 連続された塗りから対象の指示数字を特定する × × × × × × × ×

    × 2,11,1,5,1,1 元のリストに反映させると完成 × × 2,11,1,5,1,1 × × 2,11,1,5,1,1 前後にずらしてチェックしてもそのほかの可能性はなさそうなので 「5」 の一部であることが確定 × × 2,11,1,5,1,1 32 × × × × × × × × × × 2,11,1,5,1,1 × × × × × × × × × 2,11,1,5,1,1 1,5 1,5 × × × × × × × × × × 2,11,1,5,1,1 「5」 の処理は確定できないので 「5」 が届く範囲のマスは元に戻す ここまで確定 最後に残りの処理 処理11 連続された塗りから対象の指示数字を特定する