Path: csiph.com!eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Ben Bacarisse Newsgroups: comp.programming Subject: Re: A little puzzle. Date: Tue, 22 Nov 2022 15:23:56 +0000 Organization: A noiseless patient Spider Lines: 110 Message-ID: <87wn7nj9mb.fsf@bsb.me.uk> References: <875yf8nijb.fsf@bsb.me.uk> <865yf79l66.fsf@linuxsc.com> MIME-Version: 1.0 Content-Type: text/plain Injection-Info: reader01.eternal-september.org; posting-host="9b85f22d308ce2c1806d1ce4165d5a1d"; logging-data="138753"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+6LbJQCECWKjn0jxAJfZ1FLEwUiQqYXIE=" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) Cancel-Lock: sha1:NFFnKv8kRuzWbN8kIwMnn6J8s/I= sha1:FjFnNbhAJK/r89AzPvzlnXtcGz8= X-BSB-Auth: 1.1fefea753ed8551e544e.20221122152356GMT.87wn7nj9mb.fsf@bsb.me.uk Xref: csiph.com comp.programming:15942 Tim Rentsch writes: > Ben Bacarisse writes: > > [...] > >> Consider any ordered measure that "wraps round" -- bearings in degrees, >> minutes in the hour, indeed hours in either the 12 or 24 hour clock. >> The problem is to determine if a given value is in the sub-range >> specified by a start and an [end] value. >> >> I was specifically concerned with integer values where the sub-range >> includes the start value but excludes the end value. >> >> Though I am not sure this merits the term "puzzle", I suggest that >> solutions be posted with some spoiler protection. > > My answer below (forgive me for resorting to "low tech" spoiler > protection)... I think this is the safest option. > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > (spoiler alert) > > /* is_circularly_between( a, b, c ) - > * 1 if b is circularly between a and c, > * 0 otherwise > * the interval of interest [ a, c ) is understood to be > * closed at the 'a' end, and > * open at the 'c' end > * > * The parameters a, b, and c are all of a single type T, > * where T allows relational (ordering) comparisons. > * > * Assumes a, b, and c all have legitimate values. > */ > > int > is_circularly_between( T a, T b, T c ){ > return a <= c ? a <= b && b < c : a <= b || b < c; > } I am sure you know this is correct! My version is recursive, because I think it adds some clarity, but whether it really does add anything probably depends on how one arrives at the answer. bool is_circularly_between(T start, T end, T i) { return start <= end ? start <= i && i < end : !is_circularly_between(end, start, i); } (I put the parameters in a different order because I was using Haskell, and with Curried functions, is_circularly_between x y is a useful function in its own right.) The only reason I thought it worth mentioning was my failure! For the best part of an hour I thought the size of the circular range (the modulus) had to be involved. -- Ben.