# Rope Burning Riddler from fivethirtyeight.com

def explore(situation):

	ropes = situation[0]
	time = situation[1]

	# Find unextinguished ropes and make a list of those 
	# with at least 1 unlit end.
	allextinguished = True
	ropestochoose = []
	for r in range(N):
		if ropes[r][1] == 0 or ropes[r][1] > time:
			allextinguished = False
			if not ropes[r][0] ==2:
				ropestochoose.append(r)
	if allextinguished:
		# No descendent situations, so tally the intervals
		for rope in ropes:
			time = rope[1]
			if not time in times:
				times.append(time)
		# Comment-out the following block to ignore 
		# periods between extinguishings
		#for rope1 in ropes:
		#	for rope2 in ropes:
		#		time = abs(rope1[1]-rope2[1])
		#		if not time in times:
		#			times.append(time)
		return
	# A choice is to (0) do nothing, (1) ignite a first 
	# end if unignited (2) ignite (both first and) 
	# second end if unignited. The choice for a particular 
	# rope R (0 to len(ropestochoose)-1) is (choices//3**R)%3 
	# (think of choices as a base-3 numeral).
	for choices in range(3**len(ropestochoose)+1):
		# We will modify a copy of ropes
		newropes = list(ropes)
		for r in range(len(ropestochoose)):
			rope = newropes[ropestochoose[r]]
			choice = (choices//3**r)%3
			if rope[0] == 0:
				# No ends lit
				if choice == 1:
					rope = [1,time+1]
				elif choice == 2:
					rope = [2,time+.5]
			elif rope[0] == 1:
				# One end already lit
				if choice == 2:
					rope = [2,time+.5*(rope[1]-time)]
			newropes[ropestochoose[r]] = rope
		# This will prevent redundantly exploring equivalent situations
		newropes.sort(reverse=True)	
		# Find time of next extinguishing
		nexttime = N
		for rope in newropes:
			t = rope[1]
			if t > time and t < nexttime:
				nexttime = t
		newsituation = [newropes,nexttime]
		if (newropes == ropes or (newsituation in already_processed)):
			continue
		already_processed.append(newsituation)
		explore(newsituation)

# Main program

# Numbers of ropes to do
MinRopes = 1
MaxRopes = 8

for N in range(MinRopes,MaxRopes+1):
	# ropes is a list of pairs. each pair is: [ends-lit 
	# (0, 1, or 2), time (has been or will be) extinguished].
	# We start with extinction time 0 as a dummy value.
	ropes = [[0,0]]*N
	time = 0
	situation = [ropes,time]

	# Keep track of the situations we have already processed
	already_processed = [situation]

	# This is our list of the durations we can measure
	times = []

	# Recursively explore the achievable situations
	explore(situation)

	# Done. Tidy up and finish.
	if 0 in times:
		# 0 is not a duration per problem statement.
		times.remove(0)
	times.sort()
	print(N,"ropes measure",len(times), "intervals:")
	print(times)

@@ -632,17 +632,16 @@
 hings%0A%09%09
-#
 for rope
@@ -654,17 +654,16 @@
 opes:%0A%09%09
-#
 %09for rop
@@ -677,17 +677,16 @@
 opes:%0A%09%09
-#
 %09%09time =
@@ -711,17 +711,16 @@
 2%5B1%5D)%0A%09%09
-#
 %09%09if not
@@ -737,17 +737,16 @@
 imes:%0A%09%09
-#
 %09%09%09times
@@ -1053,16 +1053,18 @@
 n range(
+1,
 3**len(r
@@ -1076,18 +1076,16 @@
 ochoose)
-+1
 ):%0A%09%09# W
@@ -1665,12 +1665,21 @@
 e = 
-N%0A%09%09
+min(%5Brope%5B1%5D 
 for 
@@ -1698,74 +1698,28 @@
 opes
-:%0A%09%09%09t = rope%5B1%5D%0A%09%09%09if t %3E time and t %3C nexttime:%0A%09%09%09%09nexttime = t
+ if rope%5B1%5D %3E time%5D)
 %0A%09%09n
@@ -1964,9 +1964,9 @@
 s = 
-8
+6
 %0A%0Afo
@@ -2624,13 +2624,14 @@
 vals
-:
 %22)%0A%09
+# 
 prin

Update ropes.py