import random
import sys
def shuffle(a):
"""Yields all solutions up to mirror symmetry."""
# Process integers in decreasing order, each can be appended only
# at the beginning or the end.
s = list(reversed(sorted(a)))
stack = [s[:2]]
n = len(s)
while stack:
middle = stack.pop()
m = len(middle)
if m == n:
yield middle
else:
h = s[m]
if h - middle[0] <= middle[0] - middle[1]:
stack.append([h] + middle)
if middle[-2] - middle[-1] <= middle[-1] - h:
stack.append(middle + [h])
def check(a):
if len(a) <= 2: return True
return all([a[i] - a[i+1] <= a[i+1] - a[i+2] for i in range(len(a)-2)])
# generate a random array that has a solution
if len(sys.argv)<3:
d = sorted(random.sample(range(1000), int(sys.argv[1])))
a = [0]
for di in reversed(d):
a.append(a[-1] + di)
else:
a = map(int, sys.argv[1:])
s = list(shuffle(a))
print "# solutions to random problem:", len(list(shuffle(random.sample(range(1000000), 100))))
print "# {0} has {1} solutions. Check={2}".format(a, len(s), all(map(check, s)))
# Print solutions for gnuplot> plot "output" w lp palette
for i,sl in enumerate(s):
color = float(i)/(len(s)-1)
print
print
print '\n'.join(["%d %d %f"%(x[0],x[1],color) for x in enumerate(sl)])
aW1wb3J0IHJhbmRvbQppbXBvcnQgc3lzCgpkZWYgc2h1ZmZsZShhKToKICAiIiJZaWVsZHMgYWxsIHNvbHV0aW9ucyB1cCB0byBtaXJyb3Igc3ltbWV0cnkuIiIiCiAgIyBQcm9jZXNzIGludGVnZXJzIGluIGRlY3JlYXNpbmcgb3JkZXIsIGVhY2ggY2FuIGJlIGFwcGVuZGVkIG9ubHkKICAjIGF0IHRoZSBiZWdpbm5pbmcgb3IgdGhlIGVuZC4KICBzID0gbGlzdChyZXZlcnNlZChzb3J0ZWQoYSkpKQogIHN0YWNrID0gW3NbOjJdXQogIG4gPSBsZW4ocykKICB3aGlsZSBzdGFjazoKICAgIG1pZGRsZSA9IHN0YWNrLnBvcCgpCiAgICBtID0gbGVuKG1pZGRsZSkKICAgIGlmIG0gPT0gbjoKICAgICAgeWllbGQgbWlkZGxlCiAgICBlbHNlOgogICAgICBoID0gc1ttXQogICAgICBpZiBoIC0gbWlkZGxlWzBdIDw9IG1pZGRsZVswXSAtIG1pZGRsZVsxXToKICAgICAgICBzdGFjay5hcHBlbmQoW2hdICsgbWlkZGxlKQogICAgICBpZiBtaWRkbGVbLTJdIC0gbWlkZGxlWy0xXSA8PSBtaWRkbGVbLTFdIC0gaDoKICAgICAgICBzdGFjay5hcHBlbmQobWlkZGxlICsgW2hdKQoKZGVmIGNoZWNrKGEpOgogIGlmIGxlbihhKSA8PSAyOiByZXR1cm4gVHJ1ZQogIHJldHVybiBhbGwoW2FbaV0gLSBhW2krMV0gPD0gYVtpKzFdIC0gYVtpKzJdIGZvciBpIGluIHJhbmdlKGxlbihhKS0yKV0pCgojIGdlbmVyYXRlIGEgcmFuZG9tIGFycmF5IHRoYXQgaGFzIGEgc29sdXRpb24KaWYgbGVuKHN5cy5hcmd2KTwzOgogIGQgPSBzb3J0ZWQocmFuZG9tLnNhbXBsZShyYW5nZSgxMDAwKSwgaW50KHN5cy5hcmd2WzFdKSkpCiAgYSA9IFswXQogIGZvciBkaSBpbiByZXZlcnNlZChkKToKICAgIGEuYXBwZW5kKGFbLTFdICsgZGkpCmVsc2U6CiAgYSA9IG1hcChpbnQsIHN5cy5hcmd2WzE6XSkKCnMgPSBsaXN0KHNodWZmbGUoYSkpCgpwcmludCAiIyBzb2x1dGlvbnMgdG8gcmFuZG9tIHByb2JsZW06IiwgbGVuKGxpc3Qoc2h1ZmZsZShyYW5kb20uc2FtcGxlKHJhbmdlKDEwMDAwMDApLCAxMDApKSkpCnByaW50ICIjIHswfSBoYXMgezF9IHNvbHV0aW9ucy4gQ2hlY2s9ezJ9Ii5mb3JtYXQoYSwgbGVuKHMpLCBhbGwobWFwKGNoZWNrLCBzKSkpCiMgUHJpbnQgc29sdXRpb25zIGZvciBnbnVwbG90PiBwbG90ICJvdXRwdXQiIHcgbHAgcGFsZXR0ZQpmb3IgaSxzbCBpbiBlbnVtZXJhdGUocyk6CiAgY29sb3IgPSBmbG9hdChpKS8obGVuKHMpLTEpCiAgcHJpbnQKICBwcmludAogIHByaW50ICdcbicuam9pbihbIiVkICVkICVmIiUoeFswXSx4WzFdLGNvbG9yKSBmb3IgeCBpbiBlbnVtZXJhdGUoc2wpXSkKCiAgICA=