@ -2,11 +2,14 @@
#(height, width)
#(height, width)
import random as rnd
import random as rnd
import os
import os
import sys
import itertools
import itertools
from enum import Enum
from enum import Enum
import time
import time
import math
import math
from queue import PriorityQueue as pq
from queue import PriorityQueue as pq
from sortedcontainers import SortedList as sl
from intervaltree import IntervalTree as itree
DEBUG = True
DEBUG = True
# DEBUG=False
# DEBUG=False
@ -25,144 +28,167 @@ entries=[(0,3)]
# entries=[(7,3),(7,43)]
# entries=[(7,3),(7,43)]
# entries=[(7,3)]
# entries=[(7,3)]
passengers = None
tickTaken = 0
passengers = None
class GridSquare :
class GridSquare :
#typ: SquareType, occupant: index
#typ: SquareType
def __init__ ( self , typ , occupant ) :
def __init__ ( self , typ ) :
self . typ = typ
self . typ = typ
self . occupant = occupant
#occupAtTick is an interval tree, stores intervals where the gridSquare is occupied
def __str__ ( self ) :
#intervals are [a,b), a nice sane choice
return " ( %s | %s ) " % ( str ( self . typ ) , str ( self . occupant ) )
#values are individuals
def __repr__ ( self ) :
self . occupAtTick = itree ( )
return str ( self )
def makeGrid ( ) :
return [ [ GridSquare ( SquareType . AISLE , None ) for x in range ( 0 , width ) ] for y in range ( 0 , height ) ]
class Passenger :
class Passenger :
shuffled = 0
inter = None
interback = None
path = [ ]
recalc = True
#dest and curr are both 2-tuples
#dest and curr are both 2-tuples
def __init__ ( self , dest , curr ) :
def __init__ ( self , dest , curr ) :
self . dest = dest
self . dest = dest
self . curr = curr
self . curr = curr
self . inter = None
#Path is composed of tuples: (pos, t)
self . path = [ ]
def __str__ ( self ) :
def __str__ ( self ) :
return " ( %s | %s ) " % ( dest , curr )
return " ( %s | %s ) " % ( dest , curr )
def manhattanDistance ( pos1 , pos2 ) :
return abs ( pos1 [ 0 ] - pos2 [ 0 ] ) + abs ( pos1 [ 1 ] - pos2 [ 1 ] )
def mooreNeighbourhood ( pos ) :
def mooreNeighbourhood ( pos ) :
return [ i for i in [ ( pos [ 0 ] + 1 , pos [ 1 ] ) , ( pos [ 0 ] , pos [ 1 ] + 1 ) , ( pos [ 0 ] - 1 , pos [ 1 ] ) , ( pos [ 0 ] , pos [ 1 ] - 1 ) ] if
return [ i for i in [ ( pos [ 0 ] + 1 , pos [ 1 ] ) , ( pos [ 0 ] , pos [ 1 ] + 1 ) , ( pos [ 0 ] - 1 , pos [ 1 ] ) , ( pos [ 0 ] , pos [ 1 ] - 1 ) ] if
i [ 0 ] > = 0 and i [ 1 ] > = 0 and i [ 0 ] < height and i [ 1 ] < width ]
i [ 0 ] > = 0 and i [ 1 ] > = 0 and i [ 0 ] < height and i [ 1 ] < width ]
def nextSquare ( passenger , grid ) :
def findPath ( passenger , pid , currTick ) :
passenger . recalc = False
global passengers
passenger . path = [ ]
global grid
dist = [ [ 0 for x in range ( 0 , width ) ] for y in range ( 0 , height ) ]
prev = [ [ None for x in range ( 0 , width ) ] for y in range ( 0 , height ) ]
dest = None
#used when moving into seats
afterTick = 0
if passenger . inter == None :
dest = passenger . inter
dest = passenger . dest
else :
dest = passenger . inter
#Element format: (Tick at time of movement, Position, Time stayed in previous square)
q = pq ( )
q = pq ( )
for y in range ( 0 , height ) :
time = [ [ 10 * * 10 for x in range ( 0 , width ) ] for y in range ( 0 , height ) ]
for x in range ( 0 , width ) :
prev = [ [ None for x in range ( 0 , width ) ] for y in range ( 0 , height ) ]
if x != passenger . curr [ 1 ] or y != passenger . curr [ 0 ] :
dist [ y ] [ x ] = 10 * * 10
time [ passenger . curr [ 0 ] ] [ passenger . curr [ 1 ] ] = currTick
mn = mooreNeighbourhood ( passenger . curr )
q . put ( ( currTick , passenger . curr , 1 ) )
for ( i , man ) in enumerate ( mn ) :
if ( grid [ passenger . curr [ 0 ] ] [ passenger . curr [ 1 ] ] . typ != SquareType . SEAT or man [ 1 ] == passenger . curr [ 1 ] ) and grid [ man [ 0 ] ] [ man [ 1 ] ] . typ != SquareType . WALL and not ( grid [ man [ 0 ] ] [ man [ 1 ] ] . typ == SquareType . AISLE and grid [ man [ 0 ] ] [ man [ 1 ] ] . occupant is not None ) :
q . put ( ( 1 , man , i ) )
dist [ man [ 0 ] ] [ man [ 1 ] ] = 1
prev [ man [ 0 ] ] [ man [ 1 ] ] = ( 0 , passenger . curr , 0 )
while not q . empty ( ) :
while not q . empty ( ) :
u = q . get ( )
u = q . get ( )
if u [ 1 ] == dest :
if u [ 1 ] == dest :
grid [ u [ 1 ] [ 0 ] ] [ u [ 1 ] [ 1 ] ] . occupAtTick . addi ( u [ 0 ] , u [ 0 ] + 3 , pid )
afterTick = u [ 0 ] + 2
# passenger.path.append((u[1], u[0]))
u = prev [ u [ 1 ] [ 0 ] ] [ u [ 1 ] [ 1 ] ]
while prev [ u [ 1 ] [ 0 ] ] [ u [ 1 ] [ 1 ] ] != None :
while prev [ u [ 1 ] [ 0 ] ] [ u [ 1 ] [ 1 ] ] != None :
passenger . path . append ( u [ 1 ] )
grid [ u [ 1 ] [ 0 ] ] [ u [ 1 ] [ 1 ] ] . occupAtTick . addi ( u [ 0 ] , u [ 0 ] + u [ 2 ] , pid )
# passenger.path.append((u[1], u[0]))
u = prev [ u [ 1 ] [ 0 ] ] [ u [ 1 ] [ 1 ] ]
u = prev [ u [ 1 ] [ 0 ] ] [ u [ 1 ] [ 1 ] ]
return
# passenger.path.append((passenger.curr, currTick))
break
#The Art of Standing Still
q . put ( ( u [ 0 ] + 1 , u [ 1 ] , 1 ) )
for x in mooreNeighbourhood ( u [ 1 ] ) :
for x in mooreNeighbourhood ( u [ 1 ] ) :
# if not( grid[x[0]][x[1]].typ == SquareType.SEAT and u[1][1] != x[1]) and grid[x[0]][x[1]].typ != SquareType.WALL and (grid[x[0]][x[1]].occupant == None or grid[x[0]][x[1]].typ == SquareType.SEAT):
alt = 0
if not ( grid [ x [ 0 ] ] [ x [ 1 ] ] . typ == SquareType . SEAT and u [ 1 ] [ 1 ] != x [ 1 ] ) and grid [ x [ 0 ] ] [ x [ 1 ] ] . typ != SquareType . WALL :
if grid [ x [ 0 ] ] [ x [ 1 ] ] . typ == SquareType . SEAT :
alt = 0
if ( not ( grid [ u [ 1 ] [ 0 ] ] [ u [ 1 ] [ 1 ] ] . typ == SquareType . AISLE and u [ 1 ] [ 1 ] != x [ 1 ] ) and
if grid [ x [ 0 ] ] [ x [ 1 ] ] . typ == SquareType . SEAT or grid [ u [ 1 ] [ 0 ] ] [ u [ 1 ] [ 1 ] ] . typ == SquareType . SEAT :
len ( grid [ x [ 0 ] ] [ x [ 1 ] ] . occupAtTick [ u [ 0 ] : u [ 0 ] + 5 - 1 ] ) == 0 ) :
if grid [ x [ 0 ] ] [ x [ 1 ] ] . occupant != None :
alt = time [ u [ 1 ] [ 0 ] ] [ u [ 1 ] [ 1 ] ] + 5
alt = dist [ u [ 1 ] [ 0 ] ] [ u [ 1 ] [ 1 ] ] + 5 + 10
if alt < time [ x [ 0 ] ] [ x [ 1 ] ] :
else :
time [ x [ 0 ] ] [ x [ 1 ] ] = alt
alt = dist [ u [ 1 ] [ 0 ] ] [ u [ 1 ] [ 1 ] ] + 5
prev [ x [ 0 ] ] [ x [ 1 ] ] = u
q . put ( ( alt , x , 5 ) )
else :
else :
alt = dist [ u [ 1 ] [ 0 ] ] [ u [ 1 ] [ 1 ] ] + 1
continue
# if alt == 0:
elif grid [ x [ 0 ] ] [ x [ 1 ] ] . typ == SquareType . AISLE :
# if x == dest:
if len ( grid [ x [ 0 ] ] [ x [ 1 ] ] . occupAtTick [ u [ 0 ] + 1 : u [ 0 ] + 1 + 1 ] ) == 0 :
# print("mn: " + str(x) + ", alt: " + str(alt))
alt = time [ u [ 1 ] [ 0 ] ] [ u [ 1 ] [ 1 ] ] + 1
# print("dist" + str(x) + ": " + str(dist[x[0]][x[1]]))
if alt < time [ x [ 0 ] ] [ x [ 1 ] ] :
if alt < dist [ x [ 0 ] ] [ x [ 1 ] ] :
time [ x [ 0 ] ] [ x [ 1 ] ] = alt
dist [ x [ 0 ] ] [ x [ 1 ] ] = alt
prev [ x [ 0 ] ] [ x [ 1 ] ] = u
prev [ x [ 0 ] ] [ x [ 1 ] ] = u
q . put ( ( alt , x , 1 ) )
q . put ( ( alt , x , u [ 2 ] ) )
else :
continue
passenger . path = [ passenger . curr ]
else :
continue
# print(grid[passenger.path[3][0][0]][passenger.path[3][0][1]].occupAtTick)
def GenPassList ( ) :
global height
global width
global grid
border = [ ]
arrFile = open ( " figure2.txt " )
height = int ( arrFile . readline ( ) )
width = int ( arrFile . readline ( ) )
print ( height )
print ( width )
grid = [ [ GridSquare ( SquareType . AISLE , None ) for x in range ( 0 , width ) ] for y in range ( 0 , height ) ]
dest = passenger . dest
moveDir = None
if dest [ 0 ] > passenger . inter [ 0 ] :
moveDir = - 1
else :
moveDir = 1
mDone = False
while not mDone :
mDone = True
u = passenger . dest
while u != passenger . inter :
occup = list ( grid [ u [ 0 ] + moveDir ] [ u [ 1 ] ] . occupAtTick [ afterTick : afterTick + 5 ] )
if len ( occup ) != 0 :
if ( moveDir == 1 and passengers [ occup [ 0 ] [ 2 ] ] . dest < u ) or ( moveDir == - 1 and passengers [ occup [ 0 ] [ 2 ] ] . dest > u ) :
# if dest == (6,4):
# print(u)
mDone = False
occup2 = list ( grid [ u [ 0 ] ] [ u [ 1 ] ] . occupAtTick [ afterTick : afterTick + 5 ] )
if len ( occup2 ) != 0 :
grid [ u [ 0 ] + moveDir ] [ u [ 1 ] ] . occupAtTick . addi ( occup [ 0 ] [ 0 ] , afterTick , occup [ 0 ] [ 2 ] )
grid [ u [ 0 ] + moveDir ] [ u [ 1 ] ] . occupAtTick . remove ( occup [ 0 ] )
grid [ u [ 0 ] ] [ u [ 1 ] ] . occupAtTick . addi ( occup2 [ 0 ] [ 0 ] , afterTick , occup2 [ 0 ] [ 2 ] )
grid [ u [ 0 ] ] [ u [ 1 ] ] . occupAtTick . remove ( occup2 [ 0 ] )
grid [ u [ 0 ] + moveDir ] [ u [ 1 ] ] . occupAtTick . addi ( afterTick , 10 * * 11 , occup2 [ 0 ] [ 2 ] )
grid [ u [ 0 ] ] [ u [ 1 ] ] . occupAtTick . addi ( afterTick , 10 * * 11 , occup [ 0 ] [ 2 ] )
else :
grid [ u [ 0 ] + moveDir ] [ u [ 1 ] ] . occupAtTick . addi ( occup [ 0 ] [ 0 ] , afterTick , occup [ 0 ] [ 2 ] )
grid [ u [ 0 ] + moveDir ] [ u [ 1 ] ] . occupAtTick . remove ( occup [ 0 ] )
grid [ u [ 0 ] ] [ u [ 1 ] ] . occupAtTick . addi ( afterTick , 10 * * 11 , occup [ 0 ] [ 2 ] )
u = ( u [ 0 ] + moveDir , u [ 1 ] )
afterTick + = 4
for y in range ( 0 , height ) :
for x in range ( 0 , width + 1 ) :
char = arrFile . read ( 1 ) ;
match char :
case ' S ' :
grid [ y ] [ x ] . typ = SquareType . SEAT
border . append ( Passenger ( ( y , x ) , ( - 1 , - 1 ) ) )
case ' W ' :
grid [ y ] [ x ] . typ = SquareType . WALL
case ' . ' :
grid [ y ] [ x ] . typ = SquareType . AISLE
for x in border :
def printPath ( p ) :
sign = ( - 1 ) * * rnd . randint ( 0 , 1 )
print ( " inter: " + str ( p . inter ) )
for i in range ( 1 , 7 ) :
print ( " dest: " + str ( p . dest ) )
inc = ( - 1 ) * * i * sign * math . floor ( ( i + 1 ) / 2 )
for x in p . path :
if ( inc + x . dest [ 0 ] > 0 ) and ( inc + x . dest [ 0 ] < height ) and ( grid [ x . dest [ 0 ] + inc ] [ x . dest [ 1 ] ] . typ == SquareType . AISLE ) :
print ( str ( x [ 0 ] ) + " : " + str ( grid [ x [ 0 ] [ 0 ] ] [ x [ 0 ] [ 1 ] ] . occupAtTick [ x [ 1 ] ] ) )
x . inter = ( inc + x . dest [ 0 ] , x . dest [ 1 ] )
x . interback = x . inter
return border
btime = 3 #passengers board every btime ticks
delay = 0.01
def nunty ( x ) :
#Precomputation of all paths, later code is just output functionality
if x is None : return - 1
def compute ( ) :
return x
global btime
global passengers
global tickTaken
tick = 0
toadd = 0
#genderequality #blm #blessed #syria
for ( i , prsn ) in enumerate ( passengers ) :
for e in entries :
if toadd < len ( passengers ) and len ( grid [ e [ 0 ] ] [ e [ 1 ] ] . occupAtTick [ tick ] ) == 0 :
prsn . curr = ( e [ 0 ] , e [ 1 ] )
findPath ( prsn , i , tick )
if DEBUG :
print ( " calculating: " + str ( i ) )
tick + = btime
toadd + = 1
else :
tick + = 1
btime = 3 #passengers board every btime ticks
for row in grid :
for x in row :
# print(x.occupAtTick)
if len ( x . occupAtTick ) != 0 :
# print("list(x.occupAtTick.items)[-1][0]: " + str(list(x.occupAtTick.items())[-1][0]))
tickTaken = max ( tickTaken , list ( x . occupAtTick . items ( ) ) [ - 1 ] [ 0 ] )
print ( " Time Taken: " + str ( tickTaken ) )
def tick ( t , toad ) :
def tick ( t ) :
done = True
done = True
global btime
global btime
global delay
# print grid
# print grid
if DEBUG :
if DEBUG :
print ( chr ( 0x3000 ) , end = " " )
print ( chr ( 0x3000 ) , end = " " )
@ -186,8 +212,8 @@ def tick(t, toad):
print ( chr ( 0xFF10 + ( i % 10 ) ) , end = " " )
print ( chr ( 0xFF10 + ( i % 10 ) ) , end = " " )
for guy in row :
for guy in row :
if guy . occupant is not None :
if len ( guy . occupAtTick [ t ] ) != 0 :
print ( chr ( 0x20000 + guy . occupan t ) , end = " " )
print ( chr ( 0x20000 + list ( guy . occupAtTick [ t ] ) [ 0 ] [ 2 ] ) , end = " " )
elif guy . typ == SquareType . SEAT :
elif guy . typ == SquareType . SEAT :
print ( " : " , end = " " )
print ( " : " , end = " " )
elif guy . typ == SquareType . WALL :
elif guy . typ == SquareType . WALL :
@ -196,84 +222,70 @@ def tick(t, toad):
print ( " _ " , end = " " )
print ( " _ " , end = " " )
print ( )
print ( )
print ( " --- " )
print ( " --- " )
# print(grid[3][0].occupant, grid[3][1].occupant, passengers[nunty(grid[3][1].occupant)].dest)
printPath ( passengers [ 2 ] )
if t % btime == 0 :
for x in entries :
if toad < len ( passengers ) and grid [ x [ 0 ] ] [ x [ 1 ] ] . occupant is None :
grid [ x [ 0 ] ] [ x [ 1 ] ] . occupant = toad #added
passengers [ toad ] . curr = ( x [ 0 ] , x [ 1 ] )
toad + = 1
for ( i , man ) in enumerate ( passengers ) :
if man . curr == man . dest :
continue
if man . inter is not None and man . curr == man . inter :
man . shuffled = 3
man . inter = None
# man.recalc = True
if man . curr == ( - 1 , - 1 ) :
continue
# if i == 36 and DEBUG:
# print(nextSquare(man, grid))
done = False
#im sexist
if len ( man . path ) == 0 or man . recalc :
# if DEBUG:
# print("Recalculating: " + str(man.curr))
nextSquare ( man , grid )
nextS = man . path . pop ( )
if DEBUG :
print ( str ( man . curr ) + " , " + str ( man . interback ) + " , " + str ( man . dest ) + " , " + str ( nextS ) + " , " + str ( man . inter ) )
if passengers [ i ] . shuffled == 0 and not ( grid [ nextS [ 0 ] ] [ nextS [ 1 ] ] . typ == SquareType . AISLE and grid [ nextS [ 0 ] ] [ nextS [ 1 ] ] . occupant is not None ) :
cp = man . curr
man . curr = nextS
other = grid [ cp [ 0 ] ] [ cp [ 1 ] ]
other . occupant = grid [ man . curr [ 0 ] ] [ man . curr [ 1 ] ] . occupant #they move out of there
if other . occupant is not None :
passengers [ other . occupant ] . curr = cp
passengers [ other . occupant ] . shuffled = 5
passengers [ other . occupant ] . recalc = True
man . recalc = True
grid [ man . curr [ 0 ] ] [ man . curr [ 1 ] ] . occupant = i
for man in passengers :
if man . shuffled != 0 :
man . shuffled - = 1
if DEBUG :
if DEBUG :
# time.sleep(1.0)
# time.sleep(1.0)
# time.sleep(0.5)
# time.sleep(0.5)
# time.sleep(0.1)
# time.sleep(0.1)
# time.sleep(0.05 )
time . sleep ( 0.05 )
# time.sleep(0.02)
# time.sleep(0.02)
time . sleep ( 0.01 )
# time.sleep(0.01)
# time.sleep(0.001)
# time.sleep(0.001)
os . system ( " clear " )
os . system ( " clear " )
if done and toad > = len ( passengers ) :
print ( " Number of ticks: " + str ( t ) )
def init ( ) :
return - 1
global height
# exit()
global width
return toad
global grid
global passengers
def run ( ) :
passengers = [ ]
toad = 0
arrFile = open ( " figure2.txt " )
height = int ( arrFile . readline ( ) )
width = int ( arrFile . readline ( ) )
print ( height )
print ( width )
grid = [ [ GridSquare ( SquareType . AISLE ) for x in range ( 0 , width ) ] for y in range ( 0 , height ) ]
for y in range ( 0 , height ) :
for x in range ( 0 , width + 1 ) :
char = arrFile . read ( 1 ) ;
match char :
case ' S ' :
grid [ y ] [ x ] . typ = SquareType . SEAT
passengers . append ( Passenger ( ( y , x ) , ( - 1 , - 1 ) ) )
case ' W ' :
grid [ y ] [ x ] . typ = SquareType . WALL
case ' . ' :
grid [ y ] [ x ] . typ = SquareType . AISLE
for x in passengers :
sign = ( - 1 ) * * rnd . randint ( 0 , 1 )
for i in range ( 1 , 7 ) :
inc = ( - 1 ) * * i * sign * math . floor ( ( i + 1 ) / 2 )
if ( inc + x . dest [ 0 ] > 0 ) and ( inc + x . dest [ 0 ] < height ) and ( grid [ x . dest [ 0 ] + inc ] [ x . dest [ 1 ] ] . typ == SquareType . AISLE ) :
x . inter = ( inc + x . dest [ 0 ] , x . dest [ 1 ] )
break
def run ( end ) :
t = 0
t = 0
while toad != - 1 :
while t < end :
toad = tick ( t , toad )
tick ( t )
t + = 1
t + = 1
def main ( ) :
def main ( ) :
global passengers
global passengers
init ( )
#boarding order
#boarding order
for seediter in range ( 43 , 2000 ) :
seediter = int ( sys . argv [ 1 ] )
passengers = GenPassList ( )
print ( " Seed: " + str ( seediter ) )
print ( " Seed: " + str ( seediter ) )
rnd . seed ( seediter )
rnd . seed ( seediter )
# passengers.reverse( )
# passengers.reverse()
rnd . shuffle ( passengers )
rnd . shuffle ( passengers )
compute ( )
run ( )
run ( tickTaken )
if __name__ == " __main__ " :
if __name__ == " __main__ " :
main ( )
main ( )