Last active
September 25, 2019 11:06
-
-
Save kuribas/ea2fa43f36682f1e39e380c101c086e2 to your computer and use it in GitHub Desktop.
find subsets with sum
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE ScopedTypeVariables #-} | |
module Sums where | |
import Data.IntMap.Lazy (IntMap) | |
import Data.Maybe | |
import Data.Monoid ((<>)) | |
import qualified Data.IntMap as IntMap | |
-- find all subsets which add upto the given size, given a function to | |
-- extract the size. Only pick at most one element from each input subset. | |
sums :: forall a.(a -> Int) -> Int -> [[a]] -> [[a]] | |
sums size sum_ = fromMaybe [] . IntMap.lookup sum_ . sumsAux2 | |
where | |
sumsAux2 :: [[a]] -> IntMap [[a]] | |
sumsAux2 = foldr (\xs im -> foldr (sumsAux im) im xs) IntMap.empty | |
sumsAux :: IntMap [[a]] -> a -> IntMap [[a]] -> IntMap [[a]] | |
sumsAux origIm x newIm | |
| size x > sum_ = newIm | |
| otherwise = | |
IntMap.insertWith (<>) (size x) [[x]] $ | |
IntMap.foldrWithKey (\key val im2 -> | |
if key + size x > sum_ then im2 | |
else IntMap.insertWith (<>) (key + size x) | |
(map (x:) val) im2) | |
newIm origIm |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- find all subsets which add upto the given size, given a function to | |
-- extract the size | |
sums :: forall a.(a -> Int) -> Int -> [a] -> [[a]] | |
sums size sum_ l = | |
fromMaybe [] $ IntMap.lookup sum_ $ sumsAux l | |
where | |
sumsAux :: [a] -> IntMap [[a]] | |
sumsAux [] = IntMap.empty | |
sumsAux (x:xs) | |
| size x > sum_ = sumsAux xs | |
| otherwise = | |
IntMap.insertWith (<>) (size x) [[x]] $ | |
IntMap.foldrWithKey (\key val im2 -> | |
if key + size x > sum_ then im2 | |
else IntMap.insertWith (<>) (key + size x) | |
(map (x:) val) im2) | |
im im | |
where im = sumsAux xs |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Sums where | |
import Data.IntMap.Lazy (IntMap) | |
import Data.Maybe | |
import Data.Monoid ((<>)) | |
import qualified Data.IntMap as IntMap | |
sums :: Int -> [Int] -> [[Int]] | |
sums sum_ l = fromMaybe [] $ IntMap.lookup sum_ $ sumsAux sum_ l | |
sumsAux :: Int -> [Int] -> IntMap [[Int]] | |
sumsAux _ [] = IntMap.empty | |
sumsAux sum_ (x:xs) | |
| x > sum_ = sumsAux sum_ xs | |
| otherwise = | |
IntMap.insertWith (<>) x [[x]] $ | |
IntMap.foldrWithKey (\key val im2 -> | |
if key + x > sum_ then im2 | |
else IntMap.insertWith (<>) (key + x) | |
(map (x:) val) im2) | |
im im | |
where im = sumsAux sum_ xs |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment