From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on ip-172-31-65-14.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Ben Bacarisse Newsgroups: comp.lang.ada Subject: Re: project euler 26 Date: Thu, 07 Sep 2023 00:32:21 +0100 Organization: A noiseless patient Spider Message-ID: <87o7ieq3ne.fsf@bsb.me.uk> References: <878r9mudvj.fsf@bsb.me.uk> <87a5u1u1yv.fsf@bsb.me.uk> <8734ztttpc.fsf@bsb.me.uk> <87fs3ssl6v.fsf@bsb.me.uk> <87a5u0rts0.fsf@bsb.me.uk> <87jzt3qqlb.fsf@bsb.me.uk> MIME-Version: 1.0 Content-Type: text/plain Injection-Info: dont-email.me; posting-host="347d35c8051c6481b9483e2b861d4761"; logging-data="2833814"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/QlMWjbPMGtBcFWWr7M1rWJ7rix8VpPeg=" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.2 (gnu/linux) Cancel-Lock: sha1:uBWjBnoyd1BWjcW2vhk2ANqquZ0= sha1:j3LOEpPm8tSlA2DcATMKaKlEKxs= X-BSB-Auth: 1.77e11959ac9ce18e30e8.20230907003221BST.87o7ieq3ne.fsf@bsb.me.uk Xref: news.eternal-september.org comp.lang.ada:65608 List-Id: "Dmitry A. Kazakov" writes: > On 2023-09-06 17:16, Ben Bacarisse wrote: > >> I am curious to know how reusable this is. Can the packages be >> instantiated in such a way that the argument ranges over the elements >> of, say, and Ordered_Map? > > Sure: > > with Ada.Containers.Ordered_Maps; > > package Integer_Maps is > new Ada.Containers.Ordered_Maps (Integer, Integer); > use Integer_Maps; > package Cursor_Arguments is new Generic_Arguments (Cursor); Ah! So the arguments correspond to the "with" functions in the order listed, and, since Cursor already has Next, there no need to specify anything. One could (I've just tried) use => notation. You could have written package Arguments is new Generic_Arguments (Next => Positive'Succ, Argument_Type => Positive); in your first example -- swapping the order just to make the point obvious. This tripped me up when I was playing around with a Cursors solution. There are a couple of details that prevent your Maximum_At function from working properly in this case though. First, we can't have an empty map, because X.Last can't be compared with X.First when either is No_Element, so the test for Right < Left fails before the desired error can be raised. Second, if I try to use a Vector rather than an Ordered_Map, I am told that: test2.adb:97:05: error: instantiation error at line 12 test2.adb:97:05: error: no visible subprogram matches the specification for "<" It would seem that vector cursors can't be compared using < (at least by default). Maybe the installation needs more arguments. Anyway, I am still not sure how to write a generic test for an empty range. > package Map_Values is new Generic_Values (Integer); > package Map_Functions is > new Generic_Discrete_Comparable_Valued > (Cursor_Arguments, Map_Values); > > Then given X is a map: X : Map; > > Map_Functions.Maximum_At (X.First, X.Last, Element'Access) It's possible I was not clear about what I was aiming for. I was hoping to be able to find the maximum of some arbitrary function, taking the function's arguments from any sequential collection. Either a simple range of values, an array or vector of values, a list of values or even an ordered map of values -- any ordered list of values. The bottom line is the last argument should be something very general like the Period function. A fix (though it's not really ideal) would be to use function composition here (inventing . as the composition operator): Map_Functions.Maximum_At (X.First, X.Last, Period'Access . Element'Access) but I don't think Ada has a function composition operator, does it? Another solution would be to write Maximum_At so that it knows it has a cursor argument, but then I don't think it would work for native arrays, would it? And we'd loose plain ranges altogether. >> Maybe a more generic a solution would involve passing something that can >> be iterated over, rather than two values of an "enumerated" type? I >> mean enumerated in the mathematical sense -- it may be the wrong word in >> Ada. > > Yes, but Ada does not have built-in range types. Therefore such design will > not work out of the box with discrete types because 2..999 is not a proper > object in Ada. However, talking about abstractions, you can create an > interval type for the purpose or else use an ordered set of integers. But then (I think) the only function one could pass would be something like Element as in you example above. Using an ordered set of integers would not allow Map_Functions.Maximum_At (Set.First, Set.Last, Period'Access) would it? >> I am asking you but I am also the group. I appreciate your help, >> but don't want you to feel any obligation to keep helping! > > No problem. You seem to be on your own as far as helping out is concerned! -- Ben.