# jmoiron/euler.go

26-31

1 parent 8b59fdf commit 260844d0f152bd6757fc4f06cc6bdc17864fa0b3 committed Mar 30, 2012
Showing with 289 additions and 0 deletions.
1. +41 −0 026.go
2. +71 −0 027.go
3. +63 −0 028.go
4. +26 −0 029.go
5. +28 −0 030.go
6. +60 −0 031.go
41 026.go
 @@ -0,0 +1,41 @@ +package main + +import "fmt" + +/* use long division to see how long the cycle is */ +func cycle_length(n, d int ) int { + set := map[int]int {} + length := 0 + + for ; n != 0 ; { + if n < d { + n *= 10 + continue + } + n = n % d + // if the remainder has been encountered before, we've cycled + if set[n] > 0 { + return length + } else { + set[n] = 1 + } + length += 1 + } + // if we've gotten here, it doesn't cycle + return 0 +} + +func main() { + max := 0 + maxi := 0 + + for i:=2; i<1000; i++ { + length := cycle_length(1, i) + if length > max { + max = length + maxi = i + } + } + + fmt.Printf("%d has cycle length %d\n", maxi, max) +}
71 027.go
 @@ -0,0 +1,71 @@ +package main + +import "fmt" + +var primes = map[int]int {} + +func sieve(ch chan int, max int) { + nums := make([]int, max+1) + ch <-2 + for i:=3; i < max; i+=2 { + if nums[i] == 0 { + ch <-i + for n:=i; n <= max; n+=i { + nums[n] = 1 + } + } + } + close(ch) +} + +func init() { + // create a map of primes up to a value; 1000^2 is 1000000, + // but it seems unlikely we'll reach primes that high.. + in := make(chan int) + go sieve(in, 100000) + for next := range in { + primes[next] = 1 + } +} + +func prime_list(max int) []int { + vals := []int {} + in := make(chan int) + go sieve(in, max) + for p := range in { + vals = append(vals, p) + } + return vals +} + +// test how many numbers n^2 + an + b remains prime for +func quad_length(a, b int) int { + for i:=0; ; i++ { + v := i*i + a*i + b + if primes[v] == 0 { + return i + } + } + return -1 +} + +// note we can significantly simplify the search by noting that when n=0, +// n^2 + an + b == b and thus b must be a (positive) prime number +func main() { + bvals := prime_list(1000) + maxlen := 0 + maxa, maxb := 0, 0 + + for a:=-999 ; a < 1000; a++ { + for _,b := range bvals { + ql := quad_length(a, b) + if ql > maxlen { + fmt.Printf("New max len: n^2 + %dn + %d = %d primes\n", a, b, ql) + maxlen = ql + maxa, maxb = a, b + } + } + } + fmt.Printf("Max: n^2 + %dn + %d = %d primes\n", maxa, maxb, maxlen) + fmt.Printf("%d x %d = %d\n", maxa, maxb, maxa*maxb) +}
63 028.go
 @@ -0,0 +1,63 @@ +package main + +import "fmt" + +func ceildiv(n, d int ) int { + if n % d == 0 { + return n / d + } + return (n / d) + 1 +} + +func diagonal_sum(spiral [][]int) int{ + size := len(spiral) + sum := 0; + for i, j := 0, 0; i 0{ + moves++ + toggle = 0 + } else { + toggle++ + } + } + + fmt.Println(diagonal_sum(spiral)) +}
26 029.go
 @@ -0,0 +1,26 @@ +package main + +import ("fmt"; "math/big") + +func pow(a, b int) *big.Int { + mul := big.NewInt(int64(a)) + result := big.NewInt(int64(a)) + for i:=1; i
28 030.go
 @@ -0,0 +1,28 @@ +package main + +import ("fmt"; "strconv") + +func fifth(i uint64) uint64 { + return i*i*i*i*i +} + +func sum_fifth(s string) uint64 { + sum := uint64(0) + for _,c := range s { + n,_ := strconv.Atoi(string(c)) + sum += fifth(uint64(n)) + } + return sum +} + +func main() { + sum := 0 + for i:=2; i<2000000; i++ { + str := strconv.Itoa(i) + if sum_fifth(str) == uint64(i) { + sum += i + fmt.Printf("%d == sum_fifth(%d)\n", i, i) + } + } + fmt.Printf("%d\n", sum) +}
60 031.go
 @@ -0,0 +1,60 @@ +package main + +import "fmt" + +var values = []int {100, 50, 20, 10, 5, 2, 1} + +func main() { + // there's only one way of making it exclusively with one coin of each + // value, and we can't use £2 more than this one way, so we'll disregard + counts := []int {0, 0, 0, 0, 0, 0, 200} + + length := len(values) + pennies := length - 1 + // start at 2, one for the starting position, and 1 for the single £2 coin + tot := 2; + + // the algorithm works like this; all coins are arranged highest to lowest + // value, with 200 pennies being the starting position as valid change for + // 2GBP. The left-most coin that can be subtracted from the pennies is then + // incremented, and pennies decremented by that amount. This position is + // a "pivot", whose place is kept. + + // When the pennies reach below 2, the position to the left of the pivot + // is increased, and everything between that and the end is zeroed out. + // The remainder is set in pennies, and the algorithm starts up again. + + + for x:=0; counts[0] < 2 ; x++ { + if counts[pennies] < 2 { + for i:= pennies-1; i > 0; i-- { + if counts[i] > 0 && (counts[i-1] * values[i-1]) < 200 { + // if we can increase the next highest coin which can receive more + counts[i-1]++ + // adjust the pennies based on the value of that coin + counts[pennies] += (values[i] * counts[i]) - (values[i-1]) + counts[i] = 0 + // because we checked only one coine value and not the + // total sum, we can get an underflow in the pennies which + // will be corrected in the next loop, so increase sum if + // this did not occur + if counts[pennies] >= 0 { + tot += 1 + } + break + } + } + } + for i:= pennies-1; i >= 0 ; i-- { + if values[i] <= counts[pennies] { + counts[i] += 1 + counts[pennies] -= values[i] + tot += 1 + break + } + } + } + + fmt.Println(tot) + +}