Sudoku King turunu maksimuma çıkarın


16

Arka fon

Sudoku bir verilen bir sayı bulmacasıdır n×n boyutta kutulara bölünmüş ızgara n , her bir sayısı 1 ile n , her satır, sütun ve kutunun bir kez tam olarak görünmelidir.

Satranç oyununda, Kral sırayla 8 komşu hücrenin herhangi birine hareket edebilir. Burada "bitişik" yatay, dikey veya çapraz olarak bitişik anlamına gelir.

King'in tur Knight'ın tur bir benzetme; Chess King'in hareketleri ile verilen tahtadaki her hücreyi tam olarak bir kez ziyaret eden (muhtemelen açık) bir yoldur.

Görev

6x6 Sudoku ızgarasını düşünün:

654 | 321
123 | 654
----+----
462 | 135
315 | 246
----+----
536 | 412
241 | 563

ve bir Kral turu (başlangıç 01noktası 36):

01 02 03 | 34 35 36
31 32 33 | 04 05 06
---------+---------
30 23 28 | 27 26 07
22 29 24 | 25 09 08
---------+---------
21 19 16 | 10 14 13
20 17 18 | 15 11 12

Tur, 36 haneli sayıyı oluşturur 654654564463215641325365231214123321.

Farklı bir Kral turuna katılmak daha büyük sayılar verir; örneğin, 65<6>56446556...kesinlikle yukarıdakilerden daha büyük olan bir yol bulabilirim . Daha da yüksek sayılar elde etmek için Sudoku kartını değiştirebilirsiniz:

... | ...
.6. | ...
----+----
..6 | ...
.5. | 6..
----+----
.45 | .6.
6.. | 5..

Bu eksik tahta başlangıç ​​sırasını 666655546...9 başlangıç ​​basamağının en uygun sırası olan verir .

Göreviniz , 3'e 3 kutularla standart 9 x 9 Sudoku için bu kadar büyük bir sayı bulmaktır , yani

... | ... | ...
... | ... | ...
... | ... | ...
----+-----+----
... | ... | ...
... | ... | ...
... | ... | ...
----+-----+----
... | ... | ...
... | ... | ...
... | ... | ...

Bu zorluğun olmadığını unutmayın ; odak noktamız teorik olarak çalışan küçük bir program yazmaktan ziyade çözümleri bulmaktır.

Puanlama ve kazanma kriteri

Bir başvuru puanı, programınız tarafından bulunan 81 haneli sayıdır. En yüksek puana sahip sunum kazanır. Programınız ayrıca Sudoku ızgarasını ve Kral turunu insan tarafından okunabilir biçimde çıkarmalıdır; lütfen bunları gönderiminize ekleyin.

Programınız birden fazla sonuç verebilir; en yüksek puanınız.

Programınız için zaman sınırı yoktur. Programınız çalışmaya devam ederse ve daha sonra daha yüksek bir sayı bulursa, yayını düzenleyerek gönderimin puanını güncelleyebilirsiniz. Tiebreaker skoru elde etmek için en erken zamandır, yani ya yazı zamanı (henüz düzenlenmemişse) ya da skorun güncellenme zamanı (aksi halde).


2
Senin üzerinde bu meydan kendini aday PPCG Best için, siz "Bu oldukça kod uzunluk veya böyle kombine bazı puanından, optimize edilmiş çözüm için doğrudan soran ilk [kod meydan okuma] olasılıkla gerçek değildir." Söz Sadece bunun doğru olmadığını bilmenizi istedim - 2015'te yayınlanan En Kısa Evrensel Labirent Çıkış Dizesi var.
Esolanging Fruit

Yanıtlar:


19

Python + Z3 , 999899898789789787876789658767666545355432471632124566352413452143214125313214321, optimal

Yaklaşık yarım saat içinde çalışır,

1 3 4 8 9 7 6 2 5
2 9 7 1 5 6 8 3 4
5 6 8 4 2 3 7 9 1
4 7 6 2 1 5 9 8 3
8 5 1 6 3 9 2 4 7
9 2 3 7 8 4 1 5 6
3 8 5 9 6 1 4 7 2
6 4 9 5 7 2 3 1 8
7 1 2 3 4 8 5 6 9
81 79 78 14 15 16 54 57 56
80 12 13 77 52 53 17 55 58
34 33 11 51 76 75 18  1 59
35 10 32 50 74 72  2 19 60
 9 36 49 31 73  3 71 61 20
 8 48 37 30  4 69 70 62 21
47  7 38  5 29 68 65 22 63
46 43  6 39 28 67 66 64 23
44 45 42 41 40 27 26 25 24
999899898789789787876789658767666545355432471632124566352413452143214125313214321

kod

import z3


def adj(a):
    x, y = a
    for x1 in range(max(0, x - 1), min(9, x + 2)):
        for y1 in range(max(0, y - 1), min(9, y + 2)):
            if (x1, y1) != a:
                yield x1, y1


solver = z3.SolverFor("QF_FD")

squares = list((x, y) for x in range(9) for y in range(9))
num = {(x, y): z3.Int(f"num{x}_{y}") for x, y in squares}
for a in squares:
    solver += 1 <= num[a], num[a] <= 9
for cells in (
    [[(x, y) for y in range(9)] for x in range(9)]
    + [[(x, y) for x in range(9)] for y in range(9)]
    + [
        [(x, y) for x in range(i, i + 3) for y in range(j, j + 3)]
        for i in range(0, 9, 3)
        for j in range(0, 9, 3)
    ]
):
    solver += z3.Distinct([num[x, y] for x, y in cells])
    for k in range(1, 10):
        solver += z3.Or([num[x, y] == k for x, y in cells])

move = {
    ((x0, y0), (x1, y1)): z3.Bool(f"move{x0}_{y0}_{x1}_{y1}")
    for x0, y0 in squares
    for x1, y1 in adj((x0, y0))
}
tour = {(x, y): z3.Int(f"tour{x}_{y}") for x, y in squares}
for a in squares:
    solver += 0 <= tour[a], tour[a] < 81
for a in squares:
    solver += z3.PbEq([(move[a, b], 1) for b in adj(a)] + [(tour[a] == 80, 1)], 1)
for b in squares:
    solver += z3.PbEq([(move[a, b], 1) for a in adj(b)] + [(tour[b] == 0, 1)], 1)
solver += z3.Distinct([tour[a] for a in squares])
for t in range(81):
    solver += z3.Or([tour[a] == t for a in squares])
for a in squares:
    for b in adj(a):
        solver += move[a, b] == (tour[a] + 1 == tour[b])

value = [z3.Int(f"value{t}") for t in range(81)]
for t in range(81):
    solver += 1 <= value[t], value[t] <= 9
for a in squares:
    for t in range(81):
        solver += z3.Implies(tour[a] == t, num[a] == value[t])

assert solver.check() != z3.unsat
opt = 0
while opt < 81:
    model = solver.model()
    for y in range(9):
        print(*(model[num[x, y]] for x in range(9)))
    for y in range(9):
        print(*(f"{model[tour[x, y]].as_long() + 1:2}" for x in range(9)))
    best = [model[value[t]].as_long() for t in range(81)]
    print(*best, sep="")
    print()
    while opt < 81:
        improve = z3.Bool(f"improve{opt}_{best[opt]}")
        solver += improve == (value[opt] > best[opt])
        if solver.check(improve) != z3.unsat:
            break
        solver += value[opt] == best[opt]
        opt += 1

Elbette problemi çok fazla abarttım. Ve tamamen Z3'ün karanlık büyüsünü unuttum ...
Bubbler

@Bubbler'ın optimal bir çözümün ulaşılamayacağından emin olmak zordur. Aynı hatayı kendim yaptım - ve birisi en uygun çözümü yayınlamadan önce daha da az zaman aldı ... codegolf.stackexchange.com/a/51974/20283
trichoplax

Benimki kurtarılamaz değil, ama bu zorluğun daha büyük bir tahta ve farklı bir satranç parçası ile bir varyasyon olarak işe
yarayıp yaramayacağını
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.