Skip to content

Instantly share code, notes, and snippets.

@rlidwka
Last active April 5, 2018 19:40
Show Gist options
  • Save rlidwka/75c7dbcd705748e40b56ab49115dea41 to your computer and use it in GitHub Desktop.
Save rlidwka/75c7dbcd705748e40b56ab49115dea41 to your computer and use it in GitHub Desktop.
finding the closest frakking number
function get_digit(n, d) {
return Math.floor(n / Math.pow(10, d)) % 10
}
function is_unique(n, d) {
let m = 0
let c = Math.pow(10, d)
for (let i = d; n > c; i++, c *= 10) {
let new_m = m ^ (2 << get_digit(n, i) + 1)
if (new_m < m) return false
m = new_m
}
return true
}
function closest(a, b, n) {
if (a == null) return b
if (b == null) return a
if (a > n) return b
if (b > n) return a
return n-a < n-b ? a : b
}
function _calc(n, d, orig_n) {
if (d < 0) return is_unique(n, 0) ? n : null
//console.log('calc', n, d)
let max = Math.pow(10, d + 1)
let try_n
let above = null
try_n = null
for (let i = 1; i <= max; i *= 10) {
for (let j = 0; j <= 9; j++) {
let new_n = n + i*j
let uniq = is_unique(new_n, d)
if (uniq) {
try_n = closest(try_n, new_n, orig_n)
}
}
}
if (try_n) {
above = _calc(try_n, d - 1, orig_n)
}
let below = null
try_n = null
for (let i = 1; i <= max; i *= 10) {
for (let j = 1; j <= 9; j++) {
let new_n = n - i*j
let uniq = is_unique(new_n, d)
if (uniq) {
try_n = closest(try_n, new_n, orig_n)
}
}
}
if (try_n) {
below = _calc(try_n, d - 1, orig_n)
}
console.log('calc', n, d, '-', above, below)
return closest(above, below, orig_n)
}
function calc(n) {
if (n < 0) return -calc(-n)
if (n > 10e10) return 9876543210
return _calc(n, Math.ceil(Math.log(n) / Math.log(10)), n)
}
console.log('result', calc(5555555555))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment