ग्रेको-लैटिन वर्ग उत्पन्न करें


24

अस्वीकरण: मैं किसी भी गैर-जानवर समाधान के बारे में पता नहीं कर रहा हूँ

एक ग्रेको-लैटिन वर्ग, समान लंबाई के दो सेटों के लिए है n , कोशिकाओं की एक n×n व्यवस्था, प्रत्येक में पहले सेट के एक तत्व (पूरे वर्ग के पार) और दूसरे सेट के एक तत्व की जोड़ी है, जैसे जोड़े के सभी पहले तत्व और सभी दूसरे तत्व अपनी पंक्ति और स्तंभ में अद्वितीय हैं। सबसे आम सेट का उपयोग किया जाता है, जैसा कि एक अनुमान लगा सकता है, ग्रीक और लैटिन अक्षर के पहले n अक्षर।

यहाँ 4x4 ग्रेको-लैटिन वर्ग की एक तस्वीर है:यहाँ छवि विवरण दर्ज करें

ग्रेको-लैटिन वर्ग उतने ही उपयोगी हैं जितना कि वे ध्वनि करते हैं ( विकिपीडिया लेख में "प्रयोगों के डिजाइन, टूर्नामेंट शेड्यूलिंग और जादू के वर्गों का निर्माण" का उल्लेख है)। आपका कार्य है, एक सकारात्मक पूर्णांक n , एक n×n ग्रेको-लैटिन वर्ग उत्पन्न करने के लिए ।

इनपुट

एक सकारात्मक पूर्णांक n>2 ; यह गारंटी है कि एक n×n (यह है कि, यूनानी-लैटिन वर्ग मौजूद है n6 )।

उत्पादन

एक ग्रेको-लैटिन वर्ग जिसमें साइड लंबाई n के साथ दो आयामी सरणी, सरणी का एक सरणी, एक चपटा सरणी या आउटपुट सीधे होता है।

टिप्पणियाँ

  • आपको विशेष रूप से ग्रीक और लैटिन वर्णमाला का उपयोग करने की आवश्यकता नहीं है; उदाहरण के लिए, पॉजिटिव पूर्णांक के जोड़े को आउटपुट करने की अनुमति है।
  • यदि आप एक वर्णमाला का उपयोग करना चुनते हैं जिसे मनमाने ढंग से नहीं बढ़ाया जा सकता है, तो आपको (सैद्धांतिक रूप से, ब्रह्मांड की गर्मी से पहले आपका कोड खत्म नहीं होना चाहिए) कम से कम 20 की अधिकतम पक्ष लंबाई का समर्थन करता है।

यह , इसलिए सबसे छोटा कोड जीतता है!



क्या हमें एक वर्ग का उत्पादन करना है, या एक सूची के रूप में सभी संभावित वर्गों का उत्पादन करना ठीक है?
निक केनेडी

जवाबों:


2

जेली ,  21  20 बाइट्स

-1 कैनेडी के लिए धन्यवाद (फ्लैट आउटपुट विकल्प बाइट को बचाने की अनुमति देता है ż"þ`ẎẎQƑ$Ƈ F€p`Z€QƑƇ )

Œ!ṗ⁸Z€Q€ƑƇF€p`Z€QƑƇḢ

इसे ऑनलाइन आज़माएं! (4टीआईओ पर 60 के दशक मेंबहुत धीमी गति से, लेकिन अगर हम कार्टेशियन पावर की जगह, कॉम्बिनेशन के साथलेते हैंœc, तो यह पूरा हो जाएगा - हालांकि 5 निश्चित रूप से नहीं होगा!)

कैसे?

Œ!ṗ⁸Z€Q€ƑƇF€p`Z€QƑƇḢ - Link: integer, n
Œ!                   - all permutations of [1..n]
   ⁸                 - chain's left argument, n
  ṗ                  - Cartesian power (that is, all ways to pick n of those permutations, with replacement, not ignoring order)
    Z€               - transpose each
         Ƈ           - filter, keeping those for which:
        Ƒ            -   invariant under:
      Q€             -     de-duplicate each
          F€         - flatten each  
             `       - use this as both arguments of:
            p        -   Cartesian product
              Z€     - transpose each
                  Ƈ  - filter, keeping those for which:
                 Ƒ   -   invariant under:   
                Q    -     de-duplicate (i.e. contains all the possible pairs)
                   Ḣ - head (just one of the Latin-Greaco squares we've found)

यहाँ 20 है । मैंने मूल रूप से आपका यह स्वतंत्र रूप से लिखा था, लेकिन कुछ इसी तरह से समाप्त हो गया, और फिर क्रमपरिवर्तन राग के स्थान पर कार्टेशियन शक्ति के आपके उपयोग से कुछ प्रेरणा ली, इसलिए संभवतः आपका सुधार करने के लिए इसका उपयोग करना सबसे अच्छा है। ध्यान दें कि आपने अपनी व्याख्या में ग्रेको को याद किया है।
निक केनेडी

धन्यवाद निक, मैंने ध्यान नहीं दिया कि हमें एक चपटा संस्करण उत्पादन करने की अनुमति दी गई थी।
जोनाथन एलन

3

05AB1E , 26 23 22 बाइट्स

-3 बाइट्स एमिग्ना के लिए धन्यवाद

केविन क्रूज़सेन के लिए धन्यवाद

Lãœ.ΔIôDζ«D€í«ε€нÙgQ}P

इसे ऑनलाइन आज़माएं!


1
n<ÝI‰हो सकता है<Ýã
Emigna

... और हो सकता है L। धन्यवाद!
ग्रैमी

1
ê}DIùQÙgQ}Pएक बाइट को बचाने के लिए किया जा सकता है।
केविन क्रूज़सेन

@ केविनक्रूजसेन धन्यवाद! मैंने उसे संपादित किया।
ग्रिम जॉनी

3

आर , 164 148 बाइट्स

-म्यानी बाइट्स ग्यूसेप के लिए धन्यवाद।

n=scan()
`!`=function(x)sd(colSums(2^x))
m=function()matrix(sample(n,n^2,1),n)
while(T)T=!(l=m())|!(g=m())|!t(l)|!t(g)|1-all(1:n^2%in%(n*l+g-n))
l
g

इसे ऑनलाइन आज़माएं!

नाटकीय रूप से अक्षम - मुझे लगता है कि यह अन्य जानवर बल के दृष्टिकोण से भी बदतर है। यहां तक ​​कि n=3, यह संभवत: TIO पर टाइम आउट होगा। यहां एक वैकल्पिक संस्करण (155 बाइट्स) है जो n=3लगभग 1 सेकंड में काम करता है ।

m1nnlg

  1. all(1:n^2%in%(n*l+g-n))n2l × g
  2. कर रहे हैं lऔर gलैटिन वर्गों?

!nlg2^l2n+1-2lt(l)lgsdn=0n=1

एक अंतिम ध्यान दें: जितनी बार आर कोड गोल्फ में, मैंने कुछ बाइट्स प्राप्त करने के लिए, वैरिएबल का उपयोग किया है T, जो कि प्रारंभिक है TRUE। लेकिन इसका मतलब यह है कि जब मुझे (पैरामीटर इन ) TRUEकी परिभाषा में वास्तविक मूल्य की आवश्यकता थी, तो मुझे इसके बजाय उपयोग करना था । इसी तरह, चूंकि मैं नकार से अलग एक फ़ंक्शन के रूप में पुनर्परिभाषित कर रहा हूं, इसलिए मुझे इसके बजाय उपयोग करना पड़ा ।mreplacesample1T!1-all(...)!all(...)


2

जावास्क्रिप्ट (ईएस 6),  159 147  140 बाइट्स

का एक सपाट सरणी देता हैn×nगैर-नकारात्मक पूर्णांकों जोड़े का ।

यह एक सरल जानवर बल खोज है, और इसलिए बहुत धीमी है।

n=>(g=(m,j=0,X=n*n)=>j<n*n?!X--||m.some(([x,y],i)=>(X==x)+(Y==y)>(j/n^i/n&&j%n!=i%n),g(m,j,X),Y=X/n|0,X%=n)?o:g([...m,[X,Y]],j+1):o=m)(o=[])

इसे ऑनलाइन आज़माएं!(पहले से तैयार आउटपुट के साथ)

टिप्पणी की गई

n => (                      // n = input
  g = (                     // g is the recursive search function taking:
    m,                      //   m[] = flattened matrix
    j = 0,                  //   j   = current position in m[]
    X = n * n               //   X   = counter used to compute the current pair
  ) =>                      //
    j < n * n ?             // if j is less than n²:
      !X-- ||               //   abort right away if X is equal to 0; decrement X
      m.some(([x, y], i) => //   for each pair [x, y] at position i in m[]:
        (X == x) +          //     yield 1 if X is equal to x OR Y is equal to y
        (Y == y)            //     yield 2 if both values are equal
                            //     or yield 0 otherwise
        >                   //     test whether the above result is greater than:
        ( j / n ^ i / n &&  //       - 1 if i and j are neither on the same row
          j % n != i % n    //         nor the same column
        ),                  //       - 0 otherwise
                            //     initialization of some():
        g(m, j, X),         //       do a recursive call with all parameters unchanged
        Y = X / n | 0,      //       start with Y = floor(X / n)
        X %= n              //       and X = X % n
      ) ?                   //   end of some(); if it's falsy (or X was equal to 0):
        o                   //     just return o[]
      :                     //   else:
        g(                  //     do a recursive call:
          [...m, [X, Y]],   //       append [X, Y] to m[]
          j + 1             //       increment j
        )                   //     end of recursive call
    :                       // else:
      o = m                 //   success: update o[] to m[]
)(o = [])                   // initial call to g with m = o = []

144 ? (मेरे फोन पर, इसलिए यह पूरी तरह से सुनिश्चित नहीं है कि यह काम करता है)
झबरा

मुझे नहीं लगता कि आपको जरूरत है o, या तो; आप बस 141 केm लिए अंत में वापस आ सकते हैं
झबरा

@ शैगी दोनों संस्करणों के लिए विफल हो जाएगा n=5

2

हास्केल , 207 143 233 बाइट्स

(p,q)!(a,b)=p/=a&&q/=b
e=filter
f n|l<-[1..n]=head$0#[(c,k)|c<-l,k<-l]$[]where
	((i,j)%p)m|j==n=[[]]|1>0=[q:r|q<-p,all(q!)[m!!a!!j|a<-[0..i-1]],r<-(i,j+1)%e(q!)p$m]
	(i#p)m|i==n=[[]]|1>0=[r:o|r<-(i,0)%p$m,o<-(i+1)#e(`notElem`r)p$r:m]

इसे ऑनलाइन आज़माएं!

ठीक है, मुझे लगता है कि मुझे इस बार मिल गया। यह TIO पर n = 5, n = 6 बार के लिए ठीक काम करता है, लेकिन मुझे लगता है कि यह सिर्फ इसलिए हो सकता है क्योंकि यह नया एल्गोरिथ्म INCREDIBLY अक्षम है और मूल रूप से सभी संभावनाओं की जांच करता है जब तक कि यह एक काम नहीं करता। मैं अपने लैपटॉप पर n = 6 चला रहा हूं अब यह देखने के लिए कि क्या यह कुछ और समय के साथ समाप्त होता है।

मेरे पिछले संस्करणों में बग्स को इंगित करने के लिए @someone को फिर से धन्यवाद


1
हास्केल को मैं नहीं जानता, लेकिन मेरे लिए यह त्रुटि प्रतीत होती है जब मैं "4" को पाद लेख में बदलता हूं। 5. क्या मैं इसे सही ढंग से लागू कर रहा हूं?
मेरा सर्वनाम जुनी

@someone अच्छी पकड़ है, मुझे इस बात का परीक्षण करना चाहिए कि मैं वास्तव में निश्चित नहीं हूँ कि यहाँ क्या गलत हो रहा है, यह डिबग करने में
थोड़ा

1
मुझे लगता है कि यह अभी भी एक बग है; जब n = 5 के लिए चलाया जाता है, तो टपल (1,1) दो बार दिखाई देता है।
मेरा सर्वनाम 14

@someone मैन, यह समस्या मेरे विचार से बहुत कठिन है। मैं बस एक बार में सभी बाधाओं को बंद करने का एक विश्वसनीय तरीका नहीं खोज सकता। जैसे ही मैं एक दूसरे पर ध्यान केंद्रित करता हूं, मेरी मुट्ठी से बाहर निकल जाता है। मैं अब तक गैर-प्रतिस्पर्धी के रूप में चिह्नित करने जा रहा हूं, जब तक मुझे इस पर काम करने के लिए कुछ और समय नहीं मिल जाता। खेद के रूप में अच्छी तरह से परीक्षण के लिए नहीं होना चाहिए
user1472751

1

सी #, 520 506 494 484 बाइट्स

class P{static void Main(string[]a){int n=int.Parse(a[0]);int[,,]m=new int[n,n,2];int i=n,j,k,p,I,J;R:for(;i-->0;)for(j=n;j-->0;)for(k=2;k-->0;)if((m[i,j,k]=(m[i,j,k]+ 1) % n)!=0)goto Q;Q:for(i=n;i-->0;)for(j=n;j-->0;){for(k=2;k-->0;)for(p=n;p-->0;)if(p!=i&&m[i,j,k]==m[p,j,k]||p!=j&&m[i,j,k]==m[i,p,k])goto R;for(I=i;I<n;I++)for(J=0;J<n;J++)if(I!=i&&J!=j&&m[i,j,0]==m[I,J,0]&&m[i,j,1]==m[I,J,1])goto R;}for(i=n;i-->0;)for(j=n;j-->0;)System.Console.Write(m[i,j,0]+"-"+m[i,j,1]+" ");}}

एक वर्ग findinf का एल्गोरिथ्म बहुत सरल है। यह है ... जानवर। हाँ, यह बेवकूफी है, लेकिन कोड गोल्फ एक कार्यक्रम की गति के बारे में नहीं है, है ना?

इसे छोटा करने से पहले कोड:

using System;

public class Program
{
    static int[,,] Next(int[,,] m, int n){
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                for (int k = 0; k < 2; k++)
                {
                    if ((m[i, j, k] = (m[i, j, k] + 1) % n) != 0)
                    {
                        return m;
                    }
                }
            }
        }
        return m;
    }
    static bool Check(int[,,] m, int n)
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                for (int k = 0; k < 2; k++)
                {
                    for (int p = 0; p < n; p++)
                    {
                        if (p != i)
                            if (m[i, j, k] == m[p, j, k])
                                return false;
                    }
                    for (int p = 0; p < n; p++)
                    {
                        if (p != j)
                            if (m[i, j, k] == m[i, p, k])
                                return false;
                    }
                }
            }
        }

        for (int i_1 = 0; i_1 < n; i_1++)
        {
            for (int j_1 = 0; j_1 < n; j_1++)
            {
                int i_2 = i_1;
                for (int j_2 = j_1 + 1; j_2 < n; j_2++)
                {
                    if (m[i_1, j_1, 0] == m[i_2, j_2, 0] && m[i_1, j_1, 1] == m[i_2, j_2, 1])
                        return false;
                }
                for (i_2 = i_1 + 1; i_2 < n; i_2++)
                {
                    for (int j_2 = 0; j_2 < n; j_2++)
                    {
                        if (m[i_1, j_1, 0] == m[i_2, j_2, 0] && m[i_1, j_1, 1] == m[i_2, j_2, 1])
                            return false;
                    }
                }
            }
        }
        return true;
    }
    public static void Main()
    {
        int n = 3;
        Console.WriteLine(n);
        int maxi = (int)System.Math.Pow((double)n, (double)n*n*2);
        int[,,] m = new int[n, n, 2];
        Debug(m, n);
        do
        {
            m = Next(m, n);
            if (m == null)
            {
                Console.WriteLine("!");
                return;
            }
            Console.WriteLine(maxi--);
        } while (!Check(m, n));


        Debug(m, n);
    }

    static void Debug(int[,,] m, int n)
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                Console.Write(m[i, j, 0] + "-" + m[i, j, 1] + " ");
            }
            Console.WriteLine();
        }
        Console.WriteLine();
    }
}

अब, यदि आप इसे n = 3 के साथ परीक्षण करना चाहते हैं, तो आपको एक घंटे की तरह इंतजार करना होगा, इसलिए यहां एक और संस्करण है:

public static void Main()
{
    int n = 3;
    Console.WriteLine(n);
    int maxi = (int)System.Math.Pow((double)n, (double)n*n*2);        
    int[,,] result = new int[n, n, 2];
    Parallel.For(0, n, (I) =>
    {
        int[,,] m = new int[n, n, 2];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
            {
                m[i, j, 0] = I;
                m[i, j, 1] = I;
            }
        while (true)
        {
            m = Next(m, n);
            if (Equals(m, n, I + 1))
            {
                break;
            }
            if (Check(m, n))
            {
                Debug(m, n);
            }
        }
    });
}

अपडेट: "सार्वजनिक" को निकालना भूल गया।

अद्यतन: "सिस्टम।" इसके बजाय "सिस्टम का उपयोग करना;" इसके लिए भी धन्यवाद केविन क्रूज़सेन के , " " के बजाय "ए" का उपयोग किया।

अपडेट: गैस्ट्रोपनर और किसी के लिए धन्यवाद ।


argsहो सकता है a:)
केविन क्रूज़सेन

पाश के लिए प्रत्येक से बदल किया जा सकता है for(X = 0; X < Y; X++)करने के लिए for(X = Y; X-->0; )है, जो पाश प्रति एक बाइट को बचाने चाहिए।
गैस्ट्रोपनर

1
क्या आपने विज़ुअल सी # इंटरएक्टिव कंपाइलर आज़माया है ? यह बाइट्स बचा सकता है। आप एक अनाम फ़ंक्शन भी सबमिट कर सकते हैं। आप एक बाइट i = 0में भी निर्दिष्ट कर सकते हैं iऔर बचा सकते हैं।
मेरा सर्वनाम 8

@ किसी के सुझाव के आधार पर 405 बाइट्स । बेशक यह TIO पर 60 सेकंड के बाद बाहर है, लेकिन यह एक मेमने का उपयोग करके बाइट्स को बचाता है और अंतर्निहित के साथ इंटरएक्टिव कंपाइलर है System। भी, if((m[i,j,k]=(m[i,j,k]+ 1) % n)!=0)हो सकता है if((m[i,j,k]=-~m[i,j,k]%n)>0)
केविन क्रूज़सेन

@ केविन मुझे वास्तव में उस कोड के माध्यम से पढ़ने की तरह महसूस नहीं होता है जो इसे गोल्फ के लिए कोशिश कर रहा है। क्या आप सुनिश्चित हैं कि मुद्रण भाग सही काम करता है? ऐसा लगता है कि इसे या तो उपयोग करना चाहिए Writeया \nकॉल के अंदर स्ट्रिंग में जोड़कर बाइट को बचा सकता है या अन्यथा टूट गया है। मुझे लगता है कि आप सीधे एक सरणी भी वापस कर सकते हैं।
मेरा सर्वनाम

1

ऑक्टेव , 182 बाइट्स

बल बल विधि, TIO समय बाहर रखता है और मुझे इसे n = 3 के लिए आउटपुट प्राप्त करने के लिए कई बार चलाना पड़ा, लेकिन सैद्धांतिक रूप से यह ठीक होना चाहिए। जोड़े की बजाय (1,2) यह 1 + 2i जैसे जटिल संयुग्मों के एक मैट्रिक्स को आउटपुट करता है। यह नियम को थोड़ा बढ़ा सकता है, लेकिन मेरी राय में यह स्टाल आउटपुट आवश्यकताओं को पूरा करता है। हालांकि, कार्यरूप घोषणा के तहत दो पंक्तियों को करने का एक बेहतर तरीका होना चाहिए, लेकिन मुझे यकीन नहीं है।

function[c]=f(n)
c=[0,0]
while(numel(c)>length(unique(c))||range([imag(sum(c)),imag(sum(c.')),real(sum(c)),real(sum(c.'))])>0)
a=fix(rand(n,n)*n);b=fix(rand(n,n)*n);c=a+1i*b;
end
end

इसे ऑनलाइन आज़माएं!


0

वोल्फ्राम लैंग्वेज (गणितज्ञ) , 123 बाइट्स

P=Permutations
T=Transpose
g:=#&@@Select[T[Intersection[x=P[P@Range@#,{#}],T/@x]~Tuples~2,2<->4],DuplicateFreeQ[Join@@#]&]&

इसे ऑनलाइन आज़माएं!

मैं TwoWayRuleनोटेशन का उपयोग करता हूंTranspose[...,2<->4] एक सरणी के दूसरे और चौथे आयाम को स्वैप करने के का ; अन्यथा यह काफी सीधा है।

Ungolfed:

(* get all n-tuples of permutations *)
semiLSqs[n_] := Permutations@Range@n // Permutations[#, {n}] &;

(* Keep only the Latin squares *)
LSqs[n_] := semiLSqs[n] // Intersection[#, Transpose /@ #] &;

isGLSq[a_] := Join @@ a // DeleteDuplicates@# == # &;

(* Generate Graeco-Latin Squares from all pairs of Latin squares *)
GLSqs[n_] := 
  Tuples[LSqs[n], 2] // Transpose[#, 2 <-> 4] & // Select[isGLSq];

0

पायथन 3 , 271 267 241 बाइट्स

जानवर-बल दृष्टिकोण: ग्रेको-लैटिन वर्ग मिलने तक जोड़े के सभी क्रमपरिवर्तन उत्पन्न करें। की तुलना में कुछ भी उत्पन्न करने के लिए बहुत धीमाn=3 TIO पर ।

26 बाइट्स के लिए और करने के लिए alexz02 के लिए धन्यवाद ceilingcat 4 बाइट गोल्फ के लिए।

इसे ऑनलाइन आज़माएं!

from itertools import*
def f(n):
 s=range(n);l=len
 for r in permutations(product(s,s)):
  if all([l({x[0]for x in r[i*n:-~i*n]})*l({x[1]for x in r[i*n:-~i*n]})*l({r[j*n+i][0]for j in s})*l({r[j*n+i][1]for j in s})==n**4for i in s]):return r

स्पष्टीकरण:

from itertools import *  # We will be using itertools.permutations and itertools.product
def f(n):  # Function taking the side length as a parameter
 s = range(n)  # Generate all the numbers from 0 to n-1
 l = len  # Shortcut to compute size of sets
 for r in permutations(product(s, s)):  # Generate all permutations of all pairs (Cartesian product) of those numbers, for each permutation:
  if all([l({x[0] for x in r[i * n : (- ~ i) * n]})  # If the first number is unique in row i ...
        * l({x[1] for x in r[i * n:(- ~ i) * n]})  # ... and the second number is unique in row i ...
        * l({r[j * n + i][0] for j in s})  # ... and the first number is unique in column i ...
        * l({r[j * n + i][1] for j in s})  # ... and the second number is unique in column i ...
        == n ** 4 for i in s]):  # ... in all columns i:
   return r  # Return the square

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.