Oxaric’s Blog

A compendium of amazing things…

Euler Project Problem #102 Solution

Posted by oxaric on November 24, 2008

It uses C.


Click to directly download euler-solution-102.c

Right click to save the needed data file triangles.txt

// filename 'euler-solution-102.c'
// By: Louis Casillas, oxaric@gmail.com

// Euler Problem #102
// Determine which triangles encompass the origin.
// The file is 'triangles.txt'

#include <stdio.h>

char doesLineCrossXAxis( x1, x2 )
{
   if ( ((x1 < 0) && (x2 > 0)) || ((x1 > 0) && (x2 < 0)) )
   {
      return 1;
   }
   
   return 0;
}

char doesLineCrossYAxis( y1, y2 )
{
   if ( ((y1 < 0) && (y2 > 0)) || ((y1 > 0) && (y2 < 0)) )
   {
      return 1;
   }
   
   return 0;
}

char doesTriangleContainOrigin( x1, y1, x2, y2, x3, y3 )
{
   char does_line1_cross_x_axis = 0;
   char does_line2_cross_x_axis = 0;
   char does_line3_cross_x_axis = 0;

   char num_lines_cross_x_axis = 0;

   // line1
   if ( doesLineCrossXAxis( x1, x2 ) )
   {
      does_line1_cross_x_axis = 1;
      num_lines_cross_x_axis++;
   }

   // line2
   if ( doesLineCrossXAxis( x2, x3 ) )
   {
      does_line2_cross_x_axis = 1;
      num_lines_cross_x_axis++;
   }

   // line3
   if ( doesLineCrossXAxis( x1, x3 ) )
   {
      does_line3_cross_x_axis = 1;
      num_lines_cross_x_axis++;
   }

   // two of the lines must cross the x-axis to make it possible to contain the origin
   if ( num_lines_cross_x_axis < 2 )
   {
      return 0;
   }

   float line1_slope = 0;
   float line2_slope = 0;
   float line3_slope = 0;

   float line1_x_intercept = 0;
   float line2_x_intercept = 0;
   float line3_x_intercept = 0;

   if ( does_line1_cross_x_axis )
   {
      line1_slope = (1.0 * y1 - y2) / (x1 - x2);
      line1_x_intercept = y1 - ( 1.0 * line1_slope * x1 );      
   }

   if ( does_line2_cross_x_axis )
   {
      line2_slope = (1.0 * y2 - y3) / (x2 - x3);
      line2_x_intercept = y2 - ( 1.0 * line2_slope * x2 );
   }

   if ( does_line3_cross_x_axis )
   {
      line3_slope = (1.0 * y1 - y3) / (x1 - x3);
      line3_x_intercept = y3 - ( 1.0 * line3_slope * x3 );
   }

   if ( ((line1_x_intercept > 0) && (line2_x_intercept < 0)) ||
             ((line2_x_intercept > 0) && (line3_x_intercept < 0)) ||
             ((line1_x_intercept > 0) && (line3_x_intercept < 0)) ||
        ((line1_x_intercept < 0) && (line2_x_intercept > 0)) ||
             ((line2_x_intercept < 0) && (line3_x_intercept > 0)) ||
             ((line1_x_intercept < 0) && (line3_x_intercept > 0))

           )
   {
      return 1;
   }

   return 0;
}

int main()
{
   int number_holder = 0;
   char current_point = 1;
   char current_char;
   char is_negative_number = 0;
   int num_that_contain_origin = 0;

   int x1 = 0;
   int y1 = 0;
   int x2 = 0;
   int y2 = 0;
   int x3 = 0;
   int y3 = 0;

//printf( "\n\n%d\n\n", (int)doesTriangleContainOrigin( -340, 495, -153, -910, 835, -947 ) );

   FILE *in_file = fopen("triangles.txt", "rt");

   while( (current_char = fgetc( in_file )) != EOF )
   {   
      if ( current_char == '\r' )
      {
      }
      else if ( current_char == '\n' )
      {
         if ( is_negative_number )
         {
            number_holder *= -1;
         }
         y3 = number_holder;
         number_holder = 0;
         is_negative_number = 0;
         
//         printf( "\n\n%d\t%d\t%d\t%d\t%d\t%d", x1, y1, x2, y2, x3, y3 );
//getchar();

         if ( doesTriangleContainOrigin( x1, y1, x2, y2, x3, y3 ) )
         {
            num_that_contain_origin++;
         }

         current_point = 1;

         x1 = 0;
         y1 = 0;
         x2 = 0;
         y2 = 0;
         x3 = 0;
         y3 = 0;
      }
      else if ( current_char == ',' )
      {
         if ( is_negative_number )
         {
            number_holder *= -1;
         }

         switch( current_point )
         {
            case 1:
               x1 = number_holder;
            break;

            case 2:
               y1 = number_holder;
            break;

            case 3:
               x2 = number_holder;
            break;

            case 4:
               y2 = number_holder;
            break;

            case 5:
               x3 = number_holder;
            break;
         }

         current_point++;

         number_holder = 0;
         is_negative_number = 0;
      }
      else
      {
         // ascii value of '-' is 45, base 10
         
         if ( (int)current_char == 45 )
         {
            is_negative_number = 1;
         }
         else
         {
            number_holder *= 10;
            number_holder += (current_char - '0');
         }
      }
   }

   printf( "\n\nThe number of triangles that contain the origin is: %lu\n\n", num_that_contain_origin );
   
   fclose( in_file );

   printf("\n\n");

   return 0;
}

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>