Hump-day puzzler.

Matt Fig asked on 16 Feb 2011
Latest activity: Answer by Nikolay Chumerin on 19 Feb 2011

If you have seen this before, please let others figure it out!

if (BLANK)
    disp('I Love ')
else
    disp('MATLAB')
end

What can replace BLANK to get the print-out (exactly): I Love MATLAB

How many solutions are there? For extra pride (or pain), how long did it take you to get it?

9 comments

Andrew Newell on 16 Feb 2011

Extra challenge: I would love to see a solution for which BLANK returns TRUE.

Kenneth Eaton on 16 Feb 2011

@Andrew: Your challenge has been met. See below...

Andrew Newell on 16 Feb 2011

Nice going! How about one that exercises the entire if/then block? Can it be done?

Jan Simon on 17 Feb 2011

@Matt: A too loose formulation. Please specify "print-out" and "exactly" exactly. And I assume you mean: "What can replace BLANK <in this code snippet> to get...". You like smilies? Here you have one :-)

Matt Fig on 17 Feb 2011

@Jan, not you too! (See Walter.) ;-)

Andrew Newell on 17 Feb 2011

Personally, I prefer the solutions in which all the code introduced goes in the spot where BLANK is and there are no external routines.

Matt Fig on 17 Feb 2011

So many good ideas, thanks to all who showed their ingenuity!

Ned Gulley on 18 Feb 2011
Matt Fig on 18 Feb 2011

Cool! Thanks for the heads up, Ned.

Tags

Products

    18 answers

    Walter Roberson answered on 16 Feb 2011
    Accepted answer
    ~fprintf('I Love ')
    

    Solved in... a small number of seconds.

    8 comments

    Matt Fig on 16 Feb 2011

    Nice Walter. Of course you need to change the " to '. It took me about 1 minute to solve.

    Andrew Newell on 16 Feb 2011

    About 1 minute for me too. Went down a couple of blind alleys like [0 1] first.

    Andrew Newell on 16 Feb 2011

    Probably someone who has programmed in C would solve this quickly. With a FORTRAN background, I tend to avoid having side effects in my conditions.

    Walter Roberson on 16 Feb 2011

    fprintf(...) can be replaced with fwrite(1,...)

    Matt Fig on 16 Feb 2011

    A second solution! Walter, you should have put this as another answer. I only found the first solution.

    Oliver on 23 Feb 2011

    Where in the MatLab documentation can I read why this answer works?

    Jan Simon on 23 Feb 2011

    @Oliver: "help fprintf" tells, that FPRINTF replies the number of printed characters. "help not" explains, that 0 is replied if the argument is not zero. Finally "help if" states, that the ELSE branch is executed, if the argument of IF is 0.

    Andrew Newell on 24 Feb 2011

    In case that is not clear: >>n = fprintf('I Love ') prints 'I Love ' to the standard output and returns a value of 7 for n. In the command "if (~fprintf('I Love '))" the if statement sees ~n (which is zero, or false) and your command window sees 'I Love ' because it is by default the standard output.

    Kenneth Eaton answered on 16 Feb 2011

    Here's a pretty goofy answer:

    true) fprintf('I Love '); end; if (false
    

    2 comments

    Andrew Newell on 16 Feb 2011

    That's thinking outside the parentheses!

    Matt Fig on 16 Feb 2011

    My hat's off to you, Sir Eaton!

    Kenneth Eaton answered on 16 Feb 2011

    In response to Andrew's extra challenge for a solution in which BLANK returns true, here's an absolutely insane one:

    function output = BLANK
      disp('I Love MATLAB');                   % Display the output
      assignin('caller','disp',@shadow_disp);  % Shadow the DISP function in
                                               %   the caller workspace
      output = true;                           % Return true
    end
    function shadow_disp(~)           % This will be immediately invoked by the
      evalin('caller','clear disp');  %   next call to DISP in the caller
                                      %   workspace. It displays nothing, but it
    end                               %   unshadows DISP in the caller workspace
    

    It will also work the same way if it returns false. ;)

    1 comment

    Walter Roberson on 16 Feb 2011

    I like it!

    David Young answered on 17 Feb 2011

    If you can read very quickly:

    [fprintf('I love MATLAB') regexp('x', '(?@quit)')]
    

    0 comments

    Andrew Newell answered on 16 Feb 2011

    This version outputs it in red!

    ~fprintf(2,'I love ')
    

    1 comment

    Matt Fig on 16 Feb 2011

    Now that is cool!

    Jan Simon answered on 16 Feb 2011

    This prints the wanted string, but not in this Matlab:

    if (system('matlab -r "disp(''I Love MATLAB'')" &'))
      disp('I Love ')
    else
      disp('MATLAB')
    end
    

    4 comments

    Andrew Newell on 16 Feb 2011

    Maybe this could be turned into a virus!

    Walter Roberson on 16 Feb 2011

    It doesn't satisfy the criteria that "I Love MATLAB" be the _only_ output.

    Also in some versions there would be a loop of the prompt printing out over and over again in the spawned matlab, as you do not quit after the command.

    Jan Simon on 17 Feb 2011

    @Walter: Sorry, I cannot find an "only" in the question. There is an "exactly".
    The DISP command should run once only. Which version creates a loop and print the string over and over again?

    Matt Fig on 17 Feb 2011

    Now that is dirty! Yet original. Nice work!

    Jan Simon answered on 17 Feb 2011

    With a free interpretation of "print-out":

    if (text(0.5, 0.5, 'I Love MATLAB'))
      disp('I Love ')
    else
      disp('MATLAB')
    end
    

    I simply ignore the orphaned "I Love " - who cares about junk in the command window, if there is a fancy GUI.

    Ah, "print-out" means most likely a print-out:

    if ({axes('Visible', 'off'); text(0.5, 0.5, 'I Love MATLAB'); print})
      disp('I Love ')
    else
      disp('MATLAB')
    end
    

    I admit, Matlab complains about too many output arguments for PRINT in Matlab 6.5 and about a not assigned VARARGOUT in Matrlab 2009a. But the actual print-out is clean.

    2 comments

    Matt Fig on 17 Feb 2011

    Also dirty! I thought about including the phrase, "to the command line" in the problem description, but decided I'd omit it and see where it led.

    Matt Fig on 17 Feb 2011

    The orphaned "I Love " can be avoided by putting:

    & error

    (or similar) after the call to TEXT.

    Jonathan answered on 18 Feb 2011

    fprintf('I love MATLAB')) return%

    2 comments

    Walter Roberson on 18 Feb 2011

    Sneaky!

    Matt Fig on 18 Feb 2011

    Indeed!

    Walter Roberson answered on 16 Feb 2011

    Corrected as per Matt's note about output arguments:

    function TF = BLANK
      disp('I Love MATLAB');
      quit
    end
    

    Major time waste: trying to find a way to execute return or quit or break or exit or dbstop in an expression context to avoid having to use a named function.

    4 comments

    Matt Fig on 16 Feb 2011

    I get an error: Too many output arguments.
    See below for a fix.

    Walter Roberson on 16 Feb 2011

    Fixed, thanks Matt. This version is distinctly different than your variation. It works by quiting Matlab to avoid executing the rest of the "if" statement. This is within the boundaries of the puzzle conditions as they did not require that Matlab continue execution afterwards.

    Matt Fig on 16 Feb 2011

    LOL Walter (where's my emoticon), you are always one to know exactly what the rules are!

    David Young on 17 Feb 2011

    Time has been wasted: you can use regexp to execute quit in an expression. See my answer below (or above, as the case may be).

    Matt Fig answered on 16 Feb 2011

    A variation on Walter's theme. Though I am not sure how different this is from just calling FPRINT in the conditional, and it is not really used to replace BLANK....

    function TF = BLANK
      fprintf('%s','I Love ');
      TF = false;
    end
    

    0 comments

    Walter Roberson answered on 16 Feb 2011

    Perhaps someone might be able to get this approach to work properly:

    evalc('fwrite(1,''I Love MATLAB''),quit')

    The evalc() works, the quit happens, but the text is not displayed. Adding in an fseek(1,0,0) should in theory force a flush but it doesn't, not even if you add a pause() statement to give time for execution. Though now that I think of it, that might be because the output is being captured by the evalc().

    eval() alone cannot process the "quit" portion: it complains about unexpected matlab expression.

    1 comment

    Jan Simon on 16 Feb 2011

    if ({fprintf('I Love MATLAB\n'), evalc('keyboard')}), ...

    Andrew Newell answered on 16 Feb 2011

    A variation on Kenneth's answer that prints the message to the left of the prompt:

     true) fprintf('I Love MATLAB'); end; return; if (false

    0 comments

    Walter Roberson answered on 16 Feb 2011

    A variation on Kenneth's shadowing:

    function output = BLANK
      assignin('caller','disp',@shadow_disp);
      output = true;
    end
    function shadow_disp(S)
      disp([S 'MATLAB']);
      evalin('caller','clear disp');
    end
    

    This has the difference of using what is passed to the disp()

    2 comments

    Walter Roberson on 16 Feb 2011

    Note that the shadowing solutions do not work if the test is rewritten on a single line, as

    if (BLANK); disp('I Love '); else; disp('MATLAB'); end

    as in these cases, the value for disp() is taken at parsing time. Also, these shadowing solutions might perhaps not work in 2011b scripts as the JIT is now applied to scripts.

    Jan Simon on 17 Feb 2011

    @Walter: This does not "replace BLANK", but *defines* it.

    Walter Roberson answered on 16 Feb 2011

    Andrew:

    To exercise the entire if/else block, put the test in named file and execute it, with BLANK set to BLANK(mfilename) . BLANK.m would have a persistent variable; if the persistent variable is empty, then set the variable to something, evalc() the mfile whose name was passed in, fwrite(1) the string returned by evalc, and return false . If the persistent variable is not empty, then set it empty and return true .

    The mfile would start executing, would call BLANK, which would set its internal flag and recurse the mfile. The second call to BLANK would detect the flag being set and would return true (no recursion), so that recursed call would display the "I Love " and then exit the recursion. Now back at the first level, BLANK has captured the "I Love " and displays it suppressing the newline, and returns false, so the non-recursed mfile executes the else, printing out the "MATLAB" and exiting.

    1 comment

    Andrew Newell on 16 Feb 2011

    Whew! If we are allowed to call this code from outside, then a simpler approach could be used (see my separate post).

    Andrew Newell answered on 16 Feb 2011

    If we are allowed to save the if/else block to a file (say LoveMatlab.m), then this code could exercise both parts of the block:

    BLANK=true;
    S = evalc('LoveMatlab');
    BLANK=false;
    T = evalc('LoveMatlab');
    disp([S(1:end-1),T])
    

    1 comment

    Walter Roberson on 16 Feb 2011

    I don't feel that this fits within the spirit of the question, that the code structure shown should be what is executed and somehow that causes the desired action.

    David Young answered on 17 Feb 2011

    Assuming that execution time isn't a concern, and, please, no typing while the code is running:

    [fprintf('I love MATLAB') input('')]
    

    0 comments

    Nikolay Chumerin answered on 19 Feb 2011

    My version#1 is:

    true), [char(8*ones(1,8)) 'I Love MATLAB'], return%
    

    2 comments

    Walter Roberson on 19 Feb 2011

    Unfortunately backspace, char(8), does not back up past the carriage return and linefeed that would be output after the 'ans = ' that is emitted for the expression.

    Nikolay Chumerin on 19 Feb 2011

    Hmm... on my system (Matlab 2009b 32bit, on Win7x86) it works.

    Nikolay Chumerin answered on 19 Feb 2011

    My version#2 is:

    isunix), a=12; else a=8*ones(1,8); end; [char(a) 'I Love MATLAB'], return %
    

    works on Matlab 2007b, 2009b, Linux x64 as well as on Matlab 2009b on Win7x86 and Matlab 2010b on WinXPx86.

    0 comments

    Contact us at files@mathworks.com