Skip to content

Instantly share code, notes, and snippets.

@Phryxia
Last active March 7, 2022 09:45
Show Gist options
  • Save Phryxia/cd393a1a7d8a89bbeacd204209df94ac to your computer and use it in GitHub Desktop.
Save Phryxia/cd393a1a7d8a89bbeacd204209df94ac to your computer and use it in GitHub Desktop.
Provides some interesting map functions between natural and integer set.
// Let N := Z+ ∪ {0}
// N → Z
export function mapNaturalToInteger(x: number): number {
return x % 2 === 0 ? x / 2 : -(x + 1) / 2
}
// Z → N
export function mapIntegerToNatural(x: number): number {
return x >= 0 ? x * 2 : -2 * x - 1
}
// N × N → N
export function flatten2DNatural(x: number, y: number): number {
return (x ** 2 + 2 * x * y + y ** 2 + x + 3 * y) / 2
}
// Z × Z → N
export function flatten2DInteger(x: number, y: number): number {
const r = Math.max(Math.abs(x), Math.abs(y))
if (r === 0) return 0
const d = Math.abs(r - x) + Math.abs(r - y)
return (2 * r - 1) ** 2 + (d > 0 ? 2 * d - 1 : 0) + (x > y ? 1 : 0)
}
// N^n → N
export function flattenNaturals(x: number[]): number {
return x.reduce((acc, v) => acc === undefined ? v : flatten2DNatural(acc, v), undefined as number | undefined) as number
}
// Z^n → N
export function flattenIntegers(x: number[], s: number = 0): number {
if (s + 1 >= x.length) return mapIntegerToNatural(x[s])
if (s + 2 >= x.length) return flatten2DInteger(x[s], x[s + 1])
return flatten2DNatural(flatten2DInteger(x[s], x[s + 1]), flattenIntegers(x, s + 2))
}
@Phryxia
Copy link
Author

Phryxia commented Feb 9, 2022

These are utilities for mapping integer or natural set into the other. This is helpful when you need to represent a multi dimensional things into a single integer. These are based on counting infinite sets, which can be mapped into set of natural numbers.

Note that the set of natural numbers N here includes 0 for the practical reason. For example, you can use one of them for the key in React component, when they are related to 2D coordinate. Or you just want to put these into an array.

The key objective of implementation is achieving 1:1 completely without any unused hole with given dimension. This is the reason for discriminate flattenNaturals and flattenIntegers.

Explanation

mapNaturalToInteger

image

mapIntegerToNatural

image

flatten2DNatural

image

flatten2DInteger

image

flattenNaturals, flattenIntegers

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment