Un peu de magie booléenne

20

Défi

Étant donné la méthode C # suivante:

private static bool Test(bool a, bool b)
{
    if (a && b) return false;
    if (a) if (b) return true;
    return false;
}

Fournissez les valeurs aet bainsi cela trueest retourné.

Condition gagnante

La première entrée qui peut fournir les arguments corrects pour que la méthode donnée soit évaluée comme truegagnant.

acteur
la source
4
Bienvenue chez PPCG! Tous les défis ici nécessitent un critère de gain objectif de sorte qu'un gagnant puisse être choisi s'il y a plusieurs soumissions. Il semble qu'il n'y ait qu'une seule solution ici, donc ce défi pourrait ne pas convenir à PPCG. Pour les futurs défis, permettez-moi de recommander le bac à sable où vous pouvez obtenir des commentaires avant que le défi ne soit lancé.
Martin Ender
2
La méta-discussion est divisée sur la question de savoir si des puzzles de programmation sans critères de victoire supplémentaires sont sur le sujet , avec des réponses contradictoires étant surévaluées. Je préfère garder les questions ouvertes quand elles ne sont pas réglées, alors je vote pour rouvrir. Si vous avez des opinions, veuillez les apporter à la discussion.
xnor
2
@DenkerAffe Je ne pense pas que l'une des quatre combinaisons de paramètres évidentes fonctionne.
Martin Ender
3
en supposant qu'il existe une réponse valide, c'est une excellente question, qu'elle corresponde à ce que nous considérons normalement sur le sujet. + 1. Je pense que l'une des raisons pour lesquelles nous ne considérons pas normalement des questions comme celle-ci sur le sujet est que toutes les autres questions que j'ai vues comme celle-ci ont été posées par un débutant, et la réponse a été aveuglément évidente.
Level River St
5
@Widi Voyez, c'est pourquoi la «première solution valide» n'est peut-être pas la meilleure idée. Vous pouvez obtenir une solution inintéressante mais fonctionnelle qui ne fait que déranger certains internes via la réflexion, puis il n'y a aucune incitation pour quiconque à rechercher une solution plus intéressante sans réflexion.
Martin Ender

Réponses:

20
static void Main(string[] args)
{
    bool a, b;
    unsafe
    {
        int* pa = (int*)&a;
        int* pb = (int*)&b;
        *pa = 1;
        *pb = 2;
    }

        Console.Write(Test(a, b));
}

Cela s'imprime Truepour moi avec l'implémentation C # fournie avec Visual Studio 2015. En fait, je ne connais aucun C #, mais j'ai pensé que j'essaierais d'écrire du code C et de voir si cela fonctionnait. J'espérais que le compilateur supposerait que True est toujours représenté comme 1 et utiliserait un ET au niveau du bit. En mode Debug, c'est bien le cas (cela fonctionnait aussi avec Release). Il utilise un ET au niveau du bit pour la première condition et deux comparaisons à zéro pour la seconde:

            if (a && b) return false;
002C2E92  movzx       eax,byte ptr [ebp-3Ch]  
002C2E96  movzx       edx,byte ptr [ebp-40h]  
002C2E9A  and         eax,edx  
002C2E9C  and         eax,0FFh  
002C2EA1  mov         dword ptr [ebp-44h],eax  
002C2EA4  cmp         dword ptr [ebp-44h],0  
002C2EA8  je          002C2EB2  
002C2EAA  xor         edx,edx  
002C2EAC  mov         dword ptr [ebp-48h],edx  
002C2EAF  nop  
002C2EB0  jmp         002C2EE4  
            if (a) if (b) return true;
002C2EB2  movzx       eax,byte ptr [ebp-3Ch]  
002C2EB6  mov         dword ptr [ebp-4Ch],eax  
002C2EB9  cmp         dword ptr [ebp-4Ch],0  
002C2EBD  je          002C2EDC  
002C2EBF  movzx       eax,byte ptr [ebp-40h]  
002C2EC3  mov         dword ptr [ebp-50h],eax  
002C2EC6  cmp         dword ptr [ebp-50h],0  
002C2ECA  je          002C2EDC  
002C2ECC  mov         eax,1  
002C2ED1  and         eax,0FFh  
002C2ED6  mov         dword ptr [ebp-48h],eax  
002C2ED9  nop  
002C2EDA  jmp         002C2EE4  
            return false;
002C2EDC  xor         edx,edx  
002C2EDE  mov         dword ptr [ebp-48h],edx  
002C2EE1  nop  
002C2EE2  jmp         002C2EE4  
        }
002C2EE4  mov         eax,dword ptr [ebp-48h]  
002C2EE7  lea         esp,[ebp-0Ch]  
002C2EEA  pop         ebx  
002C2EEB  pop         esi  
002C2EEC  pop         edi  
002C2EED  pop         ebp  
002C2EEE  ret  
feersum
la source
Incroyable! J'étais totalement sûr que cela ne pourrait pas être fait
edc65
J'ai essayé la même chose mais cela ne semble pas fonctionner en Mono sous Linux.
jimmy23013
Cela ne dépendrait pas du compilateur C # (actuellement Roslyn de MS) mais plutôt du compilateur JIT (actuellement RyuJIT de MS). Bien que l'IL produit par le compilateur C # puisse également affecter ce que fait JIT.
Bob