On Sat, 26 Feb 2011, Erik Mitchell wrote:

> One thing I'd suggest looking into is Project Euler. It provides a great 
> set of computation problems to work through, and you can do it in any 
> language you like. Having real programming problems to work on helps 
> because you're not paying as much attention to the language as you are 
> figuring out how to solve the problem at hand.
>
> http://projecteuler.net/


Fun.  Never heard of it.  I'll do some using GNU commands from the bash 
prompt.  Let me know if you have ways of making these better (e.g., 
shorter or faster).


Here's my effort on Problem #1, using only GNU utils on the Bash command 
line:

seq 999 | awk '$1%5==0 || $1%3==0 {s+=$1}{print s}' | tail -1

I like to do lots of math/stats in GNU R or GNU Octave, both great 
programs, but I also do a lot of things on the Bash command line because 
it is very quick and efficient, once you've learned the tricks.  It took 
me many years to get good enough, a little at a time.  I'm sure one good 
course would do it, but I never had one.


Here's my GNU/bash answer to Problem #2:

( x=1 ; y=1 ; while [ $y -lt 4000000 ] ; do z=$y ; let y=$x+$z ; x=$z ; echo $z ; done ) | awk '$1%2==0 {s+=$1}{print s}' | tail -1


Here's my answer to Problem #3:

( x=600851475143 ; max_fac=10000 ; while [ $x -gt 1 ] ; do i=$(seq 2 $max_fac | awk -v x=$x 'x%$1==0' | head -1) ; echo $i ; let x=$x/$i ; done ) | tail -1

I did it first with a larger value of max_fac, but that slows it way down.

This will print the prime factors of the number "x" in order, as long as 
all of them are less than max_fac, but keep max_fac small because larger 
max_fac slows it down:

x=600851475143 ; max_fac=10000 ; while [ $x -gt 1 ] ; do i=$(seq 2 $max_fac | awk -v x=$x 'x%$1==0' | head -1) ; echo $i ; let x=$x/$i ; done

With a double while-loop and no max_fac, it is slow on the larger factors:

x=600851475143 ; while [ $x -gt 1 ] ; do f=2 ; while [ $(echo $f | awk -v x=$x '{print x%$1}') -gt 0 ] ; do let f=$f+1 ; done ; echo $f ; let x=$x/$f ; done


Another GNU/bash answer, this for Problem #4:

( for i in $(seq 100 999) ; do for j in $(seq 100 $i) ; do let k=$i*$j ; echo $k ; echo $k | rev ; done ; done ) | uniq -c | awk '$1 > 1' | cut -c9- | sort -n | tail -1

It isn't very efficient, though.  It took 13 minutes on my machine.  I 
could have taken a shortcut by guessing that the answer would involve 
larger numbers.  This gives the same answer in 23 seconds:

( for i in $(seq 901 999) ; do for j in $(seq 901 $i) ; do let k=$i*$j ; echo $k ; echo $k | rev ; done ; done ) | uniq -c | awk '$1 > 1' | cut -c9- | sort -n | tail -1

I did use "rev" which could be considered cheating.  It can be written in 
pure internal bash but that is awkward and a bit long.


This is my answer for Problem #5:

let x=2*3*2*5*7*2*3*11*13*2*17*19 ; echo $x

It's just too easy to do it that way.  If they wanted something bigger, 
maybe I'd program the algorithm.


Problem #6:

seq 100 | awk '{s+=$1}{s2+=$1^2}{print s^2-s2}' | tail -1


Must sleep...


Mike