4
\$\begingroup\$

The goal is to create a generator generator [...] generator generator comprehension.

  1. The generator must be created via generator comprehension.
  2. The following expression must be valid for any number of nestings: next(next(next(next(next(generator))))).

The winner is whoever achieves this with the fewest number of bytes.

\$\endgroup\$
0

2 Answers 2

11
\$\begingroup\$

Python, 31 26 25 bytes

x=(x for()in iter(set,1))

Attempt This Online!

If assignment is not allowed:

Python, 77 72 71 bytes

(gc.get_referrers(sys._getframe())[0]for()in iter(set,1))
import gc,sys

Attempt This Online!

(this is bad code)

-5 bytes on both solutions thanks to @ovs

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Wow, very cool! Thanks for demoing this, I have been trying to figure it out for a while now. \$\endgroup\$ Oct 31, 2021 at 8:03
  • 5
    \$\begingroup\$ You can save a couple bytes by using a builtin function instead of the lambda, e.g. iter(int,1) \$\endgroup\$
    – ovs
    Oct 31, 2021 at 8:44
7
\$\begingroup\$

@pxeger's solution is pretty much the end of this challenge. A generator expression must include code like (a for b in c), where a must be a generator which behaves like the outer generator expression behaves. Either a refers to the outer generator itself, or a is a shorter solution to this problem; so a shortest solution must look like x=(x for b in c). For this to be a solution, then c must be an infinite iterator.

I don't have a proof that iter(int,1) is the shortest possible way to make an infinite iterator, but it seems unbeatable. Otherwise, the only way to improve on @pxeger's solution is if you can write an infinite iterator in fewer than 11 bytes.


If we relax the rule requiring the result to be created using a generator expression, then here's a few other ideas:

Using iter: (18 bytes)

x=iter(lambda:x,1)

Using yield: (23 bytes)

def f():yield f()
x=f()

Using itertools.cycle: (44 bytes)

import itertools as i
x=i.cycle(l:=[])
l+=x,

That said, if the rule is only that the outer-most generator be created using a generator expression, and the results after that need not be generators (just things that next works on, i.e. any iterators), then a in the code above can be some solution to the relaxed challenge, instead of a self-reference: (32 bytes)

(z:=iter(lambda:z,1)for _ in[1])

This method still can't beat @pxeger's solution, unless there is a solution to the relaxed version of the challenge more than 6 bytes shorter than z:=iter(lambda:z,1). This seems pretty unlikely, and even if it is possible, it would presumably be an infinite iterator; so it would still be shorter if you plugged it into @pxeger's solution instead of this one.

\$\endgroup\$
6
  • \$\begingroup\$ I thought iter created an iterator, not a generator, are they the same thing? Also, I think the challenge requires using a generator comprehension. \$\endgroup\$
    – user
    Oct 31, 2021 at 20:34
  • \$\begingroup\$ @user "If we relax the rule requiring the result to be created using a generator expression" \$\endgroup\$
    – kaya3
    Oct 31, 2021 at 20:35
  • \$\begingroup\$ I missed that, sorry. I think you do also need a main answer that does comply with the challenge, though. \$\endgroup\$
    – user
    Oct 31, 2021 at 20:36
  • 3
    \$\begingroup\$ @user I don't believe it is possible to write a good solution which is substantially different to pxeger's solution, as I explained in the first half of my answer. Either the a part of the generator expression refers to the generator expression itself, in which case you get a version of their solution, or it does not, in which case the a part is a shorter solution to the problem. \$\endgroup\$
    – kaya3
    Oct 31, 2021 at 20:39
  • 1
    \$\begingroup\$ @pxeger Interesting idea, best I can do is l=[];l+=l,;x=(x for l[1:]in l) for 30 bytes. The alternative is l=[1];x=(l.append(1)or x for _ in l) for 36 bytes. The slice assignment is shorter than writing append but it only works if l contains copies of itself, which requires more setup. \$\endgroup\$
    – kaya3
    Nov 1, 2021 at 23:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.