import Data.Time
import Data.List
import Data.Function
data NodeList = NodeList
map1 _ q [] = q
map1 f q (x:xs) = f x : map1 f q xs
makeSums
:: [Int] -> Int -> [NodeList
] -> [NodeList
]makeSums [] _ acc = acc
makeSums
(x:xs
) maxlen acc
= makeSums xs maxlen
$ addNodeList
$ map1 addNode acc
$ filter lessLen acc
where addNodeList y = (NodeList [x] 1 x) : y
addNode
(NodeList root len
sum) = NodeList
(x:root
) (len
+1) (sum+x
) lessLen y = nlLength y < maxlen
makePairs
:: [NodeList
] -> [([Int], [Int])] -> [([Int], [Int])]makePairs [] acc = acc
makePairs
(x:xs
) acc
= makePairs xs
$ (++) acc
$ map pairNodes
$ filter sameSum xs
where sameSum y = nlSum x == (nlSum y)
pairNodes y = (nlRoot x, nlRoot y)
solve3 nums maxlen = makePairs (makeSums nums maxlen []) []
makePairs4
:: [NodeList
] -> [([Int], [Int])] -> [([Int], [Int])]makePairs4 [] acc = acc
makePairs4
(x:xs
) acc
= makePairs4 xs
$ map1 pairNodes acc
$ takeWhile sameSum xs
where sameSum y = nlSum x == (nlSum y)
pairNodes y = (nlRoot x, nlRoot y)
solve4 nums maxlen
= makePairs4
(sortBy
(compare `on` nlSum
) (makeSums nums maxlen
[])) []
where noOne [x] = False
noOne _ = True
mkPair [x,y] = [[(x,y)]]
mkPair
(x:xs
) = map ((,)x
) xs : mkPair xs
where noOne [x] = False
noOne _ = True
mkPair [x,y] = [[(x,y)]]
mkPair
(x:xs
) = map ((,)x
) xs : mkPair xs
bench f nums maxlen title = do
begT <- getCurrentTime
endT <- getCurrentTime
print $ show (diffUTCTime endT begT
) ++ " " ++ title
test m = do
--bench solve1 [1..m] (m `div` 2) "with nub"
bench solve2
[1..m
] (m `
div`
2) "without nub" --bench solve3 [1..m] (m `div` 2) "without sort filter"
bench solve4
[1..m
] (m `
div`
2) "with sort takeWhile"
main = test 14
aW1wb3J0IERhdGEuVGltZQppbXBvcnQgRGF0YS5MaXN0CmltcG9ydCBEYXRhLkZ1bmN0aW9uCiAKZGF0YSBOb2RlTGlzdCA9IE5vZGVMaXN0IAogICAgeyBubFJvb3QgIDo6IFtJbnRdCiAgICAsIG5sTGVuZ3RoIDo6IEludAogICAgLCBubFN1bSAgICA6OiBJbnQgfQogICAgZGVyaXZpbmcgKFNob3cpCgptYXAxIF8gcSBbXSAgICA9IHEKbWFwMSBmIHEgKHg6eHMpICA9IGYgeCA6IG1hcDEgZiBxIHhzCgptYWtlU3VtcyA6OiBbSW50XSAtPiBJbnQgLT4gW05vZGVMaXN0XSAtPiBbTm9kZUxpc3RdCm1ha2VTdW1zIFtdIF8gIGFjYyAgICAgICAgID0gYWNjICAgIAptYWtlU3VtcyAoeDp4cykgbWF4bGVuIGFjYyA9IG1ha2VTdW1zIHhzIG1heGxlbiAkIGFkZE5vZGVMaXN0ICQgbWFwMSBhZGROb2RlIGFjYyAkIGZpbHRlciBsZXNzTGVuIGFjYwogICAgd2hlcmUgYWRkTm9kZUxpc3QgeSA9IChOb2RlTGlzdCBbeF0gMSB4KSA6IHkKICAgICAgICAgIGFkZE5vZGUgKE5vZGVMaXN0IHJvb3QgbGVuIHN1bSkgPSBOb2RlTGlzdCAoeDpyb290KSAobGVuKzEpIChzdW0reCkgCiAgICAgICAgICBsZXNzTGVuIHkgPSBubExlbmd0aCB5IDwgbWF4bGVuCiAKbWFrZVBhaXJzIDo6IFtOb2RlTGlzdF0gLT4gWyhbSW50XSwgW0ludF0pXSAtPiBbKFtJbnRdLCBbSW50XSldCm1ha2VQYWlycyBbXSBhY2MgICAgID0gYWNjCm1ha2VQYWlycyAoeDp4cykgYWNjID0gbWFrZVBhaXJzIHhzICQgKCsrKSBhY2MgJCBtYXAgcGFpck5vZGVzICQgZmlsdGVyIHNhbWVTdW0geHMgCiAgICB3aGVyZSBzYW1lU3VtIHkgPSBubFN1bSB4ID09IChubFN1bSB5KQogICAgICAgICAgcGFpck5vZGVzIHkgPSAobmxSb290IHgsIG5sUm9vdCB5KQogCnNvbHZlMyA6OiBbSW50XSAtPiBJbnQgLT4gWyhbSW50XSwgW0ludF0pXQpzb2x2ZTMgbnVtcyBtYXhsZW4gPSBtYWtlUGFpcnMgKG1ha2VTdW1zIG51bXMgbWF4bGVuIFtdKSBbXQoKbWFrZVBhaXJzNCA6OiBbTm9kZUxpc3RdIC0+IFsoW0ludF0sIFtJbnRdKV0gLT4gWyhbSW50XSwgW0ludF0pXQptYWtlUGFpcnM0IFtdIGFjYyAgICAgPSBhY2MKbWFrZVBhaXJzNCAoeDp4cykgYWNjID0gbWFrZVBhaXJzNCB4cyAkIG1hcDEgcGFpck5vZGVzIGFjYyAkIHRha2VXaGlsZSBzYW1lU3VtIHhzIAogICAgd2hlcmUgc2FtZVN1bSB5ID0gbmxTdW0geCA9PSAobmxTdW0geSkKICAgICAgICAgIHBhaXJOb2RlcyB5ID0gKG5sUm9vdCB4LCBubFJvb3QgeSkKICAgIApzb2x2ZTQgOjogW0ludF0gLT4gSW50IC0+IFsoW0ludF0sIFtJbnRdKV0Kc29sdmU0IG51bXMgbWF4bGVuID0gbWFrZVBhaXJzNCAoc29ydEJ5IChjb21wYXJlIGBvbmAgbmxTdW0pIChtYWtlU3VtcyBudW1zIG1heGxlbiBbXSkpIFtdCgpzb2x2ZTEgbnVtcyBtYXhsZW4gPSBudWIgJCBjb25jYXQgJCBjb25jYXRNYXAgKG1rUGFpciAuIG1hcCBzbmQpICQgZmlsdGVyIG5vT25lICQKICAgICAgICAgICAgICAgICAgICBncm91cEJ5ICgoPT0pIGBvbmAgZnN0KSAkIHNvcnRCeSAoY29tcGFyZSBgb25gIGZzdCkgJCAKICAgICAgICAgICAgICAgICAgICBtYXAgKFxhIC0+IChzdW0gYSxhKSkgJAogICAgICAgICAgICAgICAgICAgIGZpbHRlciAoKDw9bWF4bGVuKS5sZW5ndGgpICQgdGFpbCAkIHN1YnNlcXVlbmNlcyBudW1zCiAgICB3aGVyZSBub09uZSBbeF0gPSBGYWxzZQogICAgICAgICAgbm9PbmUgXyA9IFRydWUKICAgICAgICAgIG1rUGFpciBbeCx5XSA9IFtbKHgseSldXQogICAgICAgICAgbWtQYWlyICh4OnhzKSA9IG1hcCAoKCwpeCkgeHMgOiBta1BhaXIgeHMKIApzb2x2ZTIgbnVtcyBtYXhsZW4gPSBjb25jYXQgJCBjb25jYXRNYXAgKG1rUGFpciAuIG1hcCBzbmQpICQgZmlsdGVyIG5vT25lICQKICAgICAgICAgICAgICAgICAgICBncm91cEJ5ICgoPT0pIGBvbmAgZnN0KSAkIHNvcnRCeSAoY29tcGFyZSBgb25gIGZzdCkgJCAKICAgICAgICAgICAgICAgICAgICBtYXAgKFxhIC0+IChzdW0gYSxhKSkgJAogICAgICAgICAgICAgICAgICAgIGZpbHRlciAoKDw9bWF4bGVuKS5sZW5ndGgpICQgdGFpbCAkIHN1YnNlcXVlbmNlcyBudW1zCiAgICB3aGVyZSBub09uZSBbeF0gPSBGYWxzZQogICAgICAgICAgbm9PbmUgXyA9IFRydWUKICAgICAgICAgIG1rUGFpciBbeCx5XSA9IFtbKHgseSldXQogICAgICAgICAgbWtQYWlyICh4OnhzKSA9IG1hcCAoKCwpeCkgeHMgOiBta1BhaXIgeHMKIApiZW5jaCBmIG51bXMgbWF4bGVuIHRpdGxlID0gZG8KICAgICAgIGJlZ1QgPC0gZ2V0Q3VycmVudFRpbWUKICAgICAgIHByaW50ICQgbGFzdCAkIGYgbnVtcyBtYXhsZW4KICAgICAgIGVuZFQgPC0gZ2V0Q3VycmVudFRpbWUKICAgICAgIHByaW50ICQgc2hvdyAoZGlmZlVUQ1RpbWUgZW5kVCBiZWdUKSArKyAiICAiICsrIHRpdGxlIAogICAgICAgCnRlc3QgbSA9IGRvCgktLWJlbmNoIHNvbHZlMSBbMS4ubV0gKG0gYGRpdmAgMikgIndpdGggbnViIgoJYmVuY2ggc29sdmUyIFsxLi5tXSAobSBgZGl2YCAyKSAid2l0aG91dCBudWIiCgktLWJlbmNoIHNvbHZlMyBbMS4ubV0gKG0gYGRpdmAgMikgIndpdGhvdXQgc29ydCBmaWx0ZXIiCgliZW5jaCBzb2x2ZTQgWzEuLm1dIChtIGBkaXZgIDIpICJ3aXRoIHNvcnQgdGFrZVdoaWxlIgoKbWFpbjo6IElPICgpIAptYWluID0gdGVzdCAxNA==
([7,8,10,11,12,13,14],[6,9,10,11,12,13,14])
"0.083884s without nub"
([3],[2,1])
"0.133114s with sort takeWhile"