Мы не можем получить одинаковый паритет, потому что только первый ход нечетен, поэтому он применяется либо к оси X, либо к оси Y, но не к обоим.
В этом случае деление на два просто удобный способ изучения каждого бита от наименее до наиболее значимого. Поскольку мы обязаны использовать каждый бит либо как вычитание (юг и запад), либо как сложение (север и восток), между двумя координатами могут возникнуть две проблемы, обнаруженные с помощью ошибки обоих этих операторов. :
(x % 2 == 0 and y % 4 == 3)
(x % 2 == 1 and y % 4 == 1)
Во-первых, в следующей позиции обеих координат может быть установлен бит без значения, что означает, что x имеет ноль, а y % 4 = 1
, что означает, что следующий бит для y также равен нулю. В этом случае мы добавляем 1 к y, что фактически добавляет 2^p
, где p
- текущая позиция нашего указателя. Это сдвигает текущий установленный бит координаты y влево и создает ноль (вычитание) в текущей позиции.
Пример: (4, 1)
x: 100
y: 1
^--- problem
solution: add 2^0 to y, creating a subtraction
110
south, north, east
Вторая проблема заключается в что x и y могут иметь бит в следующей позиции. Это когда x имеет установленный бит и y % 4 == 3
, что означает, что текущий и следующий бит y установлены. В этом случае добавление 2^p
(текущий бит) к y перевернет оба этих бита (и все смежные слева) в y, следовательно, используя первый бит в качестве вычитания, и освободит второй используемый бит по x.
Пример: (6, 3)
x: 110
y: 11
^--- problem
solution: add 2^0 to y, creating a subtraction
x: 110
y: 100
^--- problem
solution: add 2^1 to x, creating a subtraction
x: 1000
y: 100
south, west, north, east
x: - 2 + 8 = 6
y: - 1 + 4 = 3
Основываясь на результатах кода для некоторых примеров, я придумал эту процедуру. Это показывает, что минимальное двоичное число, N
, которое выражает x + y + s
как степени двух, где s
равно NOT(N)
(то есть вычитание s
, или "западное" и "южное" движения , можно сгенерировать x + y
), можно сгенерировать, добавив x + y + (NOT(x + y) >> 1)
.
function f(x, y){
let xy = x + y
console.log((xy).toString(2))
let p = 1
let s = 0
xy >>= 1
while (xy){
if (!(xy & 1))
s |= p
xy >>= 1
p <<= 1
}
console.log(s.toString(2))
console.log((x + y + s).toString(2))
console.log('')
}
var cs = [
[8, 9],
[2, 3],
[10, 5]
]
for (let [x,y] of cs)
f(x,y)