Ми кладемо кульки в фіксованому числі через бункера. Ці смітники починаються порожніми.
Empty bin (a=4): 0 0 0 0
І по черзі ми додаємо кульки до бункерів.
0 0 0 1 or
0 0 1 0 or
0 1 0 0 or
1 0 0 0
Нам потрібен швидкий спосіб переключити всі можливі стани, які приймають бункери, без дублікатів і не пропускаючи жодних, і ми не хочемо перераховувати всі можливі бункери. Тому замість цього ми присвоюємо кожній бін-конфігурації індекс.
Індекс ми присвоюємо, сортуючи можливі конфігурації певним чином:
- Сортувати за зростанням за сумою: так спочатку
0 0 0 0
, потім можливі конфігурації з додаванням 1 кулі, потім 2 тощо. Потім сортуйте кожну суму у порядку зростання від першого кошика до останнього:
0 0 0 2 0 0 1 1 0 0 2 0 0 1 0 1 0 1 1 0 0 2 0 0 etc
Потім індекс присвоюється у порядку зростання за допомогою цього списку:
0 0 0 0 -> 1 0 0 0 1 -> 2 0 0 1 0 -> 3 0 1 0 0 -> 4 1 0 0 0 -> 5 0 0 0 2 -> 6 0 0 1 1 -> 7 0 0 2 0 -> 8 0 1 0 1 -> 9 0 1 1 0 -> 10 0 2 0 0 -> 11
Правила
Створіть функцію або програму, яка приймає список будь-якого розміру з негативними цілими числами та роздруковує або виводить її індекс. Ви можете припустити, що принаймні 2. Виграє найкоротший код. Ви можете використовувати 0-індексований вихід або 1-індексований, але вказати, який ви використовуєте. Примітка: всі приклади тут є 1-індексованими.
Приклад коду
Не гольф, в R:
nodetoindex <- function(node){
a <- length(node)
t <- sum(node)
if(t == 0) return(1)
index <- choose(t-1 + a, a)
while(sum(node) != 0){
x <- node[1]
sumrest <- sum(node)
if(x == 0){
node <- node[-1]
next
}
a <- length(node[-1])
index <- index + choose(sumrest + a, a) - choose(sumrest - x + a, a)
node <- node[-1]
}
return(index + 1)
}
Тестові справи
10 10 10 10 -> 130571
3 1 4 1 5 9 -> 424407
2 9 -> 69
0 0 0 -> 1
0 0 1 -> 2
0 0 0 0 0 0 -> 1
1 0 0 0 0 1 -> 23