Skip to content

Commit

Permalink
hi
Browse files Browse the repository at this point in the history
  • Loading branch information
pgujjula committed Apr 4, 2024
1 parent 275e1b9 commit 0679edd
Showing 1 changed file with 21 additions and 1 deletion.
22 changes: 21 additions & 1 deletion docs/ALGORITHM.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,31 @@ and `ys`. Then we can define a general
applyMerge :: (Ord c) => (a -> b -> c) -> [a] -> [b] -> [c]
```
where `applyMerge f xs ys` is an ordered list of all `f x y`, where `x xs` and `y ys`. In particular, `smooth3 = applyMerge (*) powersOf2 powersOf3`.
We can also define a more general
```haskell
applyMergeBy :: (c -> c -> Ordering) -> (a -> b -> c) -> [a] -> [b] -> [c]
```

## Implementation and complexity
We can use a priority queue to maintain the frontier of elements. To determine in step 3 whether a down- or right-neighbor is unblocked, we maintain two `IntSet`s, for the `x`- and `y`- indices of all elements in the frontier. Then in step 3, if the `x`- and `y`-index of a neighbor are not in the respective `IntSet`s, the neighbor is unblocked and can be added to the frontier.

After producing $n$ elements, the size of the frontier is at most $O(\sqrt{n})$ elements. <i>(TODO: prove this)</i> Manipulating the priority queue and the `IntSet`s to yield one element takes $O(\text{log } \sqrt{n}) = O(\text{log } n)$ time. Therefore, producing $n$ elements of `applyMerge f xs ys` takes $O(n \log n)$ time and $O(\sqrt{n})$ space.
After producing $n$ elements, the size of the frontier is at most $O(\sqrt{n})$ elements. <i>(TODO: prove this)</i> Manipulating the priority queue and the `IntSet`s to produce the next element takes $O(\text{log } \sqrt{n}) = O(\text{log } n)$ time. Therefore, producing $n$ elements of `applyMerge f xs ys` takes $O(n \log n)$ time and $O(\sqrt{n})$ auxiliary space.

## Other applications

`applyMerge` is versatile!
```haskell
-- Sieve of Erastosthenes
primes :: [Int]
primes = 2 : ([3..] `minus` composites) -- `minus` from data-ordlist

composites :: [Int]
composites = applyMerge (*) primes [2..]

-- Gaussian integers in the first quadrant, ordered by norm
gaussianInts :: [Complex Int]
gaussianInts = applyMergeBy (comparing (\a b -> a*a + b*b)) (:+) [1..] [1..]
```

# Prior work
In <code>[data-ordlist](https://www.stackage.org/lts/package/data-ordlist)</code>,
Expand Down

0 comments on commit 0679edd

Please sign in to comment.