passagemath-combinat 10.6.42__cp314-cp314-musllinux_1_2_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (400) hide show
  1. passagemath_combinat/__init__.py +3 -0
  2. passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
  3. passagemath_combinat-10.6.42.dist-info/RECORD +400 -0
  4. passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
  5. passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
  6. passagemath_combinat.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  7. passagemath_combinat.libs/libsymmetrica-81fe8739.so.3.0.0 +0 -0
  8. sage/algebras/affine_nil_temperley_lieb.py +263 -0
  9. sage/algebras/all.py +24 -0
  10. sage/algebras/all__sagemath_combinat.py +35 -0
  11. sage/algebras/askey_wilson.py +935 -0
  12. sage/algebras/associated_graded.py +345 -0
  13. sage/algebras/cellular_basis.py +350 -0
  14. sage/algebras/cluster_algebra.py +2766 -0
  15. sage/algebras/down_up_algebra.py +860 -0
  16. sage/algebras/free_algebra.py +1698 -0
  17. sage/algebras/free_algebra_element.py +345 -0
  18. sage/algebras/free_algebra_quotient.py +405 -0
  19. sage/algebras/free_algebra_quotient_element.py +295 -0
  20. sage/algebras/free_zinbiel_algebra.py +885 -0
  21. sage/algebras/hall_algebra.py +783 -0
  22. sage/algebras/hecke_algebras/all.py +4 -0
  23. sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
  24. sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
  25. sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
  26. sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
  27. sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
  28. sage/algebras/iwahori_hecke_algebra.py +3095 -0
  29. sage/algebras/jordan_algebra.py +1773 -0
  30. sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
  31. sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
  32. sage/algebras/lie_conformal_algebras/all.py +18 -0
  33. sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
  34. sage/algebras/lie_conformal_algebras/examples.py +43 -0
  35. sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
  36. sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
  37. sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
  38. sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
  39. sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
  40. sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
  41. sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
  42. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
  43. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
  44. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
  45. sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
  46. sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
  47. sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
  48. sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
  49. sage/algebras/nil_coxeter_algebra.py +191 -0
  50. sage/algebras/q_commuting_polynomials.py +673 -0
  51. sage/algebras/q_system.py +608 -0
  52. sage/algebras/quantum_clifford.py +959 -0
  53. sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
  54. sage/algebras/quantum_groups/all.py +9 -0
  55. sage/algebras/quantum_groups/fock_space.py +2219 -0
  56. sage/algebras/quantum_groups/q_numbers.py +207 -0
  57. sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
  58. sage/algebras/quantum_groups/representations.py +591 -0
  59. sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
  60. sage/algebras/quantum_oscillator.py +623 -0
  61. sage/algebras/quaternion_algebra.py +20 -0
  62. sage/algebras/quaternion_algebra_element.py +55 -0
  63. sage/algebras/rational_cherednik_algebra.py +525 -0
  64. sage/algebras/schur_algebra.py +670 -0
  65. sage/algebras/shuffle_algebra.py +1011 -0
  66. sage/algebras/splitting_algebra.py +779 -0
  67. sage/algebras/tensor_algebra.py +709 -0
  68. sage/algebras/yangian.py +1082 -0
  69. sage/algebras/yokonuma_hecke_algebra.py +1018 -0
  70. sage/all__sagemath_combinat.py +35 -0
  71. sage/combinat/SJT.py +255 -0
  72. sage/combinat/affine_permutation.py +2405 -0
  73. sage/combinat/algebraic_combinatorics.py +55 -0
  74. sage/combinat/all.py +53 -0
  75. sage/combinat/all__sagemath_combinat.py +195 -0
  76. sage/combinat/alternating_sign_matrix.py +2063 -0
  77. sage/combinat/baxter_permutations.py +346 -0
  78. sage/combinat/bijectionist.py +3220 -0
  79. sage/combinat/binary_recurrence_sequences.py +1180 -0
  80. sage/combinat/blob_algebra.py +685 -0
  81. sage/combinat/catalog_partitions.py +27 -0
  82. sage/combinat/chas/all.py +23 -0
  83. sage/combinat/chas/fsym.py +1180 -0
  84. sage/combinat/chas/wqsym.py +2601 -0
  85. sage/combinat/cluster_complex.py +326 -0
  86. sage/combinat/colored_permutations.py +2039 -0
  87. sage/combinat/colored_permutations_representations.py +964 -0
  88. sage/combinat/composition_signed.py +142 -0
  89. sage/combinat/composition_tableau.py +855 -0
  90. sage/combinat/constellation.py +1729 -0
  91. sage/combinat/core.py +751 -0
  92. sage/combinat/counting.py +12 -0
  93. sage/combinat/crystals/affine.py +742 -0
  94. sage/combinat/crystals/affine_factorization.py +518 -0
  95. sage/combinat/crystals/affinization.py +331 -0
  96. sage/combinat/crystals/alcove_path.py +2013 -0
  97. sage/combinat/crystals/all.py +22 -0
  98. sage/combinat/crystals/bkk_crystals.py +141 -0
  99. sage/combinat/crystals/catalog.py +115 -0
  100. sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
  101. sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
  102. sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
  103. sage/combinat/crystals/crystals.py +257 -0
  104. sage/combinat/crystals/direct_sum.py +260 -0
  105. sage/combinat/crystals/elementary_crystals.py +1251 -0
  106. sage/combinat/crystals/fast_crystals.py +441 -0
  107. sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
  108. sage/combinat/crystals/generalized_young_walls.py +1076 -0
  109. sage/combinat/crystals/highest_weight_crystals.py +436 -0
  110. sage/combinat/crystals/induced_structure.py +695 -0
  111. sage/combinat/crystals/infinity_crystals.py +730 -0
  112. sage/combinat/crystals/kac_modules.py +863 -0
  113. sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
  114. sage/combinat/crystals/kyoto_path_model.py +497 -0
  115. sage/combinat/crystals/letters.cpython-314-x86_64-linux-musl.so +0 -0
  116. sage/combinat/crystals/letters.pxd +79 -0
  117. sage/combinat/crystals/letters.pyx +3056 -0
  118. sage/combinat/crystals/littelmann_path.py +1518 -0
  119. sage/combinat/crystals/monomial_crystals.py +1262 -0
  120. sage/combinat/crystals/multisegments.py +462 -0
  121. sage/combinat/crystals/mv_polytopes.py +467 -0
  122. sage/combinat/crystals/pbw_crystal.py +511 -0
  123. sage/combinat/crystals/pbw_datum.cpython-314-x86_64-linux-musl.so +0 -0
  124. sage/combinat/crystals/pbw_datum.pxd +4 -0
  125. sage/combinat/crystals/pbw_datum.pyx +487 -0
  126. sage/combinat/crystals/polyhedral_realization.py +372 -0
  127. sage/combinat/crystals/spins.cpython-314-x86_64-linux-musl.so +0 -0
  128. sage/combinat/crystals/spins.pxd +21 -0
  129. sage/combinat/crystals/spins.pyx +756 -0
  130. sage/combinat/crystals/star_crystal.py +290 -0
  131. sage/combinat/crystals/subcrystal.py +464 -0
  132. sage/combinat/crystals/tensor_product.py +1177 -0
  133. sage/combinat/crystals/tensor_product_element.cpython-314-x86_64-linux-musl.so +0 -0
  134. sage/combinat/crystals/tensor_product_element.pxd +35 -0
  135. sage/combinat/crystals/tensor_product_element.pyx +1870 -0
  136. sage/combinat/crystals/virtual_crystal.py +420 -0
  137. sage/combinat/cyclic_sieving_phenomenon.py +204 -0
  138. sage/combinat/debruijn_sequence.cpython-314-x86_64-linux-musl.so +0 -0
  139. sage/combinat/debruijn_sequence.pyx +355 -0
  140. sage/combinat/decorated_permutation.py +270 -0
  141. sage/combinat/degree_sequences.cpython-314-x86_64-linux-musl.so +0 -0
  142. sage/combinat/degree_sequences.pyx +588 -0
  143. sage/combinat/derangements.py +527 -0
  144. sage/combinat/descent_algebra.py +1008 -0
  145. sage/combinat/diagram.py +1551 -0
  146. sage/combinat/diagram_algebras.py +5886 -0
  147. sage/combinat/dyck_word.py +4349 -0
  148. sage/combinat/e_one_star.py +1623 -0
  149. sage/combinat/enumerated_sets.py +123 -0
  150. sage/combinat/expnums.cpython-314-x86_64-linux-musl.so +0 -0
  151. sage/combinat/expnums.pyx +148 -0
  152. sage/combinat/fast_vector_partitions.cpython-314-x86_64-linux-musl.so +0 -0
  153. sage/combinat/fast_vector_partitions.pyx +346 -0
  154. sage/combinat/fqsym.py +1977 -0
  155. sage/combinat/free_dendriform_algebra.py +954 -0
  156. sage/combinat/free_prelie_algebra.py +1141 -0
  157. sage/combinat/fully_commutative_elements.py +1077 -0
  158. sage/combinat/fully_packed_loop.py +1523 -0
  159. sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
  160. sage/combinat/gray_codes.py +311 -0
  161. sage/combinat/grossman_larson_algebras.py +667 -0
  162. sage/combinat/growth.py +4352 -0
  163. sage/combinat/hall_polynomial.py +188 -0
  164. sage/combinat/hillman_grassl.py +866 -0
  165. sage/combinat/integer_matrices.py +329 -0
  166. sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
  167. sage/combinat/k_tableau.py +4564 -0
  168. sage/combinat/kazhdan_lusztig.py +215 -0
  169. sage/combinat/key_polynomial.py +885 -0
  170. sage/combinat/knutson_tao_puzzles.py +2286 -0
  171. sage/combinat/lr_tableau.py +311 -0
  172. sage/combinat/matrices/all.py +24 -0
  173. sage/combinat/matrices/hadamard_matrix.py +3790 -0
  174. sage/combinat/matrices/latin.py +2912 -0
  175. sage/combinat/misc.py +401 -0
  176. sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
  177. sage/combinat/ncsf_qsym/all.py +21 -0
  178. sage/combinat/ncsf_qsym/combinatorics.py +317 -0
  179. sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
  180. sage/combinat/ncsf_qsym/ncsf.py +5637 -0
  181. sage/combinat/ncsf_qsym/qsym.py +4053 -0
  182. sage/combinat/ncsf_qsym/tutorial.py +447 -0
  183. sage/combinat/ncsym/all.py +21 -0
  184. sage/combinat/ncsym/bases.py +855 -0
  185. sage/combinat/ncsym/dual.py +593 -0
  186. sage/combinat/ncsym/ncsym.py +2076 -0
  187. sage/combinat/necklace.py +551 -0
  188. sage/combinat/non_decreasing_parking_function.py +634 -0
  189. sage/combinat/nu_dyck_word.py +1474 -0
  190. sage/combinat/output.py +861 -0
  191. sage/combinat/parallelogram_polyomino.py +4326 -0
  192. sage/combinat/parking_functions.py +1602 -0
  193. sage/combinat/partition_algebra.py +1998 -0
  194. sage/combinat/partition_kleshchev.py +1982 -0
  195. sage/combinat/partition_shifting_algebras.py +584 -0
  196. sage/combinat/partition_tuple.py +3114 -0
  197. sage/combinat/path_tableaux/all.py +13 -0
  198. sage/combinat/path_tableaux/catalog.py +29 -0
  199. sage/combinat/path_tableaux/dyck_path.py +380 -0
  200. sage/combinat/path_tableaux/frieze.py +476 -0
  201. sage/combinat/path_tableaux/path_tableau.py +728 -0
  202. sage/combinat/path_tableaux/semistandard.py +510 -0
  203. sage/combinat/perfect_matching.py +779 -0
  204. sage/combinat/plane_partition.py +3300 -0
  205. sage/combinat/q_bernoulli.cpython-314-x86_64-linux-musl.so +0 -0
  206. sage/combinat/q_bernoulli.pyx +128 -0
  207. sage/combinat/quickref.py +81 -0
  208. sage/combinat/recognizable_series.py +2051 -0
  209. sage/combinat/regular_sequence.py +4316 -0
  210. sage/combinat/regular_sequence_bounded.py +543 -0
  211. sage/combinat/restricted_growth.py +81 -0
  212. sage/combinat/ribbon.py +20 -0
  213. sage/combinat/ribbon_shaped_tableau.py +489 -0
  214. sage/combinat/ribbon_tableau.py +1180 -0
  215. sage/combinat/rigged_configurations/all.py +46 -0
  216. sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
  217. sage/combinat/rigged_configurations/bij_infinity.py +370 -0
  218. sage/combinat/rigged_configurations/bij_type_A.py +163 -0
  219. sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
  220. sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
  221. sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
  222. sage/combinat/rigged_configurations/bij_type_B.py +900 -0
  223. sage/combinat/rigged_configurations/bij_type_C.py +267 -0
  224. sage/combinat/rigged_configurations/bij_type_D.py +771 -0
  225. sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
  226. sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
  227. sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
  228. sage/combinat/rigged_configurations/bijection.py +143 -0
  229. sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
  230. sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
  231. sage/combinat/rigged_configurations/rc_crystal.py +461 -0
  232. sage/combinat/rigged_configurations/rc_infinity.py +540 -0
  233. sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
  234. sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
  235. sage/combinat/rigged_configurations/rigged_partition.cpython-314-x86_64-linux-musl.so +0 -0
  236. sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
  237. sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
  238. sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
  239. sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
  240. sage/combinat/rsk.py +3438 -0
  241. sage/combinat/schubert_polynomial.py +508 -0
  242. sage/combinat/set_partition.py +3318 -0
  243. sage/combinat/set_partition_iterator.cpython-314-x86_64-linux-musl.so +0 -0
  244. sage/combinat/set_partition_iterator.pyx +136 -0
  245. sage/combinat/set_partition_ordered.py +1590 -0
  246. sage/combinat/sf/abreu_nigro.py +346 -0
  247. sage/combinat/sf/all.py +52 -0
  248. sage/combinat/sf/character.py +576 -0
  249. sage/combinat/sf/classical.py +319 -0
  250. sage/combinat/sf/dual.py +996 -0
  251. sage/combinat/sf/elementary.py +549 -0
  252. sage/combinat/sf/hall_littlewood.py +1028 -0
  253. sage/combinat/sf/hecke.py +336 -0
  254. sage/combinat/sf/homogeneous.py +464 -0
  255. sage/combinat/sf/jack.py +1428 -0
  256. sage/combinat/sf/k_dual.py +1458 -0
  257. sage/combinat/sf/kfpoly.py +447 -0
  258. sage/combinat/sf/llt.py +789 -0
  259. sage/combinat/sf/macdonald.py +2019 -0
  260. sage/combinat/sf/monomial.py +525 -0
  261. sage/combinat/sf/multiplicative.py +113 -0
  262. sage/combinat/sf/new_kschur.py +1786 -0
  263. sage/combinat/sf/ns_macdonald.py +964 -0
  264. sage/combinat/sf/orthogonal.py +246 -0
  265. sage/combinat/sf/orthotriang.py +355 -0
  266. sage/combinat/sf/powersum.py +963 -0
  267. sage/combinat/sf/schur.py +880 -0
  268. sage/combinat/sf/sf.py +1653 -0
  269. sage/combinat/sf/sfa.py +7053 -0
  270. sage/combinat/sf/symplectic.py +253 -0
  271. sage/combinat/sf/witt.py +721 -0
  272. sage/combinat/shifted_primed_tableau.py +2735 -0
  273. sage/combinat/shuffle.py +830 -0
  274. sage/combinat/sidon_sets.py +146 -0
  275. sage/combinat/similarity_class_type.py +1721 -0
  276. sage/combinat/sine_gordon.py +618 -0
  277. sage/combinat/six_vertex_model.py +784 -0
  278. sage/combinat/skew_partition.py +2053 -0
  279. sage/combinat/skew_tableau.py +2989 -0
  280. sage/combinat/sloane_functions.py +8935 -0
  281. sage/combinat/specht_module.py +1403 -0
  282. sage/combinat/species/all.py +48 -0
  283. sage/combinat/species/characteristic_species.py +321 -0
  284. sage/combinat/species/composition_species.py +273 -0
  285. sage/combinat/species/cycle_species.py +284 -0
  286. sage/combinat/species/empty_species.py +155 -0
  287. sage/combinat/species/functorial_composition_species.py +148 -0
  288. sage/combinat/species/generating_series.py +673 -0
  289. sage/combinat/species/library.py +148 -0
  290. sage/combinat/species/linear_order_species.py +169 -0
  291. sage/combinat/species/misc.py +83 -0
  292. sage/combinat/species/partition_species.py +290 -0
  293. sage/combinat/species/permutation_species.py +268 -0
  294. sage/combinat/species/product_species.py +423 -0
  295. sage/combinat/species/recursive_species.py +476 -0
  296. sage/combinat/species/set_species.py +192 -0
  297. sage/combinat/species/species.py +820 -0
  298. sage/combinat/species/structure.py +539 -0
  299. sage/combinat/species/subset_species.py +243 -0
  300. sage/combinat/species/sum_species.py +225 -0
  301. sage/combinat/subword.py +564 -0
  302. sage/combinat/subword_complex.py +2122 -0
  303. sage/combinat/subword_complex_c.cpython-314-x86_64-linux-musl.so +0 -0
  304. sage/combinat/subword_complex_c.pyx +119 -0
  305. sage/combinat/super_tableau.py +821 -0
  306. sage/combinat/superpartition.py +1154 -0
  307. sage/combinat/symmetric_group_algebra.py +3774 -0
  308. sage/combinat/symmetric_group_representations.py +1830 -0
  309. sage/combinat/t_sequences.py +877 -0
  310. sage/combinat/tableau.py +9506 -0
  311. sage/combinat/tableau_residues.py +860 -0
  312. sage/combinat/tableau_tuple.py +5353 -0
  313. sage/combinat/tiling.py +2432 -0
  314. sage/combinat/triangles_FHM.py +777 -0
  315. sage/combinat/tutorial.py +1857 -0
  316. sage/combinat/vector_partition.py +337 -0
  317. sage/combinat/words/abstract_word.py +1722 -0
  318. sage/combinat/words/all.py +59 -0
  319. sage/combinat/words/alphabet.py +268 -0
  320. sage/combinat/words/finite_word.py +7201 -0
  321. sage/combinat/words/infinite_word.py +113 -0
  322. sage/combinat/words/lyndon_word.py +652 -0
  323. sage/combinat/words/morphic.py +351 -0
  324. sage/combinat/words/morphism.py +3878 -0
  325. sage/combinat/words/paths.py +2932 -0
  326. sage/combinat/words/shuffle_product.py +278 -0
  327. sage/combinat/words/suffix_trees.py +1873 -0
  328. sage/combinat/words/word.py +769 -0
  329. sage/combinat/words/word_char.cpython-314-x86_64-linux-musl.so +0 -0
  330. sage/combinat/words/word_char.pyx +847 -0
  331. sage/combinat/words/word_datatypes.cpython-314-x86_64-linux-musl.so +0 -0
  332. sage/combinat/words/word_datatypes.pxd +4 -0
  333. sage/combinat/words/word_datatypes.pyx +1067 -0
  334. sage/combinat/words/word_generators.py +2026 -0
  335. sage/combinat/words/word_infinite_datatypes.py +1218 -0
  336. sage/combinat/words/word_options.py +99 -0
  337. sage/combinat/words/words.py +2396 -0
  338. sage/data_structures/all__sagemath_combinat.py +1 -0
  339. sage/databases/all__sagemath_combinat.py +13 -0
  340. sage/databases/findstat.py +4897 -0
  341. sage/databases/oeis.py +2058 -0
  342. sage/databases/sloane.py +393 -0
  343. sage/dynamics/all__sagemath_combinat.py +14 -0
  344. sage/dynamics/cellular_automata/all.py +7 -0
  345. sage/dynamics/cellular_automata/catalog.py +34 -0
  346. sage/dynamics/cellular_automata/elementary.py +612 -0
  347. sage/dynamics/cellular_automata/glca.py +477 -0
  348. sage/dynamics/cellular_automata/solitons.py +1463 -0
  349. sage/dynamics/finite_dynamical_system.py +1249 -0
  350. sage/dynamics/finite_dynamical_system_catalog.py +382 -0
  351. sage/games/all.py +7 -0
  352. sage/games/hexad.py +704 -0
  353. sage/games/quantumino.py +591 -0
  354. sage/games/sudoku.py +889 -0
  355. sage/games/sudoku_backtrack.cpython-314-x86_64-linux-musl.so +0 -0
  356. sage/games/sudoku_backtrack.pyx +189 -0
  357. sage/groups/all__sagemath_combinat.py +1 -0
  358. sage/groups/indexed_free_group.py +489 -0
  359. sage/libs/all__sagemath_combinat.py +6 -0
  360. sage/libs/lrcalc/__init__.py +1 -0
  361. sage/libs/lrcalc/lrcalc.py +525 -0
  362. sage/libs/symmetrica/__init__.py +7 -0
  363. sage/libs/symmetrica/all.py +101 -0
  364. sage/libs/symmetrica/kostka.pxi +168 -0
  365. sage/libs/symmetrica/part.pxi +193 -0
  366. sage/libs/symmetrica/plet.pxi +42 -0
  367. sage/libs/symmetrica/sab.pxi +196 -0
  368. sage/libs/symmetrica/sb.pxi +332 -0
  369. sage/libs/symmetrica/sc.pxi +192 -0
  370. sage/libs/symmetrica/schur.pxi +956 -0
  371. sage/libs/symmetrica/symmetrica.cpython-314-x86_64-linux-musl.so +0 -0
  372. sage/libs/symmetrica/symmetrica.pxi +1172 -0
  373. sage/libs/symmetrica/symmetrica.pyx +39 -0
  374. sage/monoids/all.py +13 -0
  375. sage/monoids/automatic_semigroup.py +1054 -0
  376. sage/monoids/free_abelian_monoid.py +315 -0
  377. sage/monoids/free_abelian_monoid_element.cpython-314-x86_64-linux-musl.so +0 -0
  378. sage/monoids/free_abelian_monoid_element.pxd +16 -0
  379. sage/monoids/free_abelian_monoid_element.pyx +397 -0
  380. sage/monoids/free_monoid.py +335 -0
  381. sage/monoids/free_monoid_element.py +431 -0
  382. sage/monoids/hecke_monoid.py +65 -0
  383. sage/monoids/string_monoid.py +817 -0
  384. sage/monoids/string_monoid_element.py +547 -0
  385. sage/monoids/string_ops.py +143 -0
  386. sage/monoids/trace_monoid.py +972 -0
  387. sage/rings/all__sagemath_combinat.py +2 -0
  388. sage/sat/all.py +4 -0
  389. sage/sat/boolean_polynomials.py +405 -0
  390. sage/sat/converters/__init__.py +6 -0
  391. sage/sat/converters/anf2cnf.py +14 -0
  392. sage/sat/converters/polybori.py +611 -0
  393. sage/sat/solvers/__init__.py +5 -0
  394. sage/sat/solvers/cryptominisat.py +287 -0
  395. sage/sat/solvers/dimacs.py +783 -0
  396. sage/sat/solvers/picosat.py +228 -0
  397. sage/sat/solvers/sat_lp.py +156 -0
  398. sage/sat/solvers/satsolver.cpython-314-x86_64-linux-musl.so +0 -0
  399. sage/sat/solvers/satsolver.pxd +3 -0
  400. sage/sat/solvers/satsolver.pyx +405 -0
sage/games/sudoku.py ADDED
@@ -0,0 +1,889 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.combinat sage.modules
3
+ r"""
4
+ Sudoku Puzzles
5
+
6
+ This module provides algorithms to solve Sudoku puzzles, plus tools
7
+ for inputting, converting and displaying various ways of writing a
8
+ puzzle or its solution(s). Primarily this is accomplished with the
9
+ :class:`sage.games.sudoku.Sudoku` class, though the legacy top-level
10
+ :func:`sage.games.sudoku.sudoku` function is also available.
11
+
12
+ AUTHORS:
13
+
14
+ - Tom Boothby (2008/05/02): Exact Cover, Dancing Links algorithm
15
+ - Robert Beezer (2009/05/29): Backtracking algorithm, Sudoku class
16
+ """
17
+ ######################################################################
18
+ # Copyright (C) 2009, Robert A. Beezer <beezer@ups.edu>
19
+ #
20
+ # Distributed under the terms of the GNU General Public License (GPL)
21
+ #
22
+ # The full text of the GPL is available at:
23
+ # https://www.gnu.org/licenses/
24
+ ######################################################################
25
+
26
+ from sage.structure.sage_object import SageObject
27
+
28
+
29
+ def sudoku(m):
30
+ r"""
31
+ Solve Sudoku puzzles described by matrices.
32
+
33
+ INPUT:
34
+
35
+ - ``m`` -- a square Sage matrix over `\ZZ`, where zeros are blank entries
36
+
37
+ OUTPUT:
38
+
39
+ A Sage matrix over `\ZZ` containing the first solution found,
40
+ otherwise ``None``.
41
+
42
+ This function matches the behavior of the prior Sudoku solver
43
+ and is included only to replicate that behavior. It could be
44
+ safely deprecated, since all of its functionality is included in the :class:`~sage.games.sudoku.Sudoku` class.
45
+
46
+ EXAMPLES:
47
+
48
+ An example that was used in previous doctests. ::
49
+
50
+ sage: A = matrix(ZZ,9,[5,0,0, 0,8,0, 0,4,9, 0,0,0, 5,0,0, 0,3,0, 0,6,7, 3,0,0, 0,0,1, 1,5,0, 0,0,0, 0,0,0, 0,0,0, 2,0,8, 0,0,0, 0,0,0, 0,0,0, 0,1,8, 7,0,0, 0,0,4, 1,5,0, 0,3,0, 0,0,2, 0,0,0, 4,9,0, 0,5,0, 0,0,3])
51
+ sage: A
52
+ [5 0 0 0 8 0 0 4 9]
53
+ [0 0 0 5 0 0 0 3 0]
54
+ [0 6 7 3 0 0 0 0 1]
55
+ [1 5 0 0 0 0 0 0 0]
56
+ [0 0 0 2 0 8 0 0 0]
57
+ [0 0 0 0 0 0 0 1 8]
58
+ [7 0 0 0 0 4 1 5 0]
59
+ [0 3 0 0 0 2 0 0 0]
60
+ [4 9 0 0 5 0 0 0 3]
61
+ sage: sudoku(A)
62
+ [5 1 3 6 8 7 2 4 9]
63
+ [8 4 9 5 2 1 6 3 7]
64
+ [2 6 7 3 4 9 5 8 1]
65
+ [1 5 8 4 6 3 9 7 2]
66
+ [9 7 4 2 1 8 3 6 5]
67
+ [3 2 6 7 9 5 4 1 8]
68
+ [7 8 2 9 3 4 1 5 6]
69
+ [6 3 5 1 7 2 8 9 4]
70
+ [4 9 1 8 5 6 7 2 3]
71
+
72
+ Using inputs that are possible with the
73
+ :class:`~sage.games.sudoku.Sudoku` class,
74
+ other than a matrix, will cause an error. ::
75
+
76
+ sage: sudoku('.4..32....14..3.')
77
+ Traceback (most recent call last):
78
+ ...
79
+ ValueError: sudoku function expects puzzle to be a matrix, perhaps use the Sudoku class
80
+ """
81
+ from sage.structure.element import Matrix
82
+
83
+ if not isinstance(m, Matrix):
84
+ raise ValueError('sudoku function expects puzzle to be a matrix, perhaps use the Sudoku class')
85
+ solution = next(Sudoku(m).solve(algorithm='dlx'))
86
+ return (solution.to_matrix() if solution else None)
87
+
88
+
89
+ class Sudoku(SageObject):
90
+ r"""
91
+ An object representing a Sudoku puzzle. Primarily the purpose is to
92
+ solve the puzzle, but conversions between formats are also provided.
93
+
94
+ INPUT:
95
+
96
+ - ``puzzle`` -- the first argument can take one of three forms
97
+ * list - a Python list with elements of the puzzle in row-major order,
98
+ where a blank entry is a zero
99
+ * matrix - a square Sage matrix over `\ZZ`
100
+ * string - a string where each character is an entry of
101
+ the puzzle. For two-digit entries, a = 10, b = 11, etc.
102
+ - ``verify_input`` -- boolean (default: ``True``); use ``False`` if you know
103
+ the input is valid
104
+
105
+ EXAMPLES::
106
+
107
+ sage: a = Sudoku('5...8..49...5...3..673....115..........2.8..........187....415..3...2...49..5...3')
108
+ sage: print(a)
109
+ +-----+-----+-----+
110
+ |5 | 8 | 4 9|
111
+ | |5 | 3 |
112
+ | 6 7|3 | 1|
113
+ +-----+-----+-----+
114
+ |1 5 | | |
115
+ | |2 8| |
116
+ | | | 1 8|
117
+ +-----+-----+-----+
118
+ |7 | 4|1 5 |
119
+ | 3 | 2| |
120
+ |4 9 | 5 | 3|
121
+ +-----+-----+-----+
122
+ sage: print(next(a.solve()))
123
+ +-----+-----+-----+
124
+ |5 1 3|6 8 7|2 4 9|
125
+ |8 4 9|5 2 1|6 3 7|
126
+ |2 6 7|3 4 9|5 8 1|
127
+ +-----+-----+-----+
128
+ |1 5 8|4 6 3|9 7 2|
129
+ |9 7 4|2 1 8|3 6 5|
130
+ |3 2 6|7 9 5|4 1 8|
131
+ +-----+-----+-----+
132
+ |7 8 2|9 3 4|1 5 6|
133
+ |6 3 5|1 7 2|8 9 4|
134
+ |4 9 1|8 5 6|7 2 3|
135
+ +-----+-----+-----+
136
+ """
137
+ def __init__(self, puzzle, verify_input=True):
138
+ r"""
139
+ Initialize a Sudoku puzzle, determine its size, sanity-check the inputs.
140
+
141
+ TESTS::
142
+
143
+ sage: d = Sudoku('1.......2.9.4...5...6...7...5.9.3.......7.......85..4.7.....6...3...9.8...2.....1')
144
+ sage: d == loads(dumps(d))
145
+ True
146
+
147
+ A lame attempt to construct a puzzle from a single integer::
148
+
149
+ sage: Sudoku(8)
150
+ Traceback (most recent call last):
151
+ ...
152
+ ValueError: Sudoku puzzle must be specified as a matrix, list or string
153
+
154
+ An attempt to construct a puzzle from a non-square matrix::
155
+
156
+ sage: Sudoku(matrix(2,range(6)))
157
+ Traceback (most recent call last):
158
+ ...
159
+ ValueError: Sudoku puzzle must be a square matrix
160
+
161
+ An attempt to construct a puzzle from a string of an impossible length (9)::
162
+
163
+ sage: Sudoku('.........')
164
+ Traceback (most recent call last):
165
+ ...
166
+ ValueError: Sudoku puzzle dimension of 3 must be a perfect square
167
+
168
+ An attempt to construct a `4\times 4` puzzle from a string with a bad entry (5)::
169
+
170
+ sage: Sudoku('.1.2.......5....')
171
+ Traceback (most recent call last):
172
+ ...
173
+ ValueError: Sudoku puzzle has an invalid entry
174
+ """
175
+ from math import sqrt
176
+ from sage.structure.element import Matrix
177
+
178
+ if isinstance(puzzle, list):
179
+ puzzle_size = int(round(sqrt(len(puzzle))))
180
+ self.puzzle = tuple(puzzle)
181
+ elif isinstance(puzzle, Matrix):
182
+ puzzle_size = puzzle.ncols()
183
+ if verify_input and not puzzle.is_square():
184
+ raise ValueError('Sudoku puzzle must be a square matrix')
185
+ self.puzzle = tuple([int(x) for x in puzzle.list()])
186
+ elif isinstance(puzzle, str):
187
+ puzzle_size = int(round(sqrt(len(puzzle))))
188
+ puzzle_numeric = []
189
+ for char in puzzle:
190
+ if char.isdigit():
191
+ puzzle_numeric.append(int(char))
192
+ elif char == '.':
193
+ puzzle_numeric.append(0)
194
+ else:
195
+ puzzle_numeric.append(ord(char.upper()) - ord('A')+10)
196
+ self.puzzle = tuple(puzzle_numeric)
197
+ else:
198
+ raise ValueError('Sudoku puzzle must be specified as a matrix, list or string')
199
+ self.n = int(sqrt(puzzle_size))
200
+ if verify_input:
201
+ if self.n**4 != len(self.puzzle):
202
+ raise ValueError('Sudoku puzzle dimension of %s must be a perfect square' % puzzle_size)
203
+ for x in self.puzzle:
204
+ if (x < 0) or (x > self.n*self.n):
205
+ raise ValueError('Sudoku puzzle has an invalid entry')
206
+
207
+ def __eq__(self, other):
208
+ r"""
209
+ Compare two Sudoku puzzles, based on the underlying
210
+ representation of the puzzles as tuples.
211
+
212
+ EXAMPLES::
213
+
214
+ sage: a = Sudoku('.4..32....14..3.')
215
+ sage: b = Sudoku('8..6..9.5.............2.31...7318.6.24.....73...........279.1..5...8..36..3......')
216
+ sage: c = Sudoku('1..6..9.5.............2.31...7318.6.24.....73...........279.1..5...8..36..3......')
217
+ sage: d = Sudoku('81.6..9.5.............2.31...7318.6.24.....73...........279.1..5...8..36..3......')
218
+
219
+ sage: a == b
220
+ False
221
+ sage: b == b
222
+ True
223
+ sage: b == c
224
+ False
225
+ sage: b == d
226
+ False
227
+ """
228
+ return self.puzzle == tuple(other.to_list())
229
+
230
+ def __hash__(self):
231
+ """
232
+ Return the hash of ``self``.
233
+
234
+ EXAMPLES::
235
+
236
+ sage: a = Sudoku('.4..32....14..3.')
237
+ sage: hash(a) == hash(a.puzzle)
238
+ True
239
+ """
240
+ return hash(self.puzzle)
241
+
242
+ def __ne__(self, other):
243
+ """
244
+ Check that ``self`` is not equal to ``other``.
245
+
246
+ EXAMPLES::
247
+
248
+ sage: a = Sudoku('.4..32....14..3.')
249
+ sage: b = Sudoku('8..6..9.5.............2.31...7318.6.24.....73...........279.1..5...8..36..3......')
250
+ sage: c = Sudoku('1..6..9.5.............2.31...7318.6.24.....73...........279.1..5...8..36..3......')
251
+ sage: d = Sudoku('81.6..9.5.............2.31...7318.6.24.....73...........279.1..5...8..36..3......')
252
+
253
+ sage: a != b
254
+ True
255
+ sage: b != b
256
+ False
257
+ sage: b != c
258
+ True
259
+ sage: b != d
260
+ True
261
+ """
262
+ return not (self == other)
263
+
264
+ def _repr_(self):
265
+ r"""
266
+ Return a concise description of a Sudoku puzzle using a string representation.
267
+
268
+ See the docstring for :func:`to_ascii` for more information on the format.
269
+
270
+ EXAMPLES::
271
+
272
+ sage: s = Sudoku('.4..32....14..3.')
273
+ sage: s._repr_()
274
+ '+---+---+\n| 4| |\n|3 2| |\n+---+---+\n| |1 4|\n| |3 |\n+---+---+'
275
+ """
276
+ return self.to_ascii()
277
+
278
+ def _latex_(self):
279
+ r"""nodetex
280
+ Return a `\LaTeX` representation of a Sudoku puzzle as an array environment.
281
+
282
+ EXAMPLES::
283
+
284
+ sage: s = Sudoku('.4..32....14..3.')
285
+ sage: s._latex_()
286
+ '\\begin{array}{|*{2}{*{2}{r}|}}\\hline\n &4& & \\\\\n3&2& & \\\\\\hline\n & &1&4\\\\\n & &3& \\\\\\hline\n\\end{array}'
287
+ """
288
+ return self.to_latex()
289
+
290
+ def _matrix_(self, R=None):
291
+ r"""
292
+ Return the puzzle as a matrix to support Sage's
293
+ :func:`~sage.matrix.constructor.matrix` constructor.
294
+
295
+ The base ring will be `\ZZ` if ``None`` is provided,
296
+ and it is an error to specify any other base ring.
297
+
298
+ EXAMPLES::
299
+
300
+ sage: k = Sudoku('.4..32....14..3.')
301
+ sage: matrix(k) # indirect doctest
302
+ [0 4 0 0]
303
+ [3 2 0 0]
304
+ [0 0 1 4]
305
+ [0 0 3 0]
306
+ sage: matrix(ZZ,k)
307
+ [0 4 0 0]
308
+ [3 2 0 0]
309
+ [0 0 1 4]
310
+ [0 0 3 0]
311
+ sage: matrix(QQ,k)
312
+ Traceback (most recent call last):
313
+ ...
314
+ ValueError: Sudoku puzzles only convert to matrices over Integer Ring, not Rational Field
315
+ """
316
+ from sage.rings.integer_ring import ZZ, IntegerRing_class
317
+ if R and not isinstance(R, IntegerRing_class):
318
+ raise ValueError('Sudoku puzzles only convert to matrices over %s, not %s' % (ZZ, R))
319
+ return self.to_matrix()
320
+
321
+ def to_string(self):
322
+ r"""
323
+ Construct a string representing a Sudoku puzzle.
324
+
325
+ Blank entries are represented as periods, single
326
+ digits are not converted and two digit entries are
327
+ converted to lower-case letters where ``10 = a``,
328
+ ``11 = b``, etc. This scheme limits puzzles to
329
+ at most 36 symbols.
330
+
331
+ EXAMPLES::
332
+
333
+ sage: b = matrix(ZZ, 9, 9, [ [0,0,0,0,1,0,9,0,0], [8,0,0,4,0,0,0,0,0], [2,0,0,0,0,0,0,0,0], [0,7,0,0,3,0,0,0,0], [0,0,0,0,0,0,2,0,4], [0,0,0,0,0,0,0,5,8], [0,6,0,0,0,0,1,3,0], [7,0,0,2,0,0,0,0,0], [0,0,0,8,0,0,0,0,0] ])
334
+ sage: Sudoku(b).to_string()
335
+ '....1.9..8..4.....2.........7..3..........2.4.......58.6....13.7..2........8.....'
336
+
337
+ TESTS:
338
+
339
+ This tests the conversion of alphabetic characters as well as the
340
+ input and output of Sudoku puzzles as strings. ::
341
+
342
+ sage: j = Sudoku([0, 0, 0, 0, 10, 0, 0, 6, 9, 0, 3, 0, 0, 0, 0, 1, 13, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 14, 0, 4, 0, 0, 0, 0, 11, 0, 0, 0, 0, 5, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 15, 0, 0, 0, 0, 1, 0, 14, 0, 0, 2, 0, 11, 0, 8, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 13, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 7, 0, 16, 0, 0, 9, 0, 10, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 0, 0, 8, 0, 0, 15, 0, 0, 0, 0, 0, 1, 0, 0, 14, 0, 7, 9, 0, 12, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 0, 0, 16, 0, 7, 0, 0, 0, 0, 0, 0, 8, 4, 0, 0, 0, 0, 3, 0, 13, 0, 0, 10, 0, 5, 0, 0, 0, 0, 5, 0, 0, 0, 7, 0, 0, 14, 0, 0, 0, 12, 10, 0, 0, 0, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 4, 0, 0, 0, 13, 0, 0, 14, 0, 0, 16, 0, 9, 2, 0, 6, 0, 0, 8, 0, 0, 0, 0])
343
+ sage: st = j.to_string()
344
+ sage: st
345
+ '....a..69.3....1d.2...8....e.4....b....5..c.......7.......g...f....1.e..2.b.8..3.......4.d.....6.........f..7.g..9.a..c...5.....8..f.....1..e.79.c....b.....2...6.....g.7......84....3.d..a.5....5...7..e...ca.....3.1.......b......f....4...d..e..g.92.6..8....'
346
+ sage: st == Sudoku(st).to_string()
347
+ True
348
+
349
+ A `49\times 49` puzzle with all entries equal to 40,
350
+ which doesn't convert to a letter. ::
351
+
352
+ sage: empty = [40]*2401
353
+ sage: Sudoku(empty).to_string()
354
+ Traceback (most recent call last):
355
+ ...
356
+ ValueError: Sudoku string representation is only valid for puzzles of size 36 or smaller
357
+ """
358
+ encoded = []
359
+ for x in self.puzzle:
360
+ if x == 0:
361
+ encoded.append('.')
362
+ elif 1 <= x <= 9:
363
+ encoded.append(str(x))
364
+ elif x <= 36:
365
+ encoded.append(chr(x-10+ord('a')))
366
+ else:
367
+ raise ValueError('Sudoku string representation is only valid for puzzles of size 36 or smaller')
368
+ return ''.join(encoded)
369
+
370
+ def to_list(self):
371
+ r"""
372
+ Construct a list representing a Sudoku puzzle, in row-major order.
373
+
374
+ EXAMPLES::
375
+
376
+ sage: s = Sudoku('1.......2.9.4...5...6...7...5.9.3.......7.......85..4.7.....6...3...9.8...2.....1')
377
+ sage: s.to_list()
378
+ [1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 5, 0, 9, 0, 3, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 8, 5, 0, 0, 4, 0, 7, 0, 0, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 9, 0, 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1]
379
+
380
+ TESTS:
381
+
382
+ This tests the input and output of Sudoku puzzles as lists. ::
383
+
384
+ sage: alist = [0, 4, 0, 0, 3, 2, 0, 0, 0, 0, 1, 4, 0, 0, 3, 0]
385
+ sage: alist == Sudoku(alist).to_list()
386
+ True
387
+ """
388
+ return list(self.puzzle)
389
+
390
+ def to_matrix(self):
391
+ r"""
392
+ Construct a Sage matrix over `\ZZ` representing a Sudoku puzzle.
393
+
394
+ EXAMPLES::
395
+
396
+ sage: s = Sudoku('.4..32....14..3.')
397
+ sage: s.to_matrix()
398
+ [0 4 0 0]
399
+ [3 2 0 0]
400
+ [0 0 1 4]
401
+ [0 0 3 0]
402
+
403
+ TESTS:
404
+
405
+ This tests the input and output of Sudoku puzzles as matrices over `\ZZ`. ::
406
+
407
+ sage: g = matrix(ZZ, 9, 9, [ [1,0,0,0,0,7,0,9,0], [0,3,0,0,2,0,0,0,8], [0,0,9,6,0,0,5,0,0], [0,0,5,3,0,0,9,0,0], [0,1,0,0,8,0,0,0,2], [6,0,0,0,0,4,0,0,0], [3,0,0,0,0,0,0,1,0], [0,4,0,0,0,0,0,0,7], [0,0,7,0,0,0,3,0,0] ])
408
+ sage: g == Sudoku(g).to_matrix()
409
+ True
410
+ """
411
+ from sage.rings.integer_ring import ZZ
412
+ from sage.matrix.constructor import matrix
413
+ return matrix(ZZ, self.n*self.n, self.puzzle)
414
+
415
+ def to_ascii(self):
416
+ r"""
417
+ Construct an ASCII-art version of a Sudoku puzzle.
418
+ This is a modified version of the ASCII version of a subdivided matrix.
419
+
420
+ EXAMPLES::
421
+
422
+ sage: s = Sudoku('.4..32....14..3.')
423
+ sage: print(s.to_ascii())
424
+ +---+---+
425
+ | 4| |
426
+ |3 2| |
427
+ +---+---+
428
+ | |1 4|
429
+ | |3 |
430
+ +---+---+
431
+ sage: s.to_ascii()
432
+ '+---+---+\n| 4| |\n|3 2| |\n+---+---+\n| |1 4|\n| |3 |\n+---+---+'
433
+ """
434
+ from re import compile
435
+ n = self.n
436
+ nsquare = n*n
437
+ m = self.to_matrix()
438
+ m.subdivide(list(range(0,nsquare+1,n)), list(range(0,nsquare+1,n)))
439
+ naked_zero = compile(r'([\|, ]+)0')
440
+ blanked = naked_zero.sub(lambda x: x.group(1)+' ', m.str())
441
+ brackets = compile(r'[\[,\]]')
442
+ return brackets.sub('', blanked)
443
+
444
+ def to_latex(self):
445
+ r"""
446
+ Create a string of `\LaTeX` code representing a Sudoku puzzle or solution.
447
+
448
+ EXAMPLES::
449
+
450
+ sage: s = Sudoku('.4..32....14..3.')
451
+ sage: print(s.to_latex())
452
+ \begin{array}{|*{2}{*{2}{r}|}}\hline
453
+ &4& & \\
454
+ 3&2& & \\\hline
455
+ & &1&4\\
456
+ & &3& \\\hline
457
+ \end{array}
458
+
459
+ TESTS::
460
+
461
+ sage: s = Sudoku('.4..32....14..3.')
462
+ sage: s.to_latex()
463
+ '\\begin{array}{|*{2}{*{2}{r}|}}\\hline\n &4& & \\\\\n3&2& & \\\\\\hline\n & &1&4\\\\\n & &3& \\\\\\hline\n\\end{array}'
464
+ """
465
+ n = self.n
466
+ nsquare = n*n
467
+ array = []
468
+ array.append('\\begin{array}{|*{%s}{*{%s}{r}|}}\\hline\n' % (n, n))
469
+ gen = iter(self.puzzle)
470
+ for row in range(nsquare):
471
+ for col in range(nsquare):
472
+ entry = next(gen)
473
+ array.append(str(entry) if entry else ' ')
474
+ array.append('' if col == nsquare - 1 else '&')
475
+ array.append('\\\\\n' if (row+1) % n else '\\\\\\hline\n')
476
+ array.append('\\end{array}')
477
+ return ''.join(array)
478
+
479
+ def solve(self, algorithm='dlx'):
480
+ r"""
481
+ Return a generator object for the solutions of a Sudoku puzzle.
482
+
483
+ INPUT:
484
+
485
+ - ``algorithm`` -- string (default: ``'dlx'``); specify choice of
486
+ solution algorithm. The two possible algorithms are ``'dlx'`` and
487
+ ``'backtrack'``
488
+
489
+ OUTPUT:
490
+
491
+ A generator that provides all solutions, as objects of
492
+ the :class:`~sage.games.sudoku.Sudoku` class.
493
+
494
+ Calling ``next()`` on the returned generator just once will find
495
+ a solution, presuming it exists, otherwise it will return a
496
+ ``StopIteration`` exception. The generator may be used for
497
+ iteration or wrapping the generator with ``list()`` will return
498
+ all of the solutions as a list. Solutions are returned as
499
+ new objects of the :class:`~sage.games.sudoku.Sudoku` class,
500
+ so may be printed or converted using other methods in this class.
501
+
502
+ Generally, the DLX algorithm is very fast and very consistent.
503
+ The backtrack algorithm is very variable in its performance,
504
+ on some occasions markedly faster than DLX but usually slower
505
+ by a similar factor, with the potential to be orders of magnitude
506
+ slower. See the docstrings for the
507
+ :meth:`~sage.games.sudoku.Sudoku.dlx` and
508
+ :meth:`~sage.games.sudoku.Sudoku.backtrack_all`
509
+ methods for further discussions and examples of performance.
510
+ Note that the backtrack algorithm is limited to puzzles of
511
+ size `16\times 16` or smaller.
512
+
513
+ EXAMPLES:
514
+
515
+ This puzzle has 5 solutions, but the first one returned by each algorithm are identical. ::
516
+
517
+ sage: h = Sudoku('8..6..9.5.............2.31...7318.6.24.....73...........279.1..5...8..36..3......')
518
+ sage: h
519
+ +-----+-----+-----+
520
+ |8 |6 |9 5|
521
+ | | | |
522
+ | | 2 |3 1 |
523
+ +-----+-----+-----+
524
+ | 7|3 1 8| 6 |
525
+ |2 4 | | 7 3|
526
+ | | | |
527
+ +-----+-----+-----+
528
+ | 2|7 9 |1 |
529
+ |5 | 8 | 3 6|
530
+ | 3| | |
531
+ +-----+-----+-----+
532
+ sage: next(h.solve(algorithm='backtrack'))
533
+ +-----+-----+-----+
534
+ |8 1 4|6 3 7|9 2 5|
535
+ |3 2 5|1 4 9|6 8 7|
536
+ |7 9 6|8 2 5|3 1 4|
537
+ +-----+-----+-----+
538
+ |9 5 7|3 1 8|4 6 2|
539
+ |2 4 1|9 5 6|8 7 3|
540
+ |6 3 8|2 7 4|5 9 1|
541
+ +-----+-----+-----+
542
+ |4 6 2|7 9 3|1 5 8|
543
+ |5 7 9|4 8 1|2 3 6|
544
+ |1 8 3|5 6 2|7 4 9|
545
+ +-----+-----+-----+
546
+ sage: next(h.solve(algorithm='dlx'))
547
+ +-----+-----+-----+
548
+ |8 1 4|6 3 7|9 2 5|
549
+ |3 2 5|1 4 9|6 8 7|
550
+ |7 9 6|8 2 5|3 1 4|
551
+ +-----+-----+-----+
552
+ |9 5 7|3 1 8|4 6 2|
553
+ |2 4 1|9 5 6|8 7 3|
554
+ |6 3 8|2 7 4|5 9 1|
555
+ +-----+-----+-----+
556
+ |4 6 2|7 9 3|1 5 8|
557
+ |5 7 9|4 8 1|2 3 6|
558
+ |1 8 3|5 6 2|7 4 9|
559
+ +-----+-----+-----+
560
+
561
+ Gordon Royle maintains a list of 48072 Sudoku puzzles that each has
562
+ a unique solution and exactly 17 "hints" (initially filled boxes).
563
+ At this writing (May 2009) there is no known 16-hint puzzle with
564
+ exactly one solution. [sudoku:royle]_ This puzzle is number 3000
565
+ in his database. We solve it twice. ::
566
+
567
+ sage: b = Sudoku('8..6..9.5.............2.31...7318.6.24.....73...........279.1..5...8..36..3......')
568
+ sage: next(b.solve(algorithm='dlx')) == next(b.solve(algorithm='backtrack'))
569
+ True
570
+
571
+
572
+ These are the first 10 puzzles in a list of "Top 95" puzzles,
573
+ [sudoku:top95]_ which we use to show that the two available algorithms obtain
574
+ the same solution for each. ::
575
+
576
+ sage: top =['4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......',
577
+ ....: '52...6.........7.13...........4..8..6......5...........418.........3..2...87.....',
578
+ ....: '6.....8.3.4.7.................5.4.7.3..2.....1.6.......2.....5.....8.6......1....',
579
+ ....: '48.3............71.2.......7.5....6....2..8.............1.76...3.....4......5....',
580
+ ....: '....14....3....2...7..........9...3.6.1.............8.2.....1.4....5.6.....7.8...',
581
+ ....: '......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.',
582
+ ....: '6.2.5.........3.4..........43...8....1....2........7..5..27...........81...6.....',
583
+ ....: '.524.........7.1..............8.2...3.....6...9.5.....1.6.3...........897........',
584
+ ....: '6.2.5.........4.3..........43...8....1....2........7..5..27...........81...6.....',
585
+ ....: '.923.........8.1...........1.7.4...........658.........6.5.2...4.....7.....9.....']
586
+ sage: p = [Sudoku(top[i]) for i in range(10)]
587
+ sage: verify = [next(p[i].solve(algorithm='dlx')) == next(p[i].solve(algorithm='backtrack')) for i in range(10)]
588
+ sage: verify == [True]*10
589
+ True
590
+
591
+ TESTS:
592
+
593
+ A `25\times 25` puzzle that the backtrack algorithm is not equipped to handle. Since ``solve`` returns a generator this test will not go boom until we ask for a solution with ``next``. ::
594
+
595
+ sage: too_big = Sudoku([0]*625)
596
+ sage: next(too_big.solve(algorithm='backtrack'))
597
+ Traceback (most recent call last):
598
+ ...
599
+ ValueError: the Sudoku backtrack algorithm is limited to puzzles of size 16 or smaller
600
+
601
+ An attempt to use a non-existent algorithm. ::
602
+
603
+ sage: next(Sudoku([0]).solve(algorithm='bogus'))
604
+ Traceback (most recent call last):
605
+ ...
606
+ NotImplementedError: bogus is not an algorithm for Sudoku puzzles
607
+ """
608
+ if algorithm == 'backtrack':
609
+ if self.n > 4:
610
+ raise ValueError('the Sudoku backtrack algorithm is limited to puzzles of size 16 or smaller')
611
+ else:
612
+ gen = self.backtrack()
613
+ elif algorithm == 'dlx':
614
+ gen = self.dlx()
615
+ else:
616
+ raise NotImplementedError('%s is not an algorithm for Sudoku puzzles' % algorithm)
617
+ for soln in gen:
618
+ yield Sudoku(soln, verify_input='False')
619
+
620
+ def backtrack(self):
621
+ r"""
622
+ Return a generator which iterates through all solutions of a Sudoku puzzle.
623
+
624
+ This function is intended to be called from the
625
+ :func:`~sage.games.sudoku.Sudoku.solve` method
626
+ when the ``algorithm='backtrack'`` option is specified.
627
+ However it may be called directly as a method of an
628
+ instance of a Sudoku puzzle.
629
+
630
+ At this point, this method calls
631
+ :func:`~sage.games.sudoku_backtrack.backtrack_all` which
632
+ constructs *all* of the solutions as a list. Then the
633
+ present method just returns the items of the list one at
634
+ a time. Once Cython supports closures and a yield statement
635
+ is supported, then the contents of ``backtrack_all()``
636
+ may be subsumed into this method and the
637
+ :mod:`sage.games.sudoku_backtrack` module can be removed.
638
+
639
+ This routine can have wildly variable performance, with a
640
+ factor of 4000 observed between the fastest and slowest
641
+ `9\times 9` examples tested. Examples designed to perform
642
+ poorly for naive backtracking, will do poorly
643
+ (such as ``d`` below). However, examples meant to be
644
+ difficult for humans often do very well, with a factor
645
+ of 5 improvement over the `DLX` algorithm.
646
+
647
+ Without dynamically allocating arrays in the Cython version,
648
+ we have limited this function to `16\times 16` puzzles.
649
+ Algorithmic details are in the
650
+ :mod:`sage.games.sudoku_backtrack` module.
651
+
652
+ EXAMPLES:
653
+
654
+ This example was reported to be very difficult for human solvers.
655
+ This algorithm works very fast on it, at about half the time
656
+ of the DLX solver. [sudoku:escargot]_ ::
657
+
658
+ sage: g = Sudoku('1....7.9..3..2...8..96..5....53..9...1..8...26....4...3......1..4......7..7...3..')
659
+ sage: print(g)
660
+ +-----+-----+-----+
661
+ |1 | 7| 9 |
662
+ | 3 | 2 | 8|
663
+ | 9|6 |5 |
664
+ +-----+-----+-----+
665
+ | 5|3 |9 |
666
+ | 1 | 8 | 2|
667
+ |6 | 4| |
668
+ +-----+-----+-----+
669
+ |3 | | 1 |
670
+ | 4 | | 7|
671
+ | 7| |3 |
672
+ +-----+-----+-----+
673
+ sage: print(next(g.solve(algorithm='backtrack')))
674
+ +-----+-----+-----+
675
+ |1 6 2|8 5 7|4 9 3|
676
+ |5 3 4|1 2 9|6 7 8|
677
+ |7 8 9|6 4 3|5 2 1|
678
+ +-----+-----+-----+
679
+ |4 7 5|3 1 2|9 8 6|
680
+ |9 1 3|5 8 6|7 4 2|
681
+ |6 2 8|7 9 4|1 3 5|
682
+ +-----+-----+-----+
683
+ |3 5 6|4 7 8|2 1 9|
684
+ |2 4 1|9 3 5|8 6 7|
685
+ |8 9 7|2 6 1|3 5 4|
686
+ +-----+-----+-----+
687
+
688
+ This example has no entries in the top row and a half,
689
+ and the top row of the solution is ``987654321`` and
690
+ therefore a backtracking approach is slow, taking about
691
+ 750 times as long as the DLX solver. [sudoku:wikipedia]_ ::
692
+
693
+ sage: c = Sudoku('..............3.85..1.2.......5.7.....4...1...9.......5......73..2.1........4...9')
694
+ sage: print(c)
695
+ +-----+-----+-----+
696
+ | | | |
697
+ | | 3| 8 5|
698
+ | 1| 2 | |
699
+ +-----+-----+-----+
700
+ | |5 7| |
701
+ | 4| |1 |
702
+ | 9 | | |
703
+ +-----+-----+-----+
704
+ |5 | | 7 3|
705
+ | 2| 1 | |
706
+ | | 4 | 9|
707
+ +-----+-----+-----+
708
+ sage: print(next(c.solve(algorithm='backtrack')))
709
+ +-----+-----+-----+
710
+ |9 8 7|6 5 4|3 2 1|
711
+ |2 4 6|1 7 3|9 8 5|
712
+ |3 5 1|9 2 8|7 4 6|
713
+ +-----+-----+-----+
714
+ |1 2 8|5 3 7|6 9 4|
715
+ |6 3 4|8 9 2|1 5 7|
716
+ |7 9 5|4 6 1|8 3 2|
717
+ +-----+-----+-----+
718
+ |5 1 9|2 8 6|4 7 3|
719
+ |4 7 2|3 1 9|5 6 8|
720
+ |8 6 3|7 4 5|2 1 9|
721
+ +-----+-----+-----+
722
+ """
723
+ from .sudoku_backtrack import backtrack_all
724
+ solutions = backtrack_all(self.n, self.puzzle)
725
+ yield from solutions
726
+
727
+ def dlx(self, count_only=False):
728
+ r"""
729
+ Return a generator that iterates through all solutions of a Sudoku puzzle.
730
+
731
+ INPUT:
732
+
733
+ - ``count_only`` -- boolean (default: ``False``);
734
+ if set to ``True`` the generator returned as output will
735
+ simply generate ``None`` for each solution, so the
736
+ calling routine can count these
737
+
738
+ OUTPUT: a generator that iterates over all the solutions
739
+
740
+ This function is intended to be called from the
741
+ :func:`~sage.games.sudoku.Sudoku.solve` method
742
+ with the ``algorithm='dlx'`` option. However it
743
+ may be called directly as a method of an instance
744
+ of a Sudoku puzzle if speed is important and you
745
+ do not need automatic conversions on the output
746
+ (or even just want to count solutions without looking
747
+ at them). In this case, inputting a puzzle as a list,
748
+ with ``verify_input=False`` is the fastest way to
749
+ create a puzzle.
750
+
751
+ Or if only one solution is needed it can be obtained with
752
+ one call to ``next()``, while the existence of a solution
753
+ can be tested by catching the ``StopIteration`` exception
754
+ with a ``try``. Calling this particular method returns
755
+ solutions as lists, in row-major order. It is up to you
756
+ to work with this list for your own purposes. If you want
757
+ fancier formatting tools, use the
758
+ :func:`~sage.games.sudoku.Sudoku.solve` method, which
759
+ returns a generator that creates
760
+ :class:`sage.games.sudoku.Sudoku` objects.
761
+
762
+ EXAMPLES:
763
+
764
+ A `9\times 9` known to have one solution. We get the one
765
+ solution and then check to see if there are more or not. ::
766
+
767
+ sage: e = Sudoku('4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......')
768
+ sage: print(next(e.dlx()))
769
+ [4, 1, 7, 3, 6, 9, 8, 2, 5, 6, 3, 2, 1, 5, 8, 9, 4, 7, 9, 5, 8, 7, 2, 4, 3, 1, 6, 8, 2, 5, 4, 3, 7, 1, 6, 9, 7, 9, 1, 5, 8, 6, 4, 3, 2, 3, 4, 6, 9, 1, 2, 7, 5, 8, 2, 8, 9, 6, 4, 3, 5, 7, 1, 5, 7, 3, 2, 9, 1, 6, 8, 4, 1, 6, 4, 8, 7, 5, 2, 9, 3]
770
+ sage: len(list(e.dlx()))
771
+ 1
772
+
773
+ A `9\times 9` puzzle with multiple solutions.
774
+ Once with actual solutions, once just to count. ::
775
+
776
+ sage: h = Sudoku('8..6..9.5.............2.31...7318.6.24.....73...........279.1..5...8..36..3......')
777
+ sage: len(list(h.dlx()))
778
+ 5
779
+ sage: len(list(h.dlx(count_only=True)))
780
+ 5
781
+
782
+ A larger puzzle, with multiple solutions, but we just get one. ::
783
+
784
+ sage: j = Sudoku('....a..69.3....1d.2...8....e.4....b....5..c.......7.......g...f....1.e..2.b.8..3.......4.d.....6.........f..7.g..9.a..c...5.....8..f.....1..e.79.c....b.....2...6.....g.7......84....3.d..a.5....5...7..e...ca.....3.1.......b......f....4...d..e..g.92.6..8....')
785
+ sage: print(next(j.dlx()))
786
+ [5, 15, 16, 14, 10, 13, 7, 6, 9, 2, 3, 4, 11, 8, 12, 1, 13, 3, 2, 12, 11, 16, 8, 15, 1, 6, 7, 14, 10, 4, 9, 5, 1, 10, 11, 6, 9, 4, 3, 5, 15, 8, 12, 13, 16, 7, 14, 2, 9, 8, 7, 4, 12, 2, 1, 14, 10, 5, 16, 11, 6, 3, 15, 13, 12, 16, 4, 1, 13, 14, 9, 10, 2, 7, 11, 6, 8, 15, 5, 3, 3, 14, 5, 7, 16, 11, 15, 4, 12, 13, 8, 9, 1, 2, 10, 6, 2, 6, 13, 11, 1, 8, 5, 3, 4, 15, 14, 10, 7, 9, 16, 12, 15, 9, 8, 10, 2, 6, 12, 7, 3, 16, 5, 1, 4, 14, 13, 11, 8, 11, 3, 15, 5, 10, 4, 2, 13, 1, 6, 12, 14, 16, 7, 9, 16, 12, 14, 13, 7, 15, 11, 1, 8, 9, 4, 5, 2, 6, 3, 10, 6, 2, 10, 5, 14, 12, 16, 9, 7, 11, 15, 3, 13, 1, 4, 8, 4, 7, 1, 9, 8, 3, 6, 13, 16, 14, 10, 2, 5, 12, 11, 15, 11, 5, 9, 8, 6, 7, 13, 16, 14, 3, 1, 15, 12, 10, 2, 4, 7, 13, 15, 3, 4, 1, 10, 8, 5, 12, 2, 16, 9, 11, 6, 14, 10, 1, 6, 2, 15, 5, 14, 12, 11, 4, 9, 7, 3, 13, 8, 16, 14, 4, 12, 16, 3, 9, 2, 11, 6, 10, 13, 8, 15, 5, 1, 7]
787
+
788
+ The puzzle ``h`` from above, but purposely made unsolvable with addition in second entry. ::
789
+
790
+ sage: hbad = Sudoku('82.6..9.5.............2.31...7318.6.24.....73...........279.1..5...8..36..3......')
791
+ sage: len(list(hbad.dlx()))
792
+ 0
793
+ sage: next(hbad.dlx())
794
+ Traceback (most recent call last):
795
+ ...
796
+ StopIteration
797
+
798
+ A stupidly small puzzle to test the lower limits of arbitrary sized input. ::
799
+
800
+ sage: s = Sudoku('.')
801
+ sage: print(next(s.solve(algorithm='dlx')))
802
+ +-+
803
+ |1|
804
+ +-+
805
+
806
+ ALGORITHM:
807
+
808
+ The ``DLXCPP`` solver finds solutions to the exact-cover
809
+ problem with a "Dancing Links" backtracking algorithm.
810
+ Given a `0-1` matrix, the solver finds a subset of the
811
+ rows that sums to the all `1`'s vector. The columns
812
+ correspond to conditions, or constraints, that must be
813
+ met by a solution, while the rows correspond to some
814
+ collection of choices, or decisions. A `1` in a row
815
+ and column indicates that the choice corresponding to
816
+ the row meets the condition corresponding to the column.
817
+
818
+ So here, we code the notion of a Sudoku puzzle, and the
819
+ hints already present, into such a `0-1` matrix. Then the
820
+ :class:`sage.combinat.matrices.dlxcpp.DLXCPP` solver makes
821
+ the choices for the blank entries.
822
+ """
823
+ from sage.combinat.matrices.dlxcpp import DLXCPP
824
+
825
+ n = self.n
826
+ nsquare = n*n
827
+ nfour = nsquare*nsquare
828
+
829
+ # Boxes of the grid are numbered in row-major order
830
+ # ``rcbox`` simply maps a row-column index pair to the box number it lives in
831
+ rcbox = [ [i//n + n*(j//n) for i in range(nsquare)] for j in range(nsquare)]
832
+
833
+ # Every entry in a Sudoku puzzle satisfies four constraints
834
+ # Every location has a single entry, and each row, column and box has each symbol once
835
+ # These arrays can be thought of as assigning ID numbers to these constraints,
836
+ # and correspond to column numbers of the `0-1` matrix describing the exact cover
837
+ rows = [[i+j for i in range(nsquare)] for j in range(0, nfour, nsquare)]
838
+ cols = [[i+j for i in range(nsquare)] for j in range(nfour, 2*nfour, nsquare)]
839
+ boxes = [[i+j for i in range(nsquare)] for j in range(2*nfour, 3*nfour, nsquare)]
840
+ rowcol = [[i+j for i in range(nsquare)] for j in range(3*nfour, 4*nfour, nsquare)]
841
+
842
+ def make_row(row, col, entry):
843
+ r"""
844
+ Construct a row of the `0-1` matrix describing
845
+ the exact cover constraints for a Sudoku puzzle.
846
+
847
+ If a (zero-based) ``entry`` is placed in location
848
+ ``(row, col)`` of a Sudoku puzzle, then exactly four
849
+ constraints are satisfied: the location has this entry,
850
+ and the entry occurs in the row, column and box.
851
+ This method looks up the constraint IDs for each of
852
+ these four constraints, and returns a list of these four IDs.
853
+
854
+ TESTS::
855
+
856
+ sage: h = Sudoku('8..6..9.5.............2.31...7318.6.24.....73...........279.1..5...8..36..3......')
857
+ sage: len(list(h.solve(algorithm='dlx'))) # indirect doctest
858
+ 5
859
+ """
860
+ box = rcbox[row][col]
861
+ return [rows[row][entry], cols[col][entry], boxes[box][entry], rowcol[row][col]]
862
+
863
+ # Construct the sparse `0-1` matrix for the exact cover formulation as the ``ones`` array
864
+ # ``rowinfo`` remembers the location and entry that led to the row being added to the matrix
865
+ rowinfo = []
866
+ ones = []
867
+ gen = (entry for entry in self.puzzle)
868
+ for row in range(nsquare):
869
+ for col in range(nsquare):
870
+ puzz = next(gen)
871
+ # All (zero-based) entries are possible, or only one is possible
872
+ entries = ([puzz-1] if puzz else range(nsquare))
873
+ for entry in entries:
874
+ ones.append(make_row(row, col, entry))
875
+ rowinfo.append((row, col, entry))
876
+
877
+ # ``DLXCPP`` will solve the exact cover problem for the ``ones`` matrix
878
+ # ``cover`` will contain a subset of the row indices so that the sum of the rows is the all `1`'s vector
879
+ # These rows will represent the original hints, plus a single entry in every other location,
880
+ # consistent with the requirements imposed on a solution to a Sudoku puzzle
881
+ for cover in DLXCPP(ones):
882
+ if not count_only:
883
+ solution = [0] * nfour
884
+ for r in cover:
885
+ row, col, entry = rowinfo[r]
886
+ solution[row * nsquare + col] = entry + 1
887
+ yield solution
888
+ else:
889
+ yield None