How to ignore certain elements in a list that will go through a random process? (pending)

Asked

Viewed 249 times

2

This program finds 3x3 magic squares by brute force and prints automatically when it encounters a.

code:

import random

vetor = [1, 2, 3, 4, 5, 6, 7, 8, 9]

def magicsquare():
    return vetor[0]+vetor[1]+vetor[2]==\
           vetor[3]+vetor[4]+vetor[5]==\
           vetor[6]+vetor[7]+vetor[8]==\
           vetor[0]+vetor[3]+vetor[6]==\
           vetor[1]+vetor[4]+vetor[7]==\
           vetor[2]+vetor[5]+vetor[8]==\
           vetor[0]+vetor[4]+vetor[8]==\
           vetor[2]+vetor[4]+vetor[6]

while not magicsquare():
    random.shuffle(vetor)

print (vetor)

The program running on repl:

https://repl.it/@William33/ComposedFirstArachnid

I’m not getting the job done:

Knowing that in a magic square 3x3, the number 5 will always be in the middle, I would like to leave it already in the middle, IE, it is already, but at the time the program makes the "Random" I would like it not to touch the number 5, did not move him...

For the simple fact that, to find a magic square 3x3 with 9 the numbers, the possibilities are 362880 thus being the factor of 9...

So if I’ve practically left the number 5 in place.. will pass only 8 numbers by "Random" and the possibilities will be only 40320 which would be the factor of 8.

Now imagine in a square 4x4 with 16 numbers...

The possibilities are 20 trillion or so, 20922789888000 but if I could just leave 4 numbers in the right places that didn’t go through "Random," I would have just 12 numbers decreasing the possibilities to 479 million, ie 479001600.

The speed to find the magic squares would increase dramatically...

Now the question:

How to ignore certain elements in a list that will go through a random process?

(Continuation)

The code with implementations in 3x3 works perfectly. but with 4x4 not working follow the code:

 import random

 vetor = [4, 14, 15, 1, 9, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 16]

 def shuffle(vetor, frozen_vetor):        
 frozen = [(pos, item) for (pos,item) in enumerate(vetor) if item in 
 frozen_vetor]    
 random.shuffle(vetor)    
 for pos, item in frozen:
     index = vetor.index(item)
     vetor[pos], vetor[index] = vetor[index], vetor[pos]    

 def magicsquare():
     return vetor[0]+vetor[1]+vetor[2]+vetor[3]==\
            vetor[4]+vetor[5]+vetor[6]+vetor[7]==\
            vetor[8]+vetor[9]+vetor[10]+vetor[11]==\
            vetor[12]+vetor[13]+vetor[14]+vetor[15]==\
            vetor[0]+vetor[4]+vetor[8]+vetor[12]==\
            vetor[1]+vetor[5]+vetor[9]+vetor[13]==\
            vetor[2]+vetor[6]+vetor[10]+vetor[14]==\
            vetor[3]+vetor[7]+vetor[11]+vetor[15]==\
            vetor[0]+vetor[5]+vetor[10]+vetor[15]==\
            vetor[3]+vetor[6]+vetor[9]+vetor[12]


while not magicsquare():
    shuffle(vetor, [4, 14, 15, 1, 9])

print (vetor)

You realize I used 5 numbers already in the order of the magic square, ignoring them.. inserir a descrição da imagem aqui

Then there would be only 11 numbers for the "Random", which would give 39916800 possibilities... and would find the magic square super fast... but the program is taking too long to find the square.. then he’s probably using the 16 in the "Random" that would give 20922789888000 possibilities.. or else there must be some other error in the program..

  • So the question appears to be well-worded, self-explanatory, but her title was kind of strange to me. It seems that she is self-sufficient, so this title with "(continuation)" caught my attention negatively... if...

1 answer

1

One way is you create your own shuffle ignoring the desired elements:

def shuffle(items, frozen_items):        
    frozen = [(pos, item) for (pos, item) in enumerate(items) if item in frozen_items]    
    random.shuffle(items)    
    for pos, item in frozen:
        index = items.index(item)
        items[pos], items[index] = items[index], items[pos]

    return items

It doesn’t seem very pythonic but it is a way to ignore items when doing a shuffle.

Ex:

vector = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print shuffle(vector, [8, 9]) // mantém os números 8 e 9 na posição original

You can adapt to ignore the index instead of the number.

EDIT

To use in your code while maintaining variable usage vector by reference:

import random

vetor = [1, 2, 3, 4, 5, 6, 7, 8, 9]

def shuffle(vetor, frozen_vetor):        
    frozen = [(pos, item) for (pos,item) in enumerate(vetor) if item in frozen_vetor]    
    random.shuffle(vetor)    
    for pos, item in frozen:
        index = vetor.index(item)
        vetor[pos], vetor[index] = vetor[index], vetor[pos]    

def magicsquare():
    return vetor[0]+vetor[1]+vetor[2]==\
           vetor[3]+vetor[4]+vetor[5]==\
           vetor[6]+vetor[7]+vetor[8]==\
           vetor[0]+vetor[3]+vetor[6]==\
           vetor[1]+vetor[4]+vetor[7]==\
           vetor[2]+vetor[5]+vetor[8]==\
           vetor[0]+vetor[4]+vetor[8]==\
           vetor[2]+vetor[4]+vetor[6]

while not magicsquare():
    shuffle(vetor, [5]) # ex: mantém o número 5 na posição original

print vetor
  • Thanks Tom, but how would that look in the code? these implementations??

  • I edited with the use in your code, I do not know if this is what you want... There are other more efficient algorithms that, given an Nxn, it generates a magic square

  • I tested it here and it didn’t work it appeared this: Traceback (Most recent call last): File "python", line 23 shuffle(vector, [5]) // ex: keeps the number 5 in the original position Syntaxerror: invalid syntax

  • comment on this line is wrong... //

  • Opa blz I think now it worked yes !!!

  • Like, I don’t think it worked. 'Cause I tried it here with a 4x4.. and it’s taking too long to make the square and it wouldn’t take long, I think the "function" of ignoring the numbers was after the "Random" and not before...

  • Edit your question and put the example code with 4x4. Something else, do you really need to keep this algorithm? There are others who generate the magic square in a much faster and simpler way.

  • I will edit.. is that unfortunately I need this way even... the others are normal.. and do not reach the goal.. only so would achieve the goal.. I’ll post in 4x4.. here blz..

  • Tom, I was thinking here, really what you said, makes sense, could change the algorithm of how you find the magic square, but only with the same system of having a list and being able to ignore certain numbers.. just change the algorithm of how to find the magic squares, a different way of this vector...

Show 4 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.