The Programming Project

Wednesday, October 22, 2014

Largest exponential : Problem 99 : Project Euler

Largest exponential : Problem 99 : Project Euler

Comparing two numbers written in index form like 211 and 37 is not difficult, as any calculator would confirm that 211 = 2048 < 37 = 2187.
However, confirming that 632382518061 > 519432525806 would be much more difficult, as both numbers contain over three million digits.
Using base_exp.txt (right click and 'Save Link/Target As...'), a 22K text file containing one thousand lines with a base/exponent pair on each line, determine which line number has the greatest numerical value.

NOTE: The first two lines in the file represent the numbers in the example given above.


This is on of the easiest problem of Project Euler! Instead of calculating a^x and b^y actually to determine which one is greater, use the fact from analysis that log x is an increasing function. therefore if  a^x > b^y => x*log a > y*log b



Python Code
import math
def largestExponential():
    maxBE = 0.0
    maxLineNumber = 0
    lineNumber = 1
    val = 0.0
    f = open('base_exp.txt','r')
    for line in f:
        t = line[0:len(line)-1]
        mylist = t.split(",")
        val = float(mylist[1])*math.log(float(mylist[0]))
        if maxBE <= val:
            maxBE = val
            maxLineNumber = lineNumber
        lineNumber = lineNumber + 1   
    print("Maximum value at line Number",maxLineNumber)
largestExponential() 

Reciprocal cycles : Problem 26 : Project Euler : Python Code

Reciprocal cycles : Problem 26 : Project Euler

A unit fraction contains 1 in the numerator. The decimal representation of the unit fractions with denominators 2 to 10 are given:
1/20.5
1/30.(3)
1/40.25
1/50.2
1/60.1(6)
1/70.(142857)
1/80.125
1/90.(1)
1/100.1
Where 0.1(6) means 0.166666..., and has a 1-digit recurring cycle. It can be seen that 1/7 has a 6-digit recurring cycle.
Find the value of d < 1000 for which 1/d contains the longest recurring cycle in its decimal fraction part.

Answer:

Max Length= 985  for Decimal Expansion of 1/ 983 = .001017293997965412004069175991861648016276703967446592065106815869
786368260427263479145473041709053916581892166836215666327568667344
862665310274669379450661241098677517802644964394710071210579857578
840284842319430315361139369277721261444557477110885045778229908443
540183112919633774160732451678535096642929806714140386571719226856
561546286876907426246185147507629704984740590030518819938962360122
075279755849440488301119023397761953204476093591047812817904374364
191251271617497456765005086469989827060020345879959308240081383519
837232960325534079348931841302136317395727365208545269582909460834
181078331637843336724313326551373346897253306205493387589013224821
973550356052899287894201424211597151576805696846388606307222787385
554425228891149542217700915564598168870803662258392675483214649033
570701932858596134282807731434384537131230925737538148524923702950
152594099694811800610376398779247202441505595116988809766022380467
955239064089521871820956256358087487283825025432349949135300

 To solve this problem we have to perform the paper-pencil method of division instead of using inbuilt method of (float) division. Since the divisor if maximum of 3 digits (999) makes the case more easier. Only thing to make note of when to stop the division process, which is best understood upon dividing few examples manually. Try with 1/3, 1/7, 1/8 1/133..... In short a pattern will reappear iff in the process of division by n, let diviList be the collection of of the dividend till the mth step, at the (m+1)th step if the dividend is in diviList, you are done, break!     

Python Code

def reciprocalCycles():
    maxLength = 0
    maxN = 0
    n = 2
    while n < 1000:
        dividend = 1
        divisor = n
        quotient = "."
        diviList = ()
        diviList = diviList + (dividend,)
        while True:
            if dividend < divisor:
                dividend = dividend*10
                if dividend < divisor:
                    dividend = dividend*10
                    quotient = quotient + "0"
                    if dividend < divisor:
                        dividend = dividend*10
                        quotient = quotient + "0"
            if dividend not in diviList:
                diviList = diviList + (dividend,)
            else:
                break
            temp = dividend                   
            dividend = (dividend - (dividend/divisor)*divisor)
            quotient = quotient+str(temp/divisor)   
        if maxLength <= len(quotient):
            maxLength = len(quotient)
            maxN = n   
            q = quotient
        n = n + 1
    print "Max Length=",maxLength," for Decimal Expansion of 1/",maxN,"=",q   
reciprocalCycles()                              

Tuesday, October 21, 2014

Non-abundant sums : Problem 23 : Project Euler : Python Code


Non-abundant sums : Problem 23 : Project Euler

A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.
A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.
As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.
Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.

Python Code:

def nonAbundantSums():
    def sumOfDivisors(numb):
        sumD = 0
        if numb == 1:
            return 0
        for d in range(numb/2):
            d = d+1
            if numb%d ==0:
                sumD = sumD + d
        return sumD   
       
    limit = 28123       
    sumNonAbn = 0
    tot = 0
    AbnList = ()
    n = 12
    """ Find all the abundant Numbers"""
    while n <= limit:
        if n < sumOfDivisors(n):
            AbnList = AbnList + (n,)
            tot = tot + 1
        """print n"""   
        n = n+1
    """ A List to mark all the numbers less than limit which can be written as sum of abundant numbers"""
    UniqueAbnList = [0 for i in range(limit+1)]
        
   
    for i in range(tot):
        """ Since the list of abundant numbers is increasing once the limit crosses 15000, the sum will be always > limit """
        if AbnList[i] > 15000:
            break
        for j in range(i,tot):
            if (AbnList[i]+AbnList[j]) <= limit:
                """ Mark the numbers """
                UniqueAbnList[AbnList[i]+AbnList[j]] = 1
            j = j + 1   
        i = i + 1       
    k = 0               
    for i in UniqueAbnList:
        if UniqueAbnList[k] == 0:
            """ Add the unmarked numbers """
            sumNonAbn = sumNonAbn +k
            print k,"Cannot be written as Sum of two Abundant Numbers"
        k = k + 1   
    print sumNonAbn       
nonAbundantSums()                       

Sunday, October 19, 2014

Permuted multiples :Problem 52 : Project Euler : Python Code

Permuted multiples :Problem 52 : Project Euler

It can be seen that the number, 125874, and its double, 251748, contain exactly the same digits, but in a different order.
Find the smallest positive integer, x, such that 2x, 3x, 4x, 5x, and 6x, contain the same digits.


Python Code

def permutedMultiples():
    x = 1
    while True:
        n1 = str(2*x)
        n2 = str(3*x)
        n3 = str(4*x)
        n4 = str(5*x)
        n5 = str(6*x)
        if len(n1) != len(n2) != len(n3) != len(n4) != len(n5):
            x = x + 1
            continue
        l1 = [0 for i in range(len(n1)) ]
        l2 = [0 for i in range(len(n2)) ]
        l3 = [0 for i in range(len(n3)) ]
        l4 = [0 for i in range(len(n4)) ]
        l5 = [0 for i in range(len(n5)) ]
        for i in range (len(n1)):
            l1[i] = n1[i]
            l2[i] = n2[i]
            l3[i] = n3[i]
            l4[i] = n4[i]
            l5[i] = n5[i]
        l1.sort()
        l2.sort()
        l3.sort()
        l4.sort()
        l5.sort()
        if l1 == l2 == l3 == l4 == l5:
            break
        print "Loop variable",x   
        x = x +1
    print "x= :",x
    print "2x=:",n1
    print "3x=:",n2
    print "4x=:",n3
    print "5x=:",n4
    print "6x=:",n5   
permutedMultiples()           

Pandigital products : Problem 32 : Project Euler : Python Code

Pandigital products : Problem 32 : Project Euler

We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once; for example, the 5-digit number, 15234, is 1 through 5 pandigital.
The product 7254 is unusual, as the identity, 39 × 186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital.
Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital.
HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum.
 
 

First note that if m X n = P, by concatenating m,n and P it will be a 9-digit pandigital number if both in m & n none of the digits are repeated. I have use the function checkOneDigit(numb) to check whether in m or n frequncy of any digit is greater than 1. checkPandigital(numb) simply checks whether a number is n-digit pandigital or not. Next task is to determine the upper limit of m and n. Observe that if m or n is a 5-digit number, after concatenation it will never form a 9-digit pandigital number. Since P will be of atleast 5-digits. So after concatenation the number will consist of 11 digits (even if m is of 1 digit number) Ex. 12345 X m = abcde, after concatenation it results in 12345mabcde, (at-least 11 digits) by Pigeon Hole Principle at least on of the digits 1,2,3,....,9 has to be repeated. Hence Max(m,n) <= 4999, within this range m and n are filtered using checkOneDigit(numb)

Python Code 

  
def pandigitalProducts():

    def checkPandigital(numb):
        flag = True
        strNumber = str(numb)
        length = len(strNumber)
        if '0' in strNumber:
            return False
        nList = [0 for i in range (length)]
        for i in range (length):
            nList[i] = int(strNumber[i])
            if int(strNumber[i]) > length:
                flag = False
        if 0  in nList:
            return False       
        if flag == False:
            return False
        else:
            for i in range (length):
                if nList.count(int(strNumber[i])) > 1 :
                    flag = False
                    break
            return flag
          
    def checkOneDigit(numb):
        flag = True
        strNumber = str(numb)
        length = len(strNumber)
        if '0' in strNumber:
            return False
        nList = [0 for i in range (length)]
        for i in range (length):
            nList[i] = int(strNumber[i])
        for i in range (length):
            if nList.count(int(strNumber[i])) > 1 :
                    flag = False
                    break
        return flag
              
    sumPandigital = 0
    upperLimit = 9999
    n = 1
    pandigitalList = ()
    """ pandigitalList contains the all possible values of m and n """
    while n <= upperLimit:
        if checkOneDigit(n) == True:
            pandigitalList = pandigitalList + (n,)
        n = n+1  
    """print pandigitalList    """
    panProduct = ()
    sumP = 0  
    for d in pandigitalList:
        m = d
        for x in pandigitalList:
            product = 1
            n = x
            product = m*n
            strNumb = ""
            strNumb = strNumb + (str(m)+str(n)+str(product))
            if len(strNumb) == 9:
                if checkPandigital(int(strNumb)) == True:
                    if product not in panProduct:
                        panProduct = panProduct + (product,)
                        sumP = sumP + product
                        print m,"X",n,"=",product,"Partial Sum--------------",sumP  
    print "Required Sum is:",sumP  
pandigitalProducts()        

Saturday, October 18, 2014

Pandigital prime : Problem 41 : Project Euler : Python Code

Pandigital prime : Problem 41 : Project Euler

We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once. For example, 2143 is a 4-digit pandigital and is also prime.
What is the largest n-digit pandigital prime that exists?

 Given that 2143 is a 4-digit pandigital prime. A 5-digit or 6-digit pandigital number cannot be prime because sum of there digits is
1+2+3+4+5 = 15 which is divisible by 3 and also
1+2+3+4+5+6 = 21 which is also divisible by 3 hence the numbers will be divisible by 3 and cannot be prime so we can set the lower limit to be 654321 and upper limit to be 7654321, since a 8-digit or 9-digit pandigital number cannot be a prime by similar arguments.

Python Code

def PandigitalPrime():
    upperLimit = 7654321
    def checkPrime(numb):
        prime = True
        if numb == 1:
            return False
        else:   
            for i in range(int(numb/2)):
                i = i+2
                if numb%i == 0:
                    prime = False
                    break
            if numb == 2:
                return True
            else:           
                return prime
               
    def checkPandigital(numb):
        flag = True
        strNumber = str(numb)
        length = len(strNumber)
        nList = [0 for i in range (length)]
        for i in range (length):
            nList[i] = int(strNumber[i])
            if int(strNumber[i]) > length:
                flag = False
        if 0  in nList:
            return False        
        if flag == False:
            return False
        else:
            for i in range (length):
                if nList.count(int(strNumber[i])) > 1 :
                    flag = False
                    break
            return flag                        
                   
    n =  654321
    largestPandigitalPrime = 0
    while n <= upperLimit:
        if checkPandigital(n) == False:
            n = n + 2
            continue
        if checkPrime(n) == True:
            largestPandigitalPrime = n
            print len(str(n)),"th digit pandigital prime:",n
        n = n + 2
    print "largest Pandigital Prime is:",largestPandigitalPrime   
PandigitalPrime()                       

Coded triangle numbers : Problem 42 : Project Euler : JAVA Code

Coded triangle numbers : Problem 42 : Project Euler

The nth term of the sequence of triangle numbers is given by, tn = ½n(n+1); so the first ten triangle numbers are:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
By converting each letter in a word to a number corresponding to its alphabetical position and adding these values we form a word value. For example, the word value for SKY is 19 + 11 + 25 = 55 = t10. If the word value is a triangle number then we shall call the word a triangle word.
Using words.txt (right click and 'Save Link/Target As...'), a 16K text file containing nearly two-thousand common English words, how many are triangle words?

Note that the file words.txt has been modified, an extra ',' is added at the end of the file for easy extraction of the names. Download it and then edit it to add a ',' after "YOUTH" (the last word of the file)

JAVA Code

import java.io.*;
import java.util.*;
public class CodedTriangleNumbers {
    public static void main(String[] args) throws IOException {
        String fileName = "words.txt";
        String allNames = "";
       
        FileReader fr = new FileReader(fileName);   
        BufferedReader br = new BufferedReader(fr);
        allNames=br.readLine();
        br.close();
        fr.close();
       
        NameExtractionScores nms = new NameExtractionScores();
        System.out.println("Total number of names: "+nms.namesCount(allNames));
        System.out.println("LIST of the names:");
        nms.namesExtraction(allNames);
        System.out.println("Number of triangle words:"+nms.namesTraingular());
        }
    }
class NameExtractionScores {
    public int namesCount(String allNames) {
        for (int i = 0; i < allNames.length(); i++) {
            if (allNames.charAt(i) == ',')
                nameCount++;
            }
        return nameCount;   
        }
   
    public void namesExtraction (String allNames) {
        names = new String[nameCount];
        String temp = "";
        int k = 0;
        for (int i = 0; i < allNames.length(); i++) {
            temp = "";
           
            while ( allNames.charAt(i) != ',' ) {
                if (allNames.charAt(i) != '"')
                    temp += allNames.charAt(i++);
                else   
                    i++;
                }
               
            names[k] = "";
            names[k] +=temp;
            System.out.println(names[k++]);   
            }
        }   
    public int namesTraingular() {
        for (int i = 0; i < nameCount; i++) {
            int cSum = 0;
            boolean tFlag = false;
            for (int j = 0; j < names[i].length(); j++)
                cSum += (names[i].charAt(j)-64);
            int n = 1;
            while (n <= cSum) {
                if (n*(n+1) == 2*cSum) {
                    tFlag = true;
                    break;
                    }
                n++;   
                }   
            if (tFlag == true)
                nameTraingularTotal++;   
            }
        return nameTraingularTotal;   
        }   
    private int nameTraingularTotal = 0;   
    private int nameCount = 0;
    private String[] names;
    }