thanos-sort 0.1.1

šŸ—æ Perfectly balanced sorting - repeatedly snaps away half the elements until one survivor remains
Documentation
# Thanos Sort šŸ—æ

[![crates.io](https://img.shields.io/crates/v/thanos-sort.svg)](https://crates.io/crates/thanos-sort)
[![docs.rs](https://docs.rs/thanos-sort/badge.svg)](https://docs.rs/thanos-sort)
[![MIT license](https://img.shields.io/crates/l/thanos-sort.svg)](./LICENSE)

**āš ļø WARNING: THIS CRATE IS A JOKE. DO NOT USE FOR ACTUAL SORTING.āš ļø**

Thanos Sort "sorts" by repeatedly snapping away half the elements until one survivor remains. Perfectly balanced, as all things should be.

## Table of Contents
- [How It Works]#how-it-works
- [Installation]#installation
- [API Reference]#api-reference
  - [`thanos_sort(&mut Vec<T>) -> Vec<Vec<T>>`]#thanos_sortmut-vect---vecvect
  - [`thanos_sort_owned(&[T]) -> (Vec<T>, Vec<Vec<T>>)`]#thanos_sort_ownedt---vect-vecvect
- [Usage Examples]#usage-examples
  - [Basic Sorting]#basic-sorting
  - [Preserving Original Data]#preserving-original-data
  - [Analyzing the Elimination Process]#analyzing-the-elimination-process
  - [Visualization]#visualization
  - [Working with Custom Types]#working-with-custom-types
  - [Batch Processing]#batch-processing
- [Algorithm Details]#algorithm-details
- [Testing]#testing
- [Why Use This Crate?]#why-use-this-crate
- [Why NOT Use This Crate]#why-not-use-this-crate

## How It Works

Thanos Sort implements a "perfectly balanced" elimination strategy:

1. **Start** with a full vector of elements
2. **While** more than 1 element remains:
   - Calculate how many to keep: `ceil(n/2)` (snap away `floor(n/2)` elements)
   - Shuffle the remaining elements randomly
   - Truncate to keep only the first `ceil(n/2)` elements
   - Record the new state in history
3. **End** when only 1 (or 0) elements remain

## Installation

Add this to your `Cargo.toml`:

```toml
[dependencies]
thanos-sort = "0.1.1"
```

## API Reference

### `thanos_sort(&mut Vec<T>) -> Vec<Vec<T>>`

**What it takes:**
- A **mutable reference** to a `Vec<T>` - it will modify your original vector!

**What it returns:**
- **History**: `Vec<Vec<T>>` - A vector of vectors showing the state after each "snap"
  - Index 0: Original state
  - Index 1: After 1st snap
  - Index 2: After 2nd snap
  - ... until final state (1 element)

**Example:**
```rust
use thanos_sort::thanos_sort;

let mut my_data = vec![10, 20, 30, 40, 50, 60];
let history = thanos_sort(&mut my_data);

// The mutated original vector - now only has 1 survivor!
println!("Survivor: {:?}", my_data);  // e.g., [30]

// The history - all intermediate states
for (i, state) in history.iter().enumerate() {
    println!("After snap {}: {:?} ({} elements)", i, state, state.len());
}
// Output:
// After snap 0: [10, 20, 30, 40, 50, 60] (6 elements)
// After snap 1: [60, 30, 40] (3 elements)  - shuffled + truncated
// After snap 2: [40, 30] (2 elements)
// After snap 3: [30] (1 element)
```

---

### `thanos_sort_owned(&[T]) -> (Vec<T>, Vec<Vec<T>>)`

**What it takes:**
- A **slice** `&[T]` - your original data is **not modified**

**What it returns:**
- **Tuple** containing:
  1. **Survivor**: `Vec<T>` - The final survivor(s) (0 or 1 elements)
  2. **History**: `Vec<Vec<T>>` - Same as above, all intermediate states

**Example:**
```rust
use thanos_sort::thanos_sort_owned;

let original = vec![10, 20, 30, 40, 50, 60];
let (survivor, history) = thanos_sort_owned(&original);

// Original is untouched
println!("Original: {:?}", original);  // [10, 20, 30, 40, 50, 60]

// You get the survivor separately
println!("Survivor: {:?}", survivor);  // e.g., [30]

// Plus the full history
println!("History length: {}", history.len());  // 4 snaps
```

## Usage Examples

### Basic Sorting

```rust
use thanos_sort::thanos_sort;

let mut numbers = vec![4, 2, 7, 1, 9, 3];
let history = thanos_sort(&mut numbers);

assert_eq!(numbers.len(), 1);
assert_eq!(history.len(), 4); // 6 -> 3 -> 2 -> 1
```

### Preserving Original Data

```rust
use thanos_sort::thanos_sort_owned;

let original = vec![1, 2, 3, 4, 5];
let (survivor, history) = thanos_sort_owned(&original);

// Original is preserved
assert_eq!(original, vec![1, 2, 3, 4, 5]);
// Survivor is the result
assert_eq!(survivor.len(), 1);
// History tracks all snaps
assert_eq!(history.len(), 4); // 5 -> 3 -> 2 -> 1
```

### Analyzing the Elimination Process

```rust
use thanos_sort::thanos_sort;

let mut players = vec!["Thanos", "Iron Man", "Thor", "Captain America", "Hulk"];
let history = thanos_sort(&mut players);

// Who survived?
println!("The chosen one: {}", players[0]);

// Who got snapped at each stage?
for (snap, survivors) in history.iter().enumerate() {
    let snapped = if snap == 0 { 
        "Initial roster".to_string() 
    } else {
        let previous = &history[snap - 1];
        let eliminated: Vec<_> = previous.iter()
            .filter(|&p| !survivors.contains(p))
            .collect();
        format!("Snapped: {:?}", eliminated)
    };
    println!("Round {}: {:?} - {}", snap, survivors, snapped);
}
```

### Visualization

```rust
use thanos_sort::thanos_sort_owned;

fn visualize_thanos_sort<T: std::fmt::Debug + Clone>(data: &[T]) {
    let (survivor, history) = thanos_sort_owned(data);
    
    println!("šŸ“Š Thanos Sort Visualization");
    println!("━━━━━━━━━━━━━━━━━━━━━━━━━");
    
    for (i, state) in history.iter().enumerate() {
        let bar = "ā–ˆ".repeat(state.len());
        let snap_info = if i == 0 { 
            "START".to_string() 
        } else {
            format!("SNAP {} (kept {}/{})", i, state.len(), history[i-1].len())
        };
        println!("{:10} │ {:<10} │ {:?}", snap_info, bar, state);
    }
    
    println!("\nšŸ† SURVIVOR: {:?}", survivor);
}

// Usage
let data = vec![10, 20, 30, 40, 50, 60];
visualize_thanos_sort(&data);
```

### Working with Custom Types

```rust
use thanos_sort::thanos_sort_owned;

#[derive(Debug, Clone, PartialEq)]
struct Titan {
    name: String,
    power: u32,
}

let titans = vec![
    Titan { name: "Thanos".into(), power: 100 },
    Titan { name: "Star Lord".into(), power: 50 },
    Titan { name: "Gamora".into(), power: 75 },
    Titan { name: "Thor".into(), power: 90 },
];

let (survivor, history) = thanos_sort_owned(&titans);
println!("The strongest survives: {:?}", survivor[0]);
println!("Total snaps: {}", history.len() - 1); // 3 snaps: 4 -> 2 -> 1
```

### Batch Processing

```rust
use thanos_sort::thanos_sort_owned;

let datasets = vec![
    vec![1, 2, 3],
    vec![4, 5, 6, 7],
    vec![8, 9],
];

let results: Vec<_> = datasets.iter()
    .map(|d| thanos_sort_owned(d))
    .collect();

for (i, (survivor, history)) in results.iter().enumerate() {
    println!("Dataset {}: {} elements → {} snaps → survivor: {:?}", 
        i, 
        datasets[i].len(), 
        history.len() - 1,
        survivor
    );
}
```

## Algorithm Details

### Snap Count Behavior

Perfectly balanced, as all things should be:

| Initial Length | Snap Sequence | Total Snaps |
|----------------|---------------|-------------|
| 0 | [] | 0 |
| 1 | [1] | 0 |
| 2 | [2, 1] | 1 |
| 3 | [3, 2, 1] | 2 |
| 4 | [4, 2, 1] | 2 |
| 5 | [5, 3, 2, 1] | 3 |
| 6 | [6, 3, 2, 1] | 3 |
| 7 | [7, 4, 2, 1] | 3 |
| 8 | [8, 4, 2, 1] | 3 |
| 9 | [9, 5, 3, 2, 1] | 4 |
| 10 | [10, 5, 3, 2, 1] | 4 |

### Time Complexity

- **Best case:** O(1) - already has 0 or 1 elements
- **Average case:** O(n log n) - each snap halves the dataset
- **Worst case:** O(n log n) - same as average

### Space Complexity

- **With `thanos_sort`:** O(n log n) - storing history of all states
- **With `thanos_sort_owned`:** O(n log n) - same, plus a copy of original

## Testing

Run the test suite:

```bash
cargo test
```

This includes:
- Unit tests for edge cases
- Doctests for documentation examples
- Property-based tests for snap counts

## Why Use This Crate?

āœ… **Educational**: Demonstrates random algorithms and ownership in Rust  
āœ… **Humorous**: Perfect for code reviews and presentations  
āœ… **Visualization**: History tracking makes it great for visualizations  
āœ… **Idiomatic**: Follows Rust best practices (even though it's a joke)  
āœ… **Well-tested**: Comprehensive test suite  

## Why NOT Use This Crate

āŒ **NOT A REAL SORTING ALGORITHM** - It doesn't actually sort anything  
āŒ **DESTRUCTIVE** - Eliminates data randomly  
āŒ **NON-DETERMINISTIC** - Results vary between runs  
āŒ **INEFFICIENT** - O(n log n) for no benefit  
āŒ **USELESS** - Unless you need to randomly eliminate half your data  

**Use `data.sort_unstable()` instead.**

---

## License

MIT Ā© 2026

---

*"Perfectly balanced, as all things should be."* - Thanos