
Can you solve it?  The Greplin programming challenge - rwalker
http://challenge.greplin.com
======
shiven
Seems like I may be the only person to have used a bioinformatics approach to
the first problem! bl2seq to the rescue!! I'll explain my approach if anyone
seems interested... as I am not sure if posting solutions is acceptable here.

Edit: As others seem to be posting gist/snips etc. so I guess it is OK.

Step 0 - Copied parent string to file: p1.txt

Step 1 - Used python to reverse the entire string and copy to second file: cat
p1.txt | python -c "print raw_input()[::-1]" > p2.txt

Step 2 - Formatted the two files, so as to be parsed as FASTA, by adding
sequence name headers.

Step 3 - Use bl2seq (blastp) locally or online to align the two "sequences".
Final alignment shows only one major chunk of identity, i.e. the answer.

So, in essence, a dynamic programming algo would work.

~~~
stygianguest
If bl2seq gets the longest common subsequence I did exactly the same thing. In
haskell it just seems the right thing to do. Actually it would be damn
interesting to see if there are patterns in the solutions for every
programming language.

------
bd
_"Even if you're not looking for a job, we'd love to hear what you thought
about the challenge."_

I would be curious how many people did you lose because of phonecall
requirement (before you changed it).

Also CSV for just a list of 22 numbers wasn't really necessary.

If you do web puzzle, the best is to keep everything self-contained, no
downloads, no using external channels, just copy and paste.

FYI another Python cheater here (+Wolfram Alpha & Wikipedia, I'm lazy :).

~~~
dschoon
I don't think trivializing the combinations with Python's builtins, looking up
the fib primes with OEIS, or computing factors with Alpha is cheating. I hope,
in fact, it's the whole point of the exercise: choose the right tools for the
job. If you're writing code to test primeness or generate Fibonacci numbers, I
sure as hell don't want to hire you.

~~~
dkarl
_If you're writing code to test primeness or generate Fibonacci numbers, I
sure as hell don't want to hire you._

Maybe you should have called it the "Greplin Challenge," then, instead of the
"Greplin Programming Challenge." It's not a real task, after all; the reward
comes from accepting a completely artificial challenge. I'm going to do the
challenge before dinner tonight, and before I leave work I could get source
code for the solutions from the guy down the hall from me who did the
challenge as soon as it was posted -- and you certainly don't want to hire a
guy who recodes other people's work for no reason, right?

~~~
rwalker
Maybe we have a different hiring mindset than dschoon - we're equally happy
with people who find the answers or create the answers. In a production
system, we certainly wouldn't want hand-rolled primeness checking. But in a
programming challenge, we think it's fun to write it for yourself.

~~~
dkarl
Oops; I wrote my comment under the assumption that dschoon was with greplin,
and in retrospect I'm not sure why. Sorry about that.

------
csmajorfive
I think this would've been a better filter for hiring if the magnitude were
larger (e.g. huge string, more numbers for the combination, etc) or if there
was a strict time limit. As it is right now, I don't think the hardcore
hackers you're looking for will be that enticed.

~~~
cakeface
I think that you'd be surprised at the sheer number of applicants a very basic
programming challenge can weed out. The company that I work at has a simple
test to parse a csv file and a surprising amount of people who appear to be
good candidates bomb it.

------
cperciva
Do I get bonus marks for solving this without writing any code?

~~~
cosgroveb
I immediately went to Wikipedia, found out what type of CS problem the first
challenge was, then followed the external links at the bottom of the page to
find the Perl module I needed and installed it from CPAN.

I quit because this seemed like cheating but now I'm thinking... Maybe it was
the point? To see if I would try to find something off-the-shelf to solve the
problem quickly. Still not sure it was, because if so the challenge certainly
doesn't demonstrate that I have any CS chops. :-\

Spoiler alert: I believe this module will do the trick
[http://search.cpan.org/~gray/Tree-
Suffix-0.21/lib/Tree/Suffi...](http://search.cpan.org/~gray/Tree-
Suffix-0.21/lib/Tree/Suffix.pm)

~~~
cperciva
I didn't solve the problems using existing code either. All three are entirely
solvable by pencil and paper (or just inspection in the first case).

~~~
Timothee
How do you go about solving #2 on pen and paper? Well, calculating the
Fibonacci sequence, ok. The sum of prime divisors of X+1, I guess... though it
gets slightly harder for me after dividing by 2, 3 and 5. But how do you know
for sure that X is prime?

Based on bd's link, I'll just assume that you have super powers. (or I'm
approaching the problem the wrong way)

edit: I was starting to think about what to write for #1, but ended finding
the answer by looking at it as well.

~~~
baddox
You can use the Sieve of Eratosthenes to generate primes with pen and paper
very easily. Or, you could find a roll of paper and evaluate any computable
function (assuming unbounded paper). ;)

~~~
Timothee
It doesn't seem to make it especially easy: you still have the same problem of
having to eliminate the multiples of 61, 79, 89, etc. which are not obvious.
Yes, you can count, but it looks very time-consuming.

The problem still stands that one needs to go in the 500,000s for that problem
(thus 700s for the square root). That's still a long way to go…

I'm really curious about how cperciva did it. You're supposed to find the
first Fibonacci prime over 227,000. The first Fibonacci number over that is
obviously not prime (multiple of 3), but the one after that is not obvious
even if you have the list of primes obtained with that method.

------
gmaster1440
Nice and short Haskell solution to #3: <http://gist.github.com/617675>

Ruby solutions to #1 and #2: <http://gist.github.com/617676>
<http://gist.github.com/617678>

~~~
thomie
Nice, but don't compute the length of a list if you don't have to.

(not . null) instead of (\x -> length x > 1) is shorter, and works on infinite
lists also.

Edit: well, in case you would test for x>0.

------
grogers
That was fun, good waste of time while my code was compiling. I just used C++
and hacked up a prime seive for #2 and for #3 used a combination generator I
had previously used before -
<http://photon.poly.edu/~hbr/boost/combinations.html>

~~~
cperciva
_for #3 used a combination generator_

Congratulations, you just used an exponential-time algorithm for a polynomial-
time problem.

~~~
Deestan
Congratulations are in order, he sacrificed 400ms CPU time to save at least a
few minutes of coding time.

~~~
cperciva
I wasn't being entirely sarcastic. It never occurred to me that you could use
a non-polynomial-time algorithm.

~~~
util
All the solutions posted here seem to involve generating all subsequences.
Could you say more about your approach?

------
nene
I'm usually pretty bad at these kind of challenges (lately I tried registering
at one mind-challenges site, but I couldn't even get past the five entry-level
questions, which would have allowed me to even register), but this was
surprisingly easy. Simple brute-force methods worked for each of the three
tasks. I was totally surprised that the first time I entered the answer for
each of the tasks, it was indeed the correct one.

But then again... these are all pretty standard computer science problems,
nothing that I hadn't in some way done before.

On a side-note: Interestingly I used recursion for each of the three problems.
Well... actually for the primes-problem I got stack overflow and rewrote it to
not use recursion, but still, at least in principle :=)

~~~
danielsoneg
Agreed - I was laughing as I was writing some of my code because it was so
bad. These sort of questions are designed around algorithm design, but a one-
off problem with these small of sample sets doesn't need an elegant solution -
a hatchet job does just fine. I'm not a CS grad and my math skills are a bit
iffy, but I was able to solve all three challenges in a pretty reasonable
amount of time.

------
jah
Uh ... call a phone number? No thanks.

Edit: Excellent! Back to hacking.

~~~
seanstickle
I'm curious to know why calling a phone number was a deal-breaker.

It seemed eminently likely (to me) that it would be an automated system, but,
even if it wasn't, talking to someone isn't that big a deal to me. I certainly
wasn't concerned about long-distance charges, but I suppose that might be a
problem for some.

I thought it was a nice little twist in the problem set.

~~~
petercooper
_but, even if it wasn't, talking to someone isn't that big a deal to me._

A lot of people struggle with the phone. I certainly have, though I'm getting
better at it. I've noticed many people become spookily compliant on the phone,
endlessly listening to and being polite to even the most annoying callers
instead of just hanging up.

------
jewbacca
Oh my god, Haskell is so pretty. This is the first time I've used it to solve
math problems. Is it kosher to share solutions?

~~~
brandon
I gist'd one because I saw others sharing. I'd be curious to see how you did
things in Haskell.

------
Natsu
Damn, I have to go in to work early today or I could continue this. The first
one only took a minute or two of coding to solve in Perl. The search string
was several times longer than my code, even with use warnings & use strict in
there.

I'd write a bit of code to memoize the function before I'd do the Fibonacci
numbers, though, and I just don't have time to continue right now, even though
it's pretty easy. Are the rest of the tests like that? Do they force you to
use more efficient code, rather than simpler brute force tests so that your
code has a decent runtime?

~~~
Tichy
brute force seems to be sufficient

~~~
leif
you also probably don't want to memoize, you aren't going to re-use, so why
waste the memory?

~~~
Natsu
I wrote that right before leaving for work, so I hadn't spent any time
thinking about the problem.

Coming back, I see that I really don't need to be very efficient for any of
these problems, which I honestly find a little disappointing.

------
1amzave
So what languages did everyone use?

I decided to try a different one on each level, so I used Python, bash
(letting GNU coreutils 'factor' do the hard work), and Haskell, respectively.

~~~
nene
Ruby was my main choice + some command line tools to do bits of extra work,
like 'sort' to find the largest palindrome and 'wc' to count the results in
last exercise, and even Python command line to just manually sum the primes in
second exercise.

~~~
djacobs
Ruby has Array#sort, no command line required.

------
triangleman83
Wow the G. Address was horribly mutilated.

Four score and seven years ago our _faathers_ brought forth on this
_containent_ a new nation conceived _inz_ Liberty and dedicated to the
proposition that all men are created equal Now we are engaged in a _greaht_
civil war testing whether that _naption_ or any _nartion_ so conceived and so
dedicated can long endure We are _qmet_ on a great _battlefiemld_ of _tzhat_
war

~~~
rwalker
This was intentional - we had to tie break the longest palindrome and we
didn't want a quick diff to be able to see what we changed.

~~~
Cushman
Never mind that finding the actual text, removing the spaces and caps, and
running diff would probably take longer than coding and executing a brute
force algorithm :P

------
zmitri
The last question isn't that difficult if you brute force it and have loads of
memory. I tried to do it in python using itertools on my work thinclient and
got a memoryerror. If you however break up your combinations.. you're good to
go!

Fun, made my day. Good idea greplin dudes!

~~~
tbrownaw
Not sure what you'd need the loads of memory for?

    
    
        int[] nums = {...}
        for i = 1 to (2^length(nums) - 1)
            int[] possibility = { nums[x] where (2^x bitand i) > 0 }
            test possibility and perhaps increment hit counter

~~~
zmitri
I was at work on a crappy thin client and first tried to run
list(itertools.combinations(sequence)), which was crapping out. After I
switched it to itertools.combinations(sequence,i) and put that right into my
for loop it was fine.

------
joe_the_user
I've generally done well on job-interview programming challenges and gotten
interviews afterwards. But looking on these quiz things, I'm still frustrated
by them.

You see, all the "ordinary" question involved in job-fitting still have to be
asked and answered so sometimes I've done great in ability part only to have
really basic "culture" or requirements issue hit later when they could have
been caught immediate.

And so, even though I've enjoyed and learned something on these quizzes, the
employer who _begins_ a relationship with a quiz seems to be saying they can
demand some piece of my time without any investment on their part and this
isn't setting a _tone_ reciprocity, something I'd look for in a future
employer.

------
lisper
Too easy to solve by brute force. I'd suggest looking at Project Euler for
inspiration.

~~~
dkarl
I'm a little bored with Project Euler after solving the first 40+ problems
with brute force or near-brute force algorithms. If I wasn't using it to learn
a new language, I would have quit already. As it is, after solving one problem
I usually quit for the day instead of moving on to the next. When do the
problems pick up?

~~~
lisper
Well that depends on your level of expertise :-) I start to have unsolved
problems around #60, but found I had to start getting pretty clever long
before that. The highest number I've solved is 112, and the one before that is
102. YMMV.

------
tedc
1-2 hours! Great...now my productivity will be shot for the day.

------
stelfer
Here's mine: <http://gist.github.com/618459>

I didn't see the point in doing this in anything but C. I tried it without
cheating, and to make it as interesting to myself as possible. Also did it
after a week of writing briefs, so that was a nice way to unwind from that!
Pretty Fun.

Anyway, if I'm applying for a job (which I wasn't), the last thing I'm going
to do is send in a bunch of one-liners.

------
tylrdotorg
This really doesn't reflect a programmers skills in anyway. I managed to write
ruby to solve the problems, but I approached it to do for fun. Brain teasers
aren't going to weed out the good from bad.

Also, considering the instructions explicitly say "write code to..." I would
say using tools that give you the answers is in fact cheating. It's like math
test where you have to show your work.

------
mace
IMHO, these contrived puzzles, while fun, are really unrealistic and don't map
well to problems you'll encounter on the job which requires knowledge,
experience and creativity and do not have just one answer.

Of all of the jobs-page challenges, thesixyone's is probably the most
practical and I've seen:

<http://www.thesixtyone.com/static/jobs>

------
koblas
What about a puzzle system system -- Companies can post/host questions and
then review the answers. I've drafted a quick blog post if anybody wants to
comment more directly... Maybe I'll make it this weekends projects (since my
frid.ge clone was killed by Facebooks new groups).

<http://bit.ly/b6GC6F>

------
temugen
Python powerset() with max(), list.remove(), and sum() builtins made the last
problem's solution ~5 lines long :)

~~~
brandon
I don't know about powerset(), but challenge 3 was pretty trivial using
Python's itertools module: <http://gist.github.com/617663> (warning: spoilers)

------
olalonde
I thought the challenge was to solve everything with "grep" because of the
"Greplin" title.

------
dasil003
Here's better-than-brute-force solution to Q1 <http://gist.github.com/617715>

Is there a better algorithm? Dynamic programming of some sort? I guess we'd
need a longer string to tell the difference.

~~~
leif
I can't read ruby, but here's something a little smarter than brute force in C
(on its way to DP, but I couldn't be arsed to work out the recurrence so I
just iterated until it stabilized): <http://gist.github.com/617854>

~~~
dasil003
It looks similar to mine, but you got lucky (or unlucky depending on how you
look at it) that the longest palindrome had an odd character count.

The confusing bits in the Ruby are actually just the definition of an even and
odd palindrome finder, which are the same except for two seed values for where
the first comparison is conducted and it's length.

~~~
leif
oh whoops nice catch thx

------
btilly
Took < 10 minutes. The problems were very, very easy. If they expect people to
take 1-2 hours and have trouble with this, then the message that I would take
away from this is that their hiring bar is quite low.

~~~
JesseAldridge
[http://www.codinghorror.com/blog/2007/02/why-cant-
programmer...](http://www.codinghorror.com/blog/2007/02/why-cant-programmers-
program.html)

------
g0
<http://codepad.org/rdSirAkD> \-- Solution to third problem in 26 lines of
ruby _without_ using combinations. It's pretty fast too, gives the answer in
0.020s.

------
sahillavingia
Any points for solving part 1 just scanning the text for something that stood
out?

Seriously though, this is awesome. I'd love to know how you guys do in terms
of # of applicants and the end-result (any hires?).

------
jiaaro
solutions in python <http://gist.github.com/617686>

about 30 lines of code in the tersest style, 40ish in the readability-
obsesssive style I prefer

~~~
Natsu
I see that you did brute force primality testing, too. Am I the only one who
at least only divided by _odd_ numbers (and two) in their brute-force is_prime
function? Technically, you only need to test divide by all primes less than or
equal to sqrt(n), after all.

I guess I could have used a faster primality test, but I didn't feel like
writing anything that complex. I know there's a website out there that has a
test that works for anything under about 10 billion, if memory serves, by
using the probabalistic tests and doing a special check for the only
exception. Heck, it even gives you the factors for the largest number in its
range...

~~~
jiaaro
this code solved the problem in under 1 second.

I would say for code that is executed one time ever, even including the
sqrt(n) part is premature optimization (though I did include it)

------
_prototype_
I did the naive implementation for problem 1. (double loop, O(n __2)), in
Javascript. Took chrome about 1 minute to compute the comparisons of all
strings. I'm so lazy.

------
lamnk
Difficult level is about the same as Project Euler's problems 1x

------
siglesias
Anybody else browsing by mobile try to do Level 1 by inspection?

~~~
l0nwlf
Brute works here because of bad test case. Author could have generated a smart
test case and then optimal algorithm could be using suffix array which takes
O(n), brute would take O(n!). However a bit smart brute gave the answer in
approx 3-4 minutes ( computation + coding time). And yes, Python FTW.

~~~
orangecat
Isn't brute force just O(n^3)? Loop over each character to start potential
palindrome, loop from start character to end, reverse substring and compare.
But yeah, the test input should be longer and/or smarter. Ditto on the third
problem.

~~~
brown9-2
_reverse substring and compare_

D'oh! My _is_palindrome(word)_ just got a lot shorter, thanks :)

------
eqdw
Um, no answer on the phone. I let it ring for over a minute.

~~~
Twisol
Did you forget the 1 before the area code? I did.

------
riffraff
damn it had a typo in the fib generation for the second number and lost a lot
of time trying to factor a _massive_ number that was obviously the wrong one
:)

------
badsquare
numbers ="3,4,9,14,15,19,28,37,47,50,54,56,59,61,70,73,78,81,92,95,97].split()
numbers = [int(i) for i in numbers]

def sum_eq(lst,k): total = sum(lst) if total == k or k==0:return 1 elif total
< k or len(lst)==1:return 0 else: n1,nr = lst[0],lst[1:] return
sum_eq(nr,k-n1) + sum_eq(nr,k)

def sum_all_eq(lst): total = 0 for k in range(1,len(lst)): total +=
sum_eq(lst[0:k],lst[k]) return total

------
LordLandon
My C is terribly rusty, so I decided to not cheat with python:
<http://sprunge.us/GiDD>

How terrible is it?

------
bradly
Spoiler alert.

Here is my Part 1 implemented in Ruby. <http://gist.github.com/617566>

------
tta
Anyone know other 'challenges' like this one?

------
zaius
My solutions, in ruby:

<http://gist.github.com/617672>

Any improvements welcome!

(warning - contains the answers!)

------
hammerdr
Anyone else read Q2 as (sum of the prime factors of X) + 1? Confused me for a
good 10 minutes :(

------
orangecat
Done, as usual with these things using Python feels like cheating.

~~~
jasondavies
The last problem was really simple in Python. I was all psyched up for a big
bad end-level boss! Still, it was fun to play.

------
rpbertp13
35 mins, but in less than 40 lines of ruby

~~~
djacobs
I used Ruby, too. Nothing else required.

I think Clojure might've made things a tad easier (given all its sequence
functions), but I'm just learning it, so Ruby all the way.

That said, finding the palindromes in Ruby took me about 12 lines of code
(less if I didn't structure it using methods).

------
ajstiles
30 minutes. Would have been less but the IVR response was a little confusing.
Took about 40 lines Ruby code to solve.

------
dann
what did you put as answer for the first level?

------
droz
too easy. about 30mins and 100 lines of C#.

------
Muzza
There are only 31 known Fibonacci primes (plus a handful probable primes)...

------
hackermom
Problem 1: 2 minutes for 5 lines of PHP code. Problem 2: 1 minute of Google
and Google (why reinvent the wheel?). Problem 3: half a minute of brainwork,
15 minutes worth of tedious PHP snippet.

I got the impression that this particular test was not a good one for finding
apt programmers. The questions and the solutions were just so very "off".

------
ody
suckers ... no really, you are.

