Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9110743
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 17, 20262026-06-17T03:20:31+00:00 2026-06-17T03:20:31+00:00

The following (unoptimal) code generates all the subsets of size N for certain subset.

  • 0

The following (unoptimal) code generates all the subsets of size N for certain subset.

This code works but, as I said, is highly unoptimal. Using an intermediate list to avoid the O(log(n)) of Set.insert doesn’t seem help due to the large cost of later reconverting the list to a Set

Can anybody suggest how to optimize the code?

import qualified Data.Set as Set


subsetsOfSizeN :: Ord a => Int -> Set.Set a -> Set.Set (Set.Set a)
subsetsOfSizeN n s
  | Set.size s < n || n < 0 = error "subsetOfSizeN: wrong parameters"
  | otherwise = doSubsetsOfSizeN n s
 where doSubsetsOfSizeN n s
        | n == 0 = Set.singleton Set.empty
        | Set.size s == n = Set.singleton s
        | otherwise =
           case Set.minView s of
             Nothing -> Set.empty
             Just (firstS, restS) ->
               let partialN n = doSubsetsOfSizeN n restS in
               Set.map (Set.insert firstS) (partialN (n-1)) `Set.union` partialN n
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-17T03:20:32+00:00Added an answer on June 17, 2026 at 3:20 am

    This code works but, as I said, is highly unoptimal.

    Doesn’t seem so terribly bad to me. The number of subsets of size k of a set of size n is n `choose` k which grows rather fast for k ~ n/2. So creating all the subsets must scale badly.

    Using an intermediate list to avoid the O(log(n)) of Set.insert doesn’t seem help due to the large cost of later reconverting the list to a Set.

    Hmm, I found using lists to give better performance. Not asymptotically, I think, but a not negligible more-or-less constant factor.

    But first, there is an inefficiency in your code that is simple to repair:

    Set.map (Set.insert firstS) (partialN (n-1))
    

    Note that Set.map must rebuild a tree from scratch. But we know that firstS is always smaller than any element in any of the sets in partialN (n-1), so we can use Set.mapMonotonic that can reuse the spine of the set.

    And that principle is also what makes lists attractive, the subsets are generated in lexicographic order, so instead of Set.fromList we can use the more efficient Set.fromDistinctAscList. Transcribing the algorithm yields

    onlyLists :: Ord a => Int -> Set.Set a -> Set.Set (Set.Set a)
    onlyLists n s
        | n == 0                    = Set.singleton Set.empty
        | Set.size s < n || n < 0   = error "onlyLists: out of range n"
        | Set.size s == n           = Set.singleton s
        | otherwise                 = Set.fromDistinctAscList . map Set.fromDistinctAscList $
                                                             go n (Set.size s) (Set.toList s)
          where
            go 1 _ xs = map return xs
            go k l (x:xs)
                | k == l = [x:xs]
                | otherwise = map (x:) (go (k-1) (l-1) xs) ++ go k (l-1) xs
    

    which in the few benchmarks I’ve run is between 1.5 and 2× faster than the amended algorithm using Sets.

    And that is in turn, in my criterion benchmarks, nearly twice as fast as dave4420‘s.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Following chunk html code works as expected: <iframe src=http://www.amazon.com/></iframe> But when trying embed inner
Following leads in this thread and others, I've set up a code block where
Following code produces nothing but an error. I wish to retrieve REL attribute values
Following on from this question, I find myself writing the following code over and
Following code will compile but crash at run time: int main() { try {
Following is my code to get the default NIC in Windows XP, but the
Following is my code to find middle node of double linked list but it
Following on from one of the answers in this thread; Using XQuery in Linq
Following is the code which i am using to add events in my android
Following is a part of the code snippet that I will be using for

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.