# Thanos Sort šæ
[](https://crates.io/crates/thanos-sort)
[](https://docs.rs/thanos-sort)
[](./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:
| 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