用排除推導的方式,得到數(shù)獨的解

第一部分是,定義一些字典,用來存一些數(shù)據(jù)

# 存每個格子,已經(jīng)確定的數(shù),不確定的是‘0’
dic_shu = {
    '11': 0, '12': 0, '13': 0, '14': 0, '15': 0, '16': 0, '17': 0, '18': 0, '19': 0,
    '21': 0, '22': 0, '23': 0, '24': 0, '25': 0, '26': 0, '27': 0, '28': 0, '29': 0,
    '31': 0, '32': 0, '33': 0, '34': 0, '35': 0, '36': 0, '37': 0, '38': 0, '39': 0,
    '41': 0, '42': 0, '43': 0, '44': 0, '45': 0, '46': 0, '47': 0, '48': 0, '49': 0,
    '51': 0, '52': 0, '53': 0, '54': 0, '55': 0, '56': 0, '57': 0, '58': 0, '59': 0,
    '61': 0, '62': 0, '63': 0, '64': 0, '65': 0, '66': 0, '67': 0, '68': 0, '69': 0,
    '71': 0, '72': 0, '73': 0, '74': 0, '75': 0, '76': 0, '77': 0, '78': 0, '79': 0,
    '81': 0, '82': 0, '83': 0, '84': 0, '85': 0, '86': 0, '87': 0, '88': 0, '89': 0,
    '91': 0, '92': 0, '93': 0, '94': 0, '95': 0, '96': 0, '97': 0, '98': 0, '99': 0,

}
# 存,每個方塊(3*3),每行,每列,數(shù)字已確定的格子的數(shù)量
dic_jiu = {'fang': {
    '123_123': 0, '123_456': 0, '123_789': 0,
    '456_123': 0, '456_456': 0, '456_789': 0,
    '789_123': 0, '789_456': 0, '789_789': 0, },
    'heng': {'1_19': 0, '2_19': 0, '3_19': 0, '4_19': 0, '5_19': 0, '6_19': 0, '7_19': 0, '8_19': 0, '9_19': 0, },
    'shu': {'19_1': 0, '19_2': 0, '19_3': 0, '19_4': 0, '19_5': 0, '19_6': 0, '19_7': 0, '19_8': 0, '19_9': 0}
}
# 每個數(shù),可能出現(xiàn)在方塊中的坐標
# 2-9類似,不在重復
dic_1_9 = {
    1: {
        '123_123': [11, 12, 13, 21, 22, 23, 31, 32, 33],
        '123_456': [14, 15, 16, 24, 25, 26, 34, 35, 36],
        '123_789': [17, 18, 19, 27, 28, 29, 37, 38, 39],
        '456_123': [41, 42, 43, 51, 52, 53, 61, 62, 63],
        '456_456': [44, 45, 46, 54, 55, 56, 64, 65, 66],
        '456_789': [47, 48, 49, 57, 58, 59, 67, 68, 69],
        '789_123': [71, 72, 73, 81, 82, 83, 91, 92, 93],
        '789_456': [74, 75, 76, 84, 85, 86, 94, 95, 96],
        '789_789': [77, 78, 79, 87, 88, 89, 97, 98, 99],
    },
}
# 每行,每個數(shù)字,可能出現(xiàn)先的坐標,2-9不再重復
dic_1_9_heng = {
    1: {
        '1_19': [11, 12, 13, 14, 15, 16, 17, 18, 19],
        '2_19': [21, 22, 23, 24, 25, 26, 27, 28, 29],
        '3_19': [31, 32, 33, 34, 35, 36, 37, 38, 39],
        '4_19': [41, 42, 43, 44, 45, 46, 47, 48, 49],
        '5_19': [51, 52, 53, 54, 55, 56, 57, 58, 59],
        '6_19': [61, 62, 63, 64, 65, 66, 67, 68, 69],
        '7_19': [71, 72, 73, 74, 75, 76, 77, 78, 79],
        '8_19': [81, 82, 83, 84, 85, 86, 87, 88, 89],
        '9_19': [91, 92, 93, 94, 95, 96, 97, 98, 99],
    },
}
# 每列,每個數(shù)字,可能出現(xiàn)先的坐標,2-9不再重復
dic_1_9_shu = {
    1: {
        '19_1': [11, 21, 31, 41, 51, 61, 71, 81, 91],
        '19_2': [12, 22, 32, 42, 52, 62, 72, 82, 92],
        '19_3': [13, 23, 33, 43, 53, 63, 73, 83, 93],
        '19_4': [14, 24, 34, 44, 54, 64, 74, 84, 94],
        '19_5': [15, 25, 35, 45, 55, 65, 75, 85, 95],
        '19_6': [16, 26, 36, 46, 56, 66, 76, 86, 96],
        '19_7': [17, 27, 37, 47, 57, 67, 77, 87, 97],
        '19_8': [18, 28, 38, 48, 58, 68, 78, 88, 98],
        '19_9': [19, 29, 39, 49, 59, 69, 79, 89, 99],
    },
    
}

排除的方法
1.確定一個坐標,進行賦值
a.給坐標所屬的塊就是字典【dic_1_9】賦坐標的 int
b.給坐標所屬行,字典【dic_1_9_heng】賦坐標int
c.給坐標所屬列,字典【dic_1_9_shu】賦坐標int
2.確定一個坐標,排除
a.移除此數(shù)字,所屬,方塊、行、列,的所有其他值
b.移除別的數(shù)字,方塊、行、列此坐標
3.字典(dic_1_9/dic_1_9_heng/dic_1_9_shu)中某塊、或列、或行,已確定8個值,推出第九個值
4.某數(shù)字,某一方塊內(nèi),僅剩兩個坐標
a.兩個坐標 橫坐標一樣,排除此數(shù)字此行坐標
b.連個坐標 豎坐標一樣,排除此數(shù)字此列坐標

from jiaoben.shudu.shudu_count import *


class Testshudu:
    # 給單元格賦值
    def set_value(self, key, value: int):
        if dic_shu[key] != 0:
            print(f'出錯了,dic_shu[{key}]={dic_shu[key]},不能再賦值:{value}')
        else:

            dic_shu[key] = value
            fang = self.get_suoshufang(key)
            dic_1_9[value][fang] = int(key)
            dic_1_9_heng[value][key[0]+'_19'] = int(key)
            dic_1_9_shu[value]["19_" + key[1]] = int(key)
            self.update_tianxieshu(key, value)
            self.get_remove_dic_by1(key, value)

    # 得到位置所屬方位,左上、右上,上等
    def get_suoshufang(self, zuobiao: str):
        h = zuobiao[0]
        s = zuobiao[1]
        suoshu_fang = ''
        for fang_i in dic_jiu['fang'].keys():
            if h in fang_i[:3] and s in fang_i[3:]: suoshu_fang = fang_i
        return suoshu_fang

    # 判斷坐標是否可以移除,并移除
    def remover_dic_1_9(self, remove_dic):

        num = remove_dic['num']
        fang = remove_dic['fang']
        zhi = remove_dic['zhi']
        remove_list = dic_1_9[num][fang]
        if isinstance(remove_list,list):
            if len(remove_list)>1 and zhi in remove_list:
                dic_1_9[num][fang].remove(zhi)
            if len(remove_list) == 1:
                self.set_value(str(remove_list[0]),num)
        if isinstance(dic_1_9_heng[num][str(zhi)[0]+'_19'],list):
            if len(dic_1_9_heng[num][str(zhi)[0]+'_19']) >1 and zhi in dic_1_9_heng[num][str(zhi)[0]+'_19']:
                dic_1_9_heng[num][str(zhi)[0] + '_19'].remove(zhi)
            if len(dic_1_9_heng[num][str(zhi)[0]+'_19']) == 1:
                self.set_value(str(dic_1_9_heng[num][str(zhi)[0]+'_19'][0]),num)
        if isinstance(dic_1_9_shu[num]["19_" + str(zhi)[1]],list):
            if len(dic_1_9_shu[num]["19_" + str(zhi)[1]]) >1 and zhi in dic_1_9_shu[num]["19_" + str(zhi)[1]]:
                dic_1_9_shu[num]["19_" + str(zhi)[1]].remove(zhi)
            if len(dic_1_9_shu[num]["19_" + str(zhi)[1]]) == 1:
                self.set_value(str(dic_1_9_shu[num]["19_" + str(zhi)[1]][0]),num)


    # 確定一個位置后,移除坐標坐在橫豎兩條線上的坐標
    def get_remove_dic_by1(self, zhi, num):
        other_num_fang = self.get_suoshufang(zhi)
        for i in range(1, 10):
            if i != num:
                remove_dic = {'num': i, 'fang': other_num_fang, 'zhi': int(zhi)}
                self.remover_dic_1_9(remove_dic)
        remove_h = self.get_list_by_hs('heng', zhi)
        for i in remove_h:
            fang = self.get_suoshufang(str(i))
            remove_dic = {'num': num, 'fang': fang, 'zhi': i}
            self.remover_dic_1_9(remove_dic)
        remove_s = self.get_list_by_hs('shu', zhi)
        for i in remove_s:
            fang = self.get_suoshufang(str(i))
            remove_dic = {'num': num, 'fang': fang, 'zhi': i}
            self.remover_dic_1_9(remove_dic)

    # 根據(jù)坐標判斷
    def get_list_by_hs(self, h_or_s, zhi):
        r_zhi_l = []
        list = []
        xx = 0
        if h_or_s == 'heng':
            xx = int(zhi[1])
        if h_or_s == 'shu':
            xx = int(zhi[0])
        if xx in [1, 2, 3]:
            list = [4, 5, 6, 7, 8, 9]
        elif xx in [4, 5, 6]:
            list = [1, 2, 3, 7, 8, 9]
        elif xx in [7, 8, 9]:
            list = [1, 2, 3, 4, 5, 6]
        if h_or_s == 'heng':
            for i in list:
                h_z = int(zhi[0]) * 10
                r_zhi_l.append(h_z + i)
        if h_or_s == 'shu':
            for i in list:
                h_z = int(zhi[1])
                r_zhi_l.append(h_z + i * 10)
        return r_zhi_l

    def remove_get_two(self, num):
        for a in dic_1_9.keys():
            for b in dic_1_9[a].keys():
                linshi_list = dic_1_9[a][b]
                if isinstance(linshi_list, list) and len(linshi_list) == 2:
                    # 橫坐標一樣,說明這個數(shù)只能在 在這一行,移除當前行,別的坐標
                    if str(linshi_list[0])[0] == str(linshi_list[1])[0]:
                        remove_h = self.get_list_by_hs('heng', str(linshi_list[0]))
                        for i in remove_h:
                            fang = self.get_suoshufang(str(i))
                            remove_dic = {'num': a, 'fang': fang, 'zhi': i}
                            self.remover_dic_1_9(remove_dic)
                if isinstance(linshi_list, list) and len(linshi_list) == 2:
                    # 數(shù)字a,在當前方塊,僅有兩個坐標值,并且兩個坐標豎坐標一致,可排除坐標坐在豎坐標其他方塊中的坐標
                    if str(linshi_list[0])[1] == str(linshi_list[1])[1]:
                        remove_s = self.get_list_by_hs('shu', str(linshi_list[1]))
                        for i in remove_s:
                            fang = self.get_suoshufang(str(i))
                            remove_dic = {'num': a, 'fang': fang, 'zhi': i}
                            self.remover_dic_1_9(remove_dic)

    # 更新每個方塊,每行、每列數(shù)值已確定格子的數(shù)量
    def update_tianxieshu(self, x, value):
        fang = self.get_suoshufang(x)
        heng = x[0] + '_19'
        shu = '19_' + x[1]
        dic_jiu['fang'][fang] += 1
        dic_jiu['heng'][heng] += 1
        dic_jiu['shu'][shu] += 1
        # 方塊、橫、豎 數(shù)值已確定格子數(shù)量=8,可推導出第9個格子的數(shù)值
        if dic_jiu['fang'][fang] == 8:
            self.get_8_1('fang', fang)
        if dic_jiu['heng'][heng] == 8:
            self.get_8_1('heng', heng)
        if dic_jiu['shu'][shu] == 8:
            self.get_8_1('shu', shu)

    # 根據(jù) 已確定數(shù)值的8個格子,得到第9個格子的  數(shù)值
    def get_8_1(self, fenlei, key):
        list_1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        list_2 = []
        set_key = ''
        if fenlei == 'fang':
            for heng in key[:3]:
                for shu in key[4:]:
                    if dic_shu[heng + shu] != 0:
                        list_2.append(dic_shu[heng + shu])
                    else:
                        set_key = heng + shu

        if fenlei == 'heng':
            for i in range(1, 10):
                if dic_shu[key[0] + str(i)] != 0:
                    list_2.append(dic_shu[key[0] + str(i)])
                else:
                    set_key = key[0] + str(i)
        if fenlei == 'shu':
            for i in range(1, 10):
                if dic_shu[str(i) + key[-1]] != 0:
                    list_2.append(dic_shu[str(i) + key[-1]])
                else:
                    set_key = str(i) + key[-1]
        list3 = list(set(list_1) - set(list_2))
        self.set_value(set_key, list3[0])


def test_new():
    sd = Testshudu()
    test_dic = {'11': 5, '13': 2, '14': 4, '17': 3, '18': 6, '21': 6, '23': 4, '36': 6, '39': 2,
                '45': 2, '46': 8, '47': 5, '53': 7, '57': 8, '63': 9, '64': 7, '65': 5,
                '71': 8, '74': 6, '87': 9, '89': 8, '92': 7, '93': 1, '96': 2, '97': 4, '99': 6
                }

    for key in test_dic.keys():
        sd.set_value(key, test_dic[key])
    sd.remove_get_two(1)
    sd.remove_get_two(2)
    sd.remove_get_two(3)
    print(dic_1_9)
    print(dic_jiu)
    print(dic_1_9_heng)
    for i in range(1, 10):
        str_some = ''
        for j in range(1, 10):
            s = str(i) + str(j)
            str_some += (' ' + str(dic_shu[s]) + '-')
            if j % 3 == 0:
                str_some += '*'
        print('——————————————————————————————————————————————————————————————————————')
        print(f'第{i}行:{str_some}')

    print(type(dic_shu.keys()))

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容