20
\$\begingroup\$

Challenge

Given the following C# method:

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

Supply the values a and b so that true is returned.

Winning condition

The first entry who can supply the correct arguments to make the given method evaluate to true wins.

\$\endgroup\$
  • 4
    \$\begingroup\$ Welcome to PPCG! All challenges here need an objective winning criterion such that a winner can be chosen if there are multiple submissions. It seems there might only be a single solution here, so this challenge might not be a good fit for PPCG. For future challenges let me recommend the sandbox where you can get feedback before the challenge goes live. \$\endgroup\$ – Martin Ender Feb 28 '16 at 10:49
  • 2
    \$\begingroup\$ Meta discussion is split on whether programming puzzles without additional win criteria are on topic, with conflicting answers being upvoted. I'd rather keep questions open when it's unsettled, so I'm voting to reopen. If you have opinions, please contribute them to the discussion. \$\endgroup\$ – xnor Feb 28 '16 at 11:10
  • 2
    \$\begingroup\$ @DenkerAffe I don't think any of the four obvious parameter combinations work. \$\endgroup\$ – Martin Ender Feb 28 '16 at 11:27
  • 3
    \$\begingroup\$ assuming there is a valid answer, this is an excellent question, regardless of whether it fits what we normally consider on topic.+1. I think one of the reasons we don't normally consider questions like this on topic is that every other question I've seen like this has been by a beginner, and the answer has been blindingly obvious. \$\endgroup\$ – Level River St Feb 28 '16 at 11:50
  • 5
    \$\begingroup\$ @Widi See that's why "first valid solution" might not be the best idea. You might get an uninteresting but working solution which just messes with some internals via reflection and then there's no incentive for anyone to go looking for a more interesting solution without reflection. \$\endgroup\$ – Martin Ender Feb 28 '16 at 13:30
20
\$\begingroup\$
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));
}

This prints True for me with the C# implementation that comes with Visual Studio 2015. I actually don't know any C#, but I figured I'd try to write some C code and see if it worked. I was hoping that the compiler would assume that True is always represented as 1 and use a bitwise AND. In Debug mode, this is indeed the case (it worked with Release too). It uses a bitwise AND for the first condition and two comparisons to zero for the second:

            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  
\$\endgroup\$
  • \$\begingroup\$ Amazing! I was totally sure that it could not be done \$\endgroup\$ – edc65 Feb 28 '16 at 14:47
  • \$\begingroup\$ I have tried the same thing but it doesn't seem to work in Mono under Linux. \$\endgroup\$ – jimmy23013 Feb 28 '16 at 14:59
  • \$\begingroup\$ This would be dependent not on the C# compiler (currently Roslyn from MS) but rather on the JIT compiler (currently RyuJIT from MS). Though the IL the C# compiler produces could also affect what JIT does. \$\endgroup\$ – Bob Feb 28 '16 at 15:22

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.