on writing a while loop for rolling two dice

Chris Angelico rosuav at gmail.com
Sat Sep 11 02:03:26 EDT 2021


On Sat, Sep 11, 2021 at 3:26 PM dn via Python-list
<python-list at python.org> wrote:
>
> On 31/08/2021 01.50, Chris Angelico wrote:
> > On Mon, Aug 30, 2021 at 11:13 PM David Raymond <David.Raymond at tomtom.com> wrote:
> >>
> >>> def how_many_times():
> >>>   x, y = 0, 1
> >>>   c = 0
> >>>   while x != y:
> >>>     c = c + 1
> >>>     x, y = roll()
> >>>   return c, (x, y)
> >>
> >> Since I haven't seen it used in answers yet, here's another option using our new walrus operator
> >>
> >> def how_many_times():
> >>     roll_count = 1
> >>     while (rolls := roll())[0] != rolls[1]:
> >>         roll_count += 1
> >>     return (roll_count, rolls)
> >>
> >
> > Since we're creating solutions that use features in completely
> > unnecessary ways, here's a version that uses collections.Counter:
> >
> > def how_many_times():
> >     return next((count, rolls) for count, rolls in
> > enumerate(iter(roll, None)) if len(Counter(rolls)) == 1)
> >
> > Do I get bonus points for it being a one-liner that doesn't fit in
> > eighty characters?
>
>
> Herewith my claim to one-liner fame (assuming such leads in any way to
> virtue or fame)
>
> It retains @Peter's preference for a more re-usable roll_die() which
> returns a single event, cf the OP's roll() which returns two results).
>
>
> import itertools, random
>
> def roll_die():
>     while True:
>         yield random.randrange(1, 7)
>
> def how_many_times():
>     return list( itertools.takewhile( lambda r:r[ 0 ] != r[ 1 ],
>                                       zip( roll_die(), roll_die() )
>                                       )
>                )
>
> Also, a claim for 'bonus points' because the one-liner will fit within
> 80-characters - if only I didn't have that pernicious and vile habit of
> coding a more readable layout.
>
> It doesn't use a two-arg iter, but still rates because it does use a
> relatively-obscure member of the itertools library...
>

Nice, but that's only going to give you the ones that don't match. You
can then count those, and that's a start, but how do you capture the
matching rolls?

I smell another opportunity for gratuitous use of a language feature:
nonlocal. In a lambda function. Which may require shenanigans of epic
proportions.

ChrisA


More information about the Python-list mailing list