Skip to content

Instantly share code, notes, and snippets.

@adarshdec23
Created February 14, 2018 04:04
Show Gist options
  • Save adarshdec23/96c67d6a0d9da88e988c8f748a075e0d to your computer and use it in GitHub Desktop.
Save adarshdec23/96c67d6a0d9da88e988c8f748a075e0d to your computer and use it in GitHub Desktop.
Coding Game 2017
import sys
import math
import functools
MU = 0
MT = 1
OU = 2
OT = 3
CA = 4
DONT_REPEAT = -1
UNCERTAIN_REPEAT = 0
REPEAT_1 = 1
REPEAT_2 = 2
REPEAT_3 = 3
REPEAT_4 = 4
REPEAT_5 = 5
PLANET_ID = 0
REPETITION = 1
PRIORITY = 2
PRI_100 = 100
PRI_90 = 90
PRI_80 = 80
PRI_70 = 70
PRI_60 = 60
PRI_GAP = 55
PRI_50 = 50
PRI_40 = 40
PRI_30 = 30
PRI_20 = 20
PRI_10 = 10
PRI_0 = 0
MAX_POINTS = 5
class AdjMatrix():
adjMatrix = dict()
@staticmethod
def set(planet_a, planet_b):
if AdjMatrix.adjMatrix.get(planet_a):
AdjMatrix.adjMatrix[planet_a].append(planet_b)
else:
AdjMatrix.adjMatrix[planet_a] = [planet_b]
#Set inverse also
if AdjMatrix.adjMatrix.get(planet_b):
AdjMatrix.adjMatrix[planet_b].append(planet_a)
else:
AdjMatrix.adjMatrix[planet_b] = [planet_a]
@staticmethod
def get(planet_a, planet_b = None):
if not planet_b:
return AdjMatrix.adjMatrix.get(planet_a)
else:
if (adjMatrix.get(planet_a) and planet_b in adjMatrix[planet_a]):
return True
return False
class PlanetStatus():
planetStatus = dict()
@staticmethod
def set(planetId ,my_units, my_tolerance, other_units, other_tolerance, can_assign):
PlanetStatus.planetStatus[planetId] = [my_units, my_tolerance, other_units, other_tolerance, can_assign];
@staticmethod
def get(planetId, index = -1):
if index == -1:
if PlanetStatus.planetStatus.get(planetId):
return PlanetStatus.planetStatus[planetId]
else:
if PlanetStatus.planetStatus.get(planetId):
return PlanetStatus.planetStatus[planetId][index]
@staticmethod
def resetStatus():
planetStatus = dict()
def isCaptured(planetId):
return ( PlanetStatus.get(planetId, MU) - PlanetStatus.get(planetId, OU) < 0 )
def isMyPlanet(planetId):
return ( PlanetStatus.get(planetId, MU) - PlanetStatus.get(planetId, OU) > 0 )
def isNeutral(planetId):
return ( PlanetStatus.get(planetId, MU) - PlanetStatus.get(planetId, OU) == 0 )
def hasEnemyLink(planetId):
for otherPlanet in AdjMatrix.get(planetId):
if(isCaptured(otherPlanet)):
return True
return False
def hasGreaterEnemyCount(planetId):
enemyPlanet, myPlanet = 0, 0
for otherPlanet in AdjMatrix.get(planetId):
if(isCaptured(otherPlanet)):
enemyPlanet = enemyPlanet + 1
elif(isMyPlanet(otherPlanet)):
myPlanet = myPlanet + 1
return (enemyPlanet > myPlanet)
def compareDisplayItems(displayItem1, displayItem2):
if displayItem1[PRIORITY] > displayItem2[PRIORITY]:
return 1
if displayItem1[PRIORITY] < displayItem2[PRIORITY]:
return -1
'''Both have the same priority, sort of repeat factor
Lower the repeat the higher the preference
'''
return displayItem2[REPETITION] - displayItem1[REPETITION]
def noOfUnCapNeighbour(planetId):
finalCount = 0
for otherPlanet in AdjMatrix.get(planetId):
if(isNeutral(otherPlanet)):
finalCount += 1
return finalCount
def displayLogic(displayList, splitPlanetId):
print("Displa:splitId", splitPlanetId, file=sys.stderr)
if splitPlanetId:
#If we have a splitPlanetId, return after finishing up
for i in range(6):
print(splitPlanetId)
return
# Regular display
#Here comes the hard part
finalDisplyList = []
displayList.sort(key=functools.cmp_to_key(compareDisplayItems), reverse=True)
print("DisplayList", displayList, file=sys.stderr)
highestPriorityPlanet = displayList[0][PLANET_ID]
#If the first item is 100 PRI, then we only print 90 and 100 PRI, repeating 100 PRI if possible
if(displayList[0][PRIORITY] == PRI_100):
displayCounter = 0
while len(finalDisplyList) < MAX_POINTS :
if displayList[displayCounter][PRIORITY] < PRI_90:
if displayList[displayCounter][PRIORITY] == PRI_80 and (MAX_POINTS - len(finalDisplyList) >= 2):
#Special case, if 80 and we have two points, but 80 instead of 100
finalDisplyList.append(displayList[displayCounter][PLANET_ID])
finalDisplyList.append(displayList[displayCounter][PLANET_ID])
else:
finalDisplyList.append(displayList[0][PLANET_ID])
else:
finalDisplyList.append(displayList[displayCounter][PLANET_ID])
displayCounter += 1
else:
for oneDisplayItem in displayList:
if len(finalDisplyList) > MAX_POINTS:
break
finalDisplyList.append(oneDisplayItem[PLANET_ID])
for repititionCount in range(oneDisplayItem[REPETITION]):
if len(finalDisplyList) > MAX_POINTS:
break
finalDisplyList.append(oneDisplayItem[PLANET_ID])
#if len(finalDisplyList) != MAX_POINTS:
while(len(finalDisplyList) < MAX_POINTS):
finalDisplyList.append(highestPriorityPlanet)
#Final printing
for planetId in range(5):
print(finalDisplyList[planetId])
print("NONE") #
planet_count, edge_count = [int(i) for i in input().split()]
for i in range(edge_count):
planet_a, planet_b = [int(j) for j in input().split()]
AdjMatrix.set(planet_a, planet_b)
# game loop
while True:
PlanetStatus.resetStatus()
for i in range(planet_count):
my_units, my_tolerance, other_units, other_tolerance, can_assign = [int(j) for j in input().split()]
PlanetStatus.set(i, my_units, my_tolerance, other_units, other_tolerance, can_assign)
# Write an action using print
# To debug: print("Debug messages...", file=sys.stderr)
displayList = []
splitPlanetId = None
for planetId in range(planet_count):
if not(PlanetStatus.get(planetId, CA)) or splitPlanetId:
continue
# This planet can be used, new we check out conditions and assign priority
print(planetId," : EL:" , hasEnemyLink(planetId), "GEC",hasGreaterEnemyCount(planetId) , file=sys.stderr)
if isNeutral(planetId):
if hasEnemyLink(planetId) and not hasGreaterEnemyCount(planetId) :
displayList.append([planetId, UNCERTAIN_REPEAT, PRI_100])
elif not hasEnemyLink(planetId) :
displayList.append([planetId, UNCERTAIN_REPEAT, PRI_90])
elif hasGreaterEnemyCount(planetId):
displayList.append([planetId, REPEAT_2, PRI_80])
elif isCaptured(planetId) and (len(displayList) < 5):
print("Cap PlanetID:" , planetId , file=sys.stderr)
if not hasGreaterEnemyCount(planetId):
# Will not loose points when captured
pointsToCapture = PlanetStatus.get(planetId, OU) - PlanetStatus.get(planetId, MU) + 1
displayList.append([planetId, pointsToCapture, PRI_70])
else:
#Will loose points when captured
pointsToNeutralise = PlanetStatus.get(planetId, OU) - PlanetStatus.get(planetId, MU) + 1
displayList.append([planetId, pointsToNeutralise, PRI_60])
elif len(displayList) < 5: #run this only if we don't have anything to display
# We don't have anything we can capture
print("My PlanetID:" , planetId , file=sys.stderr)
if hasEnemyLink(planetId):
diffOfPoints = PlanetStatus.get(planetId, MU) - PlanetStatus.get(planetId, OU)
if diffOfPoints == 1 : displayList.append([planetId, REPEAT_5, PRI_40])
elif diffOfPoints == 2 : displayList.append([planetId, REPEAT_4, PRI_30])
elif diffOfPoints == 3 : displayList.append([planetId, REPEAT_3, PRI_20])
elif diffOfPoints == 4 : displayList.append([planetId, REPEAT_2, PRI_10])
else : displayList.append([planetId, REPEAT_1, PRI_0])
else:
#When no turns are left of enemy adjacent nodes
#TODO: Think of split
if noOfUnCapNeighbour(planetId) >= MAX_POINTS:
print ("Inside split", AdjMatrix.get(planetId), file=sys.stderr)
splitPlanetId = planetId
else:
displayList.append([planetId, UNCERTAIN_REPEAT, PRI_0])
#End of for loop
displayLogic(displayList, splitPlanetId)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment