Un poco de magia bool

20

Desafío

Dado el siguiente método de C #:

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

Proporcione los valores ay basí truese devuelve.

Condición ganadora

La primera entrada que puede proporcionar los argumentos correctos para hacer que el método dado se evalúe como trueganador.

actor
fuente
44
Bienvenido a PPCG! Todos los desafíos aquí necesitan un criterio objetivo ganador tal que se pueda elegir un ganador si hay múltiples presentaciones. Parece que aquí solo puede haber una solución única, por lo que este desafío podría no ser una buena opción para PPCG. Para futuros desafíos, permítanme recomendarles el sandbox donde pueden obtener comentarios antes de que el desafío se active.
Martin Ender
2
La discusión meta se divide sobre si los acertijos de programación sin criterios de ganancia adicionales están en el tema , y se votan las respuestas en conflicto. Prefiero mantener las preguntas abiertas cuando está sin resolver, así que voy a votar para reabrir. Si tiene opiniones, por favor contribuya a la discusión.
xnor
2
@DenkerAffe No creo que ninguna de las cuatro combinaciones de parámetros obvias funcione.
Martin Ender
3
suponiendo que haya una respuesta válida, esta es una excelente pregunta, independientemente de si se ajusta a lo que normalmente consideramos en el tema. + 1. Creo que una de las razones por las que normalmente no consideramos preguntas como esta en el tema es que todas las demás preguntas que he visto así han sido hechas por un principiante, y la respuesta ha sido cegadoramente obvia.
Level River St
55
@Widi Vea que por eso la "primera solución válida" podría no ser la mejor idea. Es posible que obtenga una solución poco interesante pero funcional que solo interfiere con algunas partes internas a través de la reflexión y luego no hay ningún incentivo para que alguien busque una solución más interesante sin reflexión.
Martin Ender

Respuestas:

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

Esto se imprime Truepara mí con la implementación de C # que viene con Visual Studio 2015. En realidad, no conozco ningún C #, pero pensé que intentaría escribir un código de C y ver si funcionaba. Esperaba que el compilador suponga que True siempre se representa como 1 y use un AND bit a bit. En el modo de depuración, este es el caso (también funcionó con Release). Utiliza un AND bit a bit para la primera condición y dos comparaciones a cero para la 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
fuente
¡Increíble! Estaba totalmente seguro de que no se podría hacer
edc65
He intentado lo mismo pero no parece funcionar en Mono en Linux.
jimmy23013
Esto dependería no del compilador de C # (actualmente Roslyn de MS) sino más bien del compilador JIT (actualmente RyuJIT de MS). Aunque el IL que el compilador C # produce también podría afectar lo que hace JIT.
Bob