# License: GNU GPLv3 (or later, at your choice)
from __future__ import unicode_literals
-import uno
-from com.sun.star.awt.MessageBoxType import MESSAGEBOX, INFOBOX, WARNINGBOX, ERRORBOX, QUERYBOX
-from com.sun.star.awt.MessageBoxButtons import BUTTONS_OK, BUTTONS_OK_CANCEL, BUTTONS_YES_NO, BUTTONS_YES_NO_CANCEL, BUTTONS_RETRY_CANCEL, BUTTONS_ABORT_IGNORE_RETRY
-from com.sun.star.awt.MessageBoxResults import OK, YES, NO, CANCEL
-from com.sun.star.beans import PropertyValue
-from com.sun.star.sheet import CellFlags
if 'XSCRIPTCONTEXT' in globals():
def getModel():
- return (XSCRIPTCONTEXT.getDocument(), XSCRIPTCONTEXT)
+ return (XSCRIPTCONTEXT.getDocument(), XSCRIPTCONTEXT.getComponentContext())
def debug(msg):
return
else:
def debug(msg):
print(msg)
-def MakeDraw(*args):
- return
-
+def nAk(n,k):
+ """
+ nAk(n,k) retourne le nombre d’arrangements
+ de longueur k d’un ensemble de longueur n.
+ """
+ if n<0 or k<0 or n<k:
+ return None
+ r = 1
+ for i in range(n-k+1, n+1):
+ r *= i
+ #print("nAk%s = %i" % (str((n,k)), r))
+ return r
+def nAkLO(n,k):
+ return str(nAk(int(n), int(k)))
def nCk(n,k):
"""
nCk(n,k) retourne le nombre de combinaisons
de longueur k d’un ensemble de longueur n.
"""
if n<0 or k<0 or n<k:
- raise ZeroDivisionError
+ return None
if k > n // 2:
k = n - k # more efficient and safe with smaller numbers
- c = 1
- for j in range(1,k+1):
- c = c * (n-j+1) // j
- return c
+ r = 1
+ for j in range(1, k+1):
+ r = r * (n-j+1) // j
+ #print("nCk%s = %i" % (str((n,k)), r))
+ return r
+def nCkLO(n,k):
+ return str(nCk(int(n), int(k)))
def combinOfRank(n,k,rank):
"""
combinOfRank(n, k, r) retourne les indices de permutation
DOC: <http://www.site.uottawa.ca/~lucia/courses/5165-09/GenCombObj.pdf>, p.26
"""
+ #print("combinOfRank: "+str((n,k,rank)))
if rank<0 or nCk(n,k)<rank:
- raise ZeroDivisionError
+ return None
i = 1
j = 1
c = []
if i < k:
while True: # uptoRank
nbCombins = nCk(n-j, k-i)
- if nbCombins > rank:
+ #print("i=%i j=%i rank=%i nCk(%i-%i,%i-%i)=%i" % (i,j,rank, n,j,k,i,nbCombins))
+ if nbCombins <= rank:
+ j += 1
+ rank -= nbCombins
+ #print("rank -= %i" % nbCombins)
+ else:
c.append(j)
+ #print("c = "+str(c))
i += 1
j += 1
break
- else:
- j += 1
- rank -= nbCombins
elif i == k:
c.append(j+rank) # because when i == k, nbCombins is always 1
break
else:
break
return c
+def sequenceOfRank(n, k, rank):
+ """
+ sequenceOfRank(n, k, r) retourne les indices de permutation
+ de la combinaison de k entiers parmi [1..n]
+ au rang lexicographique r dans [0 .. nAk(n,k)-1].
+
+ rankOfSequence(n, sequenceOfRank(n, k, r)) == r
+ sequenceOfRank(n, len(ns), rankOfSequence(n, ns)) == ns
+
+ DOC: <http://www.site.uottawa.ca/~lucia/courses/5165-09/GenCombObj.pdf>, p.75-77
+ Improved to work on k-sequence of permutations instead of only full permutations.
+ """
+ try:
+ rank = int(rank)
+ except ValueError:
+ return None
+ p = []
+ a = nAk(n,k)
+ for i in range(1,k+1):
+ a //= n-(i-1) # optimized a = nAk(n-i, k-i)
+ d = rank // a # greatest multiple of a, lower or equal to r
+ rank = rank % a
+ p.append(d+1)
+ for i in range(k-1,-1,-1): # important: from right to left
+ for j in range(i+1,k):
+ if p[j] >= p[i]:
+ p[j] += 1 # promote the positions in the good interval
+ return p
+def checkSequence(n,ns):
+ """
+ checkSequence(n,ns) returns the range ns flattened
+ if each element is with 1 and n, without repetition.
+ """
+ p = []
+ for row in ns: # flatten range given by LO
+ for col in row:
+ i = int(col)
+ if not(1<=i and i<=n):
+ return None
+ if i in p: # duplicate
+ return None
+ p.append(i)
+ return p
+
def rankOfCombin(n,ns):
"""
rankOfCombin(n, ns) retourne le rang lexicographique dans [0 .. nCk(n, length ns)-1]
rankOfCombin(n, combinOfRank(n, k, r)) == r
combinOfRank(n, len(ns), rankOfCombin(n, ns)) == ns
"""
- if not all(1<=x or x<=n for x in ns):
- raise ZeroDivisionError
+ ns = checkSequence(n, ns)
+ if ns == None:
+ return None
+ ns.sort()
k = len(ns)
- if n<k:
- raise ZeroDivisionError
i = 1
rank = 0
x1 = 0
rank += nCk(n-j, k-i)
i += 1
x1 = x
- return rank
-
-def nbBits(n):
+ return str(rank)
+def rankOfSequence(n, ns):
+ """
+ rankOfSequence(n, ns) retourne le rang lexicographique dans [0 .. nAk(n, len(ns))-1]
+ de la combinaison ns d’entiers parmi [1..n].
+
+ Compte le nombre d’arrangements précédant celui de rang r.
+
+ DOC: <http://www.site.uottawa.ca/~lucia/courses/5165-09/GenCombObj.pdf>, pp.74
+ """
+ rank = 0
+ ns = checkSequence(n, ns)
+ if ns == None:
+ return None
+ k = len(ns)
+ for i in range(0,k):
+ nsi = ns[i]
+ #print("ns = "+str(ns))
+ #print("rank += %i * nAk(%i,%i)" % (nsi - 1, n - (i+1), k - (i+1)))
+ rank += (nsi - 1) * nAk(n - (i+1), k - (i+1))
+ for j in range(i+1,k):
+ if nsi < ns[j]:
+ ns[j] -= 1
+ return str(rank)
+def bitSize(n):
"""
- nbBits(n) retourne le nombre de bits servant à encoder n.
+ bitSize(n) retourne le nombre de bits servant à encoder n.
"""
+ try:
+ n = int(n)
+ except ValueError:
+ return None
if n<0:
- raise ZeroDivisionError
+ return None
r = 0
while n > 0:
r += 1
map(equiprobableBits, range(0, 17+1)) == [0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4]
"""
- b = nbBits(n)
+ b = bitSize(n)
return (b if n == 2**b-1 else b-1)
def bitsOfInteger(m, n):
"""
bitsOfInteger(m, n) retourne les m premiers bits de poids faible
encodant le nombre n.
"""
+ m = int(m)
+ n = int(n)
if not(0<=m and 0<=n):
- raise ZeroDivisionError
- bs = []
+ return None
+ bs = ""
while m > 0:
(q,r) = (n//2, n%2)
- bs.append(r==1)
+ bs = ("1" if r else "0") + bs
m -= 1
n = q
return bs
-def randomOfCombin(n, k, ns):
+def interleave(cols):
"""
- randomOfCombin(n, k, ns) retourne des bits équiprobables donnés
- par la combinaison ns obtenue par tirage équiprobable
- d’une combinaison de k entiers parmi [1 .. n].
-
- WARNING: aucun bit n’est extrait du tirage ns
- dans le cas où ns a un rang lexicographique encodé par
- un nombre de bits strictement supérieur à equiprobableBits(nCk(n, k)).
+ interleave(cols) return a string interleaving the characters
+ of the strings within cols.
"""
- if not(0<=n and 0<=k and k<=n and all(1<=x and x<=n for x in ns)):
- raise ZeroDivisionError
- ns.sort()
- rank = rankOfCombin(n, ns)
- epBits = equiprobableBits(nCk(n,k))
- return bitsOfInteger(epBits, rank) \
- if nbBits(rank) <= epBits else []
-
-def randomOfFrenchLoto (n1,n2,n3,n4,n5, nc):
+ m = 0
+ for rows in cols:
+ for cell in rows:
+ try:
+ m = max(m, len(cell))
+ except TypeError:
+ return None
+ s = ""
+ for idx in range(0, m):
+ for rows in cols:
+ for cell in rows:
+ try:
+ s+=cell[idx]
+ except IndexError:
+ continue
+ return s
+def inBase(base, digits):
+ acc = 0
+ for digit in digits:
+ acc = int(digit) + (base * acc)
+ return acc
+def randomIntegerOfBits(n, bs):
"""
- randomOfFrenchLoto(n1,n2,n3,n4,n5, numComplementaire) retourne les bits équiprobables donnés
- par un tirage du Lo to Français : https://www.fdj.fr/jeux/jeux-de-tirage/loto/resultats/.
-
- Il peut produire @23@ bits équiprobables :
- sum(map(equiprobableBits, [nCk(49, 5), nCk(10, 1)]))
-
- randomOfFrenchLoto(1,2,3,4,5, 1) == [False] * (20+3)
- randomOfFrenchLoto(7,27,36,40,46, 8) == [True] * (20+3)
-
- combinOfRank(49, 5, 2 ** equiprobableBits(nCk(49,5)) - 1) == [7,27,36,40,46]
- combinOfRank(49, 5, 2 ** equiprobableBits(nCk(49,5))) == [7,27,36,40,47]
- randomOfFrenchLoto(7,27,36,40,46, 1) == [True] * 20 + [False] * 3
- randomOfFrenchLoto(7,27,36,40,47, 1) == [False,False,False]
-
- combinOfRank(10, 1, 2 ** equiprobableBits(nCk(10, 1)) - 1) == [8]
- combinOfRank(10, 1, 2 ** equiprobableBits(nCk(10, 1))) == [9]
- randomOfFrenchLoto(7,27,36,40,47, 8) == [True,True,True]
- randomOfFrenchLoto(7,27,36,40,47, 9) == []
- """
- return \
- randomOfCombin(49, 5, [n1,n2,n3,n4,n5]) + \
- randomOfCombin(10, 1, [nc])
-def randomOfEuroMillions(n1,n2,n3,n4,n5, nc1,nc2):
- """
- https://www.fdj.fr/jeux/jeux-de-tirage/euromillions/resultats
- """
- return \
- randomOfCombin(50, 5, [n1,n2,n3,n4,n5]) + \
- randomOfCombin(11, 2, [nc1,nc2])
-def randomOfSwissLoto(n1,n2,n3,n4,n5,n6, nc):
- return \
- randomOfCombin(42, 6 [n1,n2,n3,n4,n5,n6]) + \
- randomOfCombin( 6, 1 [nc])
-def randomOf6aus49(n1,n2,n3,n4,n5,n6, nc):
- return \
- randomOfCombin(49, 6, [n1,n2,n3,n4,n5,n6]) + \
- randomOfCombin(10, 1, [nc])
+ randomIntegerOfBits(n, bs) retourne le premier entier i formé par les bits bs
+ qui a le potentiel d’atteindre un entier dans [0 .. n-1],
+ ou recommence en ignorant le premier bit si n <= i.
+ """
+ n = int(n)
+ if bs == None:
+ return None
+ #print("randomIntegerOfBits: "+str((n, bs)))
+ enough = bitSize(str(n - 1))
+ #print("randomIntegerOfBits: enough="+str(enough))
+ while True:
+ bits = bs[0:enough]
+ given = len(bits)
+ bs_ = bs[enough:]
+ i = inBase(2, bits)
+ if given < enough:
+ return None
+ if n <= i:
+ bs = bits[1:] + bs_
+ else:
+ return str(i)
-g_exportedScripts = MakeDraw,
+g_exportedScripts = ()