Last active
March 7, 2022 09:45
-
-
Save Phryxia/cd393a1a7d8a89bbeacd204209df94ac to your computer and use it in GitHub Desktop.
Provides some interesting map functions between natural and integer set.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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
andflattenIntegers
.Explanation
mapNaturalToInteger
mapIntegerToNatural
flatten2DNatural
flatten2DInteger
flattenNaturals
,flattenIntegers