Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
exapunks-hackmatch-bot
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Taddeüs Kroes
exapunks-hackmatch-bot
Commits
bbbfc5be
Commit
bbbfc5be
authored
Apr 12, 2020
by
Taddeüs Kroes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Manage group sizes per group instead of per block
parent
5efb10b4
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
32 additions
and
44 deletions
+32
-44
strategy.py
strategy.py
+32
-44
No files found.
strategy.py
View file @
bbbfc5be
...
@@ -26,16 +26,15 @@ BOMB_POINTS = 5
...
@@ -26,16 +26,15 @@ BOMB_POINTS = 5
class
State
:
class
State
:
def
__init__
(
self
,
blocks
,
exa
,
held
,
colskip
,
busy
,
moves
,
groups
,
groupsizes
,
maxgroup
):
def
__init__
(
self
,
blocks
,
exa
,
held
,
colskip
,
busy
,
moves
,
blockgroups
,
groups
):
self
.
blocks
=
blocks
self
.
blocks
=
blocks
self
.
exa
=
exa
self
.
exa
=
exa
self
.
held
=
held
self
.
held
=
held
self
.
colskip
=
colskip
self
.
colskip
=
colskip
self
.
busy
=
busy
self
.
busy
=
busy
self
.
moves
=
moves
self
.
moves
=
moves
self
.
blockgroups
=
blockgroups
self
.
groups
=
groups
self
.
groups
=
groups
self
.
groupsizes
=
groupsizes
self
.
maxgroup
=
maxgroup
self
.
nrows
=
len
(
blocks
)
//
COLUMNS
self
.
nrows
=
len
(
blocks
)
//
COLUMNS
@
classmethod
@
classmethod
...
@@ -45,9 +44,9 @@ class State:
...
@@ -45,9 +44,9 @@ class State:
held
=
detect_held
(
board
,
exa
)
held
=
detect_held
(
board
,
exa
)
colskip
=
get_colskip
(
blocks
)
colskip
=
get_colskip
(
blocks
)
busy
=
get_busy
(
blocks
,
colskip
)
busy
=
get_busy
(
blocks
,
colskip
)
groups
,
groupsizes
,
maxgroup
=
get_groups
(
blocks
)
blockgroups
,
groups
=
get_groups
(
blocks
)
return
cls
(
bytearray
(
blocks
),
exa
,
held
,
bytearray
(
colskip
),
busy
,
(),
return
cls
(
bytearray
(
blocks
),
exa
,
held
,
bytearray
(
colskip
),
busy
,
(),
bytearray
(
groups
),
bytearray
(
groupsizes
),
maxgroup
)
bytearray
(
blockgroups
),
groups
)
def
copy
(
self
,
deep
):
def
copy
(
self
,
deep
):
mcopy
=
copy
if
deep
else
lambda
x
:
x
mcopy
=
copy
if
deep
else
lambda
x
:
x
...
@@ -57,9 +56,8 @@ class State:
...
@@ -57,9 +56,8 @@ class State:
mcopy
(
self
.
colskip
),
mcopy
(
self
.
colskip
),
self
.
busy
,
self
.
busy
,
self
.
moves
,
self
.
moves
,
mcopy
(
self
.
groups
),
mcopy
(
self
.
blockgroups
),
mcopy
(
self
.
groupsizes
),
mcopy
(
self
.
groups
))
self
.
maxgroup
)
def
colbusy
(
self
,
col
):
def
colbusy
(
self
,
col
):
return
(
self
.
busy
>>
col
)
&
1
return
(
self
.
busy
>>
col
)
&
1
...
@@ -93,13 +91,13 @@ class State:
...
@@ -93,13 +91,13 @@ class State:
return
score
return
score
def
locked
(
self
,
i
):
def
locked
(
self
,
i
):
block
=
self
.
blocks
[
i
]
size
,
block
=
self
.
groups
[
self
.
blockgroups
[
i
]
]
if
block
==
NOBLOCK
:
if
block
==
NOBLOCK
:
return
False
return
False
if
is_basic
(
block
):
if
is_basic
(
block
):
return
s
elf
.
groupsizes
[
i
]
>=
MIN_BASIC_GROUP_SIZE
return
s
ize
>=
MIN_BASIC_GROUP_SIZE
assert
is_bomb
(
block
)
assert
is_bomb
(
block
)
return
s
elf
.
groupsizes
[
i
]
>=
MIN_BOMB_GROUP_SIZE
return
s
ize
>=
MIN_BOMB_GROUP_SIZE
def
move
(
self
,
*
moves
):
def
move
(
self
,
*
moves
):
deep
=
any
(
move
in
(
GRAB
,
DROP
,
SWAP
)
for
move
in
moves
)
deep
=
any
(
move
in
(
GRAB
,
DROP
,
SWAP
)
for
move
in
moves
)
...
@@ -165,15 +163,14 @@ class State:
...
@@ -165,15 +163,14 @@ class State:
def
ungroup
(
self
,
i
,
visited
):
def
ungroup
(
self
,
i
,
visited
):
assert
self
.
blocks
[
i
]
==
NOBLOCK
assert
self
.
blocks
[
i
]
==
NOBLOCK
oldid
=
self
.
groups
[
i
]
oldid
=
self
.
blockgroups
[
i
]
self
.
blockgroups
[
i
]
=
0
self
.
groups
[
oldid
]
=
0
,
NOBLOCK
for
nb
in
neighbors
(
i
,
self
.
blocks
):
for
nb
in
neighbors
(
i
,
self
.
blocks
):
if
self
.
groups
[
nb
]
==
oldid
:
if
self
.
block
groups
[
nb
]
==
oldid
:
self
.
create_group
(
nb
,
visited
)
self
.
create_group
(
nb
,
visited
)
self
.
groups
[
i
]
=
0
self
.
groupsizes
[
i
]
=
0
def
place
(
self
,
i
,
block
):
def
place
(
self
,
i
,
block
):
assert
block
!=
NOBLOCK
assert
block
!=
NOBLOCK
assert
self
.
blocks
[
i
]
==
NOBLOCK
assert
self
.
blocks
[
i
]
==
NOBLOCK
...
@@ -192,10 +189,10 @@ class State:
...
@@ -192,10 +189,10 @@ class State:
block
=
self
.
blocks
[
start
]
block
=
self
.
blocks
[
start
]
group
=
tuple
(
scan
(
start
))
group
=
tuple
(
scan
(
start
))
if
group
:
if
group
:
self
.
maxgroup
=
newid
=
self
.
maxgroup
+
1
newid
=
len
(
self
.
groups
)
self
.
groups
.
append
((
len
(
group
),
block
))
for
j
in
group
:
for
j
in
group
:
self
.
groups
[
j
]
=
newid
self
.
blockgroups
[
j
]
=
newid
self
.
groupsizes
[
j
]
=
len
(
group
)
def
fragmentation
(
self
):
def
fragmentation
(
self
):
"""
"""
...
@@ -207,9 +204,9 @@ class State:
...
@@ -207,9 +204,9 @@ class State:
yi
,
xi
=
divmod
(
i
,
COLUMNS
)
yi
,
xi
=
divmod
(
i
,
COLUMNS
)
yj
,
xj
=
divmod
(
j
,
COLUMNS
)
yj
,
xj
=
divmod
(
j
,
COLUMNS
)
# for blocks in the same group, only count vertical distance so
# for blocks in the same group, only count vertical distance so
that
#
that
groups are spread out horizontally
# groups are spread out horizontally
if
self
.
groups
[
i
]
==
self
.
groups
[
j
]:
if
self
.
blockgroups
[
i
]
==
self
.
block
groups
[
j
]:
return
abs
(
yj
-
yi
)
return
abs
(
yj
-
yi
)
return
abs
(
xj
-
xi
)
+
abs
(
yj
-
yi
)
*
2
-
1
+
\
return
abs
(
xj
-
xi
)
+
abs
(
yj
-
yi
)
*
2
-
1
+
\
...
@@ -224,20 +221,10 @@ class State:
...
@@ -224,20 +221,10 @@ class State:
for
blocks
in
colors
.
values
()
for
blocks
in
colors
.
values
()
for
i
,
j
in
combinations
(
blocks
,
2
))
for
i
,
j
in
combinations
(
blocks
,
2
))
def
group_leaders
(
self
):
seen
=
set
()
for
i
,
groupid
in
enumerate
(
self
.
groups
):
if
groupid
>
0
and
groupid
not
in
seen
:
seen
.
add
(
groupid
)
yield
i
def
points
(
self
):
def
points
(
self
):
points
=
0
points
=
0
for
leader
in
self
.
group_leaders
():
for
size
,
block
in
self
.
groups
:
block
=
self
.
blocks
[
leader
]
size
=
self
.
groupsizes
[
leader
]
if
is_basic
(
block
)
and
size
>=
MIN_BASIC_GROUP_SIZE
:
if
is_basic
(
block
)
and
size
>=
MIN_BASIC_GROUP_SIZE
:
points
+=
size
points
+=
size
elif
is_bomb
(
block
)
and
size
>=
MIN_BOMB_GROUP_SIZE
:
elif
is_bomb
(
block
)
and
size
>=
MIN_BOMB_GROUP_SIZE
:
...
@@ -367,12 +354,14 @@ class State:
...
@@ -367,12 +354,14 @@ class State:
return
cls
.
points
,
cls
.
fragmentation
,
cls
.
holes
,
cls
.
nmoves
return
cls
.
points
,
cls
.
fragmentation
,
cls
.
holes
,
cls
.
nmoves
def
print_groupsizes
(
self
):
def
print_groupsizes
(
self
):
for
start
in
range
(
len
(
self
.
groupsizes
)
-
COLUMNS
,
-
1
,
-
COLUMNS
):
for
start
in
range
(
len
(
self
.
blockgroups
)
-
COLUMNS
,
-
1
,
-
COLUMNS
):
print
(
' '
.
join
(
'%-2d'
%
g
for
g
in
self
.
groupsizes
[
start
:
start
+
COLUMNS
]))
print
(
' '
.
join
(
'%-2d'
%
self
.
groups
[
g
][
0
]
for
g
in
self
.
blockgroups
[
start
:
start
+
COLUMNS
]))
def
print_groups
(
self
):
def
print_groups
(
self
):
for
start
in
range
(
len
(
self
.
groups
)
-
COLUMNS
,
-
1
,
-
COLUMNS
):
for
start
in
range
(
len
(
self
.
blockgroups
)
-
COLUMNS
,
-
1
,
-
COLUMNS
):
print
(
' '
.
join
(
'%-2d'
%
g
for
g
in
self
.
groups
[
start
:
start
+
COLUMNS
]))
print
(
' '
.
join
(
'%-2d'
%
g
for
g
in
self
.
blockgroups
[
start
:
start
+
COLUMNS
]))
def
print
(
self
):
def
print
(
self
):
print_board
(
self
.
blocks
,
self
.
exa
,
self
.
held
)
print_board
(
self
.
blocks
,
self
.
exa
,
self
.
held
)
...
@@ -430,20 +419,19 @@ def scan_group(blocks, i, block, visited):
...
@@ -430,20 +419,19 @@ def scan_group(blocks, i, block, visited):
def
get_groups
(
blocks
):
def
get_groups
(
blocks
):
groupid
=
0
blockgroups
=
[
0
]
*
len
(
blocks
)
groups
=
[
0
]
*
len
(
blocks
)
groups
=
[(
0
,
NOBLOCK
)]
groupsizes
=
[
0
]
*
len
(
blocks
)
visited
=
set
()
visited
=
set
()
for
i
,
block
in
enumerate
(
blocks
):
for
i
,
block
in
enumerate
(
blocks
):
if
block
!=
NOBLOCK
and
i
not
in
visited
:
if
block
!=
NOBLOCK
and
i
not
in
visited
:
groupid
+=
1
groupid
=
len
(
groups
)
group
=
tuple
(
scan_group
(
blocks
,
i
,
block
,
visited
))
group
=
tuple
(
scan_group
(
blocks
,
i
,
block
,
visited
))
groups
.
append
((
len
(
group
),
block
))
for
j
in
group
:
for
j
in
group
:
groups
[
j
]
=
groupid
blockgroups
[
j
]
=
groupid
groupsizes
[
j
]
=
len
(
group
)
return
groups
,
groupsizes
,
groupid
return
blockgroups
,
groups
def
neighbors
(
i
,
blocks
):
def
neighbors
(
i
,
blocks
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment