Challenge Problem 5 with Python: lambda ... Don't go deep into oneliner ... Don't

Challenge 5 problems that software engineers should solve in 1 hour In the comment, podhmo gave me a one-liner. Thank you very much. (See Original article for the actual product.)

I couldn't understand the meaning at all even if I looked at it, so I tried to break it up and make it into a shape that I could understand.

A completely unclear flow from the beginning

(lambda f: (lambda x: x(x))(lambda y: f(lambda v: y(y)(v))))

I can feel the round and round feeling, but ... it's a mystery. If you try google as it is, it seems that it is a Y combinator. It seems that you can recurse as an anonymous function. sorry. I will let you through now. Because my eyes turned around.

I gave it a name so that I could understand it

Is it like this?

c=(lambda xs:
	[ [xs[0]] ] if len(xs) <= 1 else
    __import__("itertools").chain(
        [ [xs[0], ""] + y for y in c(xs[1:]) ],
        [ [xs[0], " + "] + y for y in c(xs[1:]) ],
        [ [xs[0], " - "] + y for y in c(xs[1:]) ]
    )
)

print( "\n".join(
            [   x for x in
                [   "".join(str(y) for y in z )
                        for z in c(range(1, 10 ) )
                ]
                if eval(x) == 100
            ]
       )
)

Does that mean? I wondered if I would do that at first, but I didn't know what to do. I learned a lot.

by the way...

You can put a recursive function in ~~ def, but you can't put it in lambda ~~

It seems ~~. ~~ It's done. See below.

The one below defining c in q_5_1 with def worked fine.

def q_5_1():
    def c(xs):
        return ([[xs[0]]] if len(xs) <= 1 else
                                  __import__("itertools").chain(
                                      [[xs[0], ""] + y for y in c(xs[1:])],
                                      [[xs[0], " + "] + y for y in c(xs[1:])],
                                      [[xs[0], " - "] + y for y in c(xs[1:])]
                                )
                )
    print("\n".join(
            [   x for x in
                [   "".join(str(y) for y in z )
                        for z in c(range(1, 10 ) )
                ]
                if eval(x) == 100
            ]
        )
    )

q_5_1()

When I tried to do the same with lambda, it didn't work.

def pr(x):
    print x
    
q_5_2=(lambda:
    (lambda c=(lambda xs:
            [[xs[0]]] if len(xs) <= 1 else
            __import__("itertools").chain(
                [[xs[0], ""] + y for y in c(xs[1:])],
                [[xs[0], " + "] + y for y in c(xs[1:])],
                [[xs[0], " - "] + y for y in c(xs[1:])]
            )
        ):
            pr( "\n".join(
                    [   x for x in
                        [   "".join(str(y) for y in z )
                                for z in c(range(1, 10 ) )
                        ]
                        if eval(x) == 100
                    ]
                )
            )
    )()
)

q_5_2()

I was angry with "NameError: global name'c' is not defined". Does that mean you can't call yourself in lambda because the arguments refer to the outside environment ... Is it related to this area that there is a Y combinator?

However, it is a great teaching of H God to divide complicated things into simple functions. So, for the time being, it may not be a problem.

# coding: utf-8

do = box = lambda *x : x
switch = unbox = lambda x : x[-1]
otherwise = True

q_5_2=( lambda :
        ( lambda c = ( lambda xs :
          ( lambda f : f( f, xs ) )(lambda f, xs :
              switch(
                   len(xs) <= 1 and do( [[xs[0]]] ) 
                or otherwise    and do( __import__("itertools").chain(
                                       [[xs[0], ""] + y for y in f( f, xs[1:])],
                                       [[xs[0], " + "] + y for y in f( f, xs[1:])],
                                       [[xs[0], " - "] + y for y in f( f, xs[1:])]
                                       )
                                      )
             )
            )
          ):
            print( "\n".join(
                [ x for x in
                  [ "".join(str(y) for y in z )
                    for z in c(range(1, 10 ) )
                  ]
                  if eval(x) == 100
                ]
               )
            )
         )()
    )

q_5_2()

More concisely:

python


# coding: utf-8

do = box = lambda *x : x
switch = unbox = lambda x : x[-1]
otherwise = True

q_5_2 = lambda : (
    lambda c = lambda xs , f = lambda f, xs :
                            switch(
                                len(xs) <= 1 and do( [[xs[0]]] ) 
                                or otherwise and do( __import__("itertools").chain(
                                        [[xs[0], ""] + y for y in f( f, xs[1:])],
                                        [[xs[0], " + "] + y for y in f( f, xs[1:])],
                                        [[xs[0], " - "] + y for y in f( f, xs[1:])]
                                    )
                                )
                            )
            
            : f( f, xs ) 
        :
        print( "\n".join(
                [ x for x in
                    [ "".join(str(y) for y in z )
                        for z in c(range(1, 10 ) )
                    ]
                        if eval(x) == 100
                ]
            )
        )
    )()
    

q_5_2()

Recommended Posts

Challenge Problem 5 with Python: lambda ... Don't go deep into oneliner ... Don't
Challenge problem 5 with Python: lambda ... I decided to copy without
Python with Go
ABC163 C problem with python3
ABC188 C problem with python3
ABC187 C problem with python
Challenge LOTO 6 with Python without discipline
Face detection with Lambda (Python) + Rekognition
Using Lambda with AWS Amplify with Go
[Python] One-liner Stalin sort with 50 characters
Notify HipChat with AWS Lambda (Python)
[AWS] Using ini files with Lambda [Python]
INSERT into MySQL with Python [For beginners]
Put protocol buffers into sqlite with python
Manipulate DynamoDB data with Lambda (Node & Python)
[AtCoder] Solve ABC1 ~ 100 A problem with Python
Question: Multiple integrals with python don't work
Connect to s3 with AWS Lambda Python
Try assigning or switching with Python: lambda
Python + Selenium + Headless Chromium with aws lambda