[Tutor] Creating lists with definite (n) items without repetitions
Francesco Loffredo
fal at libero.it
Thu Sep 10 09:45:10 CEST 2015
On 09/09/2015 19:45, Francesco Loffredo via Tutor wrote:
> On 09/09/2015 18:59, Oscar Benjamin wrote:
>> I don't think the code above works. For n=27 it should count 117
>> (according to the formula I showed) but instead it comes up with 101.
>>
>> I tried it with a smaller n by setting pool to range(1, 9+1) meaning
>> that n=9. The output is:
>>
>> combos contains 84 triples.
>> maketriples(combos) contains 8 triples.
>> [(1, 2, 3),
>> (1, 4, 5),
>> (1, 6, 7),
>> (1, 8, 9),
>> (2, 4, 6),
>> (2, 5, 7),
>> (3, 4, 7),
>> (3, 5, 6)]
>>
>> However I can construct a set of 12 triples containing each number
>> exactly 4 times which is the exact Steiner triple system:
>>
>> 1 6 8
>> 1 2 3
>> 1 5 9
>> 1 4 7
>> 2 6 7
>> 2 4 9
>> 2 5 8
>> 3 5 7
>> 3 6 9
>> 3 8 4
>> 4 5 6
>> 7 8 9
>>
>> This is the number of triples predicted by the formula: 9*(9-1)/6 = 12
>>
>> --
>> Oscar
>>
> That's very interesting! This takes me to my question to Tutors:
> what's wrong with the above code?
I wrote a small routine (below) to check when and if my code and the
formula do match. It easily shows that
they only match for len(pool) == (2 ** N) - 1, with N greater or equal to 2.
My problem remains: WHY don't they match for every length? How did you
build your 12-triples set? What's wrong with my algorithm?
And, most of all (and on topic, too): how can you build a Python program
that builds your triples list?
Francesco
--------------------------------------------------------------------------------------------------------------------------------------
import pprint, itertools
poolbase =
"abcdefghijklmnopqrstuvwxyz!ABCDEFGHIJKLMNOPQRSTUVWXYZ$0123456789"
def maketriples(tuplelist):
final = []
used = set()
for a, b, c in tuplelist:
if ( ((a,b) in used) or ((b,c) in used) or ((a,c) in used) or
((b,a) in used) or ((c,b) in used) or ((c,a) in used) ):
continue
else:
final.append((a, b, c))
used.add((a,b))
used.add((a,c))
used.add((b,c))
used.add((b,a))
used.add((c,a))
used.add((c,b))
return final
def formula(sequence):
dim = len(sequence)
return (dim * (dim - 1) / 6)
matching = {}
for i in range(3, len(poolbase) + 1):
pool = poolbase[:i]
print("pool = %s: -> '%s'" % (i, pool))
combos = list(itertools.combinations(pool, 3))
print("combos contains %s triples." % len(combos))
triples = maketriples(combos)
theory = formula(pool)
print("maketriples(combos) yields %s triples." % len(triples))
print("formula(pool) gives %s." % theory)
if len(triples) == theory:
pprint.pprint(triples)
matching[len(pool)] = len(triples)
input("\n--- Press Enter ---")
print("-------------------------------------")
print("Dict of matching solutions and number of obtained triples:")
pprint.pprint(matching)
More information about the Tutor
mailing list