A program that prints out its own source code (without reading in and outputting it’s source file) is known as a quine. I’ve known about these things for years, but never really bothered trying to work it out. It requires thinking in a circular fashion which makes your head hurt :). However, a little while ago a realized that this would actually make a great programming interview question, so I thought I had better give this a crack, using Ruby – of course.
Why It’s A Great Interview Question
Before we get to the Ruby quine hackery that I came up with, here is why I think it is a great question. You see, the good thing about this question is the fact that it is relatively small (doesn’t take too much time) but at the same time it is not binary (i.e. not yes/no or knows/doesn’t know or can do/can’t do). Here is how I see it potentially panning out and what it means.
You ask the question, and they draw up an answer for you almost instantly without batting an eyelid.
- Clearly they have heard of this before, which shows they have an interest and some involvement in the wider programming community.
- Having heard of it they were sufficiently intrigued to dig further, which shows an interest and passion for their craft and a willingness to invest time and tackle interesting/challenging problems.
- If they explain it with gusto and a twinkle in their eyes :), you can be pretty sure they solved it themselves rather than looking it up, which shows they can think creatively and are actually able to solve the problems they tackle.
- If they muddle their way through it and/or can’t really explain why/how something like their solution works, they probably looked it up rather than solving it themselves. This is not such a big deal, they have thought about it and can reproduce code they’ve seen and have a general understanding of how it works. Those are all good qualities.
Regardless, if you’re here, then as far as this question is concerned, you have at least a decent and potentially very good candidate on your hands – a positive result.
You ask the question and they’ve clearly never heard of it before, but they’re quickly able to arrive at a working solution.
- You potentially have a closet superstar on your hands. They may not be as engaged in the community, since they haven’t heard the question before, but this is probably because they spent the majority of time doing what they love – coding. You next job is to find out if this is infact so.
Regardless, solving this question off-the-bat like this is praise-worthy – a positive result.
You ask the question and they’ve never heard of it, can’t come up with a solution, but are at least able to get towards the right track and can explain their thought process well and succinctly.
- They’re likely not a superstar, but they do have some reasoning skills and they are a decent communicator which means they are still potentially a solid developer.
It may not be as positive a result as you would like – but it is not a total failure and it does tell you what kind of role this person would be more suited for if you were to hire them.
You ask the question and they’ve never heard of it, can’t solve it, and can’t come up with anything logical and end up confusing themselves repeatedly.
You can probably guess what the deal is with this situation. Total fail, you can still ask a question or two for due diligence, but chances are you have a dud on your hands.
See what I mean about being able to get a lot of information about a person from such a little question. I know you guys are already awesome – since you’re following this blog and if you’re not you better start :) – and would ace this question anyway. But for academic purposes, here is what I came up with using Ruby.
A Ruby Quine
The first version I did looked like this:
ruby
def method;"def method;;end;puts method()[0, 11] + 34.chr + method + 34.chr + method()[11, method.length-11]";end;puts method()[0, 11] + 34.chr + method + 34.chr + method()[11, method.length-11]
Put it in a file and run it and we get the following output:
def method;"def method;;end;puts method()[0, 11] + 34.chr + method + 34.chr + method()[11, method.length-11]";end;puts method()[0, 11] + 34.chr + method + 34.chr + method()[11, method.length-11]
Perfect!
To things easier to understand, lets indent it a little bit (which will un-quinefy :) it, but doesn’t matter for study purposes):
```ruby def method; “def method;;end;puts method()[0, 11] + 34.chr + method + 34.chr + method()[11, method.length-11]“; end;
puts method()[0, 11] + 34.chr + method + 34.chr + method()[11, method.length-11]```
The way it works is as follows. As some point you need to have a string which will contain all the code before and after itself, but will obviously not contain itself. It doesn’t really matter what you have before the string, but it does matter what you have after. You need to have repeated access to the string. You will then cut a substring from it which will be everything before the string itself. Following this, you need a quote (“) then the string itself then another quote and then cut everything else out of the string that you hadn’t cut before. You concatenate all this together and then output the whole thing. It makes it easier to have all of it on one line so you don’t have to deal with spaces. I realize it is not the best explanation, but you really do need to spend a little bit of time and think through this yourself – you will get it for sure.
Last thing left to do was to make my quine a little shorter (apparently with quines, the shorter they are the better, or so I’ve heard). Here is what I got:
ruby
def s;"def s;;end;puts s()[0,6]+34.chr+s+34.chr+s()[6,s.length-6]";end;puts s()[0,6]+34.chr+s+34.chr+s()[6,s.length-6]
This can be made slightly shorter still, can you see how?
Here is a challenge if you’re up for it. Try and come up with a quine in Ruby that will output its source formatted/indented, perhaps using a heredoc. Is it even possible? Either way it’s good code kata.
If you can’t be bothered coming up with your own solution there is a whole bunch of them in different languages on the quine page, (but no Ruby ones that I can see).
Well, there we go, now the only thing left is to ask yourself how you think you would go, if got this kind of question in an interview?
Image by Neil Crosby