Размер int
зависит от платформы, он может быть 32-разрядным и 64-разрядным. На игровой площадке Go она 32-разрядная, на локальном компьютере - 64-разрядная.
Если мы изменим ваш пример на использование int64
вместо int
, результат будет таким же, Go Детская площадка тоже:
func findBySum(arr []int64) int64 {
result := int64(0)
sum := [32]int64{}
for i := int64(0); i < 32; i++ {
for _, v := range arr {
sum[i] += (v >> uint64(i)) & 0x1
}
sum[i] %= 3
sum[i] <<= uint(i)
result |= sum[i]
}
return result
}
func TestThree(t *testing.T) {
// except one nubmer,all other number appear three times
a1 := []int64{11, 222, 444, 444, 222, 11, 11, 17, -123, 222, -123, 444, -123} // unqiue number is 17
a2 := []int64{11, 222, 444, 444, 222, 11, 11, -17, -123, 222, -123, 444, -123} // unque number is -17
t.Log(findBySum(a1))
t.Log(findBySum(a2))
}
Вы выполняете побитовые операции, которые принимают 32-битный целочисленный размер. Чтобы получить правильные результаты локально (где ваша архитектура и, следовательно, размер int
и uint
равен 64-bit
), измените все int
s на int32
и uint
на uint32
:
func findBySum(arr []int32) int32 {
result := int32(0)
sum := [32]int32{}
for i := int32(0); i < 32; i++ {
for _, v := range arr {
sum[i] += (v >> uint32(i)) & 0x1
}
sum[i] %= 3
sum[i] <<= uint(i)
result |= sum[i]
}
return result
}
func TestThree(t *testing.T) {
// except one nubmer,all other number appear three times
a1 := []int32{11, 222, 444, 444, 222, 11, 11, 17, -123, 222, -123, 444, -123} // unqiue number is 17
a2 := []int32{11, 222, 444, 444, 222, 11, 11, -17, -123, 222, -123, 444, -123} // unque number is -17
t.Log(findBySum(a1))
t.Log(findBySum(a2))
}
Урок: если вы выполняете вычисления, результат которых зависит от размера представления, всегда будьте явными и используйте числа фиксированного размера, такие как int32
, int64
, uint32
, uint64
.