Path: csiph.com!news.swapon.de!eternal-september.org!feeder.eternal-september.org!mx02.eternal-september.org!.POSTED!not-for-mail From: Paul Rubin Newsgroups: comp.lang.forth Subject: Re: Strings and numbers Date: Thu, 10 Sep 2015 17:22:39 -0700 Organization: A noiseless patient Spider Lines: 54 Message-ID: <87oah9st2o.fsf@jester.gateway.pace.com> References: <87egjjk8kn.fsf@jester.gateway.sonic.net> <877fo0t4y0.fsf@jester.gateway.pace.com> <99b72d58-0b1a-4e09-9c34-42ebb844fff8@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: mx02.eternal-september.org; posting-host="3a9ed331cf606b0b072b7def4034f06f"; logging-data="25902"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/Yq5ZbUVd2fAH1kDlISRlB" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) Cancel-Lock: sha1:qfoIaTaaw5usJTpBIG1mm0JsOxA= sha1:hUjgSy5OLsK5YBERvZ00JdkFhSw= Xref: csiph.com comp.lang.forth:41935 Richard Todd writes: > I spent a few minutes with Paul's answer, because it's so much > nicer-looking than mine. ... This is a really interesting program to > me, because I could never have written it. It keeps searching after > it finds the solution -- an option I would never have considered, but > which really simplifies the logic. Also, num usually returns nothing, > but on one one call in the middle of the sequence it leaves 'n' on the > stack. Really nice! Wow, thanks for the kind words. The purpose of keeping on searching was to find all the solutions in the event there was more than one (I didn't know before writing that). I didn't notice that num had a variable stack effect! That's actually a code smell, imho. Originally I printed out n there instead of returning it on the stack, but saw there was only one value printed so I returned it for cleanliness reasons. I changed the program to use your multiply-by-10 trick for 32-bit systems and also to stop searching after the first solution, by throwing/catching an exception (below). > My program is over-engineered and convoluted by comparison. I've been wanting to study yours because it does a better job than mine at splitting the code into small factors, which makes it easier to avoid using locals, improving its Forth purity :). Anyway, here's my current version: ================================================================ \ http://programmingpraxis.com/2015/07/21/a-number-puzzle \ Now works in 64 and 32 bit gforth, thanks to Richard Todd \ for the multiply-by-10 trick : .bit ( i -- n ) 1 swap lshift ; \ bits are numbered from 0 : clear-bit ( n i -- n ) .bit invert and ; \ clear bit i in n : test-bit ( n i -- flag ) .bit and 0<> ; \ true if bit i is 1 : append-digit ( n i -- n ) swap 10 * + ; : num { r n s -- n } s 0= if n throw then 10 1 do n i append-digit s i test-bit over r mod 0= and if r 1+ swap s i clear-bit recurse else drop then loop ; : solve/10 ( -- n ) 1 0 $3fe ['] num catch 2nip nip ; \ cleanup stack from exception : go ( -- ) solve/10 10 m* d. cr ; go \ should print 3816547290 bye ================================================================