-
Notifications
You must be signed in to change notification settings - Fork 113
/
BlockSys.jl
71 lines (65 loc) · 1.42 KB
/
BlockSys.jl
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
module BlockSys
using Oscar
struct BlockSystems
n::Int
l::Int
cur::Array{Array{Int, 1}, 1}
function BlockSystems(n::Int, l::Int)
@assert n % l == 0
return new(n, l, [collect((i-1)*l+1:i*l) for i=1:divexact(n, l)])
end
end
function Base.iterate(B::BlockSystems)
return B.cur, deepcopy(B.cur)
end
function Base.iterate(B::BlockSystems, st::Array{Array{Int, 1}})
if B.l==1||B.l==B.n
return nothing
end
i = length(B.cur)-1
while true
j = B.l
while true
if st[i][j] < B.n - B.l + j
st[i][j] += 1
free = Set(1:B.n)
for l=1:i-1
setdiff!(free, st[l])
end
if !(st[i][j] in free)
continue
end
if length(intersect(free, Set(st[i][j]+1:B.n)))<B.l-j
continue
end
setdiff!(free, st[i][1:j])
while j < B.l
j += 1
I = intersect(free, Set(st[i][j-1]:B.n))
if isempty(I)
break
end
st[i][j] = minimum(I)
pop!(free, st[i][j])
end
i += 1
while i <= length(st)
for j=1:B.l
st[i][j] = minimum(free)
pop!(free, st[i][j])
end
i += 1
end
return deepcopy(st), st
end
j -= 1
if j == 1
i -= 1
i == 0 && return nothing
break
end
end
end
end
Base.IteratorSize(::BlockSystems) = Base.SizeUnknown()
end