N के माध्यम से 1 के साथ एक NxN ग्रिड की पंक्तियों, कॉलम और विकर्णों को भरें


26

कार्य

इनपुट N को देखते हुए, एक NxN ग्रिड उत्पन्न करें और आउटपुट करें जहाँ प्रत्येक पंक्ति, स्तंभ और दो विकर्णों में संख्या 1 से N(या 0 से Nor1 हो अगर यह आसान है)।

इनपुट

इनपुट एक सकारात्मक पूर्णांक है N। यह ग्रिड में कॉलम और पंक्तियों की संख्या का प्रतिनिधित्व करता है। इस समस्या के लिए, आप मान सकते हैं Nकि एक उचित आकार होगा, 4 ≤ N ≤ 8या ( 1 ≤ N ≤ 8यदि आप नीचे दिए गए बोनस के लिए जाते हैं)।

उत्पादन

आउटपुट N× Nग्रिड होगा। ग्रिड में, प्रत्येक पंक्ति केवल 1 संख्या शामिल N, प्रत्येक स्तंभ केवल संख्या 1 के लिए होता है N, और लंबाई के दो विकर्ण N(से एक (0,0)करने के लिए (N-1,N-1)और से एक (0,N-1)करने के लिए (N-1, 0)) केवल करने के लिए संख्या 1 शामिल N। आप 0 से नंबर का उपयोग कर सकते हैं N−1। प्रत्येक के लिए N, कई संभावित समाधान हैं, आपको केवल पहले एक को प्रिंट करने की आवश्यकता है जो आप पाते हैं। आपको संख्याओं के बीच रिक्त स्थान प्रिंट करने की आवश्यकता नहीं है।

प्रतिबन्ध

आपका कोड बार-बार परिणाम प्राप्त करने में सक्षम होना चाहिए N >= 7। यही है, यदि आप वास्तव में N = 7हर बार अपने कोड से हल चलाने और प्राप्त करने में सक्षम हैं, तो आप अच्छे हैं। एक पूर्ण सीमा के संदर्भ में, आपका कोड आपके द्वारा N = 7इसे चलाने पर 10 मिनट के भीतर हल करने में सक्षम होना चाहिए (यानी, यदि आप यादृच्छिक संख्या पर निर्भर करते हैं, तो सबसे खराब स्थिति के लिए, आपका कोड अभी भी 10 मिनट से कम समय के लिए समाप्त होना चाहिए N = 7) ।

उदाहरण

  • इनपुट: 4

    एक संभावित उत्पादन:

    1 2 3 4
    3 4 1 2
    4 3 2 1
    2 1 4 3
    
  • इनपुट: 5

    एक संभावित उत्पादन:

    1 2 3 4 5
    5 3 1 2 4
    2 5 4 3 1
    4 1 2 5 3
    3 4 5 1 2
    
  • इनपुट: 8

    एक संभावित उत्पादन:

    1 2 3 4 5 6 7 8
    2 3 1 5 4 8 6 7
    4 1 2 3 7 5 8 6
    6 4 7 8 1 2 3 5
    7 5 8 2 6 3 4 1
    5 8 4 6 2 7 1 3
    8 7 6 1 3 4 5 2
    3 6 5 7 8 1 2 4
    

स्कोरिंग

यह , इसलिए बाइट्स में सबसे छोटा कोड एक अपवाद के साथ जीता जाता है। इनपुट के N = 2, 3लिए कोई मान्य समाधान नहीं हैं। यदि आपका कोड इसे संभाल सकता है (इन मामलों के लिए कुछ भी आउटपुट के बिना पूरा करने के लिए रन करें, या एक खाली स्ट्रिंग N = 1आउटपुट करें ), और अभी भी हैंडल ( 1इसके लिए आउटपुट ), अपने बाइट की गिनती से 20% दूर ले जाएं।


1
संबंधित , लेकिन विकर्ण आवश्यकता के कारण ऐसा ग्रिड यहां काम नहीं करेगा।
xnor

मुझे यह चुनौती पसंद है लेकिन मैं इसके मूल्यों के लिए एक एल्गोरिथ्म का पता नहीं लगा सकता N। यह जावास्क्रिप्ट कोड तब काम करता है N = 1, 5 or 7जब यह किसी की मदद करता है:for(o="",y=N;y--;o+="\n")for(x=N;x--;)o+=(((N-y)*2+x)%N)+1
user81655

बहुत संबंधित, संभव डुप्लिकेट: codegolf.stackexchange.com/q/47846/15599
लेवल रिवर सेंट

@steveverrill हालांकि कोड गोल्फ नहीं था।
रैंडम

1
हो सकता है कि आपको N = 1मामले के बारे में अधिक स्पष्ट होना चाहिए : जवाब जो बोनस के लिए लक्षित हैं 1, उन्हें खाली स्ट्रिंग नहीं लौटना चाहिए ।
लिन

जवाबों:


3

पायथन 3, 275 260 बाइट्स * 0.8 = 220 208 बाइट्स

पुनरावर्ती / पीछे का दृष्टिकोण। Rपुनरावर्ती कार्य है, lसह-सूत्र wहै, रॉ Kहै, अगली प्रविष्टि है।

मैंने इसे 1d एरे में रखने के लिए चुना और इंडेक्स को सरल बनाने के लिए इसे बहुत प्रिंट किया।

r=range
n=(int)(input())
def R(A,I):
 l=I%n;w=I//n
 if I==n*n:[print(A[i*n:i*n+n])for i in r(n)];exit()
 for K in r(n):
  if all([all([A[i*n+l]!=K,w!=l or A[i+n*i]!=K,w!=n-1-l or A[n*i+n-i-1]!=K])for i in r(w)]+[A[w*n+i]!=K for i in r(l)]):R(A+[K],I+1)
R([],0)

Ungolfed संस्करण:

def Recurse(A,I,n):
 column=I%n
 row=I//n
 if I==n*n:
     [print(*A[i*n:i*n+n])for i in range(n)] # output
     exit() #end recursion
 for K in range(n):
    # try every possibility. Test if they satisfy the constraints:
    # if so, move the index on. If none of them do, we'll return None.
    # if a child returns None, we'll move onto the next potential child:
    # if all of them fail it will backtrack to the next level.
    if all([
        all([
            A[i*n+column]!=K, # column constraint
            row!=column or A[i+n*i]!=K, # diagonal constraint
            row!=n-1-column or A[n*i+n-i-1]!=K # antidiagonal constraint
            ]) for i in range(row)
        ]+[
            A[row*n+i]!=K for i in range(column) # row constraint
            ]):
        Recurse(A+[K],I+1,n)

Recurse([],0,(int)(input()))

22

फंकिटॉन , गैर-प्रतिस्पर्धी

अद्यतन करें! बड़े पैमाने पर प्रदर्शन में सुधार! n = 7 अब 10 मिनट से कम समय में पूरा होता है! नीचे देखें स्पष्टीकरण!

यह लिखने में अच्छा लगा। फनसिटॉन में लिखी गई इस समस्या के लिए यह एक ब्रूट-फोर्स सॉल्वर है। कुछ तथ्य:

  • यह STDIN पर पूर्णांक को स्वीकार करता है। कोई भी बाहरी व्हाट्सएप इसे पूर्णांक के बाद एक नई रेखा सहित तोड़ता है।
  • यह संख्या 0 से n - 1 (1 से n नहीं ) का उपयोग करता है।
  • यह ग्रिड को "पीछे की ओर" भरता है, इसलिए आपको एक समाधान मिलता है जहां नीचे की पंक्ति पढ़ती 3 2 1 0है जहां शीर्ष पंक्ति पढ़ती है 0 1 2 3
  • यह n = 1 के 0लिए सही ढंग से आउटपुट (एकमात्र समाधान) है ।
  • N = 2 और n = 3 के लिए खाली आउटपुट ।
  • जब एक निर्वासन के लिए संकलित किया जाता है, तो n = 7 के लिए लगभग 8iled मिनट लगते हैं (प्रदर्शन में सुधार से एक घंटे पहले)। संकलित किए बिना (दुभाषिया का उपयोग करते हुए) इसे लगभग 1.5 गुना लंबा लगता है, इसलिए संकलक का उपयोग करना इसके लायक है।
  • एक व्यक्तिगत मील के पत्थर के रूप में, यह पहली बार है जब मैंने एक छद्म भाषा में कार्यक्रम लिखने के बिना पूरे फनसिटॉन कार्यक्रम को लिखा। मैंने इसे वास्तविक C # पहली बार में लिखा था।
  • (हालांकि, यह पहली बार नहीं है जब मैंने फ़नसिटॉन में किसी चीज़ के प्रदर्शन में बड़े पैमाने पर सुधार करने के लिए बदलाव किया है। पहली बार मैंने ऐसा किया था जो तथ्यात्मक कार्य में था। गुणन के संचालन के आदेश को स्वैप करने के कारण बहुत बड़ा बदलाव आया। कैसे गुणन एल्गोरिथ्म काम करता है । बस अगर आप उत्सुक थे।)

बिना और देरी के:

            ┌────────────────────────────────────┐           ┌─────────────────┐
            │                                  ┌─┴─╖ ╓───╖ ┌─┴─╖   ┌──────┐    │
            │                    ┌─────────────┤ · ╟─╢ Ӂ ╟─┤ · ╟───┤      │    │
            │                    │             ╘═╤═╝ ╙─┬─╜ ╘═╤═╝ ┌─┴─╖    │    │
            │                    │               └─────┴─────┘   │ ♯ ║    │    │
            │                  ┌─┴─╖                             ╘═╤═╝    │    │
            │     ┌────────────┤ · ╟───────────────────────────────┴───┐  │    │
          ┌─┴─╖ ┌─┴─╖   ┌────╖ ╘═╤═╝ ┌──────────┐         ┌────────┐ ┌─┴─╖│    │
          │ ♭ ║ │ × ╟───┤ >> ╟───┴───┘        ┌─┴─╖       │ ┌────╖ └─┤ · ╟┴┐   │
          ╘═╤═╝ ╘═╤═╝   ╘══╤═╝          ┌─────┤ · ╟───────┴─┤ << ╟─┐ ╘═╤═╝ │   │
    ┌───────┴─────┘ ┌────╖ │            │     ╘═╤═╝         ╘══╤═╝ │   │   │   │
    │     ┌─────────┤ >> ╟─┘            │       └───────┐      │   │   │   │   │
    │     │         ╘══╤═╝            ┌─┴─╖   ╔═══╗   ┌─┴─╖ ┌┐ │   │ ┌─┴─╖ │   │
    │     │           ┌┴┐     ┌───────┤ ♫ ║ ┌─╢ 0 ║ ┌─┤ · ╟─┤├─┤   ├─┤ Ӝ ║ │   │
    │     │   ╔═══╗   └┬┘     │       ╘═╤═╝ │ ╚═╤═╝ │ ╘═╤═╝ └┘ │   │ ╘═╤═╝ │   │
    │     │   ║ 1 ╟───┬┘    ┌─┴─╖       └───┘ ┌─┴─╖ │   │      │   │   │ ┌─┴─╖ │
    │     │   ╚═══╝ ┌─┴─╖   │ ɓ ╟─────────────┤ ? ╟─┘   │    ┌─┴─╖ │   ├─┤ · ╟─┴─┐
    │     ├─────────┤ · ╟─┐ ╘═╤═╝             ╘═╤═╝   ┌─┴────┤ + ╟─┘   │ ╘═╤═╝   │
  ┌─┴─╖ ┌─┴─╖       ╘═╤═╝ │ ╔═╧═╕ ╔═══╗ ┌───╖ ┌─┴─╖ ┌─┴─╖    ╘═══╝     │   │     │
┌─┤ · ╟─┤ · ╟───┐     └┐  └─╢   ├─╢ 0 ╟─┤ ⌑ ╟─┤ ? ╟─┤ · ╟──────────────┘   │     │
│ ╘═╤═╝ ╘═╤═╝   └───┐ ┌┴┐   ╚═╤═╛ ╚═╤═╝ ╘═══╝ ╘═╤═╝ ╘═╤═╝                  │     │
│   │   ┌─┴─╖ ┌───╖ │ └┬┘   ┌─┴─╖ ┌─┘           │     │                    │     │
│ ┌─┴───┤ · ╟─┤ Җ ╟─┘  └────┤ ? ╟─┴─┐   ┌─────────────┘                    │     │
│ │     ╘═╤═╝ ╘═╤═╝         ╘═╤═╝   │   │╔════╗╔════╗                      │     │
│ │       │  ┌──┴─╖ ┌┐   ┌┐ ┌─┴─╖ ┌─┴─╖ │║ 10 ║║ 32 ║    ┌─────────────────┘     │
│ │       │  │ << ╟─┤├─┬─┤├─┤ · ╟─┤ · ╟─┘╚══╤═╝╚╤═══╝ ┌──┴──┐                    │
│ │       │  ╘══╤═╝ └┘ │ └┘ ╘═╤═╝ ╘═╤═╝     │ ┌─┴─╖ ┌─┴─╖ ┌─┴─╖                  │
│ │     ┌─┴─╖ ┌─┴─╖  ┌─┴─╖  ┌─┴─╖ ╔═╧═╕     └─┤ ? ╟─┤ · ╟─┤ % ║                  │
│ └─────┤ · ╟─┤ · ╟──┤ Ӂ ╟──┤ ɱ ╟─╢   ├───┐   ╘═╤═╝ ╘═╤═╝ ╘═╤═╝                  │
│       ╘═╤═╝ ╘═╤═╝  ╘═╤═╝  ╘═══╝ ╚═╤═╛ ┌─┴─╖ ┌─┴─╖   │     └────────────────────┘
│         └─────┤      │            └───┤ ‼ ╟─┤ ‼ ║   │        ┌──────┐
│               │      │                ╘═══╝ ╘═╤═╝   │        │ ┌────┴────╖
│               │      │                      ┌─┴─╖   │        │ │ str→int ║
│               │      └──────────────────────┤ · ╟───┴─┐      │ ╘════╤════╝
│               │          ┌─────────╖        ╘═╤═╝     │    ╔═╧═╗ ┌──┴──┐
│               └──────────┤ int→str ╟──────────┘       │    ║   ║ │ ┌───┴───┐
│                          ╘═════════╝                  │    ╚═══╝ │ │ ┌───╖ │
└───────────────────────────────────────────────────────┘          │ └─┤ × ╟─┘
           ┌──────────────┐                                  ╔═══╗ │   ╘═╤═╝
╔════╗     │ ╓───╖ ┌───╖  │                              ┌───╢ 0 ║ │   ┌─┴─╖ ╔═══╗
║ −1 ║     └─╢ Ӝ ╟─┤ × ╟──┴──────┐                       │   ╚═╤═╝ └───┤ Ӂ ╟─╢ 0 ║
╚═╤══╝       ╙───╜ ╘═╤═╝         │                       │   ┌─┴─╖     ╘═╤═╝ ╚═══╝
┌─┴──╖ ┌┐ ┌───╖ ┌┐ ┌─┴──╖ ╔════╗ │                       │ ┌─┤   ╟───────┴───────┐
│ << ╟─┤├─┤ ÷ ╟─┤├─┤ << ║ ║ −1 ║ │                       │ │ └─┬─╜ ┌─┐ ┌─────┐   │
╘═╤══╝ └┘ ╘═╤═╝ └┘ ╘═╤══╝ ╚═╤══╝ │                       │ │   └───┴─┘ │   ┌─┴─╖ │
  │         └─┘      └──────┘    │                       │ └───────────┘ ┌─┤ ? ╟─┘
  └──────────────────────────────┘         ╓───╖         └───────────────┘ ╘═╤═╝
                               ┌───────────╢ Җ ╟────────────┐                │
      ┌────────────────────────┴───┐       ╙───╜            │
      │                          ┌─┴────────────────────┐ ┌─┴─╖
    ┌─┴─╖                      ┌─┴─╖                  ┌─┴─┤ · ╟──────────────────┐
    │ ♯ ║ ┌────────────────────┤ · ╟───────┐          │   ╘═╤═╝                  │
    ╘═╤═╝ │                    ╘═╤═╝       │          │     │              ┌───╖ │
┌─────┴───┘    ┌─────────────────┴─┐   ┌───┴───┐    ┌─┴─╖ ┌─┴─╖          ┌─┤ × ╟─┴─┐
│              │                 ┌─┴─╖ │   ┌───┴────┤ · ╟─┤ · ╟──────────┤ ╘═╤═╝   │
│              │ ┌───╖ ┌───╖  ┌──┤ · ╟─┘ ┌─┴─┐      ╘═╤═╝ ╘═╤═╝        ┌─┴─╖ │     │
│         ┌────┴─┤ ♭ ╟─┤ × ╟──┘  ╘═╤═╝   │ ┌─┴─╖ ┌───╖└┐ ┌──┴─╖      ┌─┤ · ╟─┘     │
│         │      ╘═══╝ ╘═╤═╝ ┌───╖ │     │ │ × ╟─┤ Ӝ ╟─┴─┤ ÷% ╟─┐    │ ╘═╤═╝ ┌───╖ │
│   ┌─────┴───┐     ┌────┴───┤ Ӝ ╟─┴─┐   │ ╘═╤═╝ ╘═╤═╝   ╘══╤═╝ │    │   └───┤ Ӝ ╟─┘
│ ┌─┴─╖ ┌───╖ │     │ ┌────╖ ╘═╤═╝   │   └───┘   ┌─┴─╖      │   │    └────┐  ╘═╤═╝
│ │ × ╟─┤ Ӝ ╟─┘     └─┤ << ╟───┘   ┌─┴─╖ ┌───────┤ · ╟───┐  │ ┌─┴─╖ ┌───╖ │    │
│ ╘═╤═╝ ╘═╤═╝         ╘══╤═╝   ┌───┤ + ║ │       ╘═╤═╝   ├──┴─┤ · ╟─┤ × ╟─┘    │
└───┤     └────┐ ╔═══╗ ┌─┴─╖ ┌─┴─╖ ╘═╤═╝ │ ╔═══╗ ┌─┴─╖ ┌─┴─╖  ╘═╤═╝ ╘═╤═╝      │
  ┌─┴─╖ ┌────╖ │ ║ 0 ╟─┤ ? ╟─┤ = ║  ┌┴┐  │ ║ 0 ╟─┤ ? ╟─┤ = ║    │     │ ┌────╖ │
  │ × ╟─┤ << ╟─┘ ╚═══╝ ╘═╤═╝ ╘═╤═╝  └┬┘  │ ╚═══╝ ╘═╤═╝ ╘═╤═╝    │     └─┤ << ╟─┘
  ╘═╤═╝ ╘═╤══╝ ┌┐     ┌┐ │     │     └───┘       ┌─┴─╖   ├──────┘       ╘═╤══╝
    │     └────┤├──┬──┤├─┘     ├─────────────────┤ · ╟───┘                │
    │          └┘┌─┴─╖└┘       │     ┌┐   ┌┐     ╘═╤═╝ ┌┐   ┌┐            │
    └────────────┤ · ╟─────────┘   ┌─┤├─┬─┤├─┐     └───┤├─┬─┤├────────────┘
                 ╘═╤═╝             │ └┘ │ └┘ │         └┘ │ └┘
                   └───────────────┘    │    └────────────┘

पहले संस्करण की व्याख्या

N = 7. को हल करने के लिए पहले संस्करण में लगभग एक घंटे का समय लगा । निम्न में से ज्यादातर बताते हैं कि इस धीमे संस्करण ने कैसे काम किया। नीचे मैं बताऊंगा कि मैंने 10 मिनट से कम समय में इसे बनाने के लिए क्या बदलाव किया।

बिट्स में एक भ्रमण

इस कार्यक्रम को बिट्स की जरूरत है। इसे बहुत सारे बिट्स की आवश्यकता होती है, और इसे सभी सही स्थानों पर उनकी आवश्यकता होती है। अनुभवी Funciton प्रोग्रामर पहले से ही जानते हैं कि यदि आपको n बिट्स की आवश्यकता है , तो आप सूत्र का उपयोग कर सकते हैं

2 ^ n-1

जिसे फंटिसटन में व्यक्त किया जा सकता है

(1 << n) - 1

मेरे प्रदर्शन का अनुकूलन करते समय, मेरे साथ यह हुआ कि मैं इस सूत्र का उपयोग करके समान मूल्य की बहुत तेज़ी से गणना कर सकता हूं:

− (−1 << n)

मुझे आशा है कि आप मुझे क्षमा करेंगे कि मैंने इस पोस्ट में सभी समीकरण ग्राफिक्स को तदनुसार अपडेट नहीं किया।

अब, मान लें कि आप बिट्स का एक सन्निहित ब्लॉक नहीं चाहते हैं; वास्तव में, आप चाहते हैं कि नियमित अंतराल पर n बिट्स हर k -th बिट की तरह हों, जैसे:

                                 LSB
                                  ↓
00000010000001000000100000010000001
                            └──┬──┘
                               k

यह जानने के बाद इसके लिए सूत्र काफी सीधा-सीधा है:

((1 << nk) - 1) / ((1 << k) - 1)

कोड में, फ़ंक्शन n और kӜ मान लेता है और इस सूत्र की गणना करता है।

उपयोग किए गए नंबरों का ट्रैक रखना

अंतिम ग्रिड में n are संख्याएँ हैं, और प्रत्येक संख्या n संभव मानों में से कोई भी हो सकती है। प्रत्येक सेल में किस संख्या की अनुमति है, इस पर नज़र रखने के लिए, हम n keep बिट्स से मिलकर एक संख्या बनाए रखते हैं , जिसमें यह दर्शाने के लिए एक बिट सेट किया जाता है कि एक विशेष मान लिया गया है। प्रारंभ में यह संख्या 0 है, जाहिर है।

एल्गोरिथ्म नीचे-दाएं कोने में शुरू होता है। "अनुमान लगाने" के बाद पहली संख्या 0 है, हमें इस तथ्य पर नज़र रखने की आवश्यकता है कि 0 को अब किसी पंक्ति, स्तंभ और विकर्ण के साथ किसी भी सेल में अनुमति नहीं है:

LSB                               (example n=5)
 ↓
 10000 00000 00000 00000 10000
 00000 10000 00000 00000 10000
 00000 00000 10000 00000 10000
 00000 00000 00000 10000 10000
 10000 10000 10000 10000 10000
                             ↑
                            MSB

इसके लिए, हम निम्नलिखित चार मानों की गणना करते हैं:

  • वर्तमान पंक्ति: हमें प्रत्येक n- बिट बिट (एक सेल) में n बिट्स की आवश्यकता है , और फिर इसे वर्तमान पंक्ति r पर स्थानांतरित करें , याद रखें कि प्रत्येक पंक्ति में n : बिट्स हैं:

    ((1 << n () −1) / ((1 << n) ²1) << n²r

  • वर्तमान स्तंभ: हम की जरूरत n हर बिट्स n ²-वें बिट (प्रति पंक्ति एक), और फिर वर्तमान स्तंभ के लिए यह बदलाव , हर स्तंभ याद शामिल n बिट्स:

    ((1 << n () −1) / ((1 << n−) −1) << n²r

  • फॉरवर्ड विकर्ण: हमें हर बिट n की आवश्यकता है ... (क्या आपने ध्यान दिया? त्वरित, यह पता लगाओ!) ... n ( n +1) -थ बिट (अच्छा किया!), लेकिन केवल अगर हम वास्तव में हैं। आगे विकर्ण:

    ((1 << n ((n + 1)) - 1) / ((1 << n (n + 1)) - 1) यदि = r

  • बैकवर्ड विकर्ण: यहां दो चीजें। सबसे पहले, हम कैसे जानते हैं कि हम पिछड़े विकर्ण पर हैं? गणितीय रूप से, स्थिति c = ( n - 1) - r है , जो कि c = n + (- r - 1) के समान है। अरे, क्या यह आपको कुछ याद दिलाता है? यह सही है, यह दो का पूरक है, इसलिए हम डिक्रिप्ट के बजाय बिटवाइज़ निगेटिव (फ़नसिटॉन में बहुत कुशल) का उपयोग कर सकते हैं। दूसरा, ऊपर दिया गया सूत्र मानता है कि हम चाहते हैं कि कम से कम महत्वपूर्ण बिट सेट किया जाए, लेकिन पिछड़े विकर्ण में हम नहीं करते हैं, इसलिए हमें इसे ऊपर स्थानांतरित करना होगा ... क्या आप जानते हैं? ... यह सही है, एन ( एन - 1)।

    ((1 << n ((n-1)) - 1) / (((1 << n (n-1)) - 1) << n (n-1) यदि c = n + ¬r

    यह भी केवल एक ही है जहाँ हम संभावित रूप से 0 से विभाजित करते हैं यदि n = 1. हालाँकि, फ़नसिटॉन परवाह नहीं करता है। 0 0 0 सिर्फ 0 है, क्या आप नहीं जानते?

कोड में, फ़ंक्शन Җ(नीचे वाला) n और एक सूचकांक लेता है (जिसमें से यह विभाजन और शेष द्वारा आर और सी की गणना करता है), इन चार मूल्यों की गणना करता है और orउन्हें एक साथ जोड़ता है।

जानवर बल एल्गोरिथ्म

जानवर-बल एल्गोरिथ्म Ӂ(शीर्ष पर फ़ंक्शन) द्वारा कार्यान्वित किया जाता है । यह n (ग्रिड आकार), अनुक्रमणिका (जहां ग्रिड में हम वर्तमान में एक संख्या रख रहे हैं ) लेता है , और लिया ( n ³ बिट्स के साथ संख्या हमें बताती है कि हम प्रत्येक कक्ष में अभी भी कौन से नंबर रख सकते हैं)।

यह फ़ंक्शन स्ट्रिंग्स का एक क्रम देता है। प्रत्येक स्ट्रिंग ग्रिड का पूर्ण समाधान है। यह एक पूर्ण विलेय है; यदि आप इसे छोड़ देते हैं तो यह सभी समाधान लौटा देगा, लेकिन यह उन्हें एक आलसी-मूल्यांकित अनुक्रम के रूप में लौटाता है।

  • यदि इंडेक्स 0 पर पहुंच गया है, तो हमने पूरी ग्रिड को सफलतापूर्वक भर दिया है, इसलिए हम एक अनुक्रम देते हैं जिसमें खाली स्ट्रिंग (एक एकल समाधान जो कोशिकाओं में से किसी को भी शामिल नहीं करता है) है। खाली स्ट्रिंग है 0, और हम लाइब्रेरी फंक्शन का उपयोग करते हैं जो कि सिंगल-एलिमेंट सीक्वेंस में बदल जाता है।

  • नीचे प्रदर्शन सुधार के तहत वर्णित चेक यहां होता है।

  • यदि इंडेक्स अभी तक 0 तक नहीं पहुंचा है, तो हम इंडेक्स प्राप्त करने के लिए इसे 1 से घटाते हैं, जिस पर अब हमें एक नंबर (कॉल करने के लिए ix ) चाहिए।

    हम 0 से n - 1 तक के मानों वाले एक आलसी अनुक्रम उत्पन्न करने के लिए उपयोग करते हैं ।

    फिर हम ɓएक मेमने के साथ (मोनैडिक बाइंड) का उपयोग करते हैं जो निम्न क्रम में करता है:

    • में प्रासंगिक बिट पर सबसे पहले नज़र लिया तय करने के लिए संख्या यहां हों या मान्य है या नहीं। हम एक संख्या जगह कर सकते मैं अगर और सिर्फ़ अगर ले लिया और (1 << ( n × ix ) << मैं ) पहले से ही सेट नहीं है। यदि यह सेट है, तो वापस लौटें 0(खाली अनुक्रम)।
    • Җवर्तमान पंक्ति, स्तंभ और विकर्ण (ओं) के अनुरूप बिट्स की गणना करने के लिए उपयोग करें । मैं इसे द्वारा स्थानांतरित कर दिया और फिर orइसे ले लिया
    • Ӂशेष कोशिकाओं के लिए सभी समाधानों को पुनः प्राप्त करने के लिए पुनरावर्ती कॉल करें , इसे नया लिया गया और निस्तारण ix । यह अधूरे तारों का एक क्रम देता है; प्रत्येक स्ट्रिंग में ix वर्ण (अनुक्रमणिका ix तक भरा ग्रिड ) होता है।
    • का प्रयोग करें ɱ(नक्शा) समाधान thusly पाया के माध्यम से जाने और प्रयोग करने में श्रेणीबद्ध करने के लिए मैं प्रत्येक के अंत करने के लिए। यदि अनुक्रमणिका n के एक से अधिक है , तो एक नई पंक्ति में जोड़ें , अन्यथा एक स्थान।

परिणाम उत्पन्न करना

N , index = n remember (याद रखें कि हम ग्रिड को पीछे से भरते हैं) और लिया = (शुरुआत में कुछ भी नहीं लिया गया है) के Ӂसाथ मुख्य प्रोग्राम कॉल (ब्रूट फॉरेसर )। यदि इसका परिणाम एक खाली अनुक्रम है (कोई समाधान नहीं मिला), तो रिक्त स्ट्रिंग को आउटपुट करें। अन्यथा, पहले स्ट्रिंग को अनुक्रम में आउटपुट करें। ध्यान दें कि इसका मतलब है कि यह अनुक्रम के पहले तत्व का मूल्यांकन करेगा, यही कारण है कि सॉल्वर तब तक जारी नहीं होता है जब तक कि यह सभी समाधान नहीं मिला है।

प्रदर्शन में सुधार

(उन लोगों के लिए जो पहले से ही स्पष्टीकरण के पुराने संस्करण को पढ़ते हैं: कार्यक्रम अब अनुक्रमों के अनुक्रम को उत्पन्न नहीं करता है जिन्हें अलग से आउटपुट के लिए एक स्ट्रिंग में बदलने की आवश्यकता होती है; यह सीधे तार के अनुक्रम को उत्पन्न करता है। मैंने तदनुसार स्पष्टीकरण संपादित किया है। लेकिन यह मुख्य सुधार नहीं था। यहाँ यह आता है।]

मेरी मशीन पर, पहले संस्करण के संकलित निर्गमन को n = 7. हल करने में बहुत अधिक ठीक 1 घंटा लगता था। यह 10 मिनट की दी गई समय सीमा के भीतर नहीं था, इसलिए मैंने आराम नहीं किया। (ठीक है, वास्तव में, कारण कि मैं आराम नहीं करता था, क्योंकि मुझे यह विचार था कि इसे बड़े पैमाने पर कैसे गति दें।)

जैसा कि ऊपर वर्णित एल्गोरिथ्म इसकी खोज को रोक देता है और हर बार यह एक सेल का सामना करता है जिसमें लेई गई संख्या में सभी बिट्स सेट होते हैं, यह दर्शाता है कि इस सेल में कुछ भी नहीं डाला जा सकता है।

हालांकि, एल्गोरिथ्म जारी रहेगा क्षुद्रता के साथ ग्रिड को भरने के लिए अप करने के लिए सेल, जिसमें उन सभी बिट्स सेट कर रहे हैं। यह बहुत तेजी से होगा अगर यह किसी भी अभी तक भरे-से-भरे सेल के रूप में जल्द से जल्द बंद हो सकता है , जिसमें पहले से ही सभी बिट्स सेट हैं, जो पहले से ही इंगित करता है कि हम बाकी ग्रिड को कभी भी हल नहीं कर सकते हैं चाहे हम कितनी भी संख्या में डाल दें। यह। लेकिन आप कैसे कुशलता से जांचते हैं कि क्या किसी भी सेल ने अपने एन बिट्स को उन सभी के माध्यम से जाने के बिना सेट किया है?

ली गई संख्या में प्रति सेल एक बिट जोड़ने से चाल शुरू होती है । इसके बजाय जो ऊपर दिखाया गया था, वह अब इस तरह दिखता है:

LSB                               (example n=5)
 ↓
 10000 0 00000 0 00000 0 00000 0 10000 0
 00000 0 10000 0 00000 0 00000 0 10000 0
 00000 0 00000 0 10000 0 00000 0 10000 0
 00000 0 00000 0 00000 0 10000 0 10000 0
 10000 0 10000 0 10000 0 10000 0 10000 0
                                       ↑
                                      MSB

के बजाय n ³, वहाँ अब कर रहे हैं n ² ( n + 1) इस संख्या में बिट्स। वर्तमान पंक्ति / स्तंभ / विकर्ण को पॉपुलेट करने वाले फ़ंक्शन को तदनुसार बदल दिया गया है (वास्तव में, पूरी तरह से ईमानदार होने के लिए फिर से लिखा गया)। यह फ़ंक्शन अभी भी प्रति सेल केवल n बिट्स को आबाद करेगा , इसलिए हमने जो अतिरिक्त बिट जोड़ा है वह हमेशा रहेगा 0

अब, मान लें कि हम गणना के माध्यम से आधे रास्ते पर हैं, हमने सिर्फ एक 1को मध्य सेल में रखा है , और लिया गया नंबर कुछ इस तरह दिखता है:

                 current
LSB              column           (example n=5)
 ↓                 ↓
 11111 0 10010 0 01101 0 11100 0 11101 0
 00011 0 11110 0 01101 0 11101 0 11100 0
 11111 0 11110 0[11101 0]11100 0 11100 0    ← current row
 11111 0 11111 0 11111 0 11111 0 11111 0
 11111 0 11111 0 11111 0 11111 0 11111 0
                                       ↑
                                      MSB

जैसा कि आप देख सकते हैं, टॉप-लेफ्ट सेल (इंडेक्स 0) और मिडिल-लेफ्ट सेल (इंडेक्स 10) अब असंभव हैं। हम इसे सबसे कुशलता से कैसे निर्धारित करते हैं?

एक संख्या पर विचार करें जिसमें प्रत्येक सेल का 0 वां बिट सेट किया गया है, लेकिन केवल वर्तमान सूचकांक तक। इस तरह की संख्या परिचित सूत्र का उपयोग करके गणना करना आसान है:

((1 << (n + 1) i) - 1) / ((1 << (n + 1)) - 1)

यदि हम इन दो संख्याओं को एक साथ जोड़ दें तो हमें क्या मिलेगा?

LSB                                               LSB
 ↓                                                 ↓
 11111 0 10010 0 01101 0 11100 0 11101 0           10000 0 10000 0 10000 0 10000 0 10000 0        ╓───╖
 00011 0 11110 0 01101 0 11101 0 11100 0     ║     10000 0 10000 0 10000 0 10000 0 10000 0            ║
 11111 0 11110 0 11101 0 11100 0 11100 0  ═══╬═══  10000 0 10000 0 00000 0 00000 0 00000 0  ═════   ╓─╜
 11111 0 11111 0 11111 0 11111 0 11111 0     ║     00000 0 00000 0 00000 0 00000 0 00000 0  ═════   ╨
 11111 0 11111 0 11111 0 11111 0 11111 0           00000 0 00000 0 00000 0 00000 0 00000 0          o
                                       ↑                                                 ↑
                                      MSB                                               MSB

परिणाम है:

             OMG
              ↓
        00000[1]01010 0 11101 0 00010 0 00011 0
        10011 0 00001 0 11101 0 00011 0 00010 0
═════   00000[1]00001 0 00011 0 11100 0 11100 0
═════   11111 0 11111 0 11111 0 11111 0 11111 0
        11111 0 11111 0 11111 0 11111 0 11111 0

जैसा कि आप देख सकते हैं, जो अतिरिक्त बिट में जोड़ता है, जो हमने जोड़ा है, लेकिन केवल अगर उस सेल के लिए सभी बिट्स सेट हैं! इसलिए, जो कुछ करना बाकी है, वह उन बिट्स (ऊपर सूत्र के रूप में, लेकिन << n ) को बाहर निकालने के लिए है और यदि परिणाम 0 है तो जांच करें:

00000[1]01010 0 11101 0 00010 0 00011 0    ╓╖    00000 1 00000 1 00000 1 00000 1 00000 1         ╓─╖ ╓───╖
10011 0 00001 0 11101 0 00011 0 00010 0   ╓╜╙╖   00000 1 00000 1 00000 1 00000 1 00000 1        ╓╜ ╙╖    ║
00000[1]00001 0 00011 0 11100 0 11100 0   ╙╥╥╜   00000 1 00000 1 00000 0 00000 0 00000 0  ═════ ║   ║  ╓─╜
11111 0 11111 0 11111 0 11111 0 11111 0   ╓╜╙╥╜  00000 0 00000 0 00000 0 00000 0 00000 0  ═════ ╙╖ ╓╜  ╨
11111 0 11111 0 11111 0 11111 0 11111 0   ╙──╨─  00000 0 00000 0 00000 0 00000 0 00000 0         ╙─╜   o

यदि यह शून्य नहीं है, तो ग्रिड असंभव है और हम रोक सकते हैं।


3
पवित्र बकवास। यार, यह प्रभावशाली है।
देउसोवी

1
मैं दूसरी @ देसुवी की टिप्पणी, इस में बहुत प्रयास करने के लिए धन्यवाद
hargasinski

7

हास्केल, 790 * 0.80 = 632 बाइट्स

import Data.List
import Control.Monad
import Data.Array
s r=let{h as bs=[(a,b)|a<-as,b<-bs];(&)m k=(\(Just x)->x)$lookup k m;j=Just;n=Nothing;c=[1..r];q=delete;u=h[1..r]c;o=[(s,[u |u<-[h[1..r][c]|c<-c]++[h[r]c|r<-[1..r]]++[zip[1..r][1..r],zip[1..r][r,r-1..1]],s`elem`u])|s<-u];k=foldr(>=>)j;a p d g0=k[t p d2|d2<-q d(g0!p)]g0;t p d g0|not(d`elem`(g0!p))=j g0|[]<-v=n|[d2]<-v=k[t s2 d2|s2<-[(s,delete s$nub(concat(o&s)))|s<-u]&p]g1|True=k[l[s|s<-u,not(d`elem`v)]|u<-o&p]g1 where{v=q d(g0!p);g1=g0//[(p,v)];l[]_=n;l[d3]g=a d3 d g;l _ r=j r};w g0|and[case g0!s of{[_]->True;_->False}|s<-u]=j g0|True=msum[a s' d g0>>=w|d<-g0!s']where(_,s')=minimumBy(\(a,_)(b,_)->compare a b)[(l,s)|s<-u,let v=g0!s;l=length v,l>1]}in fmap(fmap(\[x]->x))$w$array((1,1),(r,r))[((i,j),[1..r])|i<-[1..r],j<-[1..r]]

मैंने देखा कि यह समस्या सुडोकू के समान है। मुझे याद है कि एक पुराना सुडोकू सॉल्वर जिसे मैंने हास्केल में पायथन में इसी अन्य पर आधारित लिखा था । यह मेरा पहला कोड गोल्फ पोस्ट या प्रयास है।

क्योंकि यह देता है यह बोनस को पूरा Nothingकरने के लिए n=2,3और Just <result>के लिए n>=4है, जहां <result>अभिन्न मूल्यों की एक 2 डी सरणी है।

ऑनलाइन दुभाषिया के लिए यहाँ देखें । वह कोड वास्तव में पोस्ट के एक से अधिक लंबा है क्योंकि ऑनलाइन दुभाषिया के पास अधिक सख्त आवश्यकताएं हैं जैसे कि एक पूरा कार्यक्रम बनता है (नियम कहते हैं कि सबमिशन एक फ़ंक्शन हो सकता है)। यह सबमिशन एक फ़ंक्शन तर्क के रूप में इनपुट लेता है।


1
कुछ त्वरित सुझाव: ए) आप परिभाषित करते हैं c=[1..r], इसलिए आप इसे oऔर भीतर उपयोग कर सकते हैं w। b) minimumBy(\(a,_)(b,_)->compare a b)[...]है head$sortOn fst[...]। ग) vमें v=g0!sकेवल एक बार उपयोग किया जाता है, इसलिए इसे बिल्कुल भी परिभाषित न करें l=length$g0!s:। d) आपके पास अभी भी कुछ दो अक्षर पैरामीटर नाम हैं। ई) के Trueसाथ 1<2और Falseसाथ बदलें 2<1। च) and[case g0!s of{[_]->True;_->False}|s<-u]है all((==1).length.(g0!))u
nimi

त्वरित युक्तियां, भाग II: g) (&)m k=को infix परिभाषित किया जा सकता है m&k=:। ज) not(dहाथी (g0!p))है notElem d$g0!p। i) concat(...)है id=<<(...)। j) hउदाहरण के लिए एक infix ऑपरेटर का उपयोग करें as%bs=
नीमी

3
त्वरित मेटा टिप्स: आप दोहरे बैकटिक्स का उपयोग करके सही तरीके से इसमें बैकटिक्स कोड को सीमांकित कर सकते हैं ​``like`this``​!
लिन

4

पायथ, 41 बाइट्स

#Km.SQQI.AmqQl{d+.TK.Tm,@@Kdd@@Kt-QddQB;K
#                                      ;   # while(True)
 Km.SQQ                                    # K = random QxQ 2d list
       I                               ;   # if ...
        .A                                 # all of...
          m                          Q     # map(range(Q))...
                +                          # concat
                 .TK                       # transpose K
                    .Tm,@@Kdd@@Kt-Qdd      # diagonals of K
                      m             d      # map(range(d))
                       ,                   # 2-elem list of...
                        @@Kdd              # K[n][n]
                             @@Kt-Qd       # and K[len(K)-n-1][n]
                    .T                     # transpose
           qQl{d                           # subarrays have no dups...
                                      B;   # ... then, break
                                        K  # output final result

क्रूर बल ftw!

चूंकि यह मूल रूप से यादृच्छिक फेरबदल की कोशिश करता रहता है जब तक कि यह काम नहीं करता है (अच्छी तरह से, यह कोशिश करता रहता है n * [shuffle(range(n))]), यह वास्तव में, वास्तव में लंबा समय लेता है। यहां कुछ परीक्षण रन दिए गए हैं जिससे आपको यह अंदाजा हो सकता है कि इसमें कितना समय लगता है:

llama@llama:~$ time echo 4 | pyth <(echo '#Km.SQQI.AmqQl{d+.TK.Tm,@@Kdd@@Kt-QddQB;K')               
[[2, 1, 0, 3], [0, 3, 2, 1], [3, 0, 1, 2], [1, 2, 3, 0]]
echo 4  0.00s user 0.00s system 0% cpu 0.001 total
pyth <(echo '#Km.SQQI.AmqQl{d+.TK.Tm,@@Kdd@@Kt-QddQB;K')  0.38s user 0.00s system 96% cpu 0.397 total

यह केवल 4x4 है, और यह आधे से थोड़ा कम आधे सेकंड में चलता है। मैं वास्तव में धोखा दे रहा हूं क्योंकि यह कुछ परीक्षणों में से सबसे अच्छा है- उनमें से अधिकांश एक या दो से अधिक लेते हैं।

मुझे अभी तक 5x5 पर एक समय मिल गया है (यह एक बार पूरा करने के लिए दौड़ा, लेकिन यह एक आरपीएल में था और मैं इसे समय पर नहीं कर रहा था)।

ध्यान दें कि इस उत्तर को पोस्ट करने के बाद समय सीमा के लिए नियम को केवल प्रश्न में संपादित किया गया था।


मुझे लगता है कि यह दस मिनट के भीतर 7x7 नहीं कर सकता है? ^ ^
लिन

@ मौरिस, कभी-कभी ऐसा हो सकता है ...;) कि एक आवश्यकता मुझे याद आती है? मुझे प्रश्न में समय सीमा का उल्लेख करते हुए कुछ भी दिखाई नहीं दे रहा है।
दरवाज़े

मैं इसे टिप्पणियों में देखता हूं, ( नई टिप्पणी नहीं , 12 घंटे पहले)
edc65

इसके बारे में क्षमा करें, मैंने तब तक इसके बारे में नहीं सोचा था जब तक कि किसी ने इसका उल्लेख नहीं किया, मैं अब चुनौती को संपादित
करूंगा

1
आपके टिप्पणी संस्करण में सार ASCII कला के लिए +1। :)
इल्मारी करोनें

3

एसडब्ल्यूआई-प्रोलॉग, 326 * 0.80 = 260.8 बाइट्स

:-use_module(library(clpfd)).
a(N):-l(N,R),m(l(N),R),append(R,V),V ins 1..N,transpose(R,C),d(0,R,D),maplist(reverse,R,S),d(0,S,E),m(m(all_distinct),[R,C,[D,E]]),m(label,R),m(p,R).
l(L,M):-length(M,L).
d(X,[H|R],[A|Z]):-nth0(X,H,A),Y is X+1,(R=[],Z=R;d(Y,R,Z)).
p([H|T]):-write(H),T=[],nl;write(' '),p(T).
m(A,B):-maplist(A,B).

संपादित करें: @Mat के लिए 16 बाइट्स सहेजे गए

प्रयोग

के a(5).लिए अपने दुभाषिया में कॉल करें N=5। यह रिटर्न falseके लिए N=2या N=3

चूंकि यह सीएलपीएफडी पुस्तकालय का उपयोग करता है इसलिए यह शुद्ध ब्रूटफोर्स नहीं है। यह प्रोग्राम N=20मेरे कंप्यूटर पर लगभग 15 सेकंड के लिए समाधान पा सकता है ।

असंगठित + स्पष्टीकरण:

यह मूल रूप से सुडोकू सॉल्वर की तरह काम करता है, सिवाय इसके कि ब्लॉक की बाधाओं को विकर्ण बाधाओं के साथ बदल दिया जाता है।

:-use_module(library(clpfd)).      % Import Constraints library

a(N):-
    l(N,R),                        % R is a list of length N
    maplist(l(N),R),               % R contains sublists, each of length N
    append(R,V),                   
    V ins 1..N,                    % Each value in the matrix is between 1 and N
    maplist(all_distinct,R),       % Values must be different on each row
    transpose(R,C),
    maplist(all_distinct,C),       % Values must be different on each column
    d(0,R,D),
    maplist(reverse,R,S),          
    d(0,S,E),
    all_distinct(D),               % Values must be different on the diagonal
    all_distinct(E),               % Values must be different on the "anti"-diagonal
    maplist(label,R),              % Affects actual values to each element
    maplist(p,R).                  % Prints each row

l(L,M):-length(M,L).               % True if L is the length of M

d(X,[H|R],[A|Z]):-nth0(X,H,A),Y is X+1,(R=[],Z=R;d(Y,R,Z)). % True if the third argument is the diagonal of the second argument

p([H|T]):-write(H),T=[],nl;write(' '),p(T).  % Prints a row separated by spaces and followed by a new line

बहुत अच्छा! आप के साथ एक बाइट बचा सकता है:maplist(maplist(all_distinct), [R,C,D,E])
चटाई

1
@mat सुझाव के लिए धन्यवाद, 16 बाइट्स बचाता है। मुझे [R,C,[D,E]]हालांकि उपयोग करने की आवश्यकता है , क्योंकि Eऔर Dसरल सूचियां हैं।
घातक

सही है, बहुत अच्छा समाधान!
चटाई 15

2
@ जानिए बस आपको बता दें, आपका समाधान सबसे प्रभावशाली था क्योंकि यह एकमात्र ऐसा N=20
तरीका है जिसे

1
@ धन्यवाद! लेकिन यह ज्यादातर प्रोलॉग के अद्भुत सीएलपीएफडी पुस्तकालय के कारण है, जो इन जैसी समस्याओं में भारी उठाने का काम करता है :)
घातक

2

CJam, 87 बाइट्स - 20% बोनस = 69.6 बाइट्स

qi__"@I/l
ŤˏūȻ
܀ᅀ൹৽჈͚
㑢鴑慚菥洠㬝᚜
"N/=:i0+\,m!f=`1LL](4e<=

उत्तर को हार्डकोड करता है। कुछ unprintables शामिल हैं। के N = 1माध्यम से काम करता है N = 8

मूल रूप से, उस रहस्यमय स्ट्रिंग में प्रत्येक पंक्ति में range(N)यूनिकोड वर्णों के रूप में एन्कोडेड सूचियों की सूची शामिल है ।

=:i0+\,m!f=क्रमांकन की सूची में अनुक्रमित, पहले सूचकांक की सूची के अंत में 0 जोड़कर, नीचे की पंक्ति का प्रतिनिधित्व करना 0 1 2 ... N-1। के लिए N < 4, परिणामी 2D सरणी बकवास है।

`1LL]एक सूची बनाता है [N, pretty output, 1, "", ""]। फिर, (4e<=पहले तत्व को इस सूची से बाहर निकालता है N, और min(N, 4) % 4शेष तत्व से वें तत्व को पुनः प्राप्त करता है। इसके लिए N >= 4, यह आउटपुट है, और अन्यथा यह पहले तीन मामलों के लिए विशेष-केस आउटपुट है।

इसे यहाँ आज़माएँ


0

सी ++, 672 * 0.80 645 * 0.80 = 516 बाइट्स

#include <iostream>
int **b,**x,**y,*d,*a,n;
#define R(i) for(i=0;i<n;i++){
#define E(e) e=new int[n];
int f(int c,int r) {int i=0,p=c-1;if(r>=n)return 1;if(c == n + 1)return f(1,r+1);R(i)int m=r==i,s=r+i==n-1;if(!b[r][i]&&!x[r][p]&&!(m&&d[p])&&!(s&&a[p])&&!y[i][p]){b[r][i]=c;x[r][p]=1;y[i][p]=1;if(m)d[p]=1;if(s)a[p]=1;if(f(c+1,r))return 1;b[r][i]=0;x[r][p]=0;y[i][p]=0;if(m)d[p]=0;if(s)a[p]=0;}}return 0;}
int main(){std::cin>>n;int i=0,j=0;b=new int*[n];x=new int*[n];y=new int*[n];E(d);E(a);R(i)E(b[i]);E(x[i]);E(y[i]); d[i]=0;a[i]=0;R(j)b[i][j]=0;x[i][j]=0;y[i][j]=0;}}if(f(1,0)){R(i)R(j)std::cout<<b[i][j];}std::cout<<std::endl;}}}

इसे यहाँ ऑनलाइन आज़माएँ

चूंकि कुछ उत्तर पहले से ही पोस्ट किए जा चुके हैं, मैंने सोचा कि मैं उन कोडों के गोल्फ संस्करण को पोस्ट करूंगा जिनका उपयोग मैंने उदाहरणों के लिए आउटपुट उत्पन्न करने के लिए किया था। यह मेरा पहली बार जवाब है , इसलिए सभी प्रतिक्रिया का स्वागत किया गया है। :)

असंगठित + स्पष्टीकरण:

अनिवार्य रूप से, कोड एक समाधान के लिए मजबूर है। यह पहली पंक्ति में शुरू होता है, 0. यह पहले स्थान पर शुरू होता है, अगर वह स्पॉट सभी चेक पास करता है, तो यह अगले नंबर पर जाता है। यदि यह पंक्ति को भरता है, तो यह अगली पंक्ति पर चला जाता है। यदि यह सभी पंक्तियों में किया गया है, तो इसका मतलब है कि एक समाधान मिल गया है। यदि स्पॉट सभी चेक पास नहीं करता है, तो यह अगले स्पॉट पर जाता है। यदि यह पंक्ति में किया जाता है, तो यह पीछे हटता है, पिछली पंक्तियों में से एक संख्या में एक समाधान को संभव होने से रोकता है।

#include <iostream>

// global variables to save bytes on passing these are function arguments
int **b, // this will store the state of the board
    **x, // if x[i][j] is true, row i of b contains the number j
    **y, // if y[i][j] is true, column i of b contains the number j
    *d,  // if d[i] the main diagonal of b contains i
    *a,  // if a[i] the antidiagonal of a contains i
    n;

// preprocessor to save bytes on repeated statements
#define R(i) for(i=0;i<n;i++){
#define E(e) e=new int[n];

// Recursively looks for a solution 
// c - the current number to insert in row r
// r - the current row to fill
int f (int c, int r) {
        int i=0,p=c-1;
        if (r >= n) return 1;             // we are done
        if (c == n + 1) return f(1,r+1);  // this row is full, move to the next row
        R(i)                              // go through the positions in this row,
                                                                            // trying to fill them with c
                int m=r==i, s=r+i==n-1;   // check if this position (r,i) is on ones
                                                                            // of the diagonals
                // if this spot isn't filled, and the row (r), column (i) and diagonals
                // (if it's on the diagonal) doesn't contain the number, fill the spot
                if (!b[r][i] && !x[r][p] && !(m&&d[p]) && !(s&&a[p]) && !y[i][p]) {
                        // fill the spot, and indicate that this row, column and diagonals 
                        // contain this number, c
                        b[r][i]=c; x[r][p]=1; y[i][p]=1;
                        if (m) d[p]=1; if (s)a[p]=1;

                        // move onto to the next number, if you find a solution, stop
                        if (f(c+1,r)) return 1;

                        // with this number in this spot, a solution is impossible, clear
                        // its, and clear the checks
                        b[r][i]=0; x[r][p]=0; y[i][p]=0;
                        if (m) d[p]=0; if (s) a[p]=0;
                }
        }

        return 0; // a solution wasn't found
}

int main() {
        std::cin >> n; // get n from STDIN

        // initialization 
        int i=0,j=0;
        b=new int*[n]; x=new int*[n]; y=new int*[n];
        E(d); E(a);
        R(i)
                E(b[i]); E(x[i]); E(y[i]); // initialization the inner arrays of b, x, y
                d[i]=0; a[i]=0;

                R(j)
                        b[i][j]=0; x[i][j]=0; y[i][j]=0; // ensure each point is initialized as 0
                }
        }

        // find a solution starting at the top-left corner and print it if it finds one
        if (f(1,0)) {
                R(i)
                        R(j)
                                std::cout<<b[i][j];
                        }
                        std::cout<<std::endl;
                }
        }
}

कोड को पुन: व्यवस्थित करने के बाद, मैंने महसूस किया कि कुछ चेक आवश्यक नहीं हो सकते हैं, जैसे कि if (x[r][p]) return f(c+1,r);। मैं इसे छोटा करने पर काम कर रहा हूं।
hargasinski

0

क्लोजर, (215 + 258) * 0.8 = 378.4 (174 + 255) * 0.8 = 343.2

दो भागों में विभाजित करें: त्रुटि की गणना Sऔर एक अनाम फ़ंक्शन जो तबू खोज के माध्यम से वास्तविक अनुकूलन करता है ।

अपडेट: कम S(समूहों के भीतर अलग-अलग मूल्य), कम इष्टतम प्रारंभिक स्थिति (कोई फेरबदल)।

(defn S[I n](count(mapcat set(vals(apply merge-with concat(flatten(for[R[(range n)]i R j R v[[(I(+(* n i)j))]]][{[1 i]v}{[2 j]v}(if(= i j){3 v})(if(=(- n 1 i)j){4 v})])))))))
#(if-let[s({1[0]2()3()}%)]s(loop[I(vec(for[R[(range %)]i R j R]i))P #{}](let[[s I](last(sort-by first(for[R[(range(count I))]i R j R I[(assoc(assoc I i(I j))j(I i))]:when(not(P I))][(S I %)I])))](if(=(*(+(* % 2)2)%)s)(partition % I)(recur I(conj P I))))))

4, 5, 6 और 7 रन के लिए सिंगल कोर बेंचमार्क (मिलीसेकंड में) 3 बार:

[[  131.855337   132.96267    138.745981]
 [ 1069.187325  1071.189488  1077.339372]
 [ 9114.736987  9206.65368   9322.656693]
 [36546.309408 36836.567267 36928.346312]]

मूल:

(defn S[I n](apply +(flatten(for[p(concat(partition n I)(for[p(apply map vector(partition n(range(count I))))](map I p))[(take-nth(inc n)I)][(rest(butlast(take-nth(dec n)I)))])](remove #{1}(vals(frequencies p)))))))
#(if-let[s({1[0]2()3()}%)]s(loop[I(vec(flatten(map shuffle(repeat %(range %)))))P #{}](let[[s I](first(sort-by first(for[R[(range(count I))]i R j R I[(assoc(assoc I i(I j))j(I i))]:when(not(P I))][(S I %)I])))](if(= s 0)(partition % I)(recur I(conj P I))))))

काश S, यह छोटा होता, लेकिन क्योंकि यह केवल एक से अधिक बार होने वाली घटनाओं को गिनता है / रुकने की कसौटी सरल है (= s 0)

कई सीपीयू साइकिल गैर-उपयोगी स्वैप के लिए बर्बाद हो जाते हैं, उदाहरण के लिए अगर यह आपके 2साथ स्वैप करता है तो स्कोर में सुधार नहीं करता है 2, और आपको पंक्तियों के बीच संख्या स्वैप करने की आवश्यकता नहीं है क्योंकि इन सभी को शुरू करने के लिए अलग-अलग मान हैं।

इंटेल 6700K (मिलीसेकंड में) के साथ बेंचमार्क:

(defn S[I n]( ... )
(def F #( ... ))

(defmacro mytime[expr]
  `(let [start# (. System (nanoTime)) ret# ~expr]
     (/ (double (- (. System (nanoTime)) start#)) 1000000.0)))

(pprint(vec(for[n[4 5 6 7]](vec(sort(repeatedly 5 #(mytime (F n)))))))

[[  43.445902   45.895107   47.277399   57.681634    62.594037]
 [ 222.964582  225.467034  240.532683  330.237721   593.686911]
 [2285.417473 2531.331068 3002.597908 6361.591714  8331.809410]
 [3569.62372  4779.062486 5725.905756 7444.941763 14120.796615]]

इसके साथ बहुआयामी pmap:

[[   8.881905  16.343714   18.87262  18.9717890   22.194430]
 [  90.963870 109.719332  163.00299  245.824443  385.365561]
 [ 355.872233 356.439256 1534.31059 2593.482767 3664.221550]
 [1307.727115 1554.00260 2068.35932 3626.878526 4029.543011]]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.