संकलन-समय पर आठ रानियों की समस्या का समाधान करें [बंद]


39

आप संकलन-समय पर आठ रानियों की पहेली हल कर सकते हैं ?

कोई भी उपयुक्त आउटपुट स्वरूप चुनें।

मुझे विशेष रूप से C ++ टेम्पलेट मेटाप्रोग्रामिंग समाधान में दिलचस्पी है, लेकिन आप ऐसी भाषाओं का उपयोग कर सकते हैं, जिनके समान निर्माण हैं, जैसे, उदाहरण के लिए, हास्केल का प्रकार प्रणाली।

आदर्श रूप से आपका मेटाफ्राम सभी समाधानों का उत्पादन करेगा। कोई हार्डकोडिंग नहीं।


आप विभिन्न भाषाओं की अनुमति क्यों नहीं देते?
उपयोगकर्ता अज्ञात

@user: क्योंकि मुझे C ++ TMP समाधान में दिलचस्पी है। यदि आप किसी ऐसी भाषा के बारे में जानते हैं, जिसमें बहुत समान रचनाएँ हैं, तो एक उत्तर पोस्ट करने के लिए स्वतंत्र महसूस करें, हालांकि।
आर। मार्टिनो फर्नांडिस

क्या मैं हास्केल की प्रकार प्रणाली का उपयोग कर सकता हूं? AFAIK यह पूरा होना चाहिए।
फ़ूजएक्सएक्सएल

@FUZxxl: हाँ। मैं प्रश्न संपादित करूंगा।
आर। मार्टिनो फर्नांडिस

क्या यह जानवर-बल-समाधान करने के लिए पर्याप्त है?
को बंद करना

जवाबों:


50

मेरे मेटा-प्रोग्राम में सभी 92 समाधान मिलते हैं। उन्हें त्रुटि संदेशों के रूप में मुद्रित किया जाता है:

error: 'solution' is not a member of 'print<15863724>'

इसका मतलब है पहली रानी को y = 1, दूसरी को y = 5, तीसरी को y = 8 और इसी तरह रखा जाना चाहिए।

सबसे पहले, कुछ उपयोगी मेटा-फ़ंक्शंस:

template <typename T>
struct return_
{
    typedef T type;
};

template <bool Condition, typename Then, typename Else>
struct if_then_else;

template <typename Then, typename Else>
struct if_then_else<true, Then, Else> : return_<Then> {};

template <typename Then, typename Else>
struct if_then_else<false, Then, Else> : return_<Else> {};

template <int N>
struct constant
{
    enum { value = N };
};

template <int N>
struct print
{
    // empty body -> member access yields a compiler error involving N
};

फिर, दो दिलचस्प मेटा-फ़ंक्शंस (एकवचन और बहुवचन पर ध्यान दें):

template <int queens, int rows, int sums, int difs, int x, int y>
struct put_queen;

template <int queens, int rows, int sums, int difs, int x>
struct put_queens : constant
     < put_queen<queens, rows, sums, difs, x, 1>::value
     + put_queen<queens, rows, sums, difs, x, 2>::value
     + put_queen<queens, rows, sums, difs, x, 3>::value
     + put_queen<queens, rows, sums, difs, x, 4>::value
     + put_queen<queens, rows, sums, difs, x, 5>::value
     + put_queen<queens, rows, sums, difs, x, 6>::value
     + put_queen<queens, rows, sums, difs, x, 7>::value
     + put_queen<queens, rows, sums, difs, x, 8>::value > {};

template <int queens, int rows, int sums, int difs, int x, int y>
struct put_queen : if_then_else<
    rows & (1 << y) || sums & (1 << (x + y)) || difs & (1 << (8 + x - y)),
    constant<0>,
    put_queens<queens * 10 + y, rows | (1 << y), sums | (1 << (x + y)),
               difs | (1 << (8 + x - y)), x + 1>
>::type {};

चर queensअब तक बोर्ड पर रखी गई रानियों के y निर्देशांक को संग्रहीत करता है। निम्नलिखित तीन चर पंक्तियों और विकर्णों को संग्रहीत करते हैं जो पहले से ही क्वीन्स द्वारा कब्जा कर लिया गया है। xऔर yस्व-व्याख्यात्मक होना चाहिए।

if_then_elseवर्तमान स्थिति अवरुद्ध है या नहीं, यह जांचने के लिए पहला तर्क । यदि यह है, तो पुनरावृत्ति रुक ​​जाती है (अर्थहीन) परिणाम 0.। अन्यथा, रानी को बोर्ड पर रखा गया है, और प्रक्रिया अगले कॉलम के साथ जारी है।

जब x 8 पर पहुंचता है, तो हमें एक समाधान मिला है:

template <int queens, int rows, int sums, int difs>
struct put_queens<queens, rows, sums, difs, 8>
{
    enum { value = print<queens>::solution };
};

चूंकि printटेम्पलेट में कोई सदस्य नहीं है solution, इसलिए कंपाइलर एक त्रुटि उत्पन्न करता है।

और अंत में, प्रक्रिया शुरू करने के लिए, हम valueखाली बोर्ड के सदस्य का निरीक्षण करते हैं:

int go = put_queens<0, 0, 0, 0, 0>::value;

पूरा कार्यक्रम विचारधारा पर पाया जा सकता है ।


2
मुझे पसंद है: 1) डेटा स्टोर करने के लिए बिटफिल्ड का उपयोग करना, 2) आउटपुट विधि का विकल्प।
आर। मार्टिनो फर्नांडिस

7
एक उत्तर के लिए बहुत अधिक अजीब।
3

यह भी x मानों का उत्पादन नहीं करना चाहिए?
डेडएमजी जूल

2
@DeadMG प्रत्येक रानी स्थान का x- मान स्ट्रिंग (1-8) में अपनी स्थिति है।
Briguy37

22

मैं एक समाधान के साथ आया जो हास्केल प्रकार प्रणाली का उपयोग करता है। मैंने मूल्य स्तर पर समस्या के मौजूदा समाधान के लिए थोड़ा सा googled , इसे थोड़ा बदल दिया, और फिर इसे प्रकार स्तर तक उठा लिया। इस पर लगाम लगी। मुझे GHC एक्सटेंशन का एक गुच्छा भी सक्षम करना पड़ा।

सबसे पहले, चूंकि पूर्णांक को टाइप स्तर पर अनुमति नहीं है, इसलिए मुझे इस समय प्राकृतिक संख्याओं को एक बार फिर से बढ़ाने की आवश्यकता है, इस प्रकार:

data Zero -- type that represents zero
data S n  -- type constructor that constructs the successor of another natural number
-- Some numbers shortcuts
type One = S Zero
type Two = S One
type Three = S Two
type Four = S Three
type Five = S Four
type Six = S Five
type Seven = S Six
type Eight = S Seven

मैंने जिस एल्गोरिथम को अनुकूलित किया है, वह भीलों पर परिवर्धन और घटाव करता है, इसलिए मुझे इन पर भी लगाम कसनी थी। प्रकार के स्तर पर कार्य को प्रकारों के लिए रिज़ॉर्ट के साथ परिभाषित किया जाता है। इसके लिए कई पैरामीटर प्रकार की कक्षाओं और कार्यात्मक निर्भरताओं के लिए एक्सटेंशन की आवश्यकता होती है। टाइप कक्षाएं "मान वापस नहीं" कर सकती हैं, इसलिए हम PROLOG के समान एक अतिरिक्त पैरामीटर का उपयोग करते हैं।

class Add a b r | a b -> r -- last param is the result
instance Add Zero b b                     -- 0 + b = b
instance (Add a b r) => Add (S a) b (S r) -- S(a) + b = S(a + b)

class Sub a b r | a b -> r
instance Sub a Zero a                     -- a - 0 = a
instance (Sub a b r) => Sub (S a) (S b) r -- S(a) - S(b) = a - b

पुनर्संयोजन को वर्ग के सिद्धांतों के साथ लागू किया जाता है, इसलिए वाक्यविन्यास थोड़ा पीछे दिखता है।

अगले बूलियन थे:

data True  -- type that represents truth
data False -- type that represents falsehood

और असमानता तुलना करने के लिए एक समारोह:

class NotEq a b r | a b -> r
instance NotEq Zero Zero False                -- 0 /= 0 = False
instance NotEq (S a) Zero True                -- S(a) /= 0 = True
instance NotEq Zero (S a) True                -- 0 /= S(a) = True
instance (NotEq a b r) => NotEq (S a) (S b) r -- S(a) /= S(b) = a /= b

और सूचियाँ ...

data Nil
data h ::: t
infixr 0 :::

class Append xs ys r | xs ys -> r
instance Append Nil ys ys                                       -- [] ++ _ = []
instance (Append xs ys rec) => Append (x ::: xs) ys (x ::: rec) -- (x:xs) ++ ys = x:(xs ++ ys)

class Concat xs r | xs -> r
instance Concat Nil Nil                                         -- concat [] = []
instance (Concat xs rec, Append x rec r) => Concat (x ::: xs) r -- concat (x:xs) = x ++ concat xs

class And l r | l -> r
instance And Nil True                    -- and [] = True
instance And (False ::: t) False         -- and (False:_) = False
instance (And t r) => And (True ::: t) r -- and (True:t) = and t

ifs भी प्रकार के स्तर पर गायब हैं ...

class Cond c t e r | c t e -> r
instance Cond True t e t  -- cond True t _ = t
instance Cond False t e e -- cond False _ e = e

और इसके साथ, मेरे द्वारा उपयोग की जाने वाली सभी सहायक मशीनरी की जगह थी। समय ही समस्या से निपटने के लिए!

एक मौजूदा बोर्ड में एक रानी को जोड़ने के लिए परीक्षण करने के लिए एक समारोह के साथ शुरू करना ठीक है:

-- Testing if it's safe to add a queen
class Safe x b n r | x b n -> r
instance Safe x Nil n True    -- safe x [] n = True
instance (Safe x y (S n) rec,
          Add c n cpn, Sub c n cmn,
          NotEq x c c1, NotEq x cpn c2, NotEq x cmn c3,
          And (c1 ::: c2 ::: c3 ::: rec ::: Nil) r) => Safe x (c ::: y) n r
    -- safe x (c:y) n = and [ x /= c , x /= c + n , x /= c - n , safe x y (n+1)]

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

मेमने की आवश्यकता को दूर करने के लिए कुछ बदलाव करने के बाद (जिसे मैं लागू कर सकता था, लेकिन मैंने एक और दिन छोड़ने का फैसला किया), यह वही है जो मूल समाधान की तरह दिखता है:

queens 0 = [[]]
-- The original used the list monad. I "unrolled" bind into concat & map.
queens n = concat $ map f $ queens (n-1)
g y x = if safe x y 1 then [x:y] else []
f y = concat $ map (g y) [1..8]

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

-- Auxiliary meta-functions
class G y x r | y x -> r
instance (Safe x y One s, Cond s ((x ::: y) ::: Nil) Nil r) => G y x r

class MapG y l r | y l -> r
instance MapG y Nil Nil
instance (MapG y xs rec, G y x g) => MapG y (x ::: xs) (g ::: rec)

-- Shortcut for [1..8]
type OneToEight = One ::: Two ::: Three ::: Four ::: Five ::: Six ::: Seven ::: Eight ::: Nil

class F y r | y -> r
instance (MapG y OneToEight m, Concat m r) => F y r -- f y = concat $ map (g y) [1..8]

class MapF l r | l -> r
instance MapF Nil Nil
instance (MapF xs rec, F x f) => MapF (x ::: xs) (f ::: rec)

और अंतिम मेटा-फंक्शन अब लिखा जा सकता है:

class Queens n r | n -> r
instance Queens Zero (Nil ::: Nil)
instance (Queens n rec, MapF rec m, Concat m r) => Queens (S n) r

जो कुछ बचा है, वह किसी प्रकार के ड्राइवर को समाधानों को हल करने के लिए टाइप-चेकिंग मशीनरी को समेटने के लिए है।

-- dummy value of type Eight
eight = undefined :: Eight
-- dummy function that asserts the Queens class
queens :: Queens n r => n -> r
queens = const undefined

यह मेटा-प्रोग्राम टाइप चेकर पर चलने वाला है, इसलिए कोई व्यक्ति आग लगा सकता है ghciऔर टाइप के लिए पूछ सकता है queens eight:

> :t queens eight

यह तेजी से डिफ़ॉल्ट पुनरावृत्ति सीमा को पार कर जाएगा (यह एक औसत 20 है)। इस सीमा को बढ़ाने के लिए, हमें विकल्प के ghciसाथ आमंत्रित करने की आवश्यकता है -fcontext-stack=N, जहां Nवांछित स्टैक डेप्थ (एन = 1000 और पंद्रह मिनट पर्याप्त नहीं है)। मैंने इसे अभी तक पूरा होने के लिए नहीं देखा है, क्योंकि इसमें बहुत लंबा समय लगता है, लेकिन मैं इसे चलाने में कामयाब रहा queens four

नहीं है एक पूरा कार्यक्रम बहुत परिणाम प्रकार मुद्रण के लिए कुछ मशीनरी के साथ ideone पर है, लेकिन वहाँ केवल queens twoसीमा से अधिक के बिना चला सकते :(


एक दिलचस्प समाधान के अलावा, यह एक मजेदार संदर्भ है जो कक्षा / उदाहरण तर्क के साथ किया जा सकता है
माइकल क्लेन

11

सी, प्रीप्रोसेसर के माध्यम से

मुझे लगता है कि ANSI समिति ने सी प्रीप्रोसेसर को ट्यूरिंग-पूर्ण होने के बिंदु तक नहीं बढ़ाने के लिए एक जागरूक विकल्प बनाया। किसी भी मामले में, यह आठ रानियों की समस्या को हल करने के लिए वास्तव में पर्याप्त शक्तिशाली नहीं है। किसी भी तरह के सामान्य फैशन में नहीं।

लेकिन यह किया जा सकता है, यदि आप लूप काउंटर को हार्ड-कोड करने के लिए तैयार हैं। लूप का कोई वास्तविक तरीका नहीं है, निश्चित रूप से, लेकिन #include __FILE__सीमित प्रकार की पुनरावृत्ति प्राप्त करने के लिए आप स्व-समावेश का उपयोग कर सकते हैं ।

#ifdef i
# if (r_(i) & 1 << j_(i)) == 0 && (p_(i) & 1 << i + j_(i)) == 0 \
                               && (n_(i) & 1 << 7 + i - j_(i)) == 0
#  if i == 0
#   undef i
#   define i 1
#   undef r1
#   undef p1
#   undef n1
#   define r1 (r0 | (1 << j0))
#   define p1 (p0 | (1 << j0))
#   define n1 (n0 | (1 << 7 - j0))
#   undef j1
#   define j1 0
#   include __FILE__
#   undef j1
#   define j1 1
#   include __FILE__
#   undef j1
#   define j1 2
#   include __FILE__
#   undef j1
#   define j1 3
#   include __FILE__
#   undef j1
#   define j1 4
#   include __FILE__
#   undef j1
#   define j1 5
#   include __FILE__
#   undef j1
#   define j1 6
#   include __FILE__
#   undef j1
#   define j1 7
#   include __FILE__
#   undef i
#   define i 0
#  elif i == 1
#   undef i
#   define i 2
#   undef r2
#   undef p2
#   undef n2
#   define r2 (r1 | (1 << j1))
#   define p2 (p1 | (1 << 1 + j1))
#   define n2 (n1 | (1 << 8 - j1))
#   undef j2
#   define j2 0
#   include __FILE__
#   undef j2
#   define j2 1
#   include __FILE__
#   undef j2
#   define j2 2
#   include __FILE__
#   undef j2
#   define j2 3
#   include __FILE__
#   undef j2
#   define j2 4
#   include __FILE__
#   undef j2
#   define j2 5
#   include __FILE__
#   undef j2
#   define j2 6
#   include __FILE__
#   undef j2
#   define j2 7
#   include __FILE__
#   undef i
#   define i 1
#  elif i == 2
#   undef i
#   define i 3
#   undef r3
#   undef p3
#   undef n3
#   define r3 (r2 | (1 << j2))
#   define p3 (p2 | (1 << 2 + j2))
#   define n3 (n2 | (1 << 9 - j2))
#   undef j3
#   define j3 0
#   include __FILE__
#   undef j3
#   define j3 1
#   include __FILE__
#   undef j3
#   define j3 2
#   include __FILE__
#   undef j3
#   define j3 3
#   include __FILE__
#   undef j3
#   define j3 4
#   include __FILE__
#   undef j3
#   define j3 5
#   include __FILE__
#   undef j3
#   define j3 6
#   include __FILE__
#   undef j3
#   define j3 7
#   include __FILE__
#   undef i
#   define i 2
#  elif i == 3
#   undef i
#   define i 4
#   undef r4
#   undef p4
#   undef n4
#   define r4 (r3 | (1 << j3))
#   define p4 (p3 | (1 << 3 + j3))
#   define n4 (n3 | (1 << 10 - j3))
#   undef j4
#   define j4 0
#   include __FILE__
#   undef j4
#   define j4 1
#   include __FILE__
#   undef j4
#   define j4 2
#   include __FILE__
#   undef j4
#   define j4 3
#   include __FILE__
#   undef j4
#   define j4 4
#   include __FILE__
#   undef j4
#   define j4 5
#   include __FILE__
#   undef j4
#   define j4 6
#   include __FILE__
#   undef j4
#   define j4 7
#   include __FILE__
#   undef i
#   define i 3
#  elif i == 4
#   undef i
#   define i 5
#   undef r5
#   undef p5
#   undef n5
#   define r5 (r4 | (1 << j4))
#   define p5 (p4 | (1 << 4 + j4))
#   define n5 (n4 | (1 << 11 - j4))
#   undef j5
#   define j5 0
#   include __FILE__
#   undef j5
#   define j5 1
#   include __FILE__
#   undef j5
#   define j5 2
#   include __FILE__
#   undef j5
#   define j5 3
#   include __FILE__
#   undef j5
#   define j5 4
#   include __FILE__
#   undef j5
#   define j5 5
#   include __FILE__
#   undef j5
#   define j5 6
#   include __FILE__
#   undef j5
#   define j5 7
#   include __FILE__
#   undef i
#   define i 4
#  elif i == 5
#   undef i
#   define i 6
#   undef r6
#   undef p6
#   undef n6
#   define r6 (r5 | (1 << j5))
#   define p6 (p5 | (1 << 5 + j5))
#   define n6 (n5 | (1 << 12 - j5))
#   undef j6
#   define j6 0
#   include __FILE__
#   undef j6
#   define j6 1
#   include __FILE__
#   undef j6
#   define j6 2
#   include __FILE__
#   undef j6
#   define j6 3
#   include __FILE__
#   undef j6
#   define j6 4
#   include __FILE__
#   undef j6
#   define j6 5
#   include __FILE__
#   undef j6
#   define j6 6
#   include __FILE__
#   undef j6
#   define j6 7
#   include __FILE__
#   undef i
#   define i 5
#  elif i == 6
#   undef i
#   define i 7
#   undef r7
#   undef p7
#   undef n7
#   define r7 (r6 | (1 << j6))
#   define p7 (p6 | (1 << 6 + j6))
#   define n7 (n6 | (1 << 13 - j6))
#   undef j7
#   define j7 0
#   include __FILE__
#   undef j7
#   define j7 1
#   include __FILE__
#   undef j7
#   define j7 2
#   include __FILE__
#   undef j7
#   define j7 3
#   include __FILE__
#   undef j7
#   define j7 4
#   include __FILE__
#   undef j7
#   define j7 5
#   include __FILE__
#   undef j7
#   define j7 6
#   include __FILE__
#   undef j7
#   define j7 7
#   include __FILE__
#   undef i
#   define i 6
#  elif i == 7
    printf("(1 %d) (2 %d) (3 %d) (4 %d) (5 %d) (6 %d) (7 %d) (8 %d)\n",
           j0 + 1, j1 + 1, j2 + 1, j3 + 1, j4 + 1, j5 + 1, j6 + 1, j7 + 1);
#  endif
# endif
#else
#include <stdio.h>
#define _cat(a, b) a ## b
#define j_(i) _cat(j, i)
#define n_(i) _cat(n, i)
#define p_(i) _cat(p, i)
#define r_(i) _cat(r, i)
int main(void)
{
# define i 0
# define j0 0
# include __FILE__
# undef j0
# define j0 1
# include __FILE__
# undef j0
# define j0 2
# include __FILE__
# undef j0
# define j0 3
# include __FILE__
# undef j0
# define j0 4
# include __FILE__
# undef j0
# define j0 5
# include __FILE__
# undef j0
# define j0 6
# include __FILE__
# undef j0
# define j0 7
# include __FILE__
# undef j0
    return 0;
}
#endif

दोहराए जाने वाले कंटेंट की भयावह मात्रा के बावजूद, मैं आपको आश्वस्त करता हूं कि यह सही मायने में आठ रानियों की समस्या को हल कर रहा है। दुर्भाग्य से एक चीज जो मैं प्रीप्रोसेसर के साथ नहीं कर सकता था वह एक सामान्य पुश-डाउन स्टैक डेटा संरचना को लागू करना है। अपशॉट यह है कि मुझे iजहां भी सेट करने के लिए एक और मूल्य का चयन करने के लिए उपयोग किया गया था, उसके मूल्य को हार्ड-कोड करना पड़ा । (मानों को प्राप्त करने के विपरीत, जो पूरी तरह से किया जा सकता है। इसीलिए #ifफाइल के शीर्ष पर, जो कि यह तय करता है कि क्या किसी रानी को वर्तमान स्थिति में जोड़ा जा सकता है, उसे आठ बार दोहराने की आवश्यकता नहीं है।)

पूर्वप्रक्रमक कोड के भीतर, iऔर jवर्तमान स्थिति का संकेत माना जा रहा है, जबकि r, pऔर nरखें ट्रैक जो की श्रेणी में और विकर्णों वर्तमान में प्लेसमेंट के लिए उपलब्ध नहीं हैं। हालाँकि, iरिकर्सन की वर्तमान गहराई को चिह्नित करने वाले काउंटर के रूप में भी दोगुना हो जाता है, इसलिए वास्तव में अन्य सभी मूल्य वास्तव में मुझे एक प्रकार की सबस्क्रिप्ट के रूप में उपयोग करते हैं, ताकि रिकर्सन से फिर से शुरू होने पर उनके मूल्यों को संरक्षित किया जाए। (और पूरी तरह से इसे बदलने के बिना एक प्रीप्रोसेसर प्रतीक के मूल्य को संशोधित करने की गंभीर कठिनाई के कारण भी।)

संकलित कार्यक्रम सभी 92 समाधान प्रिंट करता है। समाधान सीधे निष्पादन योग्य में एम्बेडेड होते हैं; प्रीप्रोसेसर आउटपुट इस तरह दिखता है:

/* ... #included content from <stdio.h> ... */
int main(void)
{
    printf("(1 %d) (2 %d) (3 %d) (4 %d) (5 %d) (6 %d) (7 %d) (8 %d)\n",
           0 + 1, 4 + 1, 7 + 1, 5 + 1, 2 + 1, 6 + 1, 1 + 1, 3 + 1);
    printf("(1 %d) (2 %d) (3 %d) (4 %d) (5 %d) (6 %d) (7 %d) (8 %d)\n",
           0 + 1, 5 + 1, 7 + 1, 2 + 1, 6 + 1, 3 + 1, 1 + 1, 4 + 1);
    printf("(1 %d) (2 %d) (3 %d) (4 %d) (5 %d) (6 %d) (7 %d) (8 %d)\n",
           0 + 1, 6 + 1, 3 + 1, 5 + 1, 7 + 1, 1 + 1, 4 + 1, 2 + 1);
    /* ... 88 more solutions ... */
    printf("(1 %d) (2 %d) (3 %d) (4 %d) (5 %d) (6 %d) (7 %d) (8 %d)\n",
           7 + 1, 3 + 1, 0 + 1, 2 + 1, 5 + 1, 1 + 1, 6 + 1, 4 + 1);
    return 0;
}

यह किया जा सकता है, भले ही यह स्पष्ट रूप से नहीं होना चाहिए।


7

यहाँ बिना किसी टेम्पलेट के C ++ 11 समाधान दिया गया है:

constexpr int trypos(
    int work, int col, int row, int rows, int diags1, int diags2,
    int rowbit, int diag1bit, int diag2bit);

constexpr int place(
    int result, int work, int col, int row, int rows, int diags1, int diags2)
{
    return result != 0 ? result
        : col == 8 ? work
        : row == 8 ? 0
        : trypos(work, col, row, rows, diags1, diags2,
                 1 << row, 1 << (7 + col - row), 1 << (14 - col - row));
}

constexpr int trypos(
    int work, int col, int row, int rows, int diags1, int diags2,
    int rowbit, int diag1bit, int diag2bit)
{
    return !(rows & rowbit) && !(diags1 & diag1bit) && !(diags2 & diag2bit)
        ? place(
            place(0, work*10 + 8-row, col + 1, 0,
                  rows | rowbit, diags1 | diag1bit, diags2 | diag2bit),
            work, col, row + 1, rows, diags1, diags2)
        : place(0, work, col, row + 1, rows, diags1, diags2);
}

int places = place(0, 0, 0, 0, 0, 0, 0);

समाधान दशमलव अंकों के रूप में एन्कोडेड है, जैसा कि फ्रेडवर्फ्लो के उत्तरों में है। GCC 4.7.1 निम्नलिखित फाइल को निम्नलिखित विधानसभा स्रोत में संकलित करता है g++ -S -std=c++11 8q.cpp:

    .file   "8q.cpp"
    .globl  places
    .data
    .align 4
    .type   places, @object
    .size   places, 4
places:
    .long   84136275
    .ident  "GCC: (GNU) 4.7.1"
    .section    .note.GNU-stack,"",@progbits

प्रतीक placesका मूल्य 84136275 है, अर्थात पहली रानी a8 पर है, दूसरा b4 आदि पर है।


0

c ++ टेम्पलेट, केवल एक टेम्पलेट क्लास के साथ परिभाषित किया गया है:

template <int N, int mask, int mask2, int mask3, int remainDigit, bool fail>
struct EQ;

template <int N, int mask, int mask2, int mask3>
struct EQ<N, mask, mask2, mask3, 0, false> {
    enum _ { Output = (char [N])1 };
};

template <int N, int mask, int mask2, int mask3, int i>
struct EQ<N, mask, mask2, mask3, i, true> { };

template <int N, int mask, int mask2, int mask3, int i>
struct EQ<N, mask, mask2, mask3, i, false> {
    enum _ { _ = 
             sizeof(EQ<N*10+1, mask|(1<<1), mask2|(1<<(1+i)), mask3|(1<<(1+8-i)), i-1, 
               (bool)(mask&(1<<1)) || (bool)(mask2&(1<<(1+i))) || (bool)(mask3&(1<<(1+8-i)))>) +
             sizeof(EQ<N*10+2, mask|(1<<2), mask2|(1<<(2+i)), mask3|(1<<(2+8-i)), i-1, 
               (bool)(mask&(1<<2)) || (bool)(mask2&(1<<(2+i))) || (bool)(mask3&(1<<(2+8-i)))>) +
             sizeof(EQ<N*10+3, mask|(1<<3), mask2|(1<<(3+i)), mask3|(1<<(3+8-i)), i-1, 
               (bool)(mask&(1<<3)) || (bool)(mask2&(1<<(3+i))) || (bool)(mask3&(1<<(3+8-i)))>) +
             sizeof(EQ<N*10+4, mask|(1<<4), mask2|(1<<(4+i)), mask3|(1<<(4+8-i)), i-1, 
               (bool)(mask&(1<<4)) || (bool)(mask2&(1<<(4+i))) || (bool)(mask3&(1<<(4+8-i)))>) +
             sizeof(EQ<N*10+5, mask|(1<<5), mask2|(1<<(5+i)), mask3|(1<<(5+8-i)), i-1, 
               (bool)(mask&(1<<5)) || (bool)(mask2&(1<<(5+i))) || (bool)(mask3&(1<<(5+8-i)))>) +
             sizeof(EQ<N*10+6, mask|(1<<6), mask2|(1<<(6+i)), mask3|(1<<(6+8-i)), i-1, 
               (bool)(mask&(1<<6)) || (bool)(mask2&(1<<(6+i))) || (bool)(mask3&(1<<(6+8-i)))>) +
             sizeof(EQ<N*10+7, mask|(1<<7), mask2|(1<<(7+i)), mask3|(1<<(7+8-i)), i-1, 
               (bool)(mask&(1<<7)) || (bool)(mask2&(1<<(7+i))) || (bool)(mask3&(1<<(7+8-i)))>) +
             sizeof(EQ<N*10+8, mask|(1<<8), mask2|(1<<(8+i)), mask3|(1<<(8+8-i)), i-1, 
               (bool)(mask&(1<<8)) || (bool)(mask2&(1<<(8+i))) || (bool)(mask3&(1<<(8+8-i)))>)};
};
int main(int argc, _TCHAR* argv[])
{
    // output all solutions to eight queens problems as error messages
    sizeof(EQ<0, 0, 0, 0, 8, false>);
    return 0;
}

इसलिए त्रुटि संदेश इस तरह दिखेगा:

C2440 त्रुटि: 'टाइप कास्ट': 'int' से 'char [15863724]' में परिवर्तित नहीं हो सकता

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