# update a value entry following some rule

i have a vector $(x_1, \dots,x_n)$ where $x_i$ belongs to some set $E$ how can i assign randomly a letter $a,b,c$ to each vector than update it following some rule these vector ?

Example $E={ x_1, x_2,x_3 }$

$(x_1, x_2,x_3)=a$

$(x_2,x_3,x_1)=a$

$(x_3,x_1,x_2)=c$

$(x_3,x_2,x_1)=whatever$

$(x_1,x_1,x_1)=whatevre$ etc...

i have a rule that if $(x_1, x_2,x_3)=a$ and $(x_2,x_3,x_1)=a$ then $(x_3,x_1,x_2)$ must be equal to $a$

edit retag close merge delete

Sort by ยป oldest newest most voted

Useful tools that can help achieve the goal here are

• the cartesian product iterator
• using a dictionary
• getting an item in a string by its index
• the randint function to pick said index at random

Define $E$ and an empty dictionary $d$:

sage: E = {3, 5, 7}
sage: d = dict()


For each element $u$ in the cartesian product $E^3$,

• if its two cyclic permutations have already been assigned a letter,
• if they turn out to be the same letter, then assign it to $u$ too,
• otherwise assign the remaining letter,
• otherwise assign a letter at random.

Define a function to assign letters to tuples in $E^3$:

def abc(E):
r"""
Return a dictionary of letters assigned to elements in E^3.

Each triple (x, y, z) in E^3 is assigned a letter among
'a', 'b', 'c', in a way that if (x, y, z) and (y, z, x) are
assigned the same values then so is (z, x, y).
"""
d = dict()
for u in cartesian_product_iterator((E, E, E)):
x, y, z = u
v = y, z, x
w = z, x, y
if v in d and w in d:
if d[v] == d[w]:
d[u] = d[v]
else:
d[u] = 'abc'.replace(d[v], '').replace(d[w], '')
else:
d[u] = 'abc'[randint(0, 2)]
return d


Define a function to check the conditions are satisfied:

def check_cyclic(d):
return all(len(set([d[(x, y, z)], d[(y, z, x)], d[(z, x, y)]])) in (1, 3)
for x, y, z in d)


Assign values with the function:

sage: d = abc({3, 5, 7})


Check the conditions are satisfied:

sage: check_cyclic(d)
True


See what values were assigned:

sage: d
{(3, 3, 3): 'c',
(3, 3, 5): 'a',
...
(3, 7, 7): 'b',
...
(3, 5, 7): 'b',
...
(5, 7, 3): 'b',
...
(7, 3, 5): 'b',
...
(7, 3, 7): 'c',
...
(7, 7, 3): 'a',
(7, 7, 5): 'b',
(7, 7, 7): 'a'}


In this case (3, 5, 7), (5, 7, 3) and (7, 3, 5) all got 'b', while (3, 7, 7), (7, 3, 7) and (7, 7, 3) got 'b', 'c', 'a'.

Note: if instead of assigning 'a', 'b', 'c' we assigned 0, 1, 2, we could slightly simplify the function abc as follows:

def abc(E):
r"""
Return a dictionary of letters assigned to elements in E^3.

Each triple (x, y, z) in E^3 is assigned a number among
0, 1, 2, in a way that if (x, y, z) and (y, z, x) are
assigned the same values then so is (z, x, y).
"""
d = dict()
for u in cartesian_product_iterator((E, E, E)):
x, y, z = u
v = y, z, x
w = z, x, y
if v in d and w in d:
if d[v] == d[w]:
d[u] = d[v]
else:
d[u] = 3 - d[u] - d[v]
else:
d[u] = randint(0, 2)
return d


Note: one could save on storage by using less keys in the dictionary, running through triples in $E^3$ only up to cyclic order. Each $(x, y, z)$ would be assigned one of 'aaa', 'bbb', 'ccc', 'abc', 'acb', 'bac', 'bca', 'cab', 'cba', with the understanding that this stores at once the values for $(x, y, z)$, $(y, z, x)$ and $(z, x, y)$. Triples of the form $(x, x, x)$ would always be assigned one of 'aaa', 'bbb', 'ccc'.

more

thank you very much @selelivere

( 2019-06-03 14:43:46 +0200 )edit

## Stats

Seen: 327 times

Last updated: May 27 '19