#Python 2.7, 463422 bytes ###thanks to NoOneIsHere for pointing out additional improvements! ###thanks to edc65 for noting not to save the list but use iterators instead!
from itertools import permutations
l,m=4,0
p=list(permutations([(1,1),(2,2),(3,3)]))
def d(s,e):
d=0
while s!=e:
x = 1x=1 if s[0]<e[0] else -1 if s[0]>e[0] else 0
y=1 if s[1]<e[1] else -1 if s[1]>e[1] else 0
s=(s[0]+x,s[1]+y)
d += d+=(1, 1.5)[x and y]
return d
l,m=4,0
for io in rangepermutations(len[(p1,1),(2,2),(3,3)]):
a,c=l-d((0,0),(p[i][0])o[0]),1
for j in range(len(p[i]o)-1):
a-=d(p[i][j]o[j],p[i][j+1]o[j+1])
c+=(0,1)[a>0]
m=max(c,m)
print m
The function calculates the distance between two points according to the given rules, the loop iterates through all permutations generated by the generator of the input and calculates the distance, if the distance is lesser than the candle lifespan it subtracts it and adds the place to the counter, if that counter is greater than the current max it substitutes it.
from itertools import permutations
lifespan, max_amount = 4, 0
perms = list(permutations([(1,1), (2,2), (3,3)]))
def distance(start_pos, end_pos):
distance = 0
while start_pos != end_pos:
mod_x = 1 if start_pos[0] < end_pos[0] else -1 if start_pos[0] > end_pos[0] else 0
mod_y = 1 if start_pos[1] < end_pos[1] else -1 if start_pos[1] > end_pos[1] else 0
start_pos = (start_pos[0] + mod_x, start_pos[1] + mod_y)
distance += (1, 1.5)[mod_x and mod_y]
return distance
lifespan, max_amount = 4, 0
for iitem in rangepermutations(len[(perms1,1), (2,2), (3,3)]):
lifespan_local, current = lifespan - distance((0,0), (perms[i][0])item[0]), 1
for j in range(len(perms[i]item) - 1):
lifespan_local -= distance(perms[i][j]item[j], perms[i][jitem[j + 1])
current += (0, 1)[lifespan_local > 0]
max_amount = max(current, max_amount)
print max_amount