diff --git a/.github/workflows/mergefile.yml b/.github/workflows/mergefile.yml index 085593a..e6e89c1 100644 --- a/.github/workflows/mergefile.yml +++ b/.github/workflows/mergefile.yml @@ -34,9 +34,11 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install ruff + pip install ruff isort - name: Run Ruff run: ruff format . + - name: import sort + run: isort --dedup code/main.py - name: Get last commit message id: last-commit run: | diff --git a/README.md b/README.md index 47f79a9..ee4a63e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # hidehic0's library +[![run unittest](https://github.com/hidehic0/library/actions/workflows/unittest.yml/badge.svg?branch=main)](https://github.com/hidehic0/library/actions/workflows/unittest.yml) +[![CodeQL Advanced](https://github.com/hidehic0/library/actions/workflows/codeql.yml/badge.svg)](https://github.com/hidehic0/library/actions/workflows/codeql.yml) +
+ [![total lines](https://tokei.rs/b1/github/hidehic0/library)](https://github.com/XAMPPRocky/tokei) ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/hidehic0/library) ![GitHub repo size](https://img.shields.io/github/repo-size/hidehic0/library) @@ -13,5 +17,3 @@ ファイルは、分割したのは、libsに、全文はcodeに、置いてあります


-[![run unittest](https://github.com/hidehic0/library/actions/workflows/unittest.yml/badge.svg?branch=main)](https://github.com/hidehic0/library/actions/workflows/unittest.yml) -[![CodeQL Advanced](https://github.com/hidehic0/library/actions/workflows/codeql.yml/badge.svg)](https://github.com/hidehic0/library/actions/workflows/codeql.yml) diff --git a/libs/math_func.py b/libs/math_func.py index c59611e..5392242 100644 --- a/libs/math_func.py +++ b/libs/math_func.py @@ -1,3 +1,6 @@ +from typing import List + + # 数学型関数 def is_prime(n): """ @@ -110,6 +113,42 @@ def factorization(n): return result +def factorization_plural(L: List[int]) -> List[List[int]]: + """ + 複数の数の素因数分解を行ないます + 計算量は、O(N * (√max(L) log log √max(L))) + みたいな感じです + + 最初に素数を列挙するため、普通の素因数分解より効率がいいです + """ + res = [] + primes = eratosthenes(int(max(L) ** 0.5) + 20) + + def solve(n): + t = [] + for p in primes: + if n % p == 0: + cnt = 0 + while n % p == 0: + cnt += 1 + n //= p + + t.append([p, cnt]) + + if n != 1: + t.append([n, 1]) + + if t == []: + t.append([n, 1]) + + return t + + for n in L: + res.append(solve(n)) + + return res + + def simple_sigma(n: int) -> int: """ 1からnまでの総和を求める関数 diff --git a/test.py b/test.py index ed0d0bf..eef396a 100644 --- a/test.py +++ b/test.py @@ -1,6 +1,6 @@ import unittest from libs.grid import coordinate_check, grid_moves -from libs.math_func import is_prime, simple_sigma +from libs.math_func import is_prime, simple_sigma, factorization_plural from libs.utils import lowerlist, upperlist, INF from libs.modint import mod_add, mod_sub @@ -51,6 +51,13 @@ def test_simple_sigma(self): with self.subTest(i=i): self.assertEqual(simple_sigma(i), ans) + def test_factorization_plural(self): + test_cases = [([5, 10], [[[5, 1]], [[2, 1], [5, 1]]])] + + for l, ans in test_cases: + with self.subTest(l=l): + self.assertEqual(factorization_plural(l), ans) + class TestUtilsVariable(unittest.TestCase): def test_lowerlist(self): diff --git a/tests/factorization_plural_new.py b/tests/factorization_plural_new.py new file mode 100644 index 0000000..88f2ef2 --- /dev/null +++ b/tests/factorization_plural_new.py @@ -0,0 +1,63 @@ +# python tests/factorization_plural_new.py 2.58s user 0.01s system 99% cpu 2.591 total + + +def eratosthenes(n): + """ + n以下の素数を列挙します + 計算量は、O(n log log n)です + 先程の素数判定法で列挙するよりも、少し速いです + 列挙した素数は昇順に並んでいます + アルゴリズムはエラトステネスです + """ + primes = [True] * (n + 1) + primes[0], primes[1] = False, False + i = 2 + while i**2 <= n: + if primes[i]: + for k in range(i * 2, n + 1, i): + primes[k] = False + + i += 1 + + return [i for i, p in enumerate(primes) if p] + + +def factorization_plural(L): + """ + 複数の数の素因数分解を行ないます + 計算量は、O(N * (√max(L) log log √max(L))) + みたいな感じです + + 最初に素数を列挙するため、普通の素因数分解より効率がいいです + """ + res = [] + primes = eratosthenes(int(max(L) ** 0.5) + 20) + + def solve(n): + t = [] + for p in primes: + if n % p == 0: + cnt = 0 + while n % p == 0: + cnt += 1 + n //= p + + t.append([p, cnt]) + + if n != 1: + t.append([n, 1]) + + if t == []: + t.append([n, 1]) + + return t + + for n in L: + res.append(solve(n)) + + return res + + +t = [10**10] * (10**4) + +factorization_plural(t) diff --git a/tests/factorization_plural_old.py b/tests/factorization_plural_old.py new file mode 100644 index 0000000..3235131 --- /dev/null +++ b/tests/factorization_plural_old.py @@ -0,0 +1,32 @@ +# python tests/factorization_plural_old.py 42.42s user 0.00s system 99% cpu 42.515 total + + +def factorization(n): + """ + nを素因数分解します + 計算量は、√Nです(要改善) + 複数回素因数分解を行なう場合は、√N以下の素数を列挙したので試し割りした法が速いです + """ + result = [] + tmp = n + for i in range(2, int(-(-(n**0.5) // 1)) + 1): + if tmp % i == 0: + cnt = 0 + while tmp % i == 0: + cnt += 1 + tmp //= i + result.append([i, cnt]) + + if tmp != 1: + result.append([tmp, 1]) + + if result == []: + result.append([n, 1]) + + return result + + +t = [10**10] * (10**4) + +for n in t: + factorization(n)