Cyclical figurate numbers

Problem 61

Triangle, square, pentagonal, hexagonal, heptagonal, and octagonal numbers are all figurate (polygonal) numbers and are generated by the following formulae:

Triangle $P_{3,n}=n(n+1)/2$ 1, 3, 6, 10, 15, ...
Square $P_{4,n}=n2$ 1, 4, 9, 16, 25, ...
Pentagonal $P_{5,n}=n(3n−1)/2$ 1, 5, 12, 22, 35, ...
Hexagonal $P_{6,n}=n(2n−1)$ 1, 6, 15, 28, 45, ...
Heptagonal $P_{7,n}=n(5n−3)/2$ 1, 7, 18, 34, 55, ...
Octagonal $P_{8,n}=n(3n−2)$ 1, 8, 21, 40, 65, ...

The ordered set of three 4-digit numbers: 8128, 2882, 8281, has three interesting properties.

The set is cyclic, in that the last two digits of each number is the first two digits of the next number (including the last number with the first). Each polygonal type: triangle ($P_{3,127}=8128$), square ($P_{4,91}=8281$), and pentagonal ($P_{5,44}=2882$), is represented by a different number in the set. This is the only set of 4-digit numbers with this property. Find the sum of the only ordered set of six cyclic 4-digit numbers for which each polygonal type: triangle, square, pentagonal, hexagonal, heptagonal, and octagonal, is represented by a different number in the set.


In [92]:
from euler import timer, Seq, fst, snd

def p061():
    
    values = ([lambda n: n*(n+1)/2, lambda n: n*n, lambda n: n*(3*n-1)/2, 
               lambda n: n*(2*n-1), lambda n: n*(5*n-3)/2, lambda n: n*(3*n-2)]
              >> Seq.mapi(lambda n: n)
              >> Seq.collect(lambda (i,fun): 
                                 Seq.initInfinite(fun)
                                 >> Seq.skipWhile(lambda n: n < 1000) 
                                 >> Seq.takeWhile(lambda n: n < 10000) 
                                 >> Seq.map(lambda n: (i+3, str(n))))
              >> Seq.toList)
    
    result = values >> Seq.map(lambda n: [n])
    
    for i in range(5):
        result = (result 
                  >> Seq.collect(lambda a: 
                                     values 
                                     >> Seq.filter(lambda b: (a[0][1][2:] == b[1][:2]))
                                     >> Seq.filter(lambda b: b[0] not in (a >> Seq.map(fst)))
                                     >> Seq.map(lambda b: [b] + a)))
        
    return (result 
            >> Seq.filter(lambda a: a[5][1][:2] == a[0][1][2:]) 
            >> Seq.head
            >> Seq.sumBy(lambda n: int(n[1])))
    
timer(p061)


result: 28684 (0.38s)

Cubic permutations

Problem 62

The cube, $41063625$ ($345^3$), can be permuted to produce two other cubes: $56623104$ ($384^3$) and $66430125$ ($405^3$). In fact, $41063625$ is the smallest cube which has exactly three permutations of its digits which are also cube.

Find the smallest cube for which exactly five permutations of its digits are cube.


In [207]:
from euler import timer

class Cube:
    def __init__(self, n, perms):
        self.n = n
        self.perms = perms

def p062():
    def make_largest_perm(n):
        k = n
        digits = [0] * 10
        ret_val = 0
        while (k>0):
            digits[k%10] += 1
            k /= 10
        for i in range(9,-1,-1):
            for j in range(0, digits[i]):
                ret_val = ret_val * 10 + i
        return ret_val

    n = 345

    cubes = {}

    while True:
        n += 1
        smallest_perm = make_largest_perm(n*n*n)

        if not(cubes.has_key(smallest_perm)):
            cubes[smallest_perm] = Cube(n, 0)

        cubes[smallest_perm].perms += 1

        if (cubes[smallest_perm].perms == 5):
            return cubes[smallest_perm].n ** 3

timer(p062)


result: 127035954683 (0.13s)

Powerful digit counts

Problem 63

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 $n$th power?


In [227]:
from euler import timer, Seq

def p063():

    f = lambda(n): (Seq.initInfinite(lambda n: n+1)
                    >> Seq.map(lambda m: m ** n)
                    >> Seq.skipWhile(lambda m: len(str(m)) < n)
                    >> Seq.takeWhile(lambda m: len(str(m)) == n)
                    >> Seq.length)

    return (Seq.initInfinite(lambda n: n+1) 
            >> Seq.map(f) 
            >> Seq.takeWhile(lambda l: l > 0) 
            >> Seq.sum)

timer(p063)


result: 49 (0.00s)

Odd period square roots

Problem 64

All square roots are periodic when written as continued fractions and can be written in the form:

$\sqrt{N} = a0 + \frac {1} {a1 + \frac {1} {a2 + \frac {1} {a3 + ...}}}$

Exactly four continued fractions, for $N ≤ 13$, have an odd period.

How many continued fractions for $N ≤ 10000$ have an odd period?


In [233]:
from euler import timer, Seq

def p064():
    def is_odd_period(n):
        r = limit = int(sqrt(n))
        if limit**2 == n:
            return False
        else:
            k, period = 1, 0
            while k !=1 or period == 0:
                k = (n - r * r) // k
                r = (limit + r) // k * k - r
                period += 1
            if period % 2 == 1: 
                return True
            else: 
                return False

    return (range(2, 10001) 
            >> Seq.filter(is_odd_period) 
            >> Seq.length)

timer(p064)


result: 1322 (0.17s)

Convergents of e

Problem 65

The square root of 2 can be written as an infinite continued fraction.

The infinite continued fraction can be written, √2 = [1;(2)], (2) indicates that 2 repeats ad infinitum. In a similar way, √23 = [4;(1,3,1,8)].

It turns out that the sequence of partial values of continued fractions for square roots provide the best rational approximations. Let us consider the convergents for √2.

Hence the sequence of the first ten convergents for √2 are:

1, 3/2, 7/5, 17/12, 41/29, 99/70, 239/169, 577/408, 1393/985, 3363/2378, ... What is most surprising is that the important mathematical constant, e = [2; 1,2,1, 1,4,1, 1,6,1 , ... , 1,2k,1, ...].

The first ten terms in the sequence of convergents for e are:

2, 3, 8/3, 11/4, 19/7, 87/32, 106/39, 193/71, 1264/465, 1457/536, ... The sum of digits in the numerator of the 10th convergent is 1+4+5+7=17.

Find the sum of digits in the numerator of the 100th convergent of the continued fraction for e.


In [30]:
from euler import timer, Seq

def p065():
    return (str((Seq.initInfinite(lambda x: [1, 2*x, 1])
                 >> Seq.skip(1)
                 >> Seq.flatten
                 >> Seq.skip(1)
                 >> Seq.scan(lambda (n,n1), i: (i*n+n1, n), (3,2))
                 >> Seq.skip(98)
                 >> Seq.head)[0]) 
            >> Seq.map(str) 
            >> Seq.map(int) 
            >> Seq.sum)

timer(p065)


result: 272 (0.00s)

Diophantine equation

Problem 66

Consider quadratic Diophantine equations of the form:

$x^2 – Dy^2 = 1$

For example, when $D=13$, the minimal solution in $x$ is $649^2 – 13×180^2 = 1$.

It can be assumed that there are no solutions in positive integers when $D$ is square.

By finding minimal solutions in $x$ for $D = {2, 3, 5, 6, 7}$, we obtain the following:

$3^2 – 2×2^2 = 1$
$2^2 – 3×1^2 = 1$
$9^2 – 5×4^2 = 1$
$5^2 – 6×2^2 = 1$
$8^2 – 7×3^2 = 1$

Hence, by considering minimal solutions in $x$ for $D ≤ 7$, the largest $x$ is obtained when $D=5$.

Find the value of $D ≤ 1000$ in minimal solutions of $x$ for which the largest value of $x$ is obtained.


In [33]:
from math import sqrt
from euler import timer, Seq, fst

def p066():
    isqrt = lambda x: int(sqrt(x))
    is_square = lambda x: x == isqrt(x) ** 2

    def continued_fraction_expansion(s):
        if is_square(s):
            return None
        a0 = isqrt(s)
        def next((d,m)):
            d = (s-m*m)/d
            return ((a0+m)/d, (d, ((a0+m)/d * d-m)))
        return Seq.unfold(next, (1,a0)) >> Seq.append([a0])

    def solve_pell_eq(s):
        return (continued_fraction_expansion(s)
                >> Seq.scan(lambda (h, k, h1, k1), a: (a*h+h1, a*k+k1, h, k), (1,0,0,1))
                >> Seq.skip(1)
                >> Seq.find(lambda (h,k,h1,k1): h*h - s*k*k == 1))

    return (Seq.initInfinite(lambda x: x+2)
            >> Seq.filter(lambda x: not(is_square(x)))
            >> Seq.takeWhile(lambda x: x <= 1000)
            >> Seq.map(lambda x: (solve_pell_eq(x)[0], x))
            >> Seq.maxBy(fst))[1]

timer(p066)


result: 661 (0.05s)

Maximum path sum II

Problem 67

By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.

3
7 4
2 4 6
8 5 9 3

That is, $3 + 7 + 4 + 9 = 23$.

Find the maximum total from top to bottom in triangle.txt (right click and 'Save Link/Target As...'), a 15K text file containing a triangle with one-hundred rows.

NOTE: This is a much more difficult version of Problem 18. It is not possible to try every route to solve this problem, as there are $2^{99}$ altogether! If you could check one trillion ($10^{12}$) routes every second it would take over twenty billion years to check them all. There is an efficient algorithm to solve it. ;o)


In [38]:
from euler import Seq, timer

def p067():
    return (
        open('data/p067.txt').read().splitlines()
        >> Seq.map(lambda s: s.split(' ') >> Seq.map(int))
        >> Seq.rev
        >> Seq.reduce(lambda a,b: a 
                      >> Seq.window(2) 
                      >> Seq.map(max) 
                      >> Seq.zip(b) 
                      >> Seq.map(sum))  
        >> Seq.head)

timer(p067)


result: 7273 (0.01s)

Magic 5-gon ring

Problem 68

Consider the following "magic" 3-gon ring, filled with the numbers 1 to 6, and each line adding to nine.


Working clockwise, and starting from the group of three with the numerically lowest external node (4,3,2 in this example), each solution can be described uniquely. For example, the above solution can be described by the set: 4,3,2; 6,2,1; 5,1,3.

It is possible to complete the ring with four different totals: 9, 10, 11, and 12. There are eight solutions in total.

TotalSolution Set
94,2,3; 5,3,1; 6,1,2
94,3,2; 6,2,1; 5,1,3
102,3,5; 4,5,1; 6,1,3
102,5,3; 6,3,1; 4,1,5
111,4,6; 3,6,2; 5,2,4
111,6,4; 5,4,2; 3,2,6
121,5,6; 2,6,4; 3,4,5
121,6,5; 3,5,4; 2,4,6

By concatenating each group it is possible to form 9-digit strings; the maximum string for a 3-gon ring is 432621513.

Using the numbers 1 to 10, and depending on arrangements, it is possible to form 16- and 17-digit strings. What is the maximum 16-digit string for a "magic" 5-gon ring?


</div>


In [48]:
chunk_by_size = lambda x, i: zip(*[iter(x)]*i)

In [50]:
from euler import timer, Seq
from itertools import permutations

perms = (permutations(range(1,11))
         >> Seq.map(lambda x: chunk_by_size(x, 2))
         >> Seq.toList)

In [53]:
get_sum = lambda a: a[0][0] + a[0][1] + a[1][1] 

# def pred(perm):

In [ ]:
# #load "Common.fs"

# open Common

# #time

# let permutations = permute [1..10] |> List.map (fun lst -> groupsOfAtMost 2 lst |> Seq.toList)

# let sum [| [| a0; a1 |]; [| _; b1 |] |] = a0 + a1 + b1       

# let pred (permutation : int[] list) =
#     let (hd::_tl as heads) = permutation |> List.map Seq.head
#     if heads |> List.forall (fun x -> hd <= x) then
#         let pairs  = seq {
#                         yield! permutation |> Seq.windowed 2
#                         yield  [| Seq.last permutation; Seq.head permutation |]
#                      } |> Seq.toArray
#         let target = sum pairs.[0]
#         pairs |> Array.forall (sum >> (=) target)
#     else false
    
# let answer = permutations 
#              |> List.filter pred
#              |> List.map (fun [a; b; c; d; e] -> 
#                  [|
#                      yield! a; yield Seq.last b
#                      yield! b; yield Seq.last c
#                      yield! c; yield Seq.last d
#                      yield! d; yield Seq.last e
#                      yield! e; yield Seq.last a
#                  |]
#                  |> Array.map string
#                  |> fun arr -> System.String.Join("", arr))
#              |> List.sort
#              |> Seq.last