0%

传说中的爱因斯坦提出的思考题

       近期看了 《别乱说,算法才不是脑筋急转弯》 这篇推文里面最后一题让人好奇(其实其他的也还不错,有些就是脑筋急转弯呀,真能用算法来写就强了),它就是是传说中的爱因斯坦提出的思考题,他宣称世界上只有2%的人能解出这个题目,你肯定听说过不下一次这道题,但也肯定你始终连题目都没记清楚过。因此也就试试解答下,居然断断续续合计花了两天,泪崩,并且还不是完美的答案。

题目内容

       据说有五个不同颜色的房间排成一排,每个房间里分别住着一个不同国籍的人,每个人都喝一种特定品牌的饮料,抽一种特定品牌的烟,养一种宠物,没有任意两个人抽相同品牌的香烟,或喝相同品牌的饮料,或养相同的宠物。

问题是谁在养鱼作为宠物?为了寻找答案,爱因斯坦给出了以下15条线索。

  1. 英国人住在红色的房子里;
  2. 瑞典人养狗作为宠物;
  3. 丹麦人喝茶;
  4. 绿房子紧挨着白房子,在白房子的左边;
  5. 绿房子的主人喝咖啡;
  6. 抽 Pall Mall 牌香烟的人养鸟;
  7. 黄色房子里的人抽 Dunhill 牌香烟;
  8. 住在中间那个房子里的人喝牛奶;
  9. 挪威人住在第一个房子里面;
  10. 抽 Blends 牌香烟的人和养猫的人相邻;
  11. 养马的人和抽 Dunhill 牌香烟的人相邻;
  12. 抽 BlueMaster 牌香烟的人喝啤酒;
  13. 德国人抽 Prince 牌香烟;
  14. 挪威人和住在蓝房子的人相邻;
  15. 抽 Blends 牌香烟的人和喝矿泉水的人相邻。

       可以说乍一看才 15个条件 不算很多,可是很难记住,特别是 各个国家各个颜色等搭配,名字又难记。

       回到解题来看,第一想到的还是一个个来推演,条件还是有所联系,如 9. 挪威人住在第一个房子里面 和 14. 挪威人和住在蓝房子的人相邻 这两个明显就可以推断 第二个房子是蓝色、又如 4. 绿房子紧挨着白房子,在白房子的左边;、5. 绿房子的主人喝咖啡;和 8. 住在中间那个房子里的人喝牛奶,可以推断出绿房子只能是在 第四个房间,也就是第五个房子是白色,剩下 红色 和 黄色,再由 1. 英国人住在红色的房子里;就可以知道房子颜色的顺序为:黄-蓝-红-绿-白。想想这样推,理应可以一步步推演出来(除非条件不够,不过怎么可能呢),就是记不住得用下本子和笔……

       可是上面的推演是人工,如果给计算机就不可能这样推演,计算机如何来推演呢?一般想到的是穷举法,并给它筛选的条件,让计算机进行大量的比较运算来得出结果。最后写出的代码,没有去修正,也存在很多错误。

条件代号

1
2
3
4
5
国籍:a(英国人、瑞典人、丹麦人、挪威人、德国人)161 - 165
房子:b(红色、绿色、白色、黄色、蓝色)177 - 181
烟:c(Pall Mall、Dunhill、Blends、BlueMaster、Prince)193 - 197
饮料:d(咖啡、牛奶、啤酒、茶、矿泉水)209 - 213
宠物:e(狗、鸟、猫、马、鱼)225 - 229

代码输出情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
10
10
10
56
56
final00 = 3080000
final remove
final04 = 247520
final04 remove
final10 = 158690
final10 remove
final11 == 22645
final11 remove
final15 == 9133
final15 remove
ffinal1 == 7199
ffinal1 remove
ffinal2 == 6538
ffinal2 remove
ffinal3 == 2480
ffinal3 remove
ffinal4 == 2192
ffinal4 remove
ffinal5 == 1219
fffinal03 remove
ffinal51 == 860
ffinal5 remove
ffinal12 == 176
fffinal03 remove
fffinal011 == 152
--------------结果----------------------------
["a4", "b4", "c2", "d5", "e3"]
["a3", "b5", "c3", "d4", "e4"]
["a1", "b1", "c1", "d2", "e2"]
["a5", "b2", "c5", "d1", "e5"]
["a2", "b3", "c4", "d3", "e1"]
---------------------------------------------

答案

       最后输出了 248 个(没有进行到处结果的操作下),打印出来,会看到还有没填充满的,依然是 0,按照下面的步骤,应该继续填充,继续过滤。不过这里其实已经出答案了,在所以数据里面会发现一个已经填满的,并且出现多次。而它其实已经通过多层校验的,所以它很可能就是要找答案,如下

[“a4”, “b4”, “c2”, “d5”, “e3”]
[“a3”, “b5”, “c3”, “d4”, “e4”]
[“a1”, “b1”, “c1”, “d2”, “e2”]
[“a5”, “b2”, “c5”, “d1”, “e5”]
[“a2”, “b3”, “c4”, “d3”, “e1”]

       对其进行人工检测,满足所有条件,也就是说它就是最后的答案:

答案:德国人🇩🇪养鱼🐟

总结

       其实找猫为条件筛选会更直接,可是这边我想排出房子排列的所有可能,并且这里的计算有重复,所以生成的数据其实很多都是重复的,还是没完成,只能说马马虎虎能看到答案。

       这应该是最笨的计算方法了,而且还不通用,因为很多条件的过滤都是人工来编写,也就是不能直接给计算机条件,让它自己过滤,所以还比较笨。

       计算机部分说到这里,后续有更好的写法也会更新。

       最后看看其他小伙伴的推演:《题目是这样的: 已知条件:有5个具有5种不同颜色的房间;每个房间里分别住着一个不同国籍的人;每个人_百度知道》,大致跟最开始人工推演的类似,这里只是为了再次确认上面的答案是否真的正确。

更新

增加全相等的去重

       全相等的去重就是指最终排列是一模一样的结果,包括 0(未知)。这是为后面补充 0 的值多样性的逻辑。这也将第一次的结果九百多个降到二百多个。对于这种去重,如果一个项去跟结果集其他所有一个个的项去相比,这个数据计算其实很多。所以想到将结果集中的一个结果转为一个id,它是所有项的十六进制排列的字符串,这样就直接比较两个结果的 id 是否一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
func deleteRepet(obj: [[[Int]]]) -> [[[Int]]] {
var objNew = [[[Int]]]()
for index in 0..<obj.count {
let objo = obj[index]
var bRepet = false
for idx in (index + 1)..<obj.count {
let objoNext = obj[idx]
if id(objo) == id(objoNext) {
bRepet = true
break
}
}
if bRepet == false {
objNew.append(objo)
}
}
return objNew
}

func id(_ objoo: [[Int]]) -> String {
var id = ""
for j in 0..<5 {
let objooo = objoo[j]
for i in 0..<5 {
let ido = String(objooo[i], radix: 16)
id += ido
}
}
return id
}
导出结果

       尝试导出已经全部填充满,并且没有为 0 项的结果。主要用于完成条件匹配,进行 0 填充的时候。这里加到进行过全相等去重之后执行,最后发现它在 fffinal011 == 152,即进行第一次填充 1个0 和条件校验之后就已经有满足的结果了。

1
2
3
if reesult(obj: ffinal5) == true {
return
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
func reesult(obj: [[[Int]]]) -> Bool {
var bFinalResult = false
for index in 0..<obj.count {
let lf = obj[index]
var llff = [[String]]()
for i in 0..<5 {
let lfo = lf[i]
var llf = [String]()
var bResult = true
for j in 0..<5 {
if lfo[j] == 0 {
bResult = false
llf.removeAll()
break
}
let vv = String(lfo[j], radix: 16)
llf.append(vv)
}
if bResult == true {
llff.append(llf)
}
else {
break
}
}
if llff.count == 5 {
print("--------------结果----------------------------")
bFinalResult = true
for idx in 0..<5 {
print("\(llff[idx])")
}
print("---------------------------------------------")
}
}
return bFinalResult
}

附件代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
func start() {
//1、将条件转换为各自可能
let o1 = [0xa1, 0xb1, 0, 0, 0]
let o2 = [0xa2, 0, 0, 0, 0xe1]
let o3 = [0xa3, 0, 0, 0xd4, 0]
let o4 = [0, 0xb2, 0, 0xd1, 0]
let o5 = [0, 0, 0xc1, 0, 0xe2]
let o6 = [0, 0xb4, 0xc2, 0, 0]
let o7 = [0, 0, 0xc4, 0xd3, 0]
let o8 = [0xa5, 0, 0xc5, 0, 0]

let o9 = [0xa4, 0, 0, 0, 0]
let o10 = [0, 0xb3, 0, 0, 0]
let o11 = [0, 0xb5, 0, 0, 0]
let o12 = [0, 0, 0xc3, 0, 0]
let o13 = [0, 0, 0, 0xd2, 0]
let o14 = [0, 0, 0, 0xd5, 0]
let o15 = [0, 0, 0, 0, 0xe3]
let o16 = [0, 0, 0, 0, 0xe4]
let o17 = [0, 0, 0, 0, 0xe5]

var os = [o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15, o16, o17]

// 2、各自可能的组合
var ons = [[Int]]()
for index in 0..<os.count {
let o = os[index]
let subIndex = index + 1
if subIndex < os.count {
for idx in subIndex..<os.count {
let ot = os[idx]
var on = [0, 0, 0, 0, 0]
var bMerge = true
for i in 0..<5 {
if o[i] == 0 || ot[i] == 0 {
if o[i] != ot[i] {
on[i] = (o[i] + ot[i])
}
}
else {
bMerge = false
break
}
}
if bMerge == true {
ons.append(on)
}
}
}
}

// 3、条件过滤,主要是 9、14、8
// condition 9
var ons9 = [[Int]]()
for index in 0..<ons.count {
let on = ons[index]
if on[0] == 0xa4, on[1] != 0xb5, on[3] != 0xd2 {
ons9.append(on)
}
}

//var l = [[[Int]]]()
var l: [Any] = [0, 0, 0, 0, 0]

// 第一个位置的所有可能
let l1 = ons9
l[0] = l1

var ons14 = [[Int]]()
for index in 0..<ons.count {
let on = ons[index]
if on[1] == 0xb5, on[0] != 0xa4, on[3] != 0xd2 {
ons14.append(on)
}
}

let l2 = ons14
l[1] = l2

// condition 8
var ons8 = [[Int]]()
for index in 0..<ons.count {
let on = ons[index]
if on[3] == 0xd2, on[1] != 0xb5, on[0] != 0xa4 {
ons8.append(on)
}
}

let l3 = ons8
l[2] = l3

var l4 = ons
for index in 0..<l1.count {
let on = l1[index]
l4.remove(at: l4.index(of: on)!)
}
for index in 0..<l2.count {
let on = l2[index]
l4.remove(at: l4.index(of: on)!)
}
for index in 0..<l3.count {
let on = l3[index]
l4.remove(at: l4.index(of: on)!)
}

var l5 = l4
l[3] = l4
l[4] = l5

print("\(l1.count)")
print("\(l2.count)")
print("\(l3.count)")
print("\(l4.count)")
print("\(l5.count)")

// 4、将简单的过滤掉之后,组合所有的5*5排列
var final = [[[Int]]]()
// l1.count
for index1 in 0..<l1.count {
let on1 = l1[index1]
// l2.count
for index2 in 0..<l2.count {
let on2 = l2[index2]
for index3 in 0..<l3.count {
let on3 = l3[index3]
for index4 in 0..<l4.count {
let on4 = l4[index4]
for index5 in 0..<l5.count {
let on5 = l5[index5]
if on4 != on5 {
let lf = [on1, on2, on3, on4, on5]
final.append(lf)
}
}
}
}
}
}

print("final00 = \(final.count)")

// 5、转换类似矩阵的计算再次过滤,主要是 4、10、11、15 这几个相邻条件

// 4. 绿房子紧挨着白房子,在白房子的左边;b2 / b3
var final4 = [[[Int]]]()
for index in 0..<final.count {
var lf = final[index]
for i in 0..<4 {
var bNext = false
var lfo = lf[i]
let ii = i + 1
var lfor = lf[ii]
if lfo[1] == 0xb2 {
if lfor[1] == 0xb3 || lfor[1] == 0 {
bNext = true
}
else {
break
}
}
else if lfo[1] == 0 {
if lfor[1] == 0xb3 || lfor[1] == 0 {
bNext = true
}
}
else if lfo[1] == 0xb3 {
break
}
if bNext == true {
for iii in (ii + 1)..<5 {
let lforr = lf[iii]
if lforr[1] == 0xb2 || lforr[1] == 0xb3 {
bNext = false
break
}
}
}
if bNext == true {
if lfo[1] == 0 {
if lfo[3] == 0xd1 {
lfo[1] = 0xb2
}
else if lfo[3] == 0, lfo[0] != 0xa3 {
lfo[1] = 0xb2
}
else {
break
}
}
if lfor[1] == 0 {
lfor[1] = 0xb3
}
lf[i] = lfo
lf[ii] = lfor
final4.append(lf)
break
}
}
}

print("final remove")
final.removeAll()
print("final04 = \(final4.count)")

// 10. 抽 Blends 牌香烟的人和养猫的人相邻;c3 / e3:195 / 227
var final10 = [[[Int]]]()
for index in 0..<final4.count {
var lf = final4[index]
for i in 0..<4 {
var bNext = false
var lfo = lf[i]
let ii = i + 1
var lfor = lf[ii]
if lfo[2] == 0xc3 {
if lfor[4] == 0xe3 {
bNext = true
}
else if lfor[4] == 0 {
lfor[4] = 0xe3
lf[ii] = lfor
bNext = true
}
else {
break;
}
}
else if lfo[4] == 0xe3 {
if lfor[2] == 0xc3 {
bNext = true
}
else if lfor[2] == 0 {
lfor[2] = 0xc3
lf[ii] = lfor
bNext = true
}
else {
break;
}
}
else if lfo[2] == 0 {
if lfor[4] == 0xe3 {
lfo[2] = 0xc3
lf[i] = lfo
bNext = true
}
else if lfor[4] == 0 {
bNext = true
}
}
else if lfo[4] == 0 {
if lfor[2] == 0xc3 {
lfo[4] = 0xe3
lf[i] = lfo
bNext = true
}
else if lfor[2] == 0 {
bNext = true
}
}
if bNext == true {
for iii in (ii + 1)..<5 {
let lforr = lf[iii]
if lforr[2] == 0xc3 || lforr[4] == 0xe3 {
bNext = false
break
}
}
}
if bNext == true {
var bInsert = true
if lfo[2] == 0, lfor[4] == 0 {
lfo[2] = 0xc3
lf[i] = lfo
lfor[4] = 0xe3
lf[ii] = lfor
let lf1 = lf
final10.append(lf1)
bInsert = false
}
if lfo[4] == 0, lfor[2] == 0 {
lfo[4] = 0xe3
lf[i] = lfo
lfor[2] = 0xc3
lf[ii] = lfor

let lf2 = lf
final10.append(lf2)
bInsert = false
}
if bInsert == true {
final10.append(lf)
}
break
}
}
}

print("final04 remove")
final4.removeAll()
print("final10 = \(final10.count)")

// 11. 养马的人和抽 Dunhill 牌香烟的人相邻;e4 / c2:228 / 194
var final11 = [[[Int]]]()
for index in 0..<final10.count {
var lf = final10[index]
for i in 0..<4 {
var bNext = false
var lfo = lf[i]
let ii = i + 1
var lfor = lf[ii]
if lfo[4] == 0xe4 {
if lfor[2] == 0xc2 {
bNext = true
}
else if lfor[2] == 0, (lfor[1] == 0xb4 || lfor[1] == 0) {// TODO: 其他不能出现这个 后续条件
lfor[2] = 0xc2
lf[ii] = lfor
bNext = true
}
else {
break
}
}
else if lfo[2] == 0xc2 {
if lfor[4] == 0xe4 {
bNext = true
}
else if lfor[4] == 0 {
lfor[4] = 0xe4
lf[ii] = lfor
bNext = true
}
else {
break
}
}
else if lfo[4] == 0 {
if lfor[2] == 0xc2 {
lfo[4] = 0xe4
lf[i] = lfo
bNext = true
}
else if lfor[2] == 0 {
bNext = true
}
}
else if lfo[2] == 0, (lfo[1] == 0xb4 || lfo[1] == 0) {
if lfor[4] == 0xe4 {
lfo[2] = 0xc2
lf[i] = lfo
bNext = true
}
else if lfor[4] == 0 {
bNext = true
}
}
if bNext == true {
for iii in (ii + 1)..<5 {
let lforr = lf[iii]
if lforr[4] == 0xe4 || lforr[2] == 0xc2 {
bNext = false
break
}
}
}
if bNext == true {
var bInsert = true
if lfo[2] == 0, lfor[4] == 0 {
if lfo[1] == 0xb4 || lfo[1] == 0 {
lfo[2] = 0xc2
lf[i] = lfo
lfor[4] = 0xe4
lf[ii] = lfor
let lf1 = lf
final10.append(lf1)
}
bInsert = false
}
if lfo[4] == 0, lfor[2] == 0 {
if lfor[1] == 0xb4 || lfor[1] == 0 {
lfo[4] = 0xe4
lf[i] = lfo
lfor[2] = 0xc2
lf[ii] = lfor

let lf2 = lf
final10.append(lf2)
}
bInsert = false
}
if bInsert == true {
final11.append(lf)
}
break
}
}
}

print("final10 remove")
final10.removeAll()
print("final11 == \(final11.count)")

// 15. 抽 Blends 牌香烟的人和喝矿泉水的人相邻。c3 / d5:195 / 213
var final15 = [[[Int]]]()
for index in 0..<final11.count {
var lf = final11[index]
for i in 0..<4 {
var bNext = false
var lfo = lf[i]
let ii = i + 1
var lfor = lf[ii]
if lfo[2] == 0xc3 {
if lfor[3] == 0xd5 {
bNext = true
}
else if lfor[3] == 0 {
lfor[3] = 0xd5
lf[ii] = lfor
bNext = true
}
else {
break
}
}
else if lfo[3] == 0xd5 {
if lfor[2] == 0xc3 {
bNext = true
}
else if lfor[2] == 0 {
lfor[2] = 0xc3
lf[ii] = lfor
bNext = true
}
else {
break
}
}
else if lfo[2] == 0 {
if lfor[3] == 0xd5 {
lfo[2] = 0xc3
lf[i] = lfo
bNext = true
}
else if lfor[3] == 0 {
bNext = true
}
}
else if lfo[3] == 0 {
if lfor[2] == 0xc3 {
lfo[3] = 0xd5
lf[i] = lfo
bNext = true
}
else if lfor[2] == 0 {
bNext = true
}
}
if bNext == true {
for iii in (ii + 1)..<5 {
let lforr = lf[iii]
if lforr[2] == 0xc3 || lforr[3] == 0xd5 {
bNext = false
break
}
}
}
if bNext == true {
var bInsert = true
if lfo[2] == 0, lfor[3] == 0 {
lfo[2] = 0xc3
lf[i] = lfo
lfor[3] = 0xd5
lf[ii] = lfor
let lf1 = lf
final15.append(lf1)
bInsert = false
}
if lfo[3] == 0, lfor[2] == 0 {
lfo[3] = 0xd5
lf[i] = lfo
lfor[2] = 0xc3
lf[ii] = lfor

let lf2 = lf
final15.append(lf2)
bInsert = false
}
if bInsert == true {
final15.append(lf)
}
break
}
}
}

print("final11 remove")
final11.removeAll()
print("final15 == \(final15.count)")

// 6、去重,即将同组合,出现相同的配置去除,下面是针对 配置1、2、3、4、5逐一去重

var ffinal1 = [[[Int]]]()
for index in 0..<final15.count {
var lf = final15[index]
var bNext = true
for j in 0..<4 {
var lfo = lf[j]
for i in (j+1)..<5 {
var lfor = lf[i]
if lfo[0] == 0 {
break
}
else if lfo[0] == lfor[0] {
bNext = false
break
}
}
if bNext == false {
break
}
}
if bNext == true {
ffinal1.append(lf)
}
}

print("final15 remove")
final15.removeAll()
print("ffinal1 == \(ffinal1.count)")


var ffinal2 = [[[Int]]]()
for index in 0..<ffinal1.count {
var lf = ffinal1[index]
var bNext = true
for j in 0..<4 {
var lfo = lf[j]
for i in (j+1)..<5 {
var lfor = lf[i]
if lfo[1] == 0 {
break
}
else if lfo[1] == lfor[1] {
bNext = false
break
}
}
if bNext == false {
break
}
}
if bNext == true {
ffinal2.append(lf)
}
}

print("ffinal1 remove")
ffinal1.removeAll()
print("ffinal2 == \(ffinal2.count)")


var ffinal3 = [[[Int]]]()
for index in 0..<ffinal2.count {
var lf = ffinal2[index]
var bNext = true
for j in 0..<4 {
var lfo = lf[j]
for i in (j+1)..<5 {
var lfor = lf[i]
if lfo[2] == 0 {
break
}
else if lfo[2] == lfor[2] {
bNext = false
break
}
}
if bNext == false {
break
}
}
if bNext == true {
ffinal3.append(lf)
}
}

print("ffinal2 remove")
ffinal2.removeAll()
print("ffinal3 == \(ffinal3.count)")


var ffinal4 = [[[Int]]]()
for index in 0..<ffinal3.count {
var lf = ffinal3[index]
var bNext = true
for j in 0..<4 {
var lfo = lf[j]
for i in (j+1)..<5 {
var lfor = lf[i]
if lfo[3] == 0 {
break
}
else if lfo[3] == lfor[3] {
bNext = false
break
}
}
if bNext == false {
break
}
}
if bNext == true {
ffinal4.append(lf)
}
}

print("ffinal3 remove")
ffinal3.removeAll()
print("ffinal4 == \(ffinal4.count)")


var ffinal5 = [[[Int]]]()
for index in 0..<ffinal4.count {
var lf = ffinal4[index]
var bNext = true
for j in 0..<4 {
var lfo = lf[j]
for i in (j+1)..<5 {
var lfor = lf[i]
if lfo[4] == 0 {
break
}
else if lfo[4] == lfor[4] {
bNext = false
break
}
}
if bNext == false {
break
}
}
if bNext == true {
ffinal5.append(lf)
}
}

print("ffinal4 remove")
ffinal4.removeAll()
print("ffinal5 == \(ffinal5.count)")


let ffinal51 = deleteRepet(obj: ffinal5)

print("fffinal03 remove")
ffinal5.removeAll()
print("ffinal51 == \(ffinal51.count)")

ffinal5 = ffinal51

if reesult(obj: ffinal5) == true {
return
}

// 7、进行填充,类似数独,这次主要添加缺一配置的(即只有一个配置为 0 的进行填充)

let cd1 = [0xa1, 0xa2, 0xa3, 0xa4, 0xa5]
let cd2 = [0xb1, 0xb2, 0xb3, 0xb4, 0xb5]
let cd3 = [0xc1, 0xc2, 0xc3, 0xc4, 0xc5]
let cd4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5]
let cd5 = [0xe1, 0xe2, 0xe3, 0xe4, 0xe5]
var cdc = [cd1, cd2, cd3, cd4, cd5]
for idx in 0..<5 {
for index in 0..<ffinal5.count {
var lf = ffinal5[index]
var cd = cdc[idx]
var i0 = -1
for i in 0..<5 {
let lfo = lf[i]
if lfo[idx] != 0 {
if let id = cd.index(of: lfo[idx]) {
cd.remove(at: id)
}
}
else {
i0 = i
}
if i == 4 {
if cd.count == 1, i0 > -1 {
var lfo = lf[i0]
lfo[idx] = cd[0]
lf[i0] = lfo
}
}
}
ffinal5[index] = lf
}
}

// 8、再次条件匹配,这些条件是前面提到的条件,列出的前8个,它们各自都有两个配置需要对应,这主要是去掉上面填写之后不符合的

var fffinal01 = [[[Int]]]()
var cdo = [o1, o2, o3, o4, o5, o6, o7, o8]

for index in 0..<ffinal5.count {
var lf = ffinal5[index]
var bInsert = true
for idx in 0..<cdo.count {
let cdoo = cdo[idx]
var ci1 = -1
var ci2 = -1
for ci in 0..<5 {
if cdoo[ci] != 0 {
if ci1 != -1 {
ci2 = ci
}
else {
ci1 = ci
}
}
}
for i in 0..<5 {
let lfo = lf[i]
if lfo[ci1] == cdoo[ci1] {
if lfo[ci2] == cdoo[ci2] || lfo[ci2] == 0 {
// fffinal01.append(lf)
// break
}
else {
bInsert = false
break
}
}
else if lfo[ci2] == cdoo[ci2] {
if lfo[ci1] == cdoo[ci1] || lfo[ci1] == 0 {
// fffinal01.append(lf)
// break
}
else {
bInsert = false
break
}
}
else {
// if i == 4 {
// fffinal01.append(lf)
// }
}
}
if bInsert == false {
break
}
}
if bInsert == true {
fffinal01.append(lf)
}
}

print("ffinal5 remove")
ffinal5.removeAll()
print("ffinal12 == \(fffinal01.count)")


let fffinal011 = deleteRepet(obj: fffinal01)

print("fffinal03 remove")
fffinal01.removeAll()
print("fffinal011 == \(fffinal011.count)")

fffinal01 = fffinal011

if reesult(obj: fffinal01) == true {
return
}

// 9、填写 缺两个配置的

var fffinal02 = [[[Int]]]()
cdc = [cd1, cd2, cd3, cd4, cd5]
for idx in 0..<5 {
for index in 0..<fffinal01.count {
var lf = fffinal01[index]
var i0 = -1
var i1 = -1
var bInsert = false
var cd = cdc[idx]
for i in 0..<5 {
let lfo = lf[i]
if lfo[idx] != 0 {
if let id = cd.index(of: lfo[idx]) {
cd.remove(at: id)
}
}
else {
if i0 != -1 {
i1 = i
}
else {
i0 = i
}
}
if i == 4 {
if cd.count == 2 {
bInsert = true
for ii in 0..<2 {
let insert0 = cd[0]
let insert1 = cd[1]

if ii == 0 {
var lfo0 = lf[i0]
lfo0[idx] = insert0

var lfo1 = lf[i1]
lfo1[idx] = insert1

lf[i0] = lfo0
lf[i1] = lfo1
let llf = lf

fffinal02.append(llf)
}
else {
var lfo0 = lf[i0]
lfo0[idx] = insert1

var lfo1 = lf[i1]
lfo1[idx] = insert0

lf[i0] = lfo0
lf[i1] = lfo1
let llf = lf

fffinal02.append(llf)
}
}
}
}
}
if bInsert == false {
fffinal02.append(lf)
}
}
}

print("fffinal01 remove")
fffinal01.removeAll()
print("fffinal02 == \(fffinal02.count)")

// 10、再次去重

var fffinal03 = [[[Int]]]()
cdo = [o1, o2, o3, o4, o5, o6, o7, o8]

for index in 0..<fffinal02.count {
var lf = fffinal02[index]
var bInsert = true
for idx in 0..<cdo.count {
let cdoo = cdo[idx]
var ci1 = -1
var ci2 = -1
for ci in 0..<5 {
if cdoo[ci] != 0 {
if ci1 != -1 {
ci2 = ci
}
else {
ci1 = ci
}
}
}
for i in 0..<5 {
let lfo = lf[i]
if lfo[ci1] == cdoo[ci1] {
if lfo[ci2] == cdoo[ci2] || lfo[ci2] == 0 {
}
else {
bInsert = false
break
}
}
else if lfo[ci2] == cdoo[ci2] {
if lfo[ci1] == cdoo[ci1] || lfo[ci1] == 0 {
}
else {
bInsert = false
break
}
}
else {
}
}
if bInsert == false {
break
}
}
if bInsert == true {
fffinal03.append(lf)
}
}

print("fffinal02 remove")
fffinal02.removeAll()
print("fffinal03 == \(fffinal03.count)")

let fffinal031 = deleteRepet(obj: fffinal03)

print("fffinal03 remove")
fffinal03.removeAll()
print("fffinal031 == \(fffinal031.count)")

fffinal03 = fffinal031

// 11、打印结果:结果还有 九百多个

print("start")

let fffffinal = fffinal03

// for index in 0..<fffffinal.count {
// let lf = fffffinal[index]
// for i in 0..<5 {
// let lfo = lf[i]
// var llf = [String]()
// for j in 0..<5 {
// let vv = String(lfo[j], radix: 16)
// llf.append(vv)
// }
// print("\(llf)")
// }
// print("--------------------------------------------------------------------------")
// }
if reesult(obj: fffffinal) == true {
return
}

print("end")

/*
12、
按理到这里还有没填充满的 0
但是,当将输出到这里的数据打印出来,发现一个已经填满,并且出现多次
因为已经填满的是通过多层校验,如下

["a4", "b4", "c2", "d5", "e3"]
["a3", "b5", "c3", "d4", "e4"]
["a1", "b1", "c1", "d2", "e2"]
["a5", "b2", "c5", "d1", "e5"]
["a2", "b3", "c4", "d3", "e1"]

对其进行人工检测,所有条件匹配,也就是说它就是最后的答案
答案:德国人🇩🇪养鱼🐟
*/

/*
其实找猫为条件筛选会更直接,可是这边我想排出房子排列的所有可能,
并且这里的计算有重复,所以生成的数据其实很多都是重复的,还是没完成,只能说只是能看到答案
*/
}