From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00,BITCOIN_SPAM_02, PDS_BTC_ID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,CP1252 X-Google-Thread: 103376,a4d2751f9487bd38,start X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-07-03 20:41:51 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!wn14feed!wn13feed!worldnet.att.net!204.127.198.203!attbi_feed3!attbi.com!sccrnsc02.POSTED!not-for-mail Message-ID: <3F04F778.5090305@attbi.com> From: "Robert I. Eachus" User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0.2) Gecko/20021120 Netscape/7.01 X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Real data for a change in the assignment operators and Bounded_String discussions. Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 8bit NNTP-Posting-Host: 24.62.164.137 X-Complaints-To: abuse@attbi.com X-Trace: sccrnsc02 1057290110 24.62.164.137 (Fri, 04 Jul 2003 03:41:50 GMT) NNTP-Posting-Date: Fri, 04 Jul 2003 03:41:50 GMT Organization: AT&T Broadband Date: Fri, 04 Jul 2003 03:41:50 GMT Xref: archiver1.google.com comp.lang.ada:40037 Date: 2003-07-04T03:41:50+00:00 List-Id: "Mr. Wideman" posted the following message to sci.crypt.random-numbers, which has nothing to do with solving secret messages but generating secure random number sequences: ======================================================================== (Maybe related to primes or the magic hexagon - also the result will be in English using the 26 letter alphabet) 1713167174342128171514138189312 3328481316215188174182917819139 9198181712743151518167123321815 3419371816421839151471821218332 8415137933719383167187431713719 2991771571431333719341915183337 13719 ========================================================================= There are no zeros and lots of ones. I thought that it might be a system like the one used by Col. Abel that had one and two digit sequences. So I wrote a quick program (less than 4 hours, including dinner and a break to watch the fireworks from the back steps. ;-) to print out some statistics: count_digits message.txt There were 191 digits. 0= 0 1= 58 2= 14 3= 32 4= 13 5= 9 6= 5 7= 23 8= 21 9= 16 00= 0 01= 0 02= 0 03= 0 04= 0 05= 0 06= 0 07= 0 08= 0 09= 0 10= 0 11= 0 12= 5 13= 8 14= 3 15= 9 16= 5 17= 8 18= 12 19= 8 20= 0 21= 6 22= 0 23= 2 24= 0 25= 0 26= 0 27= 1 28= 3 29= 2 30= 0 31= 7 32= 3 33= 8 34= 3 35= 0 36= 0 37= 7 38= 2 39= 2 40= 0 41= 5 42= 2 43= 4 44= 0 45= 0 46= 0 47= 1 48= 1 49= 0 50= 0 51= 7 52= 0 53= 1 54= 0 55= 0 56= 0 57= 1 58= 0 59= 0 60= 0 61= 0 62= 1 63= 0 64= 1 65= 0 66= 0 67= 3 68= 0 69= 0 70= 0 71= 16 72= 0 73= 0 74= 4 75= 0 76= 0 77= 1 78= 1 79= 1 80= 0 81= 10 82= 2 83= 4 84= 2 85= 0 86= 0 87= 1 88= 1 89= 1 90= 0 91= 6 92= 1 93= 5 94= 0 95= 0 96= 0 97= 0 98= 1 99= 2 The fact that 1 never follows 1 even though it it the most frequent letter seems very suspicious, so I'll probably work back and forth to come up with 1 and 2 digit representations that make sense, then try to solve it as a simple substitution. If my assumptions are right there should be at least a hundred characters, which should be plenty. But I wanted to talk about the Ada program I wrote: ----------------------------------------------------------------------------------------- with Ada.Text_IO; with Ada.Command_Line; procedure Count_Digits is -- A program to count the digits and digit -- pairs in a string. Other charaters are ignored. function Get_Data return String is use Ada.Text_IO; use Ada.Command_Line; Input_File: File_Type; function Recur return String is Buffer: String(1..80); Last_Char: Integer; begin Get_Line(Input_File,Buffer,Last_Char); if End_Of_File(Input_File) then return Buffer(1..Last_Char); else return Buffer(1..Last_Char) & Recur; end if; end Recur; begin Open(Input_File,In_File,Argument(1)); return Recur; Close(Input_File); end Get_Data; procedure Inc (Counter: in out Integer); pragma Inline(Inc); procedure Inc (Counter: in out Integer) is begin Counter := Counter + 1; end Inc; Data: String := Get_Data; Total: Integer; Previous: Character; Single: array(Character range '0'..'9') of Integer := (others => 0); Digraphs: array(Character range '0'..'9', Character range '0'..'9') of Integer := (others => (others => 0)); Start: Integer := Data'First; procedure Print_Data is use Ada.Text_IO; use Ada.Command_Line; Output_File: File_Type; package Int_IO is new Integer_IO(Integer); begin if Argument_Count > 1 then Open(Output_File, Out_File, Argument(2)); Set_Output(Output_File); end if; New_Line; Put_Line(" There were" & Integer'Image(Total) & " digits."); New_Line; for I in Character range '0'..'9' loop Put( " " & I & '='); Int_IO.Put(Single(I),3); end loop; New_Line(2); for I in Character range '0'..'9' loop for J in Character range '0'..'9' loop Put( ' ' & I & J & '='); Int_IO.Put(Digraphs(I,J),3); end loop; New_Line; end loop; New_Line; if Is_Open(Output_File) then Set_Output(Standard_Output); Close(Output_File); end if; end Print_Data; begin -- seed Digraph counting... while Data(Start) not in '0'..'9' loop Start := Start + 1; end loop; Total := 1; -- first character found Previous := Data(Start); Inc(Single(Data(Start))); -- main loop for I in Start+1.. Data'Last loop if Data(I) in '0'..'9' then Inc(Total); Inc(Single(Data(I))); Inc(Digraphs(Previous,Data(I))); Previous := Data(I); end if; end loop; Print_Data; end Count_Digits; ---------------------------------------------------------------------------------------------- First, let me get deal with the Bounded_String argument. This program is the sort of program whene some people think that Bounded_String is needed. I probably would have used a line at a time loop if I expected to deal with hundreds of lines of input. But as you can see, I read all the text data recursively, then splice it together into one String return VALUE. Which goes here: Data: String := Get_Data; The recursive function that does the splicing of lines is ten lines long. Note that if a line is longer than 80 characters, Recur will read it in more than one bite. But I don't have to worry about the layout of the input data. (Just whether the counts will get too high and mess up my neat output formatting.) You just CANNOT code like this in C or many other languages. (I can imagine trying to write that code in C, with mallocs, frees, searches for nul (strlen) and copies all over the place. Ouch!) End of Bounded_String discussion. Now onto the assignment operators. At first I thought this code would be a poster child for the idem proposal. But it was worth it to me to write: procedure Inc (Counter: in out Integer); pragma Inline(Inc); procedure Inc (Counter: in out Integer) is begin Counter := Counter + 1; end Inc; I probably could have written the Inc operation as a one-liner and left off the declaration and the pragma Inline(Inc); but it was easier to write it than to figure out if it was worth the effort. As you can see from the formatting, I definitely belong to the "if the code is unreadable it is wrong" school. The same goes for the pragma Inline in this case--it was easier to put it in than justify leaving it out. I also could have had pragma Inline for Get_Data and Print_Data, but my style is to leave out pragma Inline for procedures or functions that are called once and let the compiler figure it out. Of course, a pragma Inline for Recur would be unlikely to accomplish much. The same argument applies to closing the Input_File and Output_File. It is not really needed, but it documents that I am finished using them. Should Inc be predefined as a procudure? (In addition to as an attribute function.) No. It is clearly easier to declare the version of Inc that I want, than to remember where it is defined, what the parameters are and so on. And I certainly don't want to discuss that in ARG or WG9 meetings for something where the desired functionality fits in one line. I don't expect this to end the discussion on these two issues, but I hope it helps. The three calls in a row to Inc are much clearer than: Total := Total + 1; Single(Data(I)) := Single(Data(I)) + 1; Digraphs(Previous,Data(I))) := Digraphs(Previous,Data(I)) + 1; But part of what makes it much clearer is having the definition of Inc right there. And certainly any argument that Total +:= 1; -- or perhaps Total := idem + 1; -- or whatever is "better" than: Inc(Total); is crazy. If you count characters, the line with the fancy new operator is one character longer. Not that this is an APL contest to do something with the fewest characters. The real win is that the procedure call has fewer parts to understand: a procedure call with one parameter, and requires no language extensions. -- Robert I. Eachus �In an ally, considerations of house, clan, planet, race are insignificant beside two prime questions, which are: 1. Can he shoot? 2. Will he aim at your enemy?� -- from the Laiden novels by Sharon Lee and Steve Miller.