Résoudre le problème des huit reines au moment de la compilation [fermé]


39

Pouvez-vous résoudre le casse - tête des huit reines au moment de la compilation?

Choisissez n'importe quel format de sortie approprié.

Je suis particulièrement intéressé par une solution de métaprogrammation de modèles C ++, mais vous pouvez utiliser des langages ayant des constructions similaires, comme par exemple le système de types de Haskell.

Idéalement, votre métaprogramme afficherait toutes les solutions. Pas de codage en dur.


Pourquoi n'autorisez-vous pas différentes langues?
utilisateur inconnu

@user: Parce que je suis intéressé par une solution C ++ TMP. Si vous connaissez un langage dont les constructions sont très similaires, n'hésitez pas à poster une réponse.
R. Martinho Fernandes

Puis-je également utiliser le système de types de Haskell? Autant que je sache, il devrait être complet.
FUZxxl

@FUZxxl: Oui. Je vais éditer la question.
R. Martinho Fernandes le

Est-il suffisant de faire la solution de force brute?
cessé de tourner dans le sens anti-horaire le

Réponses:


50

Mon méta-programme trouve les 92 solutions. Ils sont imprimés sous forme de messages d'erreur:

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

Cela signifie que la première reine doit être placée à y = 1, la seconde à y = 5, la troisième à y = 8 et ainsi de suite.

Premièrement, quelques méta-fonctions utiles:

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
};

Ensuite, deux méta-fonctions intéressantes (notez le singulier et le pluriel):

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 {};

La variable queensstocke les coordonnées y des reines placées jusqu'à présent sur le tableau. Les trois variables suivantes stockent les lignes et les diagonales déjà occupées par des reines. xet ydevrait être explicite.

Le premier argument pour if_then_elsevérifier si la position actuelle est bloquée. Si c'est le cas, la récursivité s'arrête en renvoyant le résultat (sans signification) 0. Sinon, la reine est placée sur le tableau et le processus se poursuit avec la colonne suivante.

Quand x atteint 8, nous avons trouvé une solution:

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

Comme le printmodèle n'a pas de membre solution, le compilateur génère une erreur.

Et enfin, pour lancer le processus, nous inspectons le valuemembre du tableau vide:

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

Le programme complet peut être trouvé chez ideone .


2
J'aime: 1) utiliser des champs de bits pour stocker des données, 2) le choix de la méthode de sortie.
R. Martinho Fernandes

7
Trop de génialité pour une réponse.
St0le

Ne devrait-il pas aussi afficher les valeurs x?
DeadMG

2
@DeadMG La valeur x de chaque emplacement de reine est sa position dans la chaîne (1-8).
Briguy37

22

Je suis venu avec une solution qui utilise le système de type Haskell. J'ai cherché un peu une solution existante au problème au niveau de la valeur , puis je l'ai modifié un peu, puis je l'ai porté au niveau du type. Il a fallu beaucoup de réinventer. Je devais également activer plusieurs extensions GHC.

Premièrement, comme les entiers ne sont pas autorisés au niveau des types, je devais réinventer les nombres naturels une fois de plus, cette fois en tant que types:

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

L'algorithme que j'ai adapté effectue des additions et des soustractions sur les naturels, donc je devais les réinventer également. Les fonctions au niveau du type sont définies avec recours à des classes de types. Cela nécessite les extensions pour plusieurs classes de types de paramètres et dépendances fonctionnelles. Les classes de types ne peuvent pas "renvoyer de valeurs", nous utilisons donc un paramètre supplémentaire pour cela, d'une manière similaire à 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

La récursivité est implémentée avec des assertions de classe, la syntaxe est donc un peu en arrière.

Viennent ensuite les booléens:

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

Et une fonction pour faire des comparaisons d'inégalité:

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

Et des listes ...

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 sont également absents au niveau du type ...

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

Et avec cela, toutes les machines de soutien que j'ai utilisées étaient en place. Il est temps de s'attaquer au problème lui-même!

Commençant par une fonction pour tester si l'ajout d'une reine à un tableau existant est correct:

-- 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)]

Notez l'utilisation d'assertions de classe pour obtenir des résultats intermédiaires. Comme les valeurs de retour sont en réalité un paramètre supplémentaire, nous ne pouvons pas appeler les assertions directement les unes des autres. Encore une fois, si vous avez déjà utilisé PROLOG, vous trouverez peut-être ce style un peu familier.

Après avoir apporté quelques modifications pour supprimer le besoin de lambdas (que j’aurais pu mettre en œuvre, mais j’ai décidé de partir un autre jour), voici à quoi ressemblait la solution initiale:

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]

mapest une fonction d'ordre supérieur. Je pensais que mettre en œuvre des méta-fonctions d'ordre supérieur serait trop compliqué (encore une fois, les lambdas). Je me suis donc tourné vers une solution plus simple: puisque je sais quelles fonctions seront mappées, je peux implémenter des versions spécialisées mappour chacune, de sorte que ce ne sont pas fonctions d'ordre supérieur.

-- 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)

Et la dernière méta-fonction peut être écrite maintenant:

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

Il ne reste plus qu’une sorte de moteur pour convaincre les vérificateurs de types de trouver les solutions.

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

Ce méta-programme est supposé s'exécuter sur le vérificateur de types, on peut donc lancer ghciet demander le type de queens eight:

> :t queens eight

Cela dépassera assez rapidement la limite de récursivité par défaut (c'est un maigre 20). Pour augmenter cette limite, nous devons appeler ghciavec l' -fcontext-stack=Noption, où Nest la profondeur de pile souhaitée (N = 1000 et quinze minutes ne sont pas suffisants). Je n'ai pas encore vu ce processus aboutir, car cela prend beaucoup de temps, mais j'ai réussi à le faire queens four.

Il existe un programme complet sur ideone avec quelques machines pour imprimer les types de résultats, mais il ne queens twopeut fonctionner que sans dépasser les limites :(


Outre une solution intéressante, il s'agit d'une référence amusante à ce que l'on peut faire avec la logique classe / instance
Michael Klein

11

C, via le préprocesseur

Je pense que le comité ANSI a fait un choix conscient de ne pas étendre le pré-processeur C au point d’être Turing-complete. En tout cas, ce n'est pas assez puissant pour résoudre le problème des huit reines. Pas de manière générale.

Mais cela peut être fait si vous êtes prêt à coder en dur les compteurs de boucles. Bien sûr, il n'y a pas vraiment de moyen de boucler, mais vous pouvez utiliser l'auto-inclusion (via #include __FILE__) pour obtenir une sorte de récursion limitée.

#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

Malgré la quantité horrible de contenu répétitif, laissez-moi vous assurer que le problème des huit reines est résolu de façon algorithmique. Malheureusement, la seule chose que je ne pouvais pas faire avec le préprocesseur est de mettre en place une structure de données de pile générale. Le résultat est que j'ai dû coder en dur la valeur de ipartout où elle était utilisée pour sélectionner une autre valeur à définir. (Par opposition à la récupération de valeurs, ce qui pourrait être fait de manière très générale. C'est pourquoi le #ifdébut du fichier, qui détermine si une reine peut être ajoutée à la position actuelle, n'a pas besoin d'être répété huit fois.)

Dans le code préprocesseur, iet jindiquer la position actuelle étant considérée, alors que r, pet nde garder trace dont les rangs et sont actuellement indisponibles diagonales pour le placement. Toutefois, iil sert également de compteur indiquant la profondeur actuelle de la récursivité. Par conséquent, toutes les autres valeurs utilisent réellement i comme une sorte d’indice, de sorte que leurs valeurs sont préservées lors de la reprise d’une récursion. (Et aussi à cause de la difficulté sérieuse de modifier la valeur d'un symbole de préprocesseur sans la remplacer complètement.)

Le programme compilé imprime les 92 solutions. Les solutions sont intégrées directement dans l'exécutable; la sortie du préprocesseur ressemble à ceci:

/* ... #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;
}

Cela peut être fait, même si cela ne devrait clairement pas être le cas.


7

Voici une solution C ++ 11 sans aucun modèle:

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);

La solution est codée sous forme de chiffres décimaux, comme dans les réponses de FredOverflow. GCC 4.7.1 compile le fichier ci-dessus dans la source d'assemblage suivante avec 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

La valeur du symbole placesest 84136275, c'est-à-dire que la première reine est en a8, la seconde en b4, etc.


0

Modèle c ++, avec une seule classe de modèle définie:

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;
}

le message d'erreur ressemblera à ceci:

erreur C2440: 'type cast': impossible de convertir de 'int' en 'char [15863724]'

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.