Loading [Contrib]/a11y/accessibility-menu.js
Download
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
#!/usr/bin/env python3
 
# program to convert from queens and ruled out diagonals to report stats and convert to dimacs
 
import sys
 
 
def An(n):
    assert( n % 6 == 1 or n % 6 == 5)
    res = []
    for i in range(n):
        res.append([i,(2*i)%n])
    return( res)
 
def Bn(n):
    assert( n % 6 == 1 or n % 6 == 5)
    res = []
    for i in range(n):
        res.append([(2*i)%n,i])
    return( res)
 
def timesn(n,q):
    return [q[0]*n,q[1]*n]
 
def plusqueen(q1,q2):
    return [q1[0]+q2[0],q1[1]+q2[1]]
 
def offsetqueens(n,offsetq,queens):
    return [plusqueen(timesn(n,offsetq),q) for q in queens]
 
q19col0 = [0,8]
q19col19 = [19,8]
q19row0 = [17,0]
q19row19 = [17,19]
q19rest = [[1,12],[2,17],[3,7],[4,10],[5,15],[6,1],[7,16],[8,13],[9,2],[10,6],[11,18],[12,3],[13,5],[14,11],[15,9],[16,14],[18,4]]
 
def max(numbers):
    assert(len(numbers) != 0)
    max=numbers[0]
    for i in range(1,len(numbers)):
        if numbers[i] > max:
            max=numbers[i]
    return max
 
def checkrowcols(Queens):
    if(Queens == []):
        return True
    n1 = len(Queens)
    n2 = max([q[0] for q in Queens] + [q[1] for q in Queens]) + 1
    if( n1 > n2):
        return False
    rowbits = [0 for i in range(n2)]
    colbits = [0 for i in range(n2)]
    for q in Queens:
        colbits[q[0]] = 1
        rowbits[q[1]] = 1
    return ( (len([1 for i in range(n2) if rowbits[i] != 0]) == n1) and
             (len([1 for i in range(n2) if colbits[i] != 0]) == n1) )
 
def checkdiags(Queens):
    if(Queens == []):
        return True
    n1 = len(Queens)
    n2 = max([q[0] for q in Queens] + [q[1] for q in Queens]) + 1
    if( n1 > n2):
        return False
    d1bits = [0 for i in range(2*n2)]
    d2bits = [0 for i in range(2*n2)]
    for q in Queens:
        d1bits[q[0]+q[1]] = 1
        d2bits[q[0]-q[1]+n2-1] = 1
    return ( (len([1 for i in range(2*n2) if d1bits[i] != 0]) == n1) and
             (len([1 for i in range(2*n2) if d2bits[i] != 0]) == n1) )
 
def checknoattack(Queens):
    return checkrowcols(Queens) and checkdiags(Queens)
 
### e.g. reduce3to2(7,[],[],[])
 
def reduce3to2(M3):
    n3=M3[0]
    P3=M3[1]
    m3=M3[2]
    C3=M3[3]
    R3=M3[4]
    assert len(C3) == len(R3), ("different numbers of rows and columns: ")
    assert m3 == len(C3)+len(P3), "m inconsistent with length of cols and preplaced queens"
    assert m3 <= n3, ("more queens to place than places to put them: " + str(m3) + " " + str(n3))
    if P3 or C3 or R3:
        ncheck = max([q[0] for q in P3] + [q[1] for q in P3] + C3 + R3)
        assert ncheck < n3, ("Row or column required more than input value of n")
    assert(checkrowcols(P3)), ("preplaced queens have two in same row or column: " + str(P3))
    Cprime = C3 + [q[0] for q in P3]
    Rprime = R3 + [q[1] for q in P3]
    assert len(set(Rprime)) == m3, "preplaced queen in one of required rows"
    assert len(set(Cprime)) == m3, "preplaced queen in one of required cols"
    if not checkdiags(P3):
        return [n3,P3]
    if n3%3 == 2:
        nprime = n3*2+1
    else:
        nprime = n3*2-1
    an = An(nprime)
    bn = Bn(nprime)
    qscol0 = [q for q in offsetqueens(nprime,q19col0,an) if q[0] not in Cprime]
    qsrow0 = [q for q in offsetqueens(nprime,q19row0,bn) if q[1] not in Rprime]
    qsrest = qscol0+qsrow0
    for qr in q19rest:
        qsrest += [q for q in offsetqueens(nprime,qr,an)]
    Cprime.sort()
    Rprime.sort()
    QC = [[i,2*Cprime[i]] for i in range(m3)]
    QR = [[2*Rprime[i],i] for i in range(m3)]
    result = P3
    result += offsetqueens(nprime,q19col19,QC)
    result += offsetqueens(nprime,q19row19,QR)
    result += qsrest
    assert(checknoattack(result)),("Bug: computed attacking set of queens: "+str(result))
    return [19*nprime+m3,result]
 
 
def reduce4to3(n4,m4,C4,R4,D4diff,D4sum):
    n3=n4*7-3
    m3=m4+len(D4diff)+len(D4sum)
    Qdiff = [ [6*n4-3-d,3*n4-1-2*d] for d in D4diff ]
    Qsum =  [ [2*n4-2-d,n4+2*d] for d in D4sum ]
    C3=[c+3*n4-2 for c in C4]
    R3=R4
    return [n3,Qdiff+Qsum,m3,C3,R3]
 
# Special case where all rows and columns allowed
def reducesimple4to3(M4Simple):
    n = M4Simple[0]
    Ddiff = M4Simple[1]
    Dsum = M4Simple[2]
    return reduce4to3(n,n,list(range(n)),list(range(n)),Ddiff,Dsum)
 
# Numbers as read from input file
# numbers[0] = n
# numbers[1] = maxdiags
# numbers[2,4,6 ... ] = diagonal, +n-1 for difference diagonals
# numbers[3,5,7... ] = 1 for sum diag, 0 for diff
 
def diagtosimple4(numdiags,numbers):
    n = numbers[0]
    maxdiags = numbers[1]
    assert numdiags <= maxdiags, "more diagonals requested than available in input"
    assert len(numbers) >= numdiags*2 + 2, "fewer diagonals than claimed"
    Ddiff=[]
    Dsum=[]
    for i in range(numdiags):
        d=numbers[i*2+2]
        direction=numbers[i*2+2+1]
        assert(direction == 0 or direction == 1)
        if direction == 1:
            Dsum.append(d)
        else:
            Ddiff.append(d-n+1)
    return [n,Ddiff,Dsum]
     
 
 
def reducesimple4to2(M4Simple):
    return reduce3to2(reducesimple4to3(M4Simple))
 
def printqueens2(M2):
    print("letting n = ",M2[0])
    print("letting init = ",M2[1])
 
def printqueensfromdiag(numdiags,numbers):
    printqueens2(reducesimple4to2(diagtosimple4(numdiags,numbers)))