Вы почти нашли это. В следующий раз ознакомьтесь с онлайн-энциклопедией целочисленных рядов .
Вот запись: http://oeis.org/A061418
FORMULA
a(n) = ceiling[K*(3/2)^n] where K=1.08151366859...
The constant K is 2/3*K(3) (see A083286). - Ralf Stephan, May 29, 2003
Сказано:
>>> def f(n):
... K = 1.08151366859
... return int(ceil(K*(1.5)**n))
Тест на психическое здоровье:
>>> for x in range(1, 10):
... print f(x)
...
2
3
4
6
9
13
19
28
42
Круто! А как насчет 1000000:
>>> f(1000000)
Traceback (most recent call last):
File "", line 1, in
File "", line 3, in f
OverflowError: (34, 'Result too large')
Ну, я попробовал. :]
Но вы поняли идею.
Редактировать еще раз: Решение найдено! См. Тимо или Лассе В. Карлсен .
Редактировать: Используя идею смещения битов Тимо:
import gmpy
n=gmpy.mpz(2)
for _ in xrange(10**6-1):
n+=n>>1
print(n)
дает
1963756763 ... 226123087 (176092 цифры)
% time test.py > test.out
real 0m21.735s
user 0m21.709s
sys 0m0.024s
Если, с другой стороны, они не один к одному, то, используя сложный ключ, вы можете использовать сортировку представлений для объединения.
function(doc) {
if (doc.type == 'order') {
emit([doc.cartid, 1], doc);
} else if (doc.type == 'cart') {
emit([doc.id, 0], doc);
}
}
документы будут сопоставлены по карте с порядками идущий за тележкой. Код вашего приложения может легко присоединиться к этому потоку, и вы можете запрашивать конкретную карту, используя startkey и endkey.
см .: View Collation для правил сопоставления.
Вы также можете использовать сокращение для присоединения их вместе.
Просто измените функцию карты на эту:
function(doc) {
if (doc.type == 'order') {
emit([doc.cartid, 1], {cartid: doc.cartid, orders: [doc]});
} else if (doc.type == 'cart') {
emit([doc.id, 0], {cartid: doc.id, orders: [], cart: doc);
}
}
и добавьте функцию уменьшения, например, эту:
function(keys, values) {
var out = {cartid: null, orders: [], cart: null};
for (idx in values) {
var doc = values[idx];
out['cartid'] = doc.cartid;
if (doc.cart) { out['cart'] = doc.cart };
for (idx2 in doc.orders) {
out.orders.push(doc.orders[idx2]);
}
}
return out;
}
Это вернет один документ для каждой корзины, который будет содержать карту, массив документов заказа и документ корзины.
Приносим извинения, если в приведенном выше коде есть ошибки, но у меня нет под рукой тестового экземпляра couchdb, чтобы опробовать их.
Если объекты Order и Cart имеют отношение «один к одному» (как это звучит), то второй подход имеет наибольший смысл ... просто сохраните связанные объекты в одном. Это обеспечивает целостность данных, которую вы ищете, и упрощает работу; -)