Powerset of a list using abstract list functions

£可爱£侵袭症+ 提交于 2021-01-04 05:51:25

问题


Is it possible to make a racket function to return powerset of a given list?


Constraints-

  1. without explicit recursion
  2. use abstract list functions
  3. code contained in 2 lines (actual requirement)

For eg: (powerset '(1 2))

'((1 2) (1) (2) ())

in any order.

The other question I found still uses explicit recursion.


My workflow:

  1. Taking (powerset '(a b c)) as an example,
  2. First get a list of whole numbers up to (expt 2 (length list)) ;'(0 1 2 3 4 5 6 7)
  3. Convert them into their respective binary form 2->(0,1,0). So we get '((0,0,0), (0,0,1), (0,1,0), (0,1,1), (1,0,0), (1,0,1), (1,1,0), (1,1,1))
  4. map '(1 2 3) to the list of binaries. For eg: 2->'(0,1,0)->'((0,a) (1,b) (0,c))
  5. filter the resulting list with a lambda such that we keep elements with 1, like '((1,b)).
  6. Extract the powerset

Problem with my approach

It does not follow constraint of the question being in 1 line (additional to function header).

(define (powerset list)
  ( ... )) ;; ie the code is contained in 2 lines of 80 characters

I had this question in my assignment as a bonus question but I wasn't able to do it.

  1. What are abstract list functions?
  • Functions like foldl, foldr and map
  1. My bonus included 3 subparts
  • Part 1 asked to simply make this function in any way I wanted. So I used recursion to do so
  • Part 2 is the part I asked the question about. This one was particularly tough because there was an added constraint of the code to be within 2 lines
  • Part 3 was supposed to be the toughest.

Do not write any helper functions, and do not use any explicit recursion (i.e., your function cannot call itself by name). Do not use any abstract list functions. In fact, use only the following list of Racket functions, constants and special forms: cons, first, rest, empty?, empty, lambda, and cond.

However, funny thing, I studied Y-combinator and was able to solve this one (after 6 hrs of coding).


回答1:


To answer your bonus part 2:

(define (pws l) 
  (foldr (lambda (e a) (append (map (lambda (x) (cons e x)) a) a)) '(()) l))

Two lines, less than 80 chars each, first line reserved for the define (so, one line).

If append isn't allowed, then we turn the append ... map combination into a foldr as well:

(define (pws-fr l) 
  (foldr (lambda (e a)
           (foldr (lambda (x r)
                    (cons (cons e x) r))
                  a a))
         '(()) l))

or, shortened,

(define (pws-fr-1 l) 
  (foldr (lambda (e a) (foldr (lambda (x r) (cons (cons e x) r)) a a)) '(()) l))

(with precisely 80 chars in its second line).

Another way to code this is the append-map-based code (the second snippet) from this answer which, when re-coded with foldr only, becomes

(define (pws-am-fr l) 
  (foldr (lambda (e a)
           (foldr (lambda (x r)
                    (cons x (cons (cons e x) r)))
                  '() a))
         '(()) l))

or shortened,

(define (pws-am-fr1 l) (foldr (lambda (e a)
   (foldr (lambda (x r) (cons x (cons (cons e x) r))) '() a)) '(()) l))

which might or might not fulfill your requirements exactly.



来源:https://stackoverflow.com/questions/64984096/powerset-of-a-list-using-abstract-list-functions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!