Skip to content

Latest commit

 

History

History
59 lines (43 loc) · 2.11 KB

README.md

File metadata and controls

59 lines (43 loc) · 2.11 KB

History

This project arose from my attempt to solve some of the Project Euler problems using Mathematica. I found it frustrating that I had to guess how many prime numbers or how many Fibonacci numbers I'd have to scan in order to satisfy the "primes under 2 million" or "Fibonacci numbers under 4 million".

I knew how I'd solve the problem in C# or Python (chaining a bunch of IEnumerables or generators, respectively), and wanted to see how close I could get to that style in Mathematica, so I posed the question on the fledgling Mathematica Stack Exchange site.

A helpful user named WReach wrote up a great rough implementation, citing his experience with the Haskell programming language as his major source of inspiration.

I cleaned up his implementation, put it in a package, and made it look a little more native (First, Rest instead of Head, Tail). I've added a few more functions (TakeWhile, FoldList, Most, Last).

Finally, I added a helper called Lazy that lets you trivially turn many built-ins (Fibonacci[] and Prime[], in fact) into lazy sources that you can pump for as many items as you need without going to too much effort.

I'm providing this code under an MIT-style license in the hopes that others find it useful. If anyone ends up adding any new features, especially by providing Stream upvalues for more built-ins, please send me a pull request.

Happy hacking!

Examples

Project Euler #1: Find the sum of all the multiples of 3 or 5 below 1000.

Total[Lazy[Integers]~TakeWhile~((# < 1000) &)
  ~Select~((Mod[#, 3] == 0 || Mod[#, 5] == 0) &)]

Project Euler #12: What is the value of the first triangle number to have over five hundred divisors?

(* First, a non-lazy helper *)
divisorsLength[n_] := Apply[Times, #[[2]] + 1 & /@ FactorInteger[n]];

(* Then a lazy definition of the (infinite) list of all Triangular numbers. *)
triangles = FoldList[Plus, 0, Lazy[Integers]];

(* Filter that list down to just the ones with more than 500 divisors and take the first element. *)
triangles ~Select~ (divisorsLength[#] > 500 &) // First