Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
Wall Keeper solution in Creative category for Wall Keeper by JimmyCarlos
from copy import deepcopy
import random
import time
def findAdjacentTiles(R,C):
"""Find all the tiles adjacent to a given tile."""
W,H = 5,5
adjacentTiles = set()
if R != 0: adjacentTiles.add((R-1,C)) # North
if C != W-1: adjacentTiles.add((R,C+1)) # East
if R != H-1: adjacentTiles.add((R+1,C)) # South
if C != 0 : adjacentTiles.add((R,C-1)) # West
return adjacentTiles
def pressTile(R,C):
"""Press a specific tile, updating the global list."""
global A
A[R][C] = not A[R][C]
for adjacentTile in adjacentTilesDict[R][C]:
newR,newC = adjacentTile
A[newR][newC] = not A[newR][newC]
def print_grid():
"""Print the current grid."""
for R in range(5):
print(" ".join([["O","X"][A[R][C]] for C in range(5)]))
print()
def is_perfect_grid():
"""Check to see if all tiles are now clear."""
for R in range(5):
for C in range(5):
if A[R][C]: return False
else:
return True
def press_random_button():
"""Press a random button, return which index was chosen."""
R,C = random.randint(0,4), random.randint(0,4)
pressTile(R,C)
return convert_RC_to_index(R,C)
def convert_index_to_RC(index):
"""Convert an index to a row and column"""
R = (index-1)//5
C = (index-1) % 5
return (R,C)
def convert_RC_to_index(R,C):
"""Convert a row and column to an index."""
index = C + R*5 + 1
return index
def filter_panelsToClick(panelsToClick):
"""Make a solution shorter by removing any double-presses,
eg. a press of 14 at the start and at the end cancel each other out"""
return [panel for panel in range(1,26) if panelsToClick.count(panel) % 2 == 1]
def wall_keeper(lights_on):
# A and adjacentTilesDict are going to be used so much they might as well just be globals.
global A,adjacentTilesDict
# Create 2-D list to hold whether a tile is on or off
A = [[False for C in range(5)] for R in range(5)]
# Update that list with the lights_on given in the testcase.
for index in lights_on:
R,C = convert_index_to_RC(index)
A[R][C] = True
# Pre-compute all adjacent tiles to speed up algorithm
adjacentTilesDict = [[findAdjacentTiles(R,C) for C in range(5)] for R in range(5)]
# Create an empty list to store all panels needed to be clicked.
panelsToClick = []
# VERY SHAKY MAIN LOOP.
# Idea: In every iteration, click on all "off" tiles.
# This will eventually come to a stable solution where the grid doesn't change between iterations.
# If this stable solution is a complete grid, then call it a day and go home.
# If this stable solution is not the complete grid, destabilise it by clicking a random button and try again.
while True:
last_grid = deepcopy(A)
for R in range(5):
for C in range(5):
if A[R][C]:
pressTile(R,C)
panelsToClick.append(convert_RC_to_index(R,C))
# print_grid() # Not needed for checking solution.
if is_perfect_grid(): break
if A == last_grid:
panelClicked = press_random_button()
panelsToClick.append(panelClicked)
# time.sleep(0.1) # Not needed for checking solution.
# Return the finished list of presses, but filter the doubles out first.
return filter_panelsToClick(panelsToClick)
July 28, 2018
Comments: