Pietro Menna Home page

Other Recurser's solutions to CrackePop!

Some weeks ago a post about “CracklePop” in which I posted two implementations. The post can be found here. After the post, other Recurser’s shared with three more solutions. I decided to post them here.

Mark Dominus’s solution in Perl.

my @num = ("") x 101;
$num[$_*3] .= "Crackle" for 1..33;
$num[$_*5] .= "Pop"     for 1..20;
$num[$_] ||= $_ for 1..100;
shift @num;  # discard element 0
print join "\n", @num, "";

James Keene’s solution.

def fizzbuzz(a): 
return [a, "Fizz", "Buzz", "FizzBuzz"][(0x1241843 >> ((a % 15) * 2)) & 3] 

map(fizzbuzz,xrange(1,100))

At last, with Jeff Fowler’s solution in Brain Fuck which can be found here

I am really amazed to see how many different solutions can be to a very trivial problem.

Mark’s solution I could understand just by reading the code. In order to understand James’s solution I re-writed in a language I knew and debugged the code in order to understand how it worked.

Jeff’s solution I gave up! It is in Brain Fuck and I really do not understand it at all. I found really cool to get to know a really strange computer languaged which I never heard before.

A big thanks to all who shared their solution!

My limited experience with Vagrant

This week I wanted work on one of the issues from the Community App from Recurse Center. In order to be able to work on it, I had to pass through all the steps of installing a local version on my system.

The truth is it was a real pain to get the development environment working. I spent more than a full day focused to make it work on my local system. I could not make it work on my own.

Without the help from David Albert I think I would have still be stuck.

Setting up development systems in some cases is not trivial!

I am sure there are a lot of more complex scenarios than the one I worked yesterday. The community app requires to have installed (up to the date):

In order to setup each of the parts, you need to at least know a bit of each. I never used Postgres, or Elasticsearch. So both of them was a pain for me. But I am sure it can be even harder than this scenario!

##I just wanted to work on a single issue ##

As a developer (or maye a future contributor) I want to read code, write some code, and test it! I should not be bothered by the installation steps.

The diagram below shows how I could describe yesterday: at each cycle in which the installation failed I just felt sader and sader. Maybe some people would quit in the middle of the process.

DEIF

And I have to admit, I spent a full day just on the negative part of the cycle!

Nobody else should spend a day just to set up a Development environment

This is where Vagrant comes in. It allows to create scripts for setting up Virtual Machines. With these scripts you can automate the steps required to set up a Development Environment.

The idea is that only one person should pass the pain of setting up the environment, record the steps to re-create the environment and create the scripts.

Future developers should benefit from this automation.

Conclusion

If you have an OSS Project and you want more contributors, it should be easy to install the development environment. One way of achieving this is to use Vagrant.

Regarding the Recurse Center Community App, I have just sent a Pull Request which adds Vagrant support. Check it out here.

CracklePop

I remember when I applied to Recurse Center, I got asked to write a program called “Crackle Pop”. I just wonder, do all the solutions provided by all the applicants look really different? (I personally doubt it).

How I wrote it

I literally just copied the instructions and transformed it to code. I did not care if it was the best solution, or the most elegant, or even the most perfomance efficient. I actually wrote it in Ruby, but since I am learning Clojure, I will write in Clojure.

The specs:

Write a program that prints out the numbers 1 to 100 (inclusive). If the number is divisible by 3, print Crackle instead of the number. If it's divisible by 5, print Pop. If it's divisible by both 3 and 5, print CracklePop. You can use any language.

The code:

(defn cracklepop [x]
  (cond
    (= 0 (mod x 3) (mod x 5)) (println "CracklePop")
    (= (mod x 3) 0) (println "Crackle")
    (= (mod x 5) 0) (println "Pop")
    :else (println x)))

(map cracklepop (range 1 101))

Let`s try to write it different

Do not use conditionals!!!

It seems crazy, right? The spec already contains 3 ifs statements on its own. So it is so logical to write it using ifs or conditional (switch in other languages) statements.

(defn cracklepop [x]
  (let [solution-matrix {0 "CracklePop"
                         3 "Crackle"
                         5 "Pop"
                         6 "Crackle"
                         9 "Crackle"
                         10 "Pop"
                         12 "Crackle"}]
  (println (solution-matrix (mod x 15) x))))

(map cracklepop (range 1 101))

This solution does not use conditionals, but a “rotating matrix”.

What Solution is better?

I don’t know and I have not measured the runtimes of each solution. I just know that if I was asked during a job interview to write without conditionals, maybe I could have blanked for some minutes. This is because I never thought of the problem with that constrait until now. (Also the preasure of the interview would have added up).

But for sure, I still find the first solution more readable for being closer to the domain of the “requirements”.

Conclusions

There are many solutions to a same problem. Deciding on a solution should depend on the contraints defined by the non-functional requirements.

I also still think that solutions should be written as close to as possible to the domain of the problem. This way the code keeps readable.