comp.lang.ada
 help / color / mirror / Atom feed
From: "Robert I. Eachus" <eachus@mitre.org>
Subject: Sums of cubes (was Re: histrionics)
Date: 1999/09/23
Date: 1999-09-23T20:25:54+00:00	[thread overview]
Message-ID: <37EA8DEA.61D49E6A@mitre.org> (raw)
In-Reply-To: Pine.A41.3.96-heb-2.07.990923121911.143704A-100000@pluto.mscc.huji.ac.il

Ehud Lamm wrote:
> 
> If we are on the subject of VHLLs and SETL, let me ask a SETL question. I
> really don't knwo the language, only the basic idea - and since I can not
> find a PC version, it'll take some time for me to get to know it better
> (but learning something Dewar was involved in is likely to be a pleasure:
> SNOBOL, GNAT etc.)

    Good point.  It might be a nice idea to implement SETL in Ada so it
is
easily portable.  (This would be going full circle, since the first
validated
Ada implementation was in SETL!)
 
> How would you find all numbers like 407=4^3+0^3+7^3 that are equal to the
> sum of their digits' cubes?

    Interesting question, but I have found that programming in Ada works
best with a "sandwich" approach, or maybe you want to call it meet in
the middle.  To illustrate, note that one operation that we will be
doing a lot is cubing numbers.  This can be implemented in the form of a
table:

   procedure Sum_of_Cubes is 
     Cube_Table: array(0..9) of Integer :=
       (0, 1, 8, 27, 64, 125, 216, 343, 512, 729);
     -- There are other ways to initialize this table, but cut and paste
from
     -- APL and add commas is pretty quick.
     
     function Cubes(N: Integer) return Integer
       is begin return Cube_Table(N); end Cubes;
     pragma Inline(Cube);

   begin
     TBD;
   end Sum_of_Cubes;

   Okay, now to the algorithm.  There is no need to generalize to more
digits yet, and it is simple enough to write three loops.  I'll keep the
convention
that 000 and 001 are three digit numbers...

   procedure Sum_of_Cubes is
     Cube_Table: array(0..9) of Integer :=
       (0, 1, 8, 27, 64, 125, 216, 343, 512, 729);
     -- There are other ways to initialize this table, but cut and paste
from
     -- APL is very quick.
     
     function Cube(N: Integer) return Integer
       is begin return Cube_Table(N); end Cube;
     pragma Inline(Cube);

   begin
     for I in 0..9 loop
       for J in 0..9 loop
         for K in 0..9 loop
           if Cube(I) + Cube(J) + Cube(K) = 100*I + 10*J + K
           then Print_Result;
           end if;
         end loop;
       end loop;
     end loop;
   end Sum_of_Cubes;

   Now back to the low level, the computation on the right side of the
equality
can be strenth reduced.  A compiler might be smart enough to do it, but
there is no reason not to "do it ourselves" since the algorithm becomes
cleaner, IMHO.
 
   procedure Sum_of_Cubes is
     Cube_Table: array(0..9) of Integer :=
       (0, 1, 8, 27, 64, 125, 216, 343, 512, 729);
     Number: Integer := 0;     
     function Cube(N: Integer) is
       begin return Cube_Table(N); end Cube;
     pragma Inline(Cube);

   begin
     for I in 0..9 loop
       for J in 0..9 loop
         for K in 0..9 loop
           if Cube(I) + Cube(J) + Cube(K) = Number;
           then Print_Result;
           end if;
           Number := Number + 1;
         end loop;
       end loop;
     end loop;
   end Sum_of_Cubes;

   Should we do the same optimization for the sums of cubes?  It looks
like the
best solution/compromise is to do half of it:

   procedure Sum_of_Cubes is
     Cube_Table: array(0..9) of Integer :=
       (0, 1, 8, 27, 64, 125, 216, 343, 512, 729);
     Number: Integer := 0;
     Partial: Integer;     
     function Cube(N: Integer)return Integer
       is begin return Cube_Table(N); end Cube;
     pragma Inline(Cube);

   begin
     for I in 0..9 loop
       for J in 0..9 loop
         Partial := Cube(I) + Cube(J);
         for K in 0..9 loop
           if  Partial + Cube(K) = Number
           then Print_Result;
           end if;
           Number := Number + 1;
         end loop;
       end loop;
     end loop;
   end Sum_of_Cubes;

   Next step write Print_Result.  This could be done as an inline
procedure,
but it is now simple enough to do in place:

   with Ada.Integer_Test_IO; with Ada.Text_IO;
   procedure Sum_of_Cubes is
      subtype Digit is Integer range 0..9;
      Cube_Table: array(Digit) of Integer :=
           (0, 1, 8, 27, 64, 125, 216, 343, 512, 729);
     Number: Integer := 0;
     Partial: Integer;     
     function Cube(N: Integer) return Integer is
        begin return Cube_Table(N); end Cube;
     pragma Inline(Cube);

   begin
     for I in 0..9 loop
       for J in 0..9 loop
         Partial := Cube(I) + Cube(J);
         for K in 0..9 loop
           if  Partial + Cube(K) = Number;
           then Ada.Integer_Text_IO.Put(Number, 4);
           end if;
           Number := Number + 1;
         end loop;
       end loop;
     end loop;
   Ada.Text_IO.New_Line;
   end Sum_of_Cubes;

   A last cleanup that might help the compiler, but will certainly help
readers and maintainers.  There are too many instances of 0..9 in the
code.  Time for a subtype:

   with Ada.Integer_Text_IO; with Ada.Text_IO;
   procedure Sum_of_Cubes is
     subtype Digit is Integer range 0..9;
     Cube_Table: array(Digit) of Integer :=
           (0, 1, 8, 27, 64, 125, 216, 343, 512, 729);
     Number: Integer := 0;
     Partial: Integer;     
     function Cube(N: Digit) return Integer is
        begin return Cube_Table(N); end Cube;
     pragma Inline(Cube);

   begin
     for I in Digit loop
       for J in Digit loop
         Partial := Cube(I) + Cube(J);
         for K in Digit loop
           if  Partial + Cube(K) = Number
           then Ada.Integer_Text_IO.Put(Number, 4);
           end if;
           Number := Number + 1;
         end loop;
       end loop;
     end loop;
   Ada.Text_IO.New_Line;
   end Sum_of_Cubes;

   Modifying to check four digit numbers results in no new matches, but
is very easy (two new lines, two modified, if you don't count the name. 
Also, execution doesn't take long enough to measure.  Changing from
cubes to fourth power (but keeping four digits) results in an output of
    0    1 1634 8208 9474
and only requires changing one line (again ignoring name changes...) 
-- 

                                        Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




  parent reply	other threads:[~1999-09-23  0:00 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-09-09  0:00 histrionics G
1999-09-08  0:00 ` histrionics Preben Randhol
1999-09-09  0:00   ` histrionics G
1999-09-09  0:00     ` histrionics Nick Roberts
1999-09-09  0:00       ` histrionics Robert Dewar
1999-09-10  0:00         ` histrionics Vladimir Olensky
1999-09-10  0:00           ` histrionics Robert Dewar
1999-09-10  0:00             ` histrionics Ted Dennison
1999-09-11  0:00               ` histrionics Bob Collins
1999-09-12  0:00                 ` histrionics Vladimir Olensky
1999-09-13  0:00                 ` histrionics Ted Dennison
1999-09-11  0:00             ` histrionics Vladimir Olensky
1999-09-11  0:00               ` histrionics Robert Dewar
1999-09-11  0:00                 ` histrionics Vladimir Olensky
1999-09-14  0:00                 ` histrionics Robert I. Eachus
     [not found]                   ` <7s2l7b$kmr$1@nnrp1.deja.com>
     [not found]                     ` <37E81661.6DCA23E4@mitre.org>
     [not found]                       ` <7saju5$6h6$1@nnrp1.deja.com>
1999-09-22  0:00                         ` histrionics Robert I. Eachus
1999-09-22  0:00                       ` histrionics Ehud Lamm
1999-09-22  0:00                       ` histrionics p.obry
1999-09-23  0:00                   ` histrionics Ehud Lamm
1999-09-23  0:00                     ` histrionics Ehud Lamm
1999-09-23  0:00                     ` Robert I. Eachus [this message]
1999-09-24  0:00                       ` Sums of cubes (was Re: histrionics) Wes Groleau
1999-09-24  0:00                         ` Robert I. Eachus
1999-09-27  0:00                           ` Wes Groleau
1999-09-24  0:00                       ` Robert Dewar
1999-09-24  0:00                         ` Robert I. Eachus
1999-09-24  0:00                       ` Wes Groleau
1999-09-25  0:00                         ` Robert Dewar
1999-09-11  0:00               ` histrionics Robert Dewar
1999-09-11  0:00                 ` histrionics Vladimir Olensky
1999-09-13  0:00                   ` histrionics Robert Dewar
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox