以下の関数search
は、ある関数で同じ出力を持つ 2 つの入力を検索します。検索中、入力リストxs
を 2 回反復します。この入力リストは非常に大きくなる可能性があります[0..1000000000]
。の要素を保存するのではなく、衝突によって作成された HashSet を保存するためにメモリを使用したいとxs
思いxs
ますfind
。
質問:
- この理解は正しいですか?
- それをリストとして保持
xs
する場合、それが渡された場合に再計算できる方法はありfind
ますか? xs
使用するスペースを制御できる代替データ構造はありますか?xs
チェックする入力を指定するためにのみ使用されます。
型の制限がないことに注意してくださいxs
。任意の型のコレクションにすることができます。
import Data.HashSet as Set
import Data.Hashable
import Data.List
search :: (Hashable b, Eq b) => (a->b) -> [a] -> Maybe (a,a)
search h xs =
do x0 <- collision h xs
let h0 = h x0
x1 <- find (\x -> (h x) == h0) xs
return (x0,x1)
collision :: (Hashable b, Eq b) => (a->b) -> [a] -> Maybe a
collision h xs = go Set.empty xs
where
go s [] = Nothing
go s (x:xs) =
if y `Set.member` s
then Just x
else go (Set.insert y s) xs
where y = h x
main = print $ search (\x -> x `mod` 21) ([10,20..2100] :: [Int])