Saturday, January 19, 2013

Problem 20: Factorial digit sum

Q)n! means n × (n − 1) × ... × 3 × 2 × 1
For example, 10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800,
and the sum of the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27.
Find the sum of the digits in the number 100!

Solution: 
now since 100! is too large to handled by long, int or any other primitive data type in java , we again use BigInteger library. The solution is very simple:

 
import java.math.BigInteger;


public class Prob20 {

 
 public static void main(String[] args) {
 
BigInteger sum = BigInteger.ZERO;
BigInteger fact = BigInteger.ONE;
BigInteger rem;

for(int i = 1 ; i <= 100 ; i++ )
{
 fact = fact.multiply(BigInteger.valueOf(i));
 
}

 
 while(!fact.equals(BigInteger.ZERO))
 {  
  rem= fact.mod(BigInteger.TEN);
  fact=fact.divide(BigInteger.TEN);
  sum = sum.add(rem);
 } 
 
 System.out.println(sum);

 }
 }



Problem 19: Counting Sundays


You are given the following information, but you may prefer to do some research for yourself.
  • 1 Jan 1900 was a Monday.
  • Thirty days has September,
    April, June and November.
    All the rest have thirty-one,
    Saving February alone,
    Which has twenty-eight, rain or shine.
    And on leap years, twenty-nine.
  • A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.
How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?

Solution:
This is a pretty easy problem, most people will think of using Inbuilt date libraries, but then they are very slow, I solved this by brute force, I think the code is self explanatory.



public class Prob19 {

 
 public static void main(String[] args) 
 {
  int day = 1 ;
  int month = 1;
  int year = 1900;
  String dayName = "Monday";
  int maxDays =0;
  int sundayCounter =0;
  
  while( year < 2001)
  {
   while(month <= 12)
   {
   if(month  == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 )
    maxDays = 31;
   else
   if(month == 2)
   {
   if(leapCounter(year))
   {
    maxDays = 29;
   }
   else
    maxDays = 28;
   }
   else 
    maxDays = 30;
   

   while(day <= maxDays)
   {
    if(day == 1 && dayName.equalsIgnoreCase("sunday") && year > 1900)
     sundayCounter++;
    
    dayName = nextDayReturner(dayName);
    day++;
    
   }
   day  = 1;
   month ++; 
   }
   month = 1;
   year++;
  }
  
System.out.println(sundayCounter);
 }
 static String nextDayReturner(String a)
 {
 a = a.toUpperCase();

  if (a.equalsIgnoreCase("SUNDAY"))
   return "Monday";
  else
  if (a.equalsIgnoreCase("MONDAY"))
   return "Tuesday";
  else
  if (a.equalsIgnoreCase("TUESDAY"))
   return "wednesday";
  else
  if (a.equalsIgnoreCase("WEDNESDAY"))
   return "thursday";
  else
  if (a.equalsIgnoreCase("THURSDAY"))
   return "friday";
  else
  if (a.equalsIgnoreCase("FRIDAY"))
   return "saturday";
  else
   if(a.equalsIgnoreCase("SATURDAY"))
  return "sunday";
   else
    return "Error";
 }

 
 
 

static boolean leapCounter(int year)
{
  if(year%100 == 0)
 {
  if(year % 400 ==0)
   return true;
  else
   return false;
 }else
  if(year % 4 == 0)
   return true;
  else
   return false;
 
 
 
 }
 

}

Problem 18: Maximum path sum I


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
4 6
8 5 9 3
That is, 3 + 7 + 4 + 9 = 23.
Find the maximum total from top to bottom of the triangle below:
75
95 64
17 47 82
18 35 87 10
20 04 82 47 65
19 01 23 75 03 34
88 02 77 73 07 63 67
99 65 04 28 06 16 70 92
41 41 26 56 83 40 80 70 33
41 48 72 33 47 32 37 16 94 29
53 71 44 65 25 43 91 52 97 51 14
70 11 33 28 77 73 17 78 39 68 17 57
91 71 52 38 17 14 91 43 58 50 27 29 48
63 66 04 68 89 53 67 30 73 16 69 87 40 31
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23
NOTE: As there are only 16384 routes, it is possible to solve this problem by trying every route. However, Problem 67, is the same challenge with a triangle containing one-hundred rows; it cannot be solved by brute force, and requires a clever method!


Solution:
This problem can be solved by brute force, but then there's a similar problem,Problem so large that it would take years to solve that by brute force even if you have a very fast machine! By brute force the solution is simple , all you have to do is check each path, and then  find the one with maximum sum.

but since we would need to reuse the code in a later problem, I tried this using dynamic programming. I stored the triangle in an array, I read it from a file, Since a similar problem is again presented later, which is way much larger then this one, writing the array manually was not feasible. 
here's the function that reads the file and stores the triangle in a double dimensional array:





public static int[][] FileRead( String Filepath)throws IOException
 {   int Triangle[][] = {{0},{0}};
  try {
   
   FileReader fr = new FileReader(Filepath);
   FileReader fr2 = new FileReader(Filepath);
   BufferedReader br = new BufferedReader(fr);
   BufferedReader br2 = new BufferedReader(fr2);
   
   String S ;
   String Sline[];
   int lines =0;
   
   while((S=br.readLine())!=null)
   {
    
   lines++; 
   
   }
   
   Triangle = new int[lines][lines];
   Sline = new String[lines];
   
   int j= 0;
   
   while ((S=br2.readLine())!=null) 
   { 
    
    Sline = S.split(" ");
   for(int i = 0; i< sline .length=".length" i="i" integer.parseint="integer.parseint" j="j" line="line" pre="pre" triangle="triangle">


This function takes the file path as parameter and returns an integer array with the values of the triangle.
the triangle is stored in the following format:
0 0 0
7 4 0 0
2 4 6 0
8 5 9 3
now by dynamic programming we have divide the solutions into smaller solutions, that is we divide the triangle into multiple triangles in a similar way :
Two Sub-problems
we keep doing this untill we reach a minimal problem.

the java code to do this given below:

 

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;


public class Prob18 {

 /**
  * @param args
  */
 public static void main(String[] args) throws IOException
 {
 
  String s= "filepath";
  int Triangle[][] = FileRead(s);
  //System.out.println(Triangle.length);
  int lines = Triangle.length;
 

  for (int i = lines - 2; i >= 0; i--) {
      for (int j = 0; j <= i; j++) {
          Triangle[i][j] += Math.max(Triangle[i+1][j],Triangle[i+1][j+1]);
      }
  }

System.out.println(Triangle[0][0]);
 
 } 
 
 
 public static int[][] FileRead( String Filepath)throws IOException
 {   int Triangle[][] = {{0},{0}};
  try {
   
   FileReader fr = new FileReader(Filepath);
   FileReader fr2 = new FileReader(Filepath);
   BufferedReader br = new BufferedReader(fr);
   BufferedReader br2 = new BufferedReader(fr2);
   
   String S ;
   String Sline[];
   int lines =0;
   
   while((S=br.readLine())!=null)
   {
    
   lines++; 
   
   }
   
   Triangle = new int[lines][lines];
   Sline = new String[lines];
   
   int j= 0;
   
   while ((S=br2.readLine())!=null) 
   { 
    
    Sline = S.split(" ");
   for(int i = 0; i< Sline.length;i++)
   {
    Triangle[j][i] = Integer.parseInt(Sline[i]);
   }
   j++;
   }
   
  
  
   
  fr.close(); 
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   System.out.println("Error reading file");
  }
  
 return Triangle;
 }

}

"filepath" should be the path of your text file which stores the triangle.

If you have any confusions, comment , I'd be obliged to clear them.