<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BarneyBlog &#187; project euler</title>
	<atom:link href="http://www.barneyb.com/barneyblog/category/project-euler/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.barneyb.com/barneyblog</link>
	<description>Thoughts, rants, and even some code from the mind of Barney Boisvert.</description>
	<lastBuildDate>Mon, 02 Mar 2020 13:20:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Mathematic Constraint Deduction</title>
		<link>https://www.barneyb.com/barneyblog/2009/03/27/mathematic-constraint-deduction/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/03/27/mathematic-constraint-deduction/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 16:57:10 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[personal]]></category>
		<category><![CDATA[project euler]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=781</guid>
		<description><![CDATA[I didÂ  Project Euler's problem 63 last night, and it was a good one:
The 5-digit number, 16807 = 7^5, is also a fifth power. Similarly, the 9-digit number, 134217728 = 8^9, is a ninth power.
How many n-digit positive integers exist which are also an nth power?
I love this sort of problem.Â  The algorithm for a [...]]]></description>
			<content:encoded><![CDATA[<p>I didÂ  <a href="http://projecteuler.net/">Project Euler</a>'s <a href="http://projecteuler.net/index.php?section=problems&amp;id=63">problem 63</a> last night, and it was a good one:</p>
<blockquote><p>The 5-digit number, 16807 = 7^5, is also a fifth power. Similarly, the 9-digit number, 134217728 = 8^9, is a ninth power.</p>
<p>How many n-digit positive integers exist which are also an nth power?</p></blockquote>
<p>I love this sort of problem.Â  The algorithm for a brute force solution should be quite obvious: loop over bases and exponents, do the exponentiation, and see how many results' lengths match the exponent in question.Â  But the question is what the loop constraints are.Â  For this particular problem you can just write the loops, have them spit out answers, and then hit CTRL-C to terminate when the search stops finding results.Â  But that's cheating.</p>
<p>Once you get the constraints, writing the code is trivial.Â  What I couldn't figure out is how to compute the answer without the loops, though it seemed like that would be possible.Â  After getting the right answer with the scan/check method I read down the forum thread and someone had done it.Â  The proper loop constraints get you about 50% of the way, and I'd gotten another 30% of the way there, but couldn't quite get all the way.Â  I still have trouble applying logarithms correctly when stuff gets complicated.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/03/27/mathematic-constraint-deduction/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Project Euler Test Harness</title>
		<link>https://www.barneyb.com/barneyblog/2009/03/05/project-euler-test-harness/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/03/05/project-euler-test-harness/#comments</comments>
		<pubDate>Fri, 06 Mar 2009 04:39:57 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[project euler]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=710</guid>
		<description><![CDATA[Project Euler is a collection of mathematics/computer science problems, as you probably already know.  I've solved almost 50 of them so far, and I've developd a collection of utilities to make my job easier.  Some of them (factorization routines, prime generators, etc.) I'm not going to share as they are fundamental to solving certain problems.  [...]]]></description>
			<content:encoded><![CDATA[<p><a ="http://projecteuler.net/">Project Euler</a> is a collection of mathematics/computer science problems, as you probably already know.  I've solved almost 50 of them so far, and I've developd a collection of utilities to make my job easier.  Some of them (factorization routines, prime generators, etc.) I'm not going to share as they are fundamental to solving certain problems.  However, I will share my test harness, as it's probably generally useful, and it contains no "secrets".</p>
<p>Why build a custom harness?  Well, I originally considered using JUnit (or whatever) as a simple runner, but since there isn't anything to test, it didn't feel right.  It also doesn't provide a good way to get timing information for the runs.  And since I was originally using strictly Groovy, I didn't want to impose any more "ceremony" than I needed to.  I've since started doing some problems in Java simply for the performance (as well as converting some of those "secret" routines), and have generalized my harness.</p>
<p>First, here are the file templates for Groovy:</p>
<pre>import util.Runner

new <span style="color: #ff0000;">Runner</span>() {
  <span style="color: #0000ff;">// put some code here, eh?</span>
}</pre>
<p>and for Java:</p>
<pre>import util.Runner;
import util.java.Solver;

public class BruteForce {
  public static void main(String[] args) {
    new <span style="color: #ff0000;">Runner</span>(new <span style="color: #339966;">Solver</span>() {
      public Object solve() {
        <span style="color: #0000ff;">// put some code here, eh?</span>
        return null;
      }
    });
  }
}</pre>
<p>As expected the Java version requires quite a bit more ceremony, even though the semantics of the two templates are identical.  The Solver interface (used for Java) is as follows:</p>
<pre>package util.java;

public interface <span style="color: #339966;">Solver </span>{
   public Object solve();
}</pre>
<p>Finally, the <span style="color: #ff0000;">Runner</span> class, which is implemented in Groovy.  As you can see from the templates, it accepts either a <span style="color: #339966;">Solver</span> instance or a Groovy closure, and treats the two in exactly the same way, excepting that it picks between <span style="color: #339966;">Solver</span>.solve() and Closure.call() based on the type.</p>
<pre>package util

import util.java.Solver

class <span style="color: #ff0000;">Runner</span> {

  private static ThreadLocal timer = new InheritableThreadLocal()
  private static int timerCount = 0

  def Runner(solver) {
    this(true, solver)
  }

  def Runner(doIt, solver) {
    if (! doIt) {
      return
    }
    startTimer()
    // this will send an update every five or so seconds
    volatile def updateThread
    updateThread = Thread.startDaemon {
      while (true) {
        Thread.sleep(5000)
        if (updateThread == null) {
          break // after the sleep, before the log
        }
        log("still executing...")
      }
    }
    try {
      log("starting...")
      def result;
      if (solver instanceof <span style="color: #339966;">Solver</span>) {    // the closure/Solver switch
        result = solver.solve()          //  |
      } else { // better be a Closure    //  |
        result = solver.call()           //  |
      }                                  //  V
      stopTimer()
      if (result instanceof String) {
        try {
          result = new BigInteger(result)
        } catch (e) {
          // oh well
        }
      }
      if (result instanceof Integer || result instanceof Long || result instanceof BigInteger) {
        log("result: $result")
      } else {
        def s = "" + result
        if (s.length() > 100) {
          s = s[0..<97] + "..."
        }
        log("result was not numeric: $s", System.err)
      }
    } finally {
      updateThread = null
    }
  }

  def elapsed() {
    get().elapsed
  }

  def formatElapsed(e) {
    def seconds = e.intdiv(1000)
    def millis = e % 1000
    def s = ""
    if (seconds >= 60) {
      s += seconds.intdiv(60) + ":"
      seconds = seconds % 60
    }
    if (s.length() > 0 &#038;&#038; seconds < 10) {
      s += "0$seconds"
    } else {
      s += seconds
    }
    if (millis < 10) {
      s += ".00$millis"
    } else if (millis < 100) {
      s += ".0$millis"
    } else {
      s += ".$millis"
    }
    s
  }

  def log(Object msg, out=System.out) {
    def t = get()
    out.println "[${t.index}: ${formatElapsed(t.elapsed)}] $msg"
  }

  private startTimer() {
    Runner.timer.set(new TimerData(++timerCount))
  }

  private stopTimer() {
    get().stop()
  }

  private get() {
    def t = Runner.timer.get()
    if (! t) {
      throw new IllegalStateException("No timer has been started...")
    }
    t
  }
}

class TimerData {
  def index
  def startDate
  def stopDate

  def TimerData(threadIndex) {
    index = threadIndex
    startDate = new Date()
  }

  def stop() {
    stopDate = new Date()
  }

  def getElapsed() {
    if (running) {
      return new Date().time - startDate.time
    } else {
      return stopDate.time - startDate.time
    }
  }

  boolean isRunning() {
    stopDate == null
  }
}</pre>
<p>There's a lot of stuff going on there, but primarily it's setting up a timing framework, a background thread to tell you it's still running every 5 seconds, and doing some magic with the returned solution.  As you can see, the constructor takes an optional first parameter for whether to execute.  Useful if you have multiple Runners in a single script/class, but only want to run some of them. <a href="https://maxinternet.biz/best-gas-grills-under-300">https://maxinternet.biz/best-gas-grills-under-300</a></p>
<p>It wasn't my intent, but building this out was quite educational in the way the Java/Groovy interplay works.  Write Groovy for whatever you can, and write Java for the bits that need it.  As you can see from the templates, Java requires a lot more work, but it has benefits.  I was quite pleased to be able to use my Groovy harness (which leverages all kinds of Groovy goodness) for my Java solutions.  I originally figured I'd have to port it to Java to use it with both languages, but not the case.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/03/05/project-euler-test-harness/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Groovy Letdown</title>
		<link>https://www.barneyb.com/barneyblog/2009/03/02/a-groovy-letdown/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/03/02/a-groovy-letdown/#comments</comments>
		<pubDate>Tue, 03 Mar 2009 06:18:42 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[coldfusion]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[project euler]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=704</guid>
		<description><![CDATA[I'm a huge fan of Groovy, but it's major downside drove over me like a bus this evening.Â  What's that, you say?Â  Performance, of course.Â  Runtime "stuff" necessarily happens at runtime, and therefore affects performance.Â  Does this matter in most cases?Â  No, absolutely not.Â  In general it's far cheaper to buy hardware than to employ [...]]]></description>
			<content:encoded><![CDATA[<p>I'm a huge fan of Groovy, but it's major downside drove over me like a bus this evening.Â  What's that, you say?Â  Performance, of course.Â  Runtime "stuff" necessarily happens at runtime, and therefore affects performance.Â  Does this matter in most cases?Â  No, absolutely not.Â  In general it's far cheaper to buy hardware than to employ developers, so ease of development and maintenance almost always trumps raw performance.Â  This is why we use high level languages as opposed to writing everything in assembler.</p>
<p>As you probably expect, I was working on Project Euler.Â  <a href="http://projecteuler.net/index.php?section=problems&amp;id=39">Problem 39</a>, to be specific.Â  The algorithm is simple, and if you pay attention, you don't even have to do the full scan to get the answer.Â  However, I couldn't get within the minute boundary with my algorithm.Â  I did a whole bunch of optimizations to ensure I was doing absolutely as little work as possible (including stopping the search at the known answer!) and still couldn't even come close to the minute deadline.</p>
<p>On a whim, I took my brutish, unoptimized version (because the syntax was less Groovy-ish) and dropped it into a Java class.Â  I had to add a pile of semicolons and variable types, insert a couple imports, and convert a GString, but the rest was untouched.Â  Full scan (from 1-1000) in 172 milliseconds.Â  Needless to say I was disappointed.</p>
<p>Am I going to abandon Groovy for Java?Â  Hell no.Â  But definitely going to consider reimplementing some of my hard-core subroutines in Java.Â  Just another case of knowing your tools so you can pick the right one for the job.Â  And just to be clear, I have no expectation that this sort of performance difference is in any way indicative of Groovy's general performance.Â  In fact, I find Groovy to be ridiculously fast, in general, because I'm typically doing far higher-level operations (like using Hibernate).</p>
<p>One interesting point was that copy and pasting the Java version into a Groovy file and running it (with all the semicolons and explicit variable typings) didn't affect the Groovy performance much.Â  That surprised me.Â  Apparently the Groovy compiler treats 'int' as 'Integer' or something similar.Â  I've never looked into it very deeply, but worth mentioning I thought.</p>
<p>Also interesting is that CFSCRIPT on CF 8.0.1 turns in times that are slightly faster than Groovy running through <a href="http://www.barneyb.com/barneyblog/projects/cfgroovy/" target="_self">CFGroovy</a> on the same page.Â  I would have expected the reverse since CF uses java.lang.Double internally, but it seems the lack of unboxing/reboxing makes up for the floating point calculations.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/03/02/a-groovy-letdown/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Public Project Euler Dashboards</title>
		<link>https://www.barneyb.com/barneyblog/2009/02/20/public-project-euler-dashboards/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/02/20/public-project-euler-dashboards/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 07:24:16 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[project euler]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=696</guid>
		<description><![CDATA[Project Euler doesn't support any kind of public stats for users, which is kind of lame I thought.Â  I posted about it on the Project forum and got no response, so I built my own: http://barneyb.com/projecteuler/.Â  The code is a total hack, faking a login to grab the protected profile page and then doing some [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://projecteuler.net/">Project Euler</a> doesn't support any kind of public stats for users, which is kind of lame I thought.Â  I posted about it on the Project forum and got no response, so I built my own: <a href="http://barneyb.com/projecteuler/">http://barneyb.com/projecteuler/</a>.Â  The code is a total hack, faking a login to grab the protected profile page and then doing some string ripping, an xmlParse, and a few xmlSearches on the returned HTML to extract the relevant data.Â  However, it works quite well, and with how stable their site's backing code seems to be, I'm not terribly concerned.</p>
<p>The first version just showed my stats (it had my tokens hard coded).Â  The current version has the ability to create a dashboard for any user via the new link at the bottom of the page.Â  You have to supply either your credentials or your browser cookies so the server can get your data, but there isn't any server-side storage of anything.Â  The URL token that identifies the dashboard as yours also carries the tokens needed to fetch data from Project Euler.Â  If needed, they're extracted at runtime and used.</p>
<p>Whether anyone will ever use it, who knows, but it was an interesting set of problems to deal with.Â  Also be good to clean up the URLs a bit, but didn't figure it was worth it at this point.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/02/20/public-project-euler-dashboards/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Prime Factorization</title>
		<link>https://www.barneyb.com/barneyblog/2009/02/05/prime-factorization/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/02/05/prime-factorization/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 06:38:49 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[project euler]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=690</guid>
		<description><![CDATA[In my ongoing rampage through the Project Euler problems I've needed a prime factorization routine several times, and figured I'd share it as a complement to the sieve I shared last week.Â  Implemented in Groovy, of course.Â  Typing is a little strange on first glimpse because Groovy uses Integer by default which only supports values [...]]]></description>
			<content:encoded><![CDATA[<p>In my ongoing rampage through the <a href="http://projecteuler.net/">Project Euler</a> problems I've needed a prime factorization routine several times, and figured I'd share it as a complement to the <a href="http://www.barneyb.com/barneyblog/2009/01/29/the-groovy-sieve-of-barney/">sieve I shared last week</a>.Â  Implemented in Groovy, of course.Â  Typing is a little strange on first glimpse because Groovy uses Integer by default which only supports values up to 2.1 billion.Â  So there are a number of explicit BigInteger types/casts.</p>
<pre>def factor(BigInteger num) {
  def factors = []
  while (num % 2 == 0) {
    factors.push(2)
    num = (BigInteger)(num / 2)
  }
  BigInteger end = floor(sqrt(num))
  for (def currFactor = 3; num &gt; 1 &amp;&amp; currFactor &lt;= end; currFactor += 2) {
    if (num % currFactor == 0) {
      while (num % currFactor == 0) {
        factors.push(currFactor)
        num = (BigInteger)(num /currFactor)
      }
      end = (BigInteger) floor(sqrt(num))
    }
  }
  if (num != 1 || factors.size() == 0) {
    factors.push(num)
  }
  factors
}</pre>
<p>The algorithm is pretty simple: loop through all odd numbers and see if they're a factor of the target number.Â  There's a special case at the top for two (the only even prime), which then lets the loop skip all the even numbers (effectively cutting it's work in half).Â  There's also a special case at the bottom for ones.Â  If you attempt to factor one or a prime number, you'll get that number back as the only item in the list, otherwise you'll get only prime factors (and no, one is not prime).Â  Note that the list can contain duplicates; the method returns <strong>all</strong> prime factors, not just distinct ones.</p>
<p>Why does this work?Â  Because by the time the loop gets to each number all of it's factors have been processed, so it can't be both a factor of the target number and composite (non-prime).Â  So if it's a factor, it has to be prime as well.</p>
<p>For those of you who follow me on Twitter (<a href="http://twitter.com/barneyb">@barneyb</a>), this is not the crappy algorithm I first implemented.Â  This is the good one.Â  My first attempt was an "inversion" of the sieve algorithm which resulted in <em>huge</em> amounts of unneeded work and memory consumption because of the data structures involved.Â  The second algorithm is virtually identical, just the data structures are different (enormously simpler).Â  I wasn't really that far off with the first attempt, I just didn't do a good job of distilling the problem down to it's essence, so I was doing a lot of extra work (three-orders-of-magnitude extra).</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/02/05/prime-factorization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Project Euler</title>
		<link>https://www.barneyb.com/barneyblog/2009/02/05/project-euler/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/02/05/project-euler/#comments</comments>
		<pubDate>Thu, 05 Feb 2009 17:52:51 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[project euler]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=687</guid>
		<description><![CDATA[In the comments to my post about my prime sieve from last week, Duncan pointed me to Project Euler, which is a collection of math problems that you can solve.Â  Not sure if it makes me crazy that I think it's really cool, but I do.Â  Even better, once you solve a problem, you gain [...]]]></description>
			<content:encoded><![CDATA[<p>In the comments to my post about my <a href="http://www.barneyb.com/barneyblog/2009/01/29/the-groovy-sieve-of-barney/">prime sieve</a> from last week, <a href="http://duncan99.wordpress.com/">Duncan</a> pointed me to <a href="http://projecteuler.net/">Project Euler</a>, which is a collection of math problems that you can solve.Â  Not sure if it makes me crazy that I think it's really cool, but I do.Â  Even better, once you solve a problem, you gain access to a protected forum thread and a nice PDF writeup discussing the problem and possible solutions.</p>
<p>For example, <a href="http://projecteuler.net/index.php?section=problems&amp;id=1">problem 1</a> can be solved by a simple loop/modulo algorithm, but that gets expensive as the range increases in size (it's O(n)).Â  For &lt;1,000 it's quite speedy, but for &lt;1,000,000 it takes a long time.Â  There is a far better algorithm using a series expansion/summation that operates O(1).Â  The writeup includes discussion of both algorithms, including code.Â  Very cool.</p>
<p>If you want to find me out, I'm 'barneyb'.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/02/05/project-euler/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
