• m0ffx (unregistered) in reply to cole
    cole:
    akatherder:
    Most interviewers will look at the FizBuz question with 4 possible outcomes:
    1. You have no idea what you're doing and can't come up with a decent solution.
    2. You are a novice and have three different cases. One for Fiz, one for Buz, and one for FizBuz.
    3. You are competent and only need to use the two cases.
    4. You are eloquent and come up with a solution, they don't quite understand but it seems to work.
    How praytell do you do it in two? You have three test cases. 3, 5, 15 <- counts up to three cases in my book, so how do two tests determine if it's three states? Granted, my original reply also assumed that you don't return an endline after every test, only where you had a result in the first place. but I tried for simplicity rather than breakproof usage.

    No doubt everyone will point out how hideous this code is. But it at least demonstrates how you don't have to test for fizbuz explicitly. Is bash shell.

    j=0; for i in {1..100}; do if [ expr $i % 3 = 0 ] ; then echo -n fiz ; else j=expr $j + 1; fi; if [ expr $i % 5 = 0 ] ; then echo -n buzz; else j=expr $j + 1; fi; if [ $j = 2 ] ; then echo -n $i; fi; echo; j=0; done

  • (cs) in reply to captcha: suscipit
    captcha: suscipit:
    curtmack:
    For what it's worth, here's my solution to FizBuz, in C++
    #include <stdio>
    #include <iostream>
    
    using namespace std;
    
    int main (int nargs, const char* pszargs[]) {
      for (int i=1; i <= 100; i++) {
        cout << i << ": ";
        //don't ask why I made this next line the way I did
        //it's Monday
        cout << (i%3 ? "" : "Fiz") << (i%5 ? "" : "Buz");
        cout << '\n';
      }
      return 0;
    }

    EDIT: Err, semicolon on the return 0 might be helpful.

    The original question asks that you print numbers, but print Fiz instead of the number if it's a multiple of 3, and Buz instead of the number if it's a multiple of 5, and FizBuz instead of the number if it's a multiple of both. It also doesn't specify that the numbers should be on separate lines.

    Doesn't make it less trivial, but it does allow for ever so slightly more clever solutions.

    Thanks for the info.

    As for stdio, I coded this in 2 minutes and didn't feel like looking up whether or not I actually needed stdio, or whether or not it had a .h. As for hungarian notation, I have no idea what the hell that is. And I did use \n instead of endl, unless you meant it the other way around, in which case I've got nothing. I just hate using endl. Remember C++ compilers account for the newline/carriage return controversy.

    In conclusion, if anything, this is merely further proof it's a bad idea to ask high school students with only a fundamental grasp of programming to do work for you ;)

  • DanM (unregistered)

    If the text was "The dog went grrrowl" and the search string was "rr". How many times would you find it?

  • Anonymous Scheme weenie at the end of the day (unregistered)

    Just to make everybody happy, here's FizBuz, written concisely in Scheme with an iteration construct.

    (do ((i 1 (+ i 1)))
        ((> i 100) (values))
      (printf "~a\n" (cond ((= 0 (modulo i 15)) "FizBuz")
                           ((= 0 (modulo i 5)) "Buz")
                           ((= 0 (modulo i 3)) "Fiz")
                           (#t i))))   
    

    It uses three tests. But it's clear about what it's doing.

    Now what you should be doing is playing the advanced Buz game. Print "Buz" instead of the number if the number is a multiple of 7 or has a 7 digit in it. Good times.

  • Mazellan (unregistered) in reply to Sad Bug Killer
    Sad Bug Killer:
    I think the point is to weed out the complete muppets, the ones that don't have a clue, similar to that Fiz Buz problem that had its 15 nanoseconds of Internet fame a while ago. (The problem was something along the lines of: for every number from 1 to 100 print Fiz if it's divisible by 3, Buz if it's divisible by 5 and FizBuz if it's divisble by both 3 and 5. It appeared that surprisingly low percentage of potential hires managed to solve this highly sophisticated problem)
    im not sure about the original question but all numbers between 1 and 100 are divisible by 3 and 5 if the question says they must be a whole number (ie. no fractions/decimals) then it would be different. 1 / 5 = .2 1 / 3 = .3333r so 1 == fizbuz
  • (cs) in reply to Mazellan
    Mazellan:
    im not sure about the original question but all numbers between 1 and 100 are divisible by 3 and 5 if the question says they must be a whole number (ie. no fractions/decimals) then it would be different. 1 / 5 = .2 1 / 3 = .3333r so 1 == fizbuz

    Gentlemen, I hereby present The Real WTF.

  • Adam (unregistered)
    #!/usr/bin/perl
    my $text = <<EOT;
    Polly put the kettle on, polly put the kettle on, polly put the kettle on we\'ll all have tea
    EOT
    my @subtexts = qw( Polly polly ll x Polx );
    my @letters = split( //, $text );
    foreach my $subtext ( @subtexts ) {
        LETTER: for( my $i = 0; $i < @letters; ++$i ) {
            my @subletters = split( //, $subtext );
            for( my $j = 0; $j < @subletters; ++$j ) {
                next LETTER if( lc $letters[$i+$j] ne lc $subletters[$j] );
            }
            print $i+1," ";
        }
        print "\n";
    }
    </pre>
    

    That's all I have to add.

  • (cs)
    function substr_match($search,$string){
    	for($x=0;$x<=strlen($string)-1-strlen($search);$x++){
    		if(substr(strtolower($string),$x,strlen($search))===strtolower($search))$foundPositions[]=$x+1;
    	}
    	return $foundPositions;
    }
    

    this is knocked down to minimal space. execution-wise I would set up the lenths as values instead of recalcing each iteration....

  • (cs)

    Filter this with sort -n:

    #!/usr/bin/env python
    
    fizbuz = set(range(0, 101, 15))
    fiz    = set(range(0, 101,  3)) - fizbuz
    buz    = set(range(0, 101,  5)) - fizbuz
    
    for i in fizbuz: print i, "fizbuz"
    for i in fiz:    print i, "fiz"
    for i in buz:    print i, "buz"
    
  • (cs)
    def strIndex(s, token):
      s = s.lower()
      token = token.lower()
      
      ret = []
      for i in range(len(s) - len(token) + 1):
        for j in range(len(token)):
          if s[i + j] != token[j]:
            break
        else:
          ret.append(i)
      return ret
    
    if __name__ == '__main__':
      s = ' Polly put the kettle on, polly put the kettle on, polly put the kettle on we\'ll all have tea'
      for token in ('Polly', 'polly', 'll', 'x', 'Polx'):
        print strIndex(s, token)
    

    For the heck of it, here's a python version with a for-break-else loop.

    TRWTF is those who questioned why the index starts with 1 instead of 0. You gotta read the requirement more carefully -- there's a space at the beginning of the input text :P

  • Otto (unregistered) in reply to Kasper

    Honestly if you are re-implementing Boyer-Moore from scratch for an interview question then either you or the interviewer is doing it wrong.

  • The Fake WTF (unregistered) in reply to Sam
    Sam:
    I think the fact that the requirement was to not use any string manipulation function makes this problem a bit silly and excessive.

    While barring the use of any Substring function or Contains function could have left the door open to:

    I wouldn't assume that the subtext cannot contain spaces.

  • hexatron (unregistered)

    I think part of the point of 'find substrings' is that the names of all those predefines convenience functions are actually taking up more of your brain cells than their implementation:

    int rchar(char *str, char c){ int j= 0; char *s= str; while(*s) if(*s++==c) j= s-str; return j-1; }

    Or is it called lastCharOf? or RChar? Whee--how many lost brain cells? Are you a programmer or a fukin dictionary?

  • (cs) in reply to Sam
    Sam:
    I think the fact that the requirement was to not use any string manipulation function makes this problem a bit silly and excessive.

    While barring the use of any Substring function or Contains function could have left the door open to:

    string[] splitString = input.Split(' ');
    foreach string word in splitString
        // etc
    

    And is significantly easier to do, barring any string manipulation function would require you to traverse individual characters, looking for spaces, keeping track of indicies, etc. Even C contains an strtok function, and C barely has any string manipulation functions. Why ask someone to dramatically re-invent the wheel? Could someone implementing the code above not be able to demonstrate an understanding of a number of functions in C#?

    Programming tests are fine; I think when they get too ridiculously abstract and pointless is when they just get silly.

    • Sam

    Uhmmm, WHAT? What do spaces and tokens have to do with anything?

    You are given two strings A and B. Find all of the occurences of B in A.

    Any good programmer can sit down and write the program in a few minutes. Sure its reinventing the wheel, but guess what you've got a short amount of time to interview. Reinvent.

    If I asked that question, and got a response about spaces and tokens, I'd say "No Hire."

    By the way, I used to ask people strcmp. I got about %10 success rate with <1% writing it like K&R.

  • (cs)

    Hey guys, I 'rm -rf /'ed instead of 'rm -rf ./', how do I undo it?

    plz send me teh codez.

  • demon (unregistered) in reply to Fanguad
    Fanguad:
    I once got asked "given two points, how would you find the distance between them?"

    My brain went into overdrive trying to find the hidden meaning behind the question. Were they talking three-dimensional points? Are the points moving? Are they some sort of weird hyper-points?

    I hesitantly responded, "The square root of delta x squared plus delta y squared?" The interviewer nodded and told me, "You'd be amazed at how many people have trouble with that."

    I thought the answer is: "1st, you take a measuring tape..." you get the idea ;-)

  • IMakeFractals (unregistered) in reply to Fanguad
    Fanguad:
    I once got asked "given two points, how would you find the distance between them?"

    My brain went into overdrive trying to find the hidden meaning behind the question. Were they talking three-dimensional points? Are the points moving? Are they some sort of weird hyper-points?

    I hesitantly responded, "The square root of delta x squared plus delta y squared?" The interviewer nodded and told me, "You'd be amazed at how many people have trouble with that."

    Maybe I've been too much maths recently, but I would have understood that to be about abritrary points in an arbitary space. I would have said something along the lines of:

    "I'd use a sensible metric function for the space and evaluate it for the two points. If they're simply points in a Euclidian space, then the metric is the square root of the sum of the squared difference for each ordinate. In a Manhattan space, then the metric is the sum of the absolute difference for each ordinate. It gets a little more interesting if they're points on the surface of a sphere or a torus or something."

  • sholdowa (unregistered) in reply to The Enterpriser

    private char myToLower(char c) { return (char) (c | 0x20); }

    ??

  • sholdowa (unregistered) in reply to Anonymous Scheme weenie at the end of the day
    Anonymous Scheme weenie at the end of the day:
    Just to make everybody happy, here's FizBuz, written concisely in Scheme with an iteration construct.
    (do ((i 1 (+ i 1)))
        ((> i 100) (values))
      (printf "~a\n" (cond ((= 0 (modulo i 15)) "FizBuz")
                           ((= 0 (modulo i 5)) "Buz")
                           ((= 0 (modulo i 3)) "Fiz")
                           (#t i))))   
    

    It uses three tests. But it's clear about what it's doing.

    Now what you should be doing is playing the advanced Buz game. Print "Buz" instead of the number if the number is a multiple of 7 or has a 7 digit in it. Good times.

    C. Personally, I only use 2 tests (:

    for ( i = 1 i <= 100; i++ ) { printf ( "%d: ", $i ); if ( ! (i % 3)) { puts ( "Fiz" ); } if ( ! (i % 5)) { puts ( "Buz" ); } putc ( '\n'); }

  • (cs)

    You're all fired. 2 comparisons worst case. ZERO division or modulo operators. 1/3 as many cycles in the loop. Example code that does the same thing using the lame way available below for comparison.

    #include <stdio.h>
    
    // the sweet way
    int main(void)
    {
      unsigned int next = 5;
      unsigned int i;
      
      for(i = 3; i < 101; i += 3)
      {
        if(i == next)
        {
          printf("fiz(%d)buz(%d)\n", i, i);
          next += 5;
        }
        else
        {
          if(i > next)
          {
            printf("buz(%d)\n", next);
            next += 5;
          }
          printf("fiz(%d)\n", i);
        }
      }
      if(i >= next) printf("buz(%d)\n", next);
    
      return 0;
    }
    
    // the lame way
    int main(void)
    {
      unsigned int i;
      
      for(i = 1; i < 101; i++)
      {
        if(i % 3 == 0)
        {
          if(i % 5 == 0) printf("fiz(%d)buz(%d)\n", i, i);
          else printf("fiz(%d)\n", i);
        }
        else
        {
          if(i % 5 == 0) printf("buz(%d)\n", i);
        }
      }
      return 0;
    }
    
  • (cs) in reply to Stilgar
    Stilgar:
    The Enterpriser:
    toLower is a String method...

    private char myToLower(char c) { if(c > 63 && c < 91) return (char) (c + 32);

    return c; }

    but that is ToLower for char which is not String method

    Correct. Since the spec says not to use String methods, it is required to write your own code for lowering the case of a letter (if that is part of your solution). Hence this method which would be combined with a loop through a char[] representing the input string. As others have already posted the code for the loop, I didn't feel the need to repeat that part.

    • as has been mentioned, char.ToLower() also exists, so I guess that would be simpler.
  • (cs) in reply to sholdowa
    sholdowa:
    private char myToLower(char c) { return (char) (c | 0x20); }

    ??

    try it...

  • null (unregistered) in reply to Saaid
    Saaid:
    Andrew:
    blindio:
    Why not just skip the middle man, post the interview question directly on various internet help boards, then approach those who answer it with job offers. Should give about the same success rate.

    The ones who answer the questions on the help boards already have jobs.

    And they spend their time on message boards.

    Said the guy on TheDailyWTF.

  • Ian Potter (unregistered)

    Here's my solution in PHP; probably slow and it uses recursion, but since this the question is basically "build a simple regular expression matcher," recursion is nice.

    function myMatch($text, $subtext)
    {
      $textLength = strlen($text);
      $subLength = strlen($subtext);
      $results = array();
      
      for($i = 0; $i < $textLength - $subLength; $i++)
      {
        if(caseInsensitiveCharMatch($text[$i], $subtext[0]))
        {
          if (myInnerMatch($text, $i + 1, $subtext, 1, $subLength - 1))
            $results[] = $i + 1;      
        }
      }
      
      return $results;
    }
    
    function myInnerMatch($fullText, $start, $stringToMatch, $nextCharPosToMatch, $charsLeftToMatch)
    {
      if (caseInsensitiveCharMatch($fullText[$start], $stringToMatch[$nextCharPosToMatch]))
      {
        $charsLeftToMatch--;
        if ($charsLeftToMatch != 0) // More to match
          return myInnerMatch($fullText, $start + 1, $stringToMatch, $nextCharPosToMatch + 1, $charsLeftToMatch);
        else // we matched the last character
          return true;    
      }
      else // does not match, bail out
        return false;
    }
    
    function caseInsensitiveCharMatch($left, $right)
    {
      $cLeft = ord($left);
      $cRight = ord($right);
      if ($cLeft == $cRight ||
        $cLeft - 32 == $cRight ||
        $cRight - 32 == $cLeft)
        return true;
      else
        return false;
    }
  • Iain Collins (unregistered) in reply to Erik
    Erik:
    I'm all for coding tests for potential hires, but why would your coding test try to ascertain whether or not the interviewee was capable of producing code in a way that you yourselves admit they would never do in real life?

    I'm in agreement, it seems pointless to me too. When looking for good developers, having someone prove they can "do things the wrong way" is simply less effective than having someone provide a positive demonstration of their ability.

    I have the same disregard for interview techniques such as riddles (as distinct from being asked to solve a genuine, practical problems), the specific meaning or behavior of truly obscure protocol errors or methods (from memory) and the ability demonstrate a telepathic ability / hive mind - as required when it is deemed necessary to guess specific answer the interviewer is looking for ("Okay then, so those are 3 valid ways of doing it you've just mentioned, but what if you couldn't do any of them then how would you do it? No - that wasn't the one I was thinking of either, try again.").

    I was looking around London about a year ago and enquired three positions, at a range of different companies. No interviewer bothered to check out open source software I've written or checkout my svn repository or any of my previous work in any way (even though I'd email links ahead encouraging them to do so, and all the had to do was click on them to see some examples).

    Purely theoretical exercises, riddles, buzzword bingo, pretending to be "more-agile-than-thou" and all seem to be vogue.

    Perhaps it's just me, but here in London in particular there seems to be an abundance of developers who can give all the right responses to academic maths questions, say all the right things about "how agile they are", get all the latest buzzwords right and name drop the flavor-of-the-month languages and frameworks, but can't actually write decent[0] software at the end of the day (and often require a large team of developers to even attempt anything, even when they are writing fairly straightforward software).

    [0] i.e. That is (broadly) scalable, straight forward to maintain, cross platform, standards compliant, written in an appropriate language (etc). I've heard those things described as "too obvious" to be worth enquiring about, even by teams who I know have fundamental issues with those very problems.

  • Anonymous Scheme weenie about to go to bed (unregistered) in reply to sholdowa
    sholdowa:
    C. Personally, I only use 2 tests (:

    for ( i = 1 i <= 100; i++ ) { printf ( "%d: ", $i ); if ( ! (i % 3)) { puts ( "Fiz" ); } if ( ! (i % 5)) { puts ( "Buz" ); } putc ( '\n'); }

    That's nice but it doesn't actually solve the problem because you printed out the numbers even when you printed Fiz or Buz.

    Have a look here: http://imranontech.com/2007/01/24/using-fizzbuzz-to-find-developers-who-grok-coding/. You see that TRWTF all along was that some of us knew what the customer wanted (have the computer play the Buzz game), and some of us only knew what the customer told us (for values of customer equal to Sad Bug Killer -- see Page 1 of the comments).

    This is hard to do with just two tests in C, but being able to overwrite the value of the number helps. See below:

    void main()
    {
    int i;
    for(i = 1; i <= 100; i++)
      {
        char s[7] = {0};
        int pos = 0;
        sprintf(s, "%d", i);
        if(!(i % 3))
          {
            pos = sprintf(s, "Fiz");
          }
        if(!(i % 5))
          {
            sprintf(s + pos, "Buz");
          }
        puts(s);
      }
    }
    

    This may be premature, but I think I win.

  • (cs) in reply to Zolcos
    Zolcos:
    #include <iostream>
    int main(int argc,char** argv)
    {
    int fiz=0,buz=0;
    while(fiz<=100||buz<=100) std::cout << ((fiz<buz)?((fiz+=3)?"fiz":""):((buz<fiz)?((buz+=5)?"buz":""):((((fiz+=3) + (buz+=5))?"fizbuz":"")))) << std::endl;
    return 0;
    }
    </pre>
    Using ?: when you know the second part will never come up? Why not use the comma operator? That's what it's for. (Note that code using the comma operator normally deserves to be refactored anyway.)
  • apathetic (unregistered)

    At first I wrote this function in C, but someone told me that it was not correct since I did not implement Knuth Morris Pratt algorithm, that pissed me off because that was not the task, but when i noticed that "hellohello" for the context "hellohellohello" returned 1, i just had to redo it, however, since this task was for C#, where you can compare strings using the == operator, I rewrote it in PHP which is pretty much the same thing as C#.

    <?php
    
    	function substring($string, $start, $len)
    		{
    			
    			$len = $start + $len;
    			
    			for(; $start < $len; $start++)
    				$ret = $ret . $string[$start];
    			
    			return $ret;
    			
    		}
    
    	function len($string)
    		{
    			
    			$i = 0;
    			
    			while($string[$i] != '')
    				$i++;	
    				
    			return $i;
    			
    		}
    	
    	function matches($text, $context)
    		{
    			
    			$matches = 0;
    			
    			for($i = 0; $i < len($context); $i++)
    				if (strtolower(substring($context, $i, len($text))) == strtolower($text))
    					$matches++;
    		
    			return $matches;
    				
    		}
    	
    	echo matches("hellohello", "hellohellohello");
    
    ?>
  • Kuba (unregistered) in reply to Anonymous slightly humbled Scheme weenie
    Anonymous slightly humbled Scheme weenie:
    While you may be correct about Lisp-likes not providing iteration in general

    Huh? Common Lisp provides a fairly complex and slightly under-specified iteration powerhouse known as do. The example in the tutorial is only a tip of the iceberg: http://www.n-a-n-o.com/lisp/cmucl-tutorials/LISP-tutorial-18.html

  • bigfoot (unregistered)

    I wouldn't hire ANY of you. The only requirement was that you not use any of the built-in string functions, but it never said you could not use any of the builtin Regular Expression functions. Here's a WORKING (yes, actually tested) example.

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions;

    namespace TestParser { class Program { static void Main( string[] args ) { string text = "Polly put the kettle on, polly put the kettle on, polly put the kettle on we'll all have tea"; RunParser( text, "Polly" ); RunParser( text, "polly" ); RunParser( text, "ll" ); RunParser( text, "x" ); RunParser( text, "Polx" ); Console.ReadKey(); }

    	static void RunParser( string text, string subtext )
    	{
    		StringBuilder b = new StringBuilder();
    		List<int> list = ParseByRegex( text, subtext );
    		foreach ( int index in list )
    		{
    			if ( b.Length > 0 )
    				b.Append( ", " );
    			// the expected output is 1-based, not zero-based.
    			b.Append( ( index + 1 ).ToString() );
    		}
    		if ( b.Length > 0 ) // only generate output is matches were found
    			Console.WriteLine( b.ToString() );
    	}
    
    	static public List<int> ParseByRegex( string text, string subtext )
    	{
    		List<int> matches = new List<int>();
    		Regex match = new Regex( subtext, RegexOptions.IgnoreCase );
    		MatchCollection list = match.Matches( text );
    		foreach ( Match m in list )
    		{
    			matches.Add( m.Index ); // requirement is for index
    		}
    		return matches;
    	}
    }
    

    }

  • greg (unregistered)

    must...not...implement...fizzbuzz...either...damn.

    Example in Clean:

    module fizzbuzz
    //     Ye Fizzbuzz programme...
    import StdEnv
    fizz    = 5
    buzz    = 9
    say:: Int -> String
    say   i
    |  i rem (lcm fizz buzz) == 0    =   "fizzbuzz"
    |  i rem fizz            == 0    =   "fizz"
    |  i rem buzz            == 0    =   "buzz"
    |  otherwise                     =   toString i
    Start = map say  [1..100]
    That's the whole, compilable program. "lcm" is least common multiple, "Start" is the equivalent of the "main" function, "map", as in Python, Haskell, &c, means "apply this here function to every element of this here list."

    Despite appearances this code is completely statically type-checked by the compiler.

    That's the sum total of my Clean coding to date. Took 15 minutes, including checking the book for all the keywords and standard functions. Probably an experienced Clean coder could do it in one line, without the guards ("|").

    By the way, Fizzbuzz is example 1-2 in David Flanagan's Java Examples in a Nutshell, O'Reilly 1997. Yup... right after "Hello, world!".

  • genius (unregistered) in reply to Fanguad

    the correct answer is

    "with a ruler"

  • poop (unregistered) in reply to The Enterpriser
    The Enterpriser:
    private char myToLower(char c) { if(c > 63 && c < 91) return (char) (c + 32);

    return c; }

    so ASCII 64 (@) is an uppercase character? and what about non-ASCII environments?

  • greg (unregistered) in reply to joe_bruin
    joe_bruin:
    You're all fired. 2 comparisons worst case. ZERO division or modulo operators. 1/3 as many cycles in the loop. Example code that does the same thing using the lame way available below for comparison.
    ....
    

    No, Joe. You're fired. Professional programming is about communicating with other programmers. (Since you're a professional, it can be taken for granted that you can get the computer to do what you want.)

    Master coders all advise you to do things the simple, obvious, easily understood way, unless there is an overwhelming reason to do something different... in which case, you document the reason and the algorithm, provide copious hints for the maintainer, including asserts and invariants, and provide references to standard texts that will assist the maintainer.

    This is a courtesy from one professional to another: it saves the reader's time.

    My own experience both as a maintainer of other people's code, and as a supervisor of people maintaining my code, bears out what I have read... doing what they say does save time. And therefore money.

    Your code fails on all counts. It's not the code of a professional.

  • greg (unregistered) in reply to m0ffx
    m0ffx:
    cole:
    How praytell do you do it in two? You have three test cases. 3, 5, 15 <- counts up to three cases in my book, so how do two tests determine if it's three states? Granted, my original reply also assumed that you don't return an endline after every test, only where you had a result in the first place. but I tried for simplicity rather than breakproof usage.

    No doubt everyone will point out how hideous this code is. But it at least demonstrates how you don't have to test for fizbuz explicitly. Is bash shell.

    j=0; for i in {1..100}; do if [ expr $i % 3 = 0 ] ; then echo -n fiz ; else j=expr $j + 1; fi; if [ expr $i % 5 = 0 ] ; then echo -n buzz; else j=expr $j + 1; fi; if [ $j = 2 ] ; then echo -n $i; fi; echo; j=0; done

    You still have 3 tests, and your code takes twice as long to read and be confident about than the "naive" code. See my reply to Joe Bruin.

    Please, coders: professional coding is writing for people. Time-poor people. Write to be understood as easily as possible.

  • (cs)

    The real WTF is that interviewers continue to ask for nonsense, toy code snippets in interviews, and think this is the proper way to gauge if a candidate is a good coder. Being an uber-geek and knowing how to solve this FizzBuzz crap doesn't make you a good developer - creating working software that does what it's intended to do and helps the business you work for is.

  • Mikkel (unregistered) in reply to Sam
    Sam:
    I think the fact that the requirement was to not use any string manipulation function makes this problem a bit silly and excessive.

    While barring the use of any Substring function or Contains function could have left the door open to:

    string[] splitString = input.Split(' ');
    foreach string word in splitString
        // etc
    

    And is significantly easier to do, barring any string manipulation function would require you to traverse individual characters, looking for spaces, keeping track of indicies, etc. Even C contains an strtok function, and C barely has any string manipulation functions. Why ask someone to dramatically re-invent the wheel? Could someone implementing the code above not be able to demonstrate an understanding of a number of functions in C#?

    Programming tests are fine; I think when they get too ridiculously abstract and pointless is when they just get silly.

    • Sam

    Yeah but that is a very ineffective way of doing it, consider doing that test in the bible - you would spend a lot of time and memory since you need to contain all words split in memory - and you are at a minimum passing through the whole set of strings twice (once to make them, once to test).

    There are some very effective string searching algorithms running in N+M which also only uses up N+M bytes of memory + a few pointers - it can even be modified to only read a byte from M at a time cutting the memory usage down to N+1+pointers. (Not a C# programmer, don't know how close to memory you can get) On top of that with minor modifications you can search for multiple words in a single pass.

    Oh and the poor guy who send a delete with no where clause, oh my. Guess most cowboy programmers have tried that - which is why no one is allowed to execute embedded SQL here.

  • (cs)

    I'd give them a FizBuz solution in BeFunge, just to annoy them:

    55*4*v    _  v           
    v   <>:1-:^              
        |:<$     <     ,*48< 
        @>0"zif">:#,_$      v
    >:3%!|    >0"zub">:#,_$^ 
         >:5%!|              
    v  "buz"0<>:.          ^ 
             |!%5:          <
    >:#,_   $>             ^  
    

    yes, it works. yes, I am bored at work ;)

  • True Brit (unregistered)

    Oh, this is too good to pass on. I can't remember which of the dozen or so interviews I had in London last year gave me this test, so 'MonkeyCode' can rest assured I'm not going to blow his cover.

    What I -will- say is that I spent an hour writing a solution for this problem, including full comments to explain what I was doing, how it worked, and even what built-in methods I'd use in preference in The Real World. It did exactly as asked in terms of output generation, and even had a bit of basic validation in there to prevent exceptions due to empty string inputs, etc.

    It was basic stuff, amounting to maybe 25-30 lines of code (including comments) but it did the job exactly as specified and was fairly bullet-proof to boot. I got a response about a week later. I forget the exact wording, but the essence of it made me laugh out loud and think of TDWTF.

    My solution was 'not enterprise-y enough'.

  • Khanmots (unregistered) in reply to curtmack
    curtmack:
    And I did use \n instead of endl, unless you meant it the other way around, in which case I've got nothing. I just hate using endl. Remember C++ compilers account for the newline/carriage return controversy.

    Not sure if anyone else has mentioned this... but there is a difference between '\n' and endl that it seems you're missing. endl flushes the buffer being written to, '\n' doesn't.

  • null (unregistered)

    A Python example of FizBuz using objects:

    class Fiz(object): def init(self, number): self.number = number def check(self): return self.number % 3 == 0

    class Buz(object): def init(self, number): self.number = number def check(self): return self.number % 5 == 0

    for i in range(1,101): out = '' fiz = Fiz(i) buz = Buz(i) if fiz.check() == True: out += 'Fiz' if buz.check() == True: out += 'Buz' if out == '': out = str(i) print "%s" % out

    And to the guy claiming there's only two comparisons needed, he's flat out wrong. There are four test cases (is % 3, is % 5, is both, is neither). Just because you can easily combine two or more of them into a single test doesn't mean the test cases don't still exist.

  • Vq (unregistered)

    fizzbuzz n=head$filter(not.null)[concat[s|(s,d)<-[("Fizz",3),("Buzz",5)],mod n d==0],show n]

    Couldn't resist writing an obfuscated Haskell fizzbuzz.

  • Mister Bee (unregistered) in reply to bigfoot
    bigfoot:
    I wouldn't hire ANY of you. The only requirement was that you not use any of the built-in string functions, but it never said you could not use any of the builtin Regular Expression functions. Here's a WORKING (yes, actually tested) example.

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions;

    namespace TestParser { class Program { static void Main( string[] args ) { string text = "Polly put the kettle on, polly put the kettle on, polly put the kettle on we'll all have tea"; RunParser( text, "Polly" ); RunParser( text, "polly" ); RunParser( text, "ll" ); RunParser( text, "x" ); RunParser( text, "Polx" ); Console.ReadKey(); }

    	static void RunParser( string text, string subtext )
    	{
    		StringBuilder b = new StringBuilder();
    		List<int> list = ParseByRegex( text, subtext );
    		foreach ( int index in list )
    		{
    			if ( b.Length > 0 )
    				b.Append( ", " );
    			// the expected output is 1-based, not zero-based.
    			b.Append( ( index + 1 ).ToString() );
    		}
    		if ( b.Length > 0 ) // only generate output is matches were found
    			Console.WriteLine( b.ToString() );
    	}
    
    	static public List<int> ParseByRegex( string text, string subtext )
    	{
    		List<int> matches = new List<int>();
    		Regex match = new Regex( subtext, RegexOptions.IgnoreCase );
    		MatchCollection list = match.Matches( text );
    		foreach ( Match m in list )
    		{
    			matches.Add( m.Index ); // requirement is for index
    		}
    		return matches;
    	}
    }
    

    }

    I wouldn't hire you either, for deliberate and malicious over-engineering and willful under-use of ternary operators:

    ..snip..
                foreach (Match m in new Regex(subtext.Text, RegexOptions.IgnoreCase).Matches(text.Text))
                    resultText.Append((resultText.Length > 0 ? "," : "") + ((m.Index + 1).ToString()));
    ..snip..
    
  • brian j. parker (unregistered)

    London being a world city, I'd think you'd have the cream of the crop available.

    This was probably anonymized, but presumably from a comparable city. I wouldn't think that in any similar city you'd have trouble.

  • ais523 (unregistered) in reply to StarLite
    StarLite:
    I'd give them a FizBuz solution in BeFunge, just to annoy them:
    55*4*v    _  v           
    v   <>:1-:^              
        |:<$     <     ,*48< 
        @>0"zif">:#,_$      v
    >:3%!|    >0"zub">:#,_$^ 
         >:5%!|              
    v  "buz"0<>:.          ^ 
             |!%5:          <
    >:#,_   $>             ^  
    

    yes, it works. yes, I am bored at work ;)

    Heh, while you were writing FizBuz in Befunge, I was writing the substring problem in INTERCAL. This isn't case-insensitive yet, however; but INTERCAL string handling is painful enough as it is. Absolutely nothing here from any standard string library, because INTERCAL doesn't have a string library.

    	DO ,1 <- #1
    	PLEASE DO .31 <- #1
    	DO .32 <- #2
    	DO STASH .31 + .32
    	DO .31 <- #0
    	DO .32 <- #0
    	PLEASE DO STASH .31 + .31 + .32
            DO .999 <- .21/.31
    	DO COME FROM #3$"'#65535~"'?.21$#10'~'#0$#65535'"'~#1"
    	DO COME FROM (17) ONCE
    	DO WRITE IN ,1
    	DO .2 <- .21
    	DO .1 <- ,1 SUB #1
    	DO (1000) NEXT
    	DO .21 <- .3 ~ #255
    (1)	DO STASH .31
    (2)	DON'T STASH .32
    (11)	DO NOTHING
    	PLEASE DO REINSTATE (2)
    	PLEASE DO ABSTAIN FROM (1)
    	DO .999 <- .21/.32
    (17)	PLEASE DO .32 <- .31
    	PLEASE DO RETRIEVE .32 + .32 + .31
    	MAYBE DON'T GIVE UP
    	MAYBE COME FROM #4$"!31~.31'~#1"
    (33)	DO RETRIEVE .31
    	DO COME FROM (58)
    (35)	DO .5 <- '?.31$.32'~'#0$#65535'
    	DO RETRIEVE .31 + .32
    (29)   	DO ABSTAIN .32 FROM (32)
    (58)	DO NOTHING
    	DO COME FROM #5$"'.5~.5'~#1"
    	DO COME FROM (55)
    (55)	DO GO BACK
    (32)	DO COME FROM (29) AGAIN
    	DO .1 <- #1
    (40)	DO COME FROM (36)
    	PLEASE DO RETRIEVE .31
    (36)	PLEASE DO (1020) NEXT
    	PLEASE DO COME FROM #6$"!31~.31'~#1"
    	DO READ OUT .1
    	DO COME FROM (56)
    (56)	DO GO BACK
    

    This was tested to work under C-INTERCAL 0.28 (open-source, download available from http://intercal.freeshell.org/); incidentally, it exposes a bug in C-INTERCAL 0.26, so a newer version than that is needed. A CLC-INTERCAL version would be significantly more complicated (but easier to make case-insensitive).

    Oh, and if anyone here is insane enough to ask me how it works, I'd be delighted to answer. This code is confusingly written even by INTERCAL standards...

  • Piotr Sulecki (unregistered) in reply to Robert S. Robbins
    Robert S. Robbins:
    I'd just use a ruler and measure the distance. This question does not imply that we are not talking about physical points.

    If we're talking about physical points, it would require us to define the observer position and speed as well... relativity, you know.

  • (cs) in reply to Fanguad
    Fanguad:
    I once got asked "given two points, how would you find the distance between them?"
    The right answer would be something like this: Given a vector that is the difference between the two points, the distance is the square root of the sum of each squared vector component.

    If you're going to answer "with a ruler", you have to prefix it with "given a ruler whose number of dimensions are more than or equal to the number of dimensions of the points"... Actually, scratch that. It assumes that the two points have an equal number of dimensions.

  • (cs)

    If asked to do this in the interview, I'd first tell them that I'm going to write this as if I had no restrictions on using the String methods to use as a template. So, I might end up with something like so:

    private static void Search( string stringToSearch , string searchString , int startIndex, ICollection<string> foundIndexes ) { int index = stringToSearch.IndexOf( searchString , startIndex , StringComparison.CurrentCultureIgnoreCase ); if ( index == -1 ) return; foundIndexes.Add( index.ToString() );

    if ( ( index + 1 ) >= stringToSearch.Length )
    	return;
    
    Search( stringToSearch, searchString, index + 1, foundIndexes );
    

    }

    Then I'd tell the interviewer that if they really wanted the equivalent routine without the use of String methods, to give me Reflector and I'll implement the equivalent of Length and IndexOf using their core implementation. If displeased with that, I'd retort, "Hey, why stop there? Why not require that I write my own compiler? Why not preclude the use loops or recursion? Why let me use those funny parentheses and commas?"

    Sometimes interviewers try to be too clever for their own good. If you really want to test someone's ability, the right solution is to come up with a reasonable test. One company with whom I consulted actually created a small project for interviewees. They asked the candidate to build a simple ASP.NET form that had to talk to three or four tables with a many-many relationship. They gave them a workstation with access to the Internet so they could dig up any information they wanted. In addition, they kept a few of the specs intentionally vague and told the developer that at any time they could ask the interviewer for clarity. It was amazing how many failed miserably. Many spun their wheels and never asked for clarity. Many couldn't even get past opening Visual Studio.

  • (cs)

    Sounds to me like Paula Bean is out on the prowl again. Please send me teh brillant codez.

  • (cs)

    How about:

    switch( i % 15 )
    {
      case 0:
        std::cout << "buzfiz\n";
        break;
    
      case 3: case 6: case 9: case 12:
        std::cout << "buz\n";
        break;
    
      case 5: case 10:
        std::cout << "fiz\n";
        break;
    
      default:
        std::cout << i << '\n';
    }
    

    And of course run that in a loop.

    You could also create a table with cached values. The real issue is what it would be used for in real life.

Leave a comment on “Code examples and interviews”

Log In or post as a guest

Replying to comment #:

« Return to Article