Path: csiph.com!eternal-september.org!feeder.eternal-september.org!nntp.eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c Subject: Re: Cookies in boxes - algorithmic challenge Date: Wed, 08 Apr 2026 08:42:11 -0700 Organization: A noiseless patient Spider Lines: 147 Message-ID: <86tstlwjak.fsf@linuxsc.com> References: <20260401163447.000052de@yahoo.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Date: Wed, 08 Apr 2026 15:42:14 +0000 (UTC) Injection-Info: dont-email.me; posting-host="078da6b6fdfa8b5cb04ea822fecda5b3"; logging-data="3891192"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19ggJ0QG4uP/0T2Pr5pBz0nMFce9lQ0Gg4=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:0Kr04MGT/gQfiLAyky3Tik48ezQ= sha1:5PvcmWkgMz/N1Lqe4ZoXQoDfWaY= Xref: csiph.com comp.lang.c:397424 Michael S writes: [...] Here I am again, ready now to write a more substantive response. > So, here is the challenge: > There are 20 sorts of cookies, 10 of each sort. They are placed in > 20 boxes, again, 10 cookies in each boxes. You have to take exactly > one cookie from each box, all 20 of different sorts. > Smart math heads proved that for any distribution a solution exists. > I don't ask you to repeat the proof. Just peek cookies! I think the problem is interesting. I thought I would try coding something up. > It's obvious that one can find the solution by exhausting. Don't do > it. Indeed, the number of possible peek orders is finite, but ii is > large - 2.4e18. > Be smarter. > On modern PC I want to get a solution in less than 1 msec, bonus for > less than 50usec. [.. C code to drive an exercise a proposed solution ..] > You have to implement function solver() in module solver.c I ran into trouble when I tried to work within the posted framework to drive a solver. The difficulties were of several kinds. The code didn't compile in my standard compilation environment, which is roughly this (the c99 might be c11 but that made no difference): gcc -x c -std=c99 -pedantic ... I was able to work through that problem but it was irksome. The second difficulty is the interface to solver() seems rather clunky to me, maybe not for the input but for the output, and it wasn't clear to me what the specification is for the output (I did manage to figure this out but only much later). I was having to put more effort into figuring out the interface than solving the problem. Finally I abandoned the idea of working within the structure of the posted driver code and wrote a solver to my own specification. Doing that was fairly straightforward and took half an hour or so (disclaimer: after I had spent a good amount of time just thinking about the problem). After writing the solver I reimplemented a driver framework to drive it, conforming to the interface I was using. Some debugging was needed to get everything working. I did some rudimentary time measurements for the solver. Results were good (more about the specifics later). After doing the new solver I went back to the posted driver code, and grafted together the new solver with the orginal driver. Some glue code was needed to reconcile the differences in interface between the new solver and the original driver. Then I needed to figure out the semantics of the output, which were different than what I expected and originally understood. I figured all that out and got things working. Sadly the code was uglier than I would have liked. After that, I talked to a friend to try a different approach to producing a solution. After some light editing by myself -- mostly just formatting and some name changes -- the code below was put into the hopper. (Note: I claim no credit for code below. I did some editing to make it more readable but beyond that none of it is a result of my efforts.) #include #include "solver.h" static uint32_t adjacent[ N_BOXES ]; static int cookie_of_box[ N_BOXES ]; static int box_of_cookie[ N_BOXES ]; static uint32_t seen; static int search( int b ){ uint32_t m = adjacent[b]; while( m ){ uint32_t bit = m & -m; m ^= bit; int c = __builtin_ctz( bit ); if( seen & 1u<