Um pouco de mágica bool

20

Desafio

Dado o seguinte método C #:

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

Fornecer os valores ae bpara que trueé devolvido.

Condição vencedora

A primeira entrada que pode fornecer os argumentos corretos para fazer com que o método especificado seja avaliado em truevitórias.

ator
fonte
4
Bem-vindo ao PPCG! Todos os desafios aqui precisam de um critério de vitória objetivo, de modo que um vencedor possa ser escolhido se houver vários envios. Parece que pode haver apenas uma solução aqui, então esse desafio pode não ser um bom ajuste para o PPCG. Para desafios futuros, deixe-me recomendar o sandbox, onde você pode obter feedback antes que o desafio seja lançado.
Martin Ender
2
A meta-discussão é dividida sobre se os quebra-cabeças de programação sem critérios adicionais de vitória estão no tópico , com respostas conflitantes sendo votadas. Prefiro manter as perguntas em aberto quando não for resolvida, por isso estou votando para reabrir. Se você tiver opiniões, contribua com elas para a discussão.
xnor 28/02
2
@ DenkerAffe Eu não acho que nenhuma das quatro combinações óbvias de parâmetros funcione.
Martin Ender
3
supondo que haja uma resposta válida, essa é uma excelente pergunta, independentemente de se encaixar no que normalmente consideramos no tópico. Eu acho que uma das razões pelas quais normalmente não consideramos perguntas como essa no tópico é que todas as outras perguntas que eu já vi dessa forma foram feitas por iniciantes, e a resposta foi cegamente óbvia.
Level River St
5
@Widi Veja por que a "primeira solução válida" pode não ser a melhor idéia. Você pode obter uma solução desinteressante, mas funcional, que apenas mexe com alguns elementos internos via reflexão e, em seguida, não há incentivo para que alguém procure uma solução mais interessante sem reflexão.
Martin Ender

Respostas:

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

Isso é impresso Truepara mim com a implementação C # que acompanha o Visual Studio 2015. Na verdade, eu não conheço nenhum C #, mas imaginei que tentaria escrever um código C e ver se funcionava. Eu esperava que o compilador assumisse que True sempre é representado como 1 e use um AND bit a bit. No modo Debug, esse é realmente o caso (também funcionou com o Release). Ele usa AND bit a bit para a primeira condição e duas comparações com zero para a segunda:

            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
fonte
Surpreendente! Eu estava totalmente certo de que não poderia ser feito
edc65
Eu tentei a mesma coisa, mas parece não funcionar em Mono no Linux.
Jimmy23013
Isso dependeria não do compilador C # (atualmente Roslyn do MS), mas do compilador JIT (atualmente RyuJIT do MS). Embora o IL que o compilador C # produz também possa afetar o que o JIT faz.
28416 Bob