简体   繁体   中英

Making a latin square

Im trying to get a question done for some school homework, and im just having the worst case of brain farts humanity has ever seen. The the question asks for three things.

• It reads a number N on a line by itself. This will be the order of a Latin square. The order must be a positive integer, eg, N > 0.

• It reads N lines of N of numbers, ie, it reads console input for a square of numbers.

• It checks whether the sequence of numbers is a Latin square or not. Your program should display the message “yes” if it satisfies the above criteria, or “no” if it does not.

My current code is this:

def makelatin():

order = int(input("Enter the order of the latin square: "))

latin = [int(x) for x in input("enter the latin square with spaces inbetween the numbers: ").split()]




def checklatin(latin) :

    numbers = set(range(1, len(latin) + 1))

    if (any(set(row) != numbers for row in latin) or any(set(col) != numbers for col in zip(*latin))) :

        print ("False")

    print ("True")

checklatin(a) 

So what ive thought of is this, Make a latin square, then check it. My probelm is, im currently stuck on the makelatin part. The user inputs the order of the latin square, and then they enter the square in a input.

Example:

"enter order of square" = 3

"enter the square" = 3 2 1 1 3 2 2 1 3 

Which would make a latin square like this

3 2 1 

1 3 2 

2 1 3 

This doesn't need to make a square, but it does help me visualize it a bit better.

So my main question is, is there a good way to make the user entered latin square into an actual latin square?

To note, im not looking for any answers, im just wanting some help to get past my mental block.

I got it, sorry to bug you guys! the answer is this

def makelatin():

    order = int(input("Enter the order of the latin square: "))
    latin = [int(x) for x in input("enter the latin square with spaces inbetween the numbers: ").split()]

    return (list(zip(*(iter(latin),) * order)))


def checklatin(latin) :
    numbers = set(range(1, len(latin) + 1))
    if (any(set(row) != numbers for row in latin) or any(set(col) != numbers for col in zip(*latin))) :
        print ("False")
    else:
        print ("True")

#a = [[1, 2, 3, 4, 5],
     [2, 3, 5, 1, 4],
     [3, 5, 4, 2, 1],
     [4, 1, 2, 5, 3],
     [5, 4, 1, 3, 2]]


checklatin(makelatin())

if you don't mind I use matlab:

n=5;
% create an empty matrix of NaNs.
latinSquare=nan(n);
% fill the 1st column.
latinSquare(:,1)=1:n;

% define a variable of how we want to shift the 1s column to fill the remaining columns.
% ballanced order:
shiftsize=(.5-mod(1:n-1,2))/.5.*ceil((1:n-1)/2);
% normal order:
%shiftsize=n-1:-1:1;


for col=2:n
    latinSquare(:,col)=circshift((1:n)',shiftsize(col-1));
end

and this will be the output for the ballanced latin square:

ans =

 1     2     5     3     4
 2     3     1     4     5
 3     4     2     5     1
 4     5     3     1     2
 5     1     4     2     3

this is the normal Latin square:

ans =

 1     2     3     4     5
 2     3     4     5     1
 3     4     5     1     2
 4     5     1     2     3
 5     1     2     3     4

now I rewrite it with python:

def latin_square(n, mod='ballanced'):

  import numpy as np

  mat = np.empty((n,n,))*np.nan

  mat[:,0] = range(1,n+1)

  if mod=='ballanced':
    shift = (.5-np.mod(np.array(range(1,n)),2))/.5*np.ceil(np.array(range(1,n))/2)
    shift = shift.astype(int)
  elif mod=='normal':
    shift = np.array(range(n-1, -1, -1))

  for col in range(1, n):
    mat[:, col] = np.roll(mat[:,0], shift[col-1])
    
  return(mat)
    

latin_square(6)

array([[1., 2., 6., 3., 5., 4.],
   [2., 3., 1., 4., 6., 5.],
   [3., 4., 2., 5., 1., 6.],
   [4., 5., 3., 6., 2., 1.],
   [5., 6., 4., 1., 3., 2.],
   [6., 1., 5., 2., 4., 3.]])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM