Coverage for /usr/lib/python3/dist-packages/sympy/ntheory/digits.py: 21%
28 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
1from collections import defaultdict
3from sympy.utilities.iterables import multiset, is_palindromic as _palindromic
4from sympy.utilities.misc import as_int
7def digits(n, b=10, digits=None):
8 """
9 Return a list of the digits of ``n`` in base ``b``. The first
10 element in the list is ``b`` (or ``-b`` if ``n`` is negative).
12 Examples
13 ========
15 >>> from sympy.ntheory.digits import digits
16 >>> digits(35)
17 [10, 3, 5]
19 If the number is negative, the negative sign will be placed on the
20 base (which is the first element in the returned list):
22 >>> digits(-35)
23 [-10, 3, 5]
25 Bases other than 10 (and greater than 1) can be selected with ``b``:
27 >>> digits(27, b=2)
28 [2, 1, 1, 0, 1, 1]
30 Use the ``digits`` keyword if a certain number of digits is desired:
32 >>> digits(35, digits=4)
33 [10, 0, 0, 3, 5]
35 Parameters
36 ==========
38 n: integer
39 The number whose digits are returned.
41 b: integer
42 The base in which digits are computed.
44 digits: integer (or None for all digits)
45 The number of digits to be returned (padded with zeros, if
46 necessary).
48 """
50 b = as_int(b)
51 n = as_int(n)
52 if b < 2:
53 raise ValueError("b must be greater than 1")
54 else:
55 x, y = abs(n), []
56 while x >= b:
57 x, r = divmod(x, b)
58 y.append(r)
59 y.append(x)
60 y.append(-b if n < 0 else b)
61 y.reverse()
62 ndig = len(y) - 1
63 if digits is not None:
64 if ndig > digits:
65 raise ValueError(
66 "For %s, at least %s digits are needed." % (n, ndig))
67 elif ndig < digits:
68 y[1:1] = [0]*(digits - ndig)
69 return y
72def count_digits(n, b=10):
73 """
74 Return a dictionary whose keys are the digits of ``n`` in the
75 given base, ``b``, with keys indicating the digits appearing in the
76 number and values indicating how many times that digit appeared.
78 Examples
79 ========
81 >>> from sympy.ntheory import count_digits
83 >>> count_digits(1111339)
84 {1: 4, 3: 2, 9: 1}
86 The digits returned are always represented in base-10
87 but the number itself can be entered in any format that is
88 understood by Python; the base of the number can also be
89 given if it is different than 10:
91 >>> n = 0xFA; n
92 250
93 >>> count_digits(_)
94 {0: 1, 2: 1, 5: 1}
95 >>> count_digits(n, 16)
96 {10: 1, 15: 1}
98 The default dictionary will return a 0 for any digit that did
99 not appear in the number. For example, which digits appear 7
100 times in ``77!``:
102 >>> from sympy import factorial
103 >>> c77 = count_digits(factorial(77))
104 >>> [i for i in range(10) if c77[i] == 7]
105 [1, 3, 7, 9]
106 """
107 rv = defaultdict(int, multiset(digits(n, b)).items())
108 rv.pop(b) if b in rv else rv.pop(-b) # b or -b is there
109 return rv
112def is_palindromic(n, b=10):
113 """return True if ``n`` is the same when read from left to right
114 or right to left in the given base, ``b``.
116 Examples
117 ========
119 >>> from sympy.ntheory import is_palindromic
121 >>> all(is_palindromic(i) for i in (-11, 1, 22, 121))
122 True
124 The second argument allows you to test numbers in other
125 bases. For example, 88 is palindromic in base-10 but not
126 in base-8:
128 >>> is_palindromic(88, 8)
129 False
131 On the other hand, a number can be palindromic in base-8 but
132 not in base-10:
134 >>> 0o121, is_palindromic(0o121)
135 (81, False)
137 Or it might be palindromic in both bases:
139 >>> oct(121), is_palindromic(121, 8) and is_palindromic(121)
140 ('0o171', True)
142 """
143 return _palindromic(digits(n, b), 1)