Math doesn’t work correctly:
> 212227119877294391 * 86400
On non-broken rubies:
> 212227119877294391 * 86400
(This has something to do with Fixnums that are larger than 32 bits failing to jump to Bignums correctly. I do not know whether it affects other 64bit versions of ruby)
I realized that I’ll never be able to finish inventing a programming language if I don’t learn a LISP first.
So I’ve been playing with Project Euler with a Clojure repl, and … well, it’s not ruby and it’s not Haskell.
But it has a lot of lazy data structures, so I decided to pretend I was writing Haskell anyway and see what happens.
Here’s a Haskell-ish way to generate the fibonacci numbers:
let fib = 1 : 1 : (map (uncurry (+)) (zip (drop 1 fib) fib))
So I decided to port it directly to Clojure. It wouldn’t be possible to do in a language that didn’t have lazy sequences, but I was able to do it in Clojure pretty straightforwardly. Here’s a before-and-after, so you can see how the two definitions relate:
let fib = 1:1 : (map (uncurry (+)) ( zip (drop 1 fib ) fib ) ) (defn fib  ( lazy-cat [ 1 1 ] (map (partial apply + ) ( partition 2 (interleave (drop 1 (fib)) (fib) ) ) ) ) )
Gosh, you know, after a while you don’t even see those parentheses.
Let’s see how it works!
Here’s Haskell, for reference:
Prelude> take 30 fib
And the Clojure:
user=> (take 30 (fib))
java.lang.OutOfMemoryError: Java heap space
(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393
Well, there you have it.
Which is really just a physical projection of a 3D model I made in CAD:
which was really challenging since I had never really used 3D CAD before at all.
after some flailing about, I came up with a process that looked like this:
I think I can probably do better in the future. It seems like it should be possible to make a toolchain that does (image)->Trace->Extrude->Rotate->Translate->Export without human intervention.
If I had that, I’d actually work on writing a program that solved the interesting parts of the sundial (most of which I solved on paper for this prototype)
I’ve been trying to learn some old-school algorithms; the sort of things that CS people study but rarely come up at programming gigs.
The thing is, descriptions of algorithms online tend to suck. and open source implementations of textbook algorithms tend to suck.
So, I’m going to try to improve the situation. So, here’s my first attempt. A* algorithm in simple readable ruby: https://github.com/jes5199/astar/blob/master/astar.rb
In real code, we found a very, very slow loop. Changing two characters:
+=is about 100 seconds.
<<is around 1/3 of a second.
+= on a string creates a copy and then discards the original, while
<< allows the ruby interpreter to intelligently resize the buffer.
The only gotcha is that
<< will mutate your string object, which means that it’s not safe to use on a method’s parameters.
#dup those strings, if you need to append to them.
Rogues are very keen in their profession, and know already much more than we can teach them respecting their several kinds of roguery.
I love everything about this internet artifact I’ve found: http://en.wikipedia.org/wiki/Full_disclosure#History . Actually, I want you to have today’s snapshot of the wikipedia article - I suspect that eventually this page will get cleaned up into an encyclopedia article, and it’s just too nice as work of (oh, I don’t know) postmodern literature? cyberspace effluvia? bird cage lining?
————— Forwarded message —————
From: Markus Roberts <email@example.com>
Date: Tue, Sep 14, 2010 at 1:57 PM
Subject: [Puppet-dev] Oops
To: puppet-dev <firstname.lastname@example.org>
Funny story: as the number of developers working on Puppet and related projects at PuppetLabs has increased, the average distance between them has dropped geometrically*, to the point that if we want to discuss something we’re working on with someone, we can (in many cases literally) reach out and tap a fellow developer on the shoulder. This is great for us but it has had an unfortunate unintended consequence: we’ve been doing more and more face-to-face discussions and less and less on this list.
This wasn’t intentional and (though it seems blindingly obvious in hindsight) wasn’t expected either. It was, as one five year old put it, a blundersight.
So we’re going to try something we hope will fix things; office chat is still going to go on as normal — we’ll spare you our debates about whether we should try having lunch at the place with the cult videos on all the TVs again or who’s going to show the new developer the ropes — but if anyone starts to have a substantive discussion about Puppet & friends we’ll cut them off and tell them to tell it to the list.
That means that when we’re kicking around ideas you’ll get to see them and put in your two cents worth on equal footing with the developers in the office (since we really do want your input). It also means that you’ll get to see some ideas that never go anywhere, and crazy things that are (mercifully) shot down in their first few hours. But then you’ll also get to see the direction of our thinking long before some of it results in a line of code, and help us shape it before anything is settled.
Hopefully, it’ll be just like the old days.
— PuppetLab Developer Team:
* Actually, it’s probably something like k*(sqrt(s^2/n)-r) for n developers of mean radius r in a s x s office, with k some constant around 3.
I participated in the 2010 ICFP programming contest a couple weeks ago, and my team (“vorpal”) did the best of any team I’ve been on yet: 16th place.
While I’m waiting for teammate Paul Berry to write a detailed retelling of our progress, it occurred to me that I want to share the most elegant function I’ve written in a long time:
type Fuel = [[[Integer]]]
parseFuel :: String -> (Fuel, String)
parseFuel = parseTritList $ parseTritList $ parseTritList $ parseIntSchemeTwo
where I was taking a string of trinary digits and creating a “Fuel”, which turned out to be, in the context of the puzzle, a list of lists of lists of integers.
It helps that the ICFP’s serialization format was elegantly recursive, but I can’t help but have the feeling that Haskell functions are composable in a way that other languages aren’t. Which is frustrating, because generally I don’t want to be writing Haskell, there’s just occasional moments like this where it’s a perfect fit.
In traditional haskell style, I’ll give you the type signature of the component functions, and leave the implementation as an exercise for the reader:
parseIntSchemeTwo :: String -> (Integer, String)
parseTritList :: (String -> (a, String)) -> String -> ([a], String)