README.md

# Hunt-Szymanski diff

A port of the [Hunt-Szymanski](https://en.wikipedia.org/wiki/Hunt%E2%80%93Szymanski_algorithm) diff algorithm to Elixir, with a focus on performance and memory efficiency.

This library is particularly suited for longer texts such as wiki pages or blog articles.

## Credits

This library was generated with assistance from ChatGPT.\
While I guided its development and reviewed the implementation, the core algorithm was recreated by AI.

## Usage

```elixir
left = """
Roses are red,
Violets are blue,
Sugar is sweet,
And so are you.
"""

right = """
Roses are blue,
Violets are blue,
I love fluffy clouds,
And so are you.
"""

# 1. Diff two strings

diff = HSDiff.diff(left, right)

# => 
# [
#   del: ["Roses are red,"],
#   ins: ["Roses are blue,"],
#   eq: ["Violets are blue,"],
#   del: ["Sugar is sweet,"],
#   ins: ["I love fluffy clouds,"],
#   eq: ["And so are you."],
#   eq: [""]
# ]


# 2. Optimize the diff result

optimized = HSDiff.optimize(diff)

# => 
# [
#   del: 1,
#   ins: ["Roses are blue,"],
#   eq: 1,
#   del: 1,
#   ins: ["I love fluffy clouds,"],
#   eq: 2
# ]


# 3. Patch 

restored = HSDiff.patch(left, optimized) 

# => "Roses are blue,\nViolets are blue,\nI love fluffy clouds,\nAnd so are you.\n"
```

## Why Use Hunt-Szymanski Diff?

Elixir’s standard library already provides `String.myers_difference/2` to generate diffs between strings (and lists). However:

- **High Memory Usage**: For larger inputs (e.g., a typical article or blog post), `String.myers_difference/2` can quickly use gigabytes of memory. (Note: this can be alleviated by chunking the input into smaller pieces)
- **Small vs Large Inputs**: `String.myers_difference/2` performs well for short strings or larger strings with small changes. But for large-scale diffs—such as comparing entire documents—the Hunt–Szymanski line-based diff is more memory-efficient and performs better.

In short, if you need a diff algorithm for big textual data, Hunt–Szymanski can help you avoid the heavy memory footprint that comes with other approaches.

## Installation

Add `hunt_szymanski_diff` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:hunt_szymanski_diff, "~> 0.1.0"}
  ]
end
```