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.
- passagemath_combinat/__init__.py +3 -0
- passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
- passagemath_combinat-10.6.42.dist-info/RECORD +400 -0
- passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
- passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
- passagemath_combinat.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
- passagemath_combinat.libs/libsymmetrica-81fe8739.so.3.0.0 +0 -0
- sage/algebras/affine_nil_temperley_lieb.py +263 -0
- sage/algebras/all.py +24 -0
- sage/algebras/all__sagemath_combinat.py +35 -0
- sage/algebras/askey_wilson.py +935 -0
- sage/algebras/associated_graded.py +345 -0
- sage/algebras/cellular_basis.py +350 -0
- sage/algebras/cluster_algebra.py +2766 -0
- sage/algebras/down_up_algebra.py +860 -0
- sage/algebras/free_algebra.py +1698 -0
- sage/algebras/free_algebra_element.py +345 -0
- sage/algebras/free_algebra_quotient.py +405 -0
- sage/algebras/free_algebra_quotient_element.py +295 -0
- sage/algebras/free_zinbiel_algebra.py +885 -0
- sage/algebras/hall_algebra.py +783 -0
- sage/algebras/hecke_algebras/all.py +4 -0
- sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
- sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
- sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
- sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
- sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
- sage/algebras/iwahori_hecke_algebra.py +3095 -0
- sage/algebras/jordan_algebra.py +1773 -0
- sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
- sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
- sage/algebras/lie_conformal_algebras/all.py +18 -0
- sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
- sage/algebras/lie_conformal_algebras/examples.py +43 -0
- sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
- sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
- sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
- sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
- sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
- sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
- sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
- sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
- sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
- sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
- sage/algebras/nil_coxeter_algebra.py +191 -0
- sage/algebras/q_commuting_polynomials.py +673 -0
- sage/algebras/q_system.py +608 -0
- sage/algebras/quantum_clifford.py +959 -0
- sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
- sage/algebras/quantum_groups/all.py +9 -0
- sage/algebras/quantum_groups/fock_space.py +2219 -0
- sage/algebras/quantum_groups/q_numbers.py +207 -0
- sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
- sage/algebras/quantum_groups/representations.py +591 -0
- sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
- sage/algebras/quantum_oscillator.py +623 -0
- sage/algebras/quaternion_algebra.py +20 -0
- sage/algebras/quaternion_algebra_element.py +55 -0
- sage/algebras/rational_cherednik_algebra.py +525 -0
- sage/algebras/schur_algebra.py +670 -0
- sage/algebras/shuffle_algebra.py +1011 -0
- sage/algebras/splitting_algebra.py +779 -0
- sage/algebras/tensor_algebra.py +709 -0
- sage/algebras/yangian.py +1082 -0
- sage/algebras/yokonuma_hecke_algebra.py +1018 -0
- sage/all__sagemath_combinat.py +35 -0
- sage/combinat/SJT.py +255 -0
- sage/combinat/affine_permutation.py +2405 -0
- sage/combinat/algebraic_combinatorics.py +55 -0
- sage/combinat/all.py +53 -0
- sage/combinat/all__sagemath_combinat.py +195 -0
- sage/combinat/alternating_sign_matrix.py +2063 -0
- sage/combinat/baxter_permutations.py +346 -0
- sage/combinat/bijectionist.py +3220 -0
- sage/combinat/binary_recurrence_sequences.py +1180 -0
- sage/combinat/blob_algebra.py +685 -0
- sage/combinat/catalog_partitions.py +27 -0
- sage/combinat/chas/all.py +23 -0
- sage/combinat/chas/fsym.py +1180 -0
- sage/combinat/chas/wqsym.py +2601 -0
- sage/combinat/cluster_complex.py +326 -0
- sage/combinat/colored_permutations.py +2039 -0
- sage/combinat/colored_permutations_representations.py +964 -0
- sage/combinat/composition_signed.py +142 -0
- sage/combinat/composition_tableau.py +855 -0
- sage/combinat/constellation.py +1729 -0
- sage/combinat/core.py +751 -0
- sage/combinat/counting.py +12 -0
- sage/combinat/crystals/affine.py +742 -0
- sage/combinat/crystals/affine_factorization.py +518 -0
- sage/combinat/crystals/affinization.py +331 -0
- sage/combinat/crystals/alcove_path.py +2013 -0
- sage/combinat/crystals/all.py +22 -0
- sage/combinat/crystals/bkk_crystals.py +141 -0
- sage/combinat/crystals/catalog.py +115 -0
- sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
- sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
- sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
- sage/combinat/crystals/crystals.py +257 -0
- sage/combinat/crystals/direct_sum.py +260 -0
- sage/combinat/crystals/elementary_crystals.py +1251 -0
- sage/combinat/crystals/fast_crystals.py +441 -0
- sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
- sage/combinat/crystals/generalized_young_walls.py +1076 -0
- sage/combinat/crystals/highest_weight_crystals.py +436 -0
- sage/combinat/crystals/induced_structure.py +695 -0
- sage/combinat/crystals/infinity_crystals.py +730 -0
- sage/combinat/crystals/kac_modules.py +863 -0
- sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
- sage/combinat/crystals/kyoto_path_model.py +497 -0
- sage/combinat/crystals/letters.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/crystals/letters.pxd +79 -0
- sage/combinat/crystals/letters.pyx +3056 -0
- sage/combinat/crystals/littelmann_path.py +1518 -0
- sage/combinat/crystals/monomial_crystals.py +1262 -0
- sage/combinat/crystals/multisegments.py +462 -0
- sage/combinat/crystals/mv_polytopes.py +467 -0
- sage/combinat/crystals/pbw_crystal.py +511 -0
- sage/combinat/crystals/pbw_datum.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/crystals/pbw_datum.pxd +4 -0
- sage/combinat/crystals/pbw_datum.pyx +487 -0
- sage/combinat/crystals/polyhedral_realization.py +372 -0
- sage/combinat/crystals/spins.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/crystals/spins.pxd +21 -0
- sage/combinat/crystals/spins.pyx +756 -0
- sage/combinat/crystals/star_crystal.py +290 -0
- sage/combinat/crystals/subcrystal.py +464 -0
- sage/combinat/crystals/tensor_product.py +1177 -0
- sage/combinat/crystals/tensor_product_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/crystals/tensor_product_element.pxd +35 -0
- sage/combinat/crystals/tensor_product_element.pyx +1870 -0
- sage/combinat/crystals/virtual_crystal.py +420 -0
- sage/combinat/cyclic_sieving_phenomenon.py +204 -0
- sage/combinat/debruijn_sequence.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/debruijn_sequence.pyx +355 -0
- sage/combinat/decorated_permutation.py +270 -0
- sage/combinat/degree_sequences.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/degree_sequences.pyx +588 -0
- sage/combinat/derangements.py +527 -0
- sage/combinat/descent_algebra.py +1008 -0
- sage/combinat/diagram.py +1551 -0
- sage/combinat/diagram_algebras.py +5886 -0
- sage/combinat/dyck_word.py +4349 -0
- sage/combinat/e_one_star.py +1623 -0
- sage/combinat/enumerated_sets.py +123 -0
- sage/combinat/expnums.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/expnums.pyx +148 -0
- sage/combinat/fast_vector_partitions.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/fast_vector_partitions.pyx +346 -0
- sage/combinat/fqsym.py +1977 -0
- sage/combinat/free_dendriform_algebra.py +954 -0
- sage/combinat/free_prelie_algebra.py +1141 -0
- sage/combinat/fully_commutative_elements.py +1077 -0
- sage/combinat/fully_packed_loop.py +1523 -0
- sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
- sage/combinat/gray_codes.py +311 -0
- sage/combinat/grossman_larson_algebras.py +667 -0
- sage/combinat/growth.py +4352 -0
- sage/combinat/hall_polynomial.py +188 -0
- sage/combinat/hillman_grassl.py +866 -0
- sage/combinat/integer_matrices.py +329 -0
- sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
- sage/combinat/k_tableau.py +4564 -0
- sage/combinat/kazhdan_lusztig.py +215 -0
- sage/combinat/key_polynomial.py +885 -0
- sage/combinat/knutson_tao_puzzles.py +2286 -0
- sage/combinat/lr_tableau.py +311 -0
- sage/combinat/matrices/all.py +24 -0
- sage/combinat/matrices/hadamard_matrix.py +3790 -0
- sage/combinat/matrices/latin.py +2912 -0
- sage/combinat/misc.py +401 -0
- sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
- sage/combinat/ncsf_qsym/all.py +21 -0
- sage/combinat/ncsf_qsym/combinatorics.py +317 -0
- sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
- sage/combinat/ncsf_qsym/ncsf.py +5637 -0
- sage/combinat/ncsf_qsym/qsym.py +4053 -0
- sage/combinat/ncsf_qsym/tutorial.py +447 -0
- sage/combinat/ncsym/all.py +21 -0
- sage/combinat/ncsym/bases.py +855 -0
- sage/combinat/ncsym/dual.py +593 -0
- sage/combinat/ncsym/ncsym.py +2076 -0
- sage/combinat/necklace.py +551 -0
- sage/combinat/non_decreasing_parking_function.py +634 -0
- sage/combinat/nu_dyck_word.py +1474 -0
- sage/combinat/output.py +861 -0
- sage/combinat/parallelogram_polyomino.py +4326 -0
- sage/combinat/parking_functions.py +1602 -0
- sage/combinat/partition_algebra.py +1998 -0
- sage/combinat/partition_kleshchev.py +1982 -0
- sage/combinat/partition_shifting_algebras.py +584 -0
- sage/combinat/partition_tuple.py +3114 -0
- sage/combinat/path_tableaux/all.py +13 -0
- sage/combinat/path_tableaux/catalog.py +29 -0
- sage/combinat/path_tableaux/dyck_path.py +380 -0
- sage/combinat/path_tableaux/frieze.py +476 -0
- sage/combinat/path_tableaux/path_tableau.py +728 -0
- sage/combinat/path_tableaux/semistandard.py +510 -0
- sage/combinat/perfect_matching.py +779 -0
- sage/combinat/plane_partition.py +3300 -0
- sage/combinat/q_bernoulli.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/q_bernoulli.pyx +128 -0
- sage/combinat/quickref.py +81 -0
- sage/combinat/recognizable_series.py +2051 -0
- sage/combinat/regular_sequence.py +4316 -0
- sage/combinat/regular_sequence_bounded.py +543 -0
- sage/combinat/restricted_growth.py +81 -0
- sage/combinat/ribbon.py +20 -0
- sage/combinat/ribbon_shaped_tableau.py +489 -0
- sage/combinat/ribbon_tableau.py +1180 -0
- sage/combinat/rigged_configurations/all.py +46 -0
- sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
- sage/combinat/rigged_configurations/bij_infinity.py +370 -0
- sage/combinat/rigged_configurations/bij_type_A.py +163 -0
- sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
- sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
- sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
- sage/combinat/rigged_configurations/bij_type_B.py +900 -0
- sage/combinat/rigged_configurations/bij_type_C.py +267 -0
- sage/combinat/rigged_configurations/bij_type_D.py +771 -0
- sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
- sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
- sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
- sage/combinat/rigged_configurations/bijection.py +143 -0
- sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
- sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
- sage/combinat/rigged_configurations/rc_crystal.py +461 -0
- sage/combinat/rigged_configurations/rc_infinity.py +540 -0
- sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
- sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
- sage/combinat/rigged_configurations/rigged_partition.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
- sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
- sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
- sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
- sage/combinat/rsk.py +3438 -0
- sage/combinat/schubert_polynomial.py +508 -0
- sage/combinat/set_partition.py +3318 -0
- sage/combinat/set_partition_iterator.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/set_partition_iterator.pyx +136 -0
- sage/combinat/set_partition_ordered.py +1590 -0
- sage/combinat/sf/abreu_nigro.py +346 -0
- sage/combinat/sf/all.py +52 -0
- sage/combinat/sf/character.py +576 -0
- sage/combinat/sf/classical.py +319 -0
- sage/combinat/sf/dual.py +996 -0
- sage/combinat/sf/elementary.py +549 -0
- sage/combinat/sf/hall_littlewood.py +1028 -0
- sage/combinat/sf/hecke.py +336 -0
- sage/combinat/sf/homogeneous.py +464 -0
- sage/combinat/sf/jack.py +1428 -0
- sage/combinat/sf/k_dual.py +1458 -0
- sage/combinat/sf/kfpoly.py +447 -0
- sage/combinat/sf/llt.py +789 -0
- sage/combinat/sf/macdonald.py +2019 -0
- sage/combinat/sf/monomial.py +525 -0
- sage/combinat/sf/multiplicative.py +113 -0
- sage/combinat/sf/new_kschur.py +1786 -0
- sage/combinat/sf/ns_macdonald.py +964 -0
- sage/combinat/sf/orthogonal.py +246 -0
- sage/combinat/sf/orthotriang.py +355 -0
- sage/combinat/sf/powersum.py +963 -0
- sage/combinat/sf/schur.py +880 -0
- sage/combinat/sf/sf.py +1653 -0
- sage/combinat/sf/sfa.py +7053 -0
- sage/combinat/sf/symplectic.py +253 -0
- sage/combinat/sf/witt.py +721 -0
- sage/combinat/shifted_primed_tableau.py +2735 -0
- sage/combinat/shuffle.py +830 -0
- sage/combinat/sidon_sets.py +146 -0
- sage/combinat/similarity_class_type.py +1721 -0
- sage/combinat/sine_gordon.py +618 -0
- sage/combinat/six_vertex_model.py +784 -0
- sage/combinat/skew_partition.py +2053 -0
- sage/combinat/skew_tableau.py +2989 -0
- sage/combinat/sloane_functions.py +8935 -0
- sage/combinat/specht_module.py +1403 -0
- sage/combinat/species/all.py +48 -0
- sage/combinat/species/characteristic_species.py +321 -0
- sage/combinat/species/composition_species.py +273 -0
- sage/combinat/species/cycle_species.py +284 -0
- sage/combinat/species/empty_species.py +155 -0
- sage/combinat/species/functorial_composition_species.py +148 -0
- sage/combinat/species/generating_series.py +673 -0
- sage/combinat/species/library.py +148 -0
- sage/combinat/species/linear_order_species.py +169 -0
- sage/combinat/species/misc.py +83 -0
- sage/combinat/species/partition_species.py +290 -0
- sage/combinat/species/permutation_species.py +268 -0
- sage/combinat/species/product_species.py +423 -0
- sage/combinat/species/recursive_species.py +476 -0
- sage/combinat/species/set_species.py +192 -0
- sage/combinat/species/species.py +820 -0
- sage/combinat/species/structure.py +539 -0
- sage/combinat/species/subset_species.py +243 -0
- sage/combinat/species/sum_species.py +225 -0
- sage/combinat/subword.py +564 -0
- sage/combinat/subword_complex.py +2122 -0
- sage/combinat/subword_complex_c.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/subword_complex_c.pyx +119 -0
- sage/combinat/super_tableau.py +821 -0
- sage/combinat/superpartition.py +1154 -0
- sage/combinat/symmetric_group_algebra.py +3774 -0
- sage/combinat/symmetric_group_representations.py +1830 -0
- sage/combinat/t_sequences.py +877 -0
- sage/combinat/tableau.py +9506 -0
- sage/combinat/tableau_residues.py +860 -0
- sage/combinat/tableau_tuple.py +5353 -0
- sage/combinat/tiling.py +2432 -0
- sage/combinat/triangles_FHM.py +777 -0
- sage/combinat/tutorial.py +1857 -0
- sage/combinat/vector_partition.py +337 -0
- sage/combinat/words/abstract_word.py +1722 -0
- sage/combinat/words/all.py +59 -0
- sage/combinat/words/alphabet.py +268 -0
- sage/combinat/words/finite_word.py +7201 -0
- sage/combinat/words/infinite_word.py +113 -0
- sage/combinat/words/lyndon_word.py +652 -0
- sage/combinat/words/morphic.py +351 -0
- sage/combinat/words/morphism.py +3878 -0
- sage/combinat/words/paths.py +2932 -0
- sage/combinat/words/shuffle_product.py +278 -0
- sage/combinat/words/suffix_trees.py +1873 -0
- sage/combinat/words/word.py +769 -0
- sage/combinat/words/word_char.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/words/word_char.pyx +847 -0
- sage/combinat/words/word_datatypes.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/words/word_datatypes.pxd +4 -0
- sage/combinat/words/word_datatypes.pyx +1067 -0
- sage/combinat/words/word_generators.py +2026 -0
- sage/combinat/words/word_infinite_datatypes.py +1218 -0
- sage/combinat/words/word_options.py +99 -0
- sage/combinat/words/words.py +2396 -0
- sage/data_structures/all__sagemath_combinat.py +1 -0
- sage/databases/all__sagemath_combinat.py +13 -0
- sage/databases/findstat.py +4897 -0
- sage/databases/oeis.py +2058 -0
- sage/databases/sloane.py +393 -0
- sage/dynamics/all__sagemath_combinat.py +14 -0
- sage/dynamics/cellular_automata/all.py +7 -0
- sage/dynamics/cellular_automata/catalog.py +34 -0
- sage/dynamics/cellular_automata/elementary.py +612 -0
- sage/dynamics/cellular_automata/glca.py +477 -0
- sage/dynamics/cellular_automata/solitons.py +1463 -0
- sage/dynamics/finite_dynamical_system.py +1249 -0
- sage/dynamics/finite_dynamical_system_catalog.py +382 -0
- sage/games/all.py +7 -0
- sage/games/hexad.py +704 -0
- sage/games/quantumino.py +591 -0
- sage/games/sudoku.py +889 -0
- sage/games/sudoku_backtrack.cpython-314-x86_64-linux-musl.so +0 -0
- sage/games/sudoku_backtrack.pyx +189 -0
- sage/groups/all__sagemath_combinat.py +1 -0
- sage/groups/indexed_free_group.py +489 -0
- sage/libs/all__sagemath_combinat.py +6 -0
- sage/libs/lrcalc/__init__.py +1 -0
- sage/libs/lrcalc/lrcalc.py +525 -0
- sage/libs/symmetrica/__init__.py +7 -0
- sage/libs/symmetrica/all.py +101 -0
- sage/libs/symmetrica/kostka.pxi +168 -0
- sage/libs/symmetrica/part.pxi +193 -0
- sage/libs/symmetrica/plet.pxi +42 -0
- sage/libs/symmetrica/sab.pxi +196 -0
- sage/libs/symmetrica/sb.pxi +332 -0
- sage/libs/symmetrica/sc.pxi +192 -0
- sage/libs/symmetrica/schur.pxi +956 -0
- sage/libs/symmetrica/symmetrica.cpython-314-x86_64-linux-musl.so +0 -0
- sage/libs/symmetrica/symmetrica.pxi +1172 -0
- sage/libs/symmetrica/symmetrica.pyx +39 -0
- sage/monoids/all.py +13 -0
- sage/monoids/automatic_semigroup.py +1054 -0
- sage/monoids/free_abelian_monoid.py +315 -0
- sage/monoids/free_abelian_monoid_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/monoids/free_abelian_monoid_element.pxd +16 -0
- sage/monoids/free_abelian_monoid_element.pyx +397 -0
- sage/monoids/free_monoid.py +335 -0
- sage/monoids/free_monoid_element.py +431 -0
- sage/monoids/hecke_monoid.py +65 -0
- sage/monoids/string_monoid.py +817 -0
- sage/monoids/string_monoid_element.py +547 -0
- sage/monoids/string_ops.py +143 -0
- sage/monoids/trace_monoid.py +972 -0
- sage/rings/all__sagemath_combinat.py +2 -0
- sage/sat/all.py +4 -0
- sage/sat/boolean_polynomials.py +405 -0
- sage/sat/converters/__init__.py +6 -0
- sage/sat/converters/anf2cnf.py +14 -0
- sage/sat/converters/polybori.py +611 -0
- sage/sat/solvers/__init__.py +5 -0
- sage/sat/solvers/cryptominisat.py +287 -0
- sage/sat/solvers/dimacs.py +783 -0
- sage/sat/solvers/picosat.py +228 -0
- sage/sat/solvers/sat_lp.py +156 -0
- sage/sat/solvers/satsolver.cpython-314-x86_64-linux-musl.so +0 -0
- sage/sat/solvers/satsolver.pxd +3 -0
- sage/sat/solvers/satsolver.pyx +405 -0
sage/games/hexad.py
ADDED
|
@@ -0,0 +1,704 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
# sage.doctest: needs sage.symbolic
|
|
3
|
+
r"""
|
|
4
|
+
Hexads in S(5, 6, 12)
|
|
5
|
+
|
|
6
|
+
This module completes a 5-element subset of a 12-set `X`
|
|
7
|
+
into a hexad in a Steiner system `S(5, 6, 12)` using Curtis
|
|
8
|
+
and Conway's "kitten method". The labeling is either the
|
|
9
|
+
"modulo 11" labeling or the "shuffle" labeling.
|
|
10
|
+
|
|
11
|
+
The main functions implemented in this file are
|
|
12
|
+
:meth:`Minimog.blackjack_move` and :meth:`Minimog.find_hexad`.
|
|
13
|
+
|
|
14
|
+
Enter ``blackjack_move?``
|
|
15
|
+
for help to play blackjack (i.e., the rules of the game), or
|
|
16
|
+
``find_hexad?`` for help finding hexads of `S(5, 6, 12)` in
|
|
17
|
+
the shuffle labeling.
|
|
18
|
+
|
|
19
|
+
This picture is the kitten in the "shuffle" labeling::
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
6
|
|
23
|
+
|
|
24
|
+
9
|
|
25
|
+
|
|
26
|
+
10 8
|
|
27
|
+
|
|
28
|
+
7 2 5
|
|
29
|
+
|
|
30
|
+
9 4 11 9
|
|
31
|
+
|
|
32
|
+
10 8 3 10 8
|
|
33
|
+
|
|
34
|
+
1 0
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
The corresponding MINIMOG is::
|
|
38
|
+
|
|
39
|
+
┌─────┬─────┬─────┬─────┐
|
|
40
|
+
│ 6 │ 3 │ 0 │ 9 │
|
|
41
|
+
├─────┼─────┼─────┼─────┤
|
|
42
|
+
│ 5 │ 2 │ 7 │ 10 │
|
|
43
|
+
├─────┼─────┼─────┼─────┤
|
|
44
|
+
│ 4 │ 1 │ 8 │ 11 │
|
|
45
|
+
└─────┴─────┴─────┴─────┘
|
|
46
|
+
|
|
47
|
+
which is specified by the global variable ``minimog_shuffle``.
|
|
48
|
+
|
|
49
|
+
See the docstrings for :meth:`Minimog.find_hexad` and
|
|
50
|
+
:meth:`Minimog.blackjack_move` for further details and examples.
|
|
51
|
+
|
|
52
|
+
AUTHOR:
|
|
53
|
+
|
|
54
|
+
David Joyner (2006-05)
|
|
55
|
+
|
|
56
|
+
REFERENCES:
|
|
57
|
+
|
|
58
|
+
- [Cu1984]_
|
|
59
|
+
|
|
60
|
+
- [Co1984]_
|
|
61
|
+
|
|
62
|
+
- [CS1986]_
|
|
63
|
+
|
|
64
|
+
- [KR2001]_
|
|
65
|
+
|
|
66
|
+
Some details are also online at: https://www.permutationpuzzles.org/hexad/
|
|
67
|
+
"""
|
|
68
|
+
# ****************************************************************************
|
|
69
|
+
# Copyright (C) 2005 David Joyner <wdjoyner@gmail.com>
|
|
70
|
+
#
|
|
71
|
+
# Distributed under the terms of the GNU General Public License (GPL),
|
|
72
|
+
# version 2 or later (at your choice)
|
|
73
|
+
#
|
|
74
|
+
# https://www.gnu.org/licenses/
|
|
75
|
+
# ****************************************************************************
|
|
76
|
+
|
|
77
|
+
from sage.rings.infinity import infinity
|
|
78
|
+
from sage.matrix.matrix_space import MatrixSpace
|
|
79
|
+
from sage.matrix.constructor import matrix
|
|
80
|
+
from sage.rings.finite_rings.finite_field_constructor import GF
|
|
81
|
+
from sage.calculus.calculus import SR
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def view_list(L):
|
|
85
|
+
"""
|
|
86
|
+
This provides a printout of the lines, crosses and squares
|
|
87
|
+
of the MINIMOG, as in Curtis' paper [Cu1984]_.
|
|
88
|
+
|
|
89
|
+
EXAMPLES::
|
|
90
|
+
|
|
91
|
+
sage: from sage.games.hexad import *
|
|
92
|
+
sage: M = Minimog(type='shuffle')
|
|
93
|
+
sage: view_list(M.line[1])
|
|
94
|
+
<BLANKLINE>
|
|
95
|
+
[0 0 0]
|
|
96
|
+
[1 1 1]
|
|
97
|
+
[0 0 0]
|
|
98
|
+
sage: view_list(M.cross[1])
|
|
99
|
+
<BLANKLINE>
|
|
100
|
+
[1 1 1]
|
|
101
|
+
[0 0 1]
|
|
102
|
+
[0 0 1]
|
|
103
|
+
sage: view_list(M.square[1])
|
|
104
|
+
<BLANKLINE>
|
|
105
|
+
[0 0 0]
|
|
106
|
+
[1 1 0]
|
|
107
|
+
[1 1 0]
|
|
108
|
+
"""
|
|
109
|
+
return matrix(GF(2), 3, 3, lambda x, y: 1 if (x, y) in L else 0)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def picture_set(A, L) -> set:
|
|
113
|
+
"""
|
|
114
|
+
This is needed in the :meth:`Minimog.find_hexad` function below.
|
|
115
|
+
|
|
116
|
+
EXAMPLES::
|
|
117
|
+
|
|
118
|
+
sage: from sage.games.hexad import *
|
|
119
|
+
sage: M = Minimog(type='shuffle')
|
|
120
|
+
sage: picture_set(M.picture00, M.cross[2])
|
|
121
|
+
{5, 7, 8, 9, 10}
|
|
122
|
+
sage: picture_set(M.picture02, M.square[7])
|
|
123
|
+
{2, 3, 5, 8}
|
|
124
|
+
"""
|
|
125
|
+
return {A[x] for x in L}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class Minimog:
|
|
129
|
+
r"""
|
|
130
|
+
This implements the Conway/Curtis minimog idea for describing
|
|
131
|
+
the Steiner triple system `S(5, 6, 12)`.
|
|
132
|
+
|
|
133
|
+
EXAMPLES::
|
|
134
|
+
|
|
135
|
+
sage: from sage.games.hexad import *
|
|
136
|
+
sage: Minimog(type='shuffle')
|
|
137
|
+
Minimog of type shuffle
|
|
138
|
+
sage: M = Minimog(type = "modulo11")
|
|
139
|
+
sage: M.minimog
|
|
140
|
+
[ 0 3 +Infinity 2]
|
|
141
|
+
[ 5 9 8 10]
|
|
142
|
+
[ 4 1 6 7]
|
|
143
|
+
"""
|
|
144
|
+
def __init__(self, type='shuffle'):
|
|
145
|
+
self.type = type
|
|
146
|
+
MS34 = MatrixSpace(SR, 3, 4)
|
|
147
|
+
minimog_modulo11 = MS34([[0, 3, infinity, 2], [5, 9, 8, 10], [4, 1, 6, 7]])
|
|
148
|
+
minimog_shuffle = MS34([[6, 3, 0, 9], [5, 2, 7, 10], [4, 1, 8, 11]])
|
|
149
|
+
if type == "shuffle":
|
|
150
|
+
self.minimog = minimog_shuffle
|
|
151
|
+
elif type == "modulo11":
|
|
152
|
+
self.minimog = minimog_modulo11
|
|
153
|
+
else:
|
|
154
|
+
raise ValueError("that Minimog type is not implemented")
|
|
155
|
+
# This initializes the variables in the game.
|
|
156
|
+
MS34 = MatrixSpace(SR, 3, 4)
|
|
157
|
+
A = self.minimog
|
|
158
|
+
MS33 = MatrixSpace(SR, 3, 3)
|
|
159
|
+
self.picture00 = MS33([[A[(1, 0)], A[(2, 3)], A[(0, 1)]], [A[(2, 2)], A[(1, 1)], A[(2, 0)]], [A[(0, 3)], A[(1, 3)], A[(1, 2)]]])
|
|
160
|
+
# self.picture00 is the "picture at 6"
|
|
161
|
+
self.picture02 = MS33([[A[(1, 0)], A[(2, 3)], A[(0, 1)]], [A[(1, 1)], A[(2, 0)], A[(2, 2)]], [A[(1, 2)], A[(0, 3)], A[(1, 3)]]])
|
|
162
|
+
# self.picture02 is the "picture at 1"
|
|
163
|
+
self.picture21 = MS33([[A[(2, 2)], A[(1, 3)], A[(0, 1)]], [A[(0, 3)], A[(2, 3)], A[(2, 0)]], [A[(1, 0)], A[(1, 1)], A[(1, 2)]]])
|
|
164
|
+
# self.picture21 is the "picture at 0"
|
|
165
|
+
|
|
166
|
+
self.line = list(range(12))
|
|
167
|
+
self.line[0] = {(0, 0), (0, 1), (0, 2)}
|
|
168
|
+
self.line[1] = {(1, 0), (1, 1), (1, 2)}
|
|
169
|
+
self.line[2] = {(2, 0), (2, 1), (2, 2)}
|
|
170
|
+
self.line[3] = {(0, 2), (1, 2), (2, 2)}
|
|
171
|
+
self.line[4] = {(0, 1), (1, 1), (2, 1)}
|
|
172
|
+
self.line[5] = {(0, 0), (1, 0), (2, 0)}
|
|
173
|
+
self.line[6] = {(0, 0), (1, 1), (2, 2)}
|
|
174
|
+
self.line[7] = {(2, 0), (0, 1), (1, 2)}
|
|
175
|
+
self.line[8] = {(0, 2), (1, 0), (2, 1)}
|
|
176
|
+
self.line[9] = {(2, 0), (1, 1), (0, 2)}
|
|
177
|
+
self.line[10] = {(0, 0), (1, 2), (2, 1)}
|
|
178
|
+
self.line[11] = {(1, 0), (0, 1), (2, 2)}
|
|
179
|
+
|
|
180
|
+
self.cross = list(range(18))
|
|
181
|
+
self.cross[0] = {(0, 0), (0, 1), (0, 2), (1, 0), (2, 0)}
|
|
182
|
+
self.cross[1] = {(0, 0), (0, 1), (0, 2), (1, 2), (2, 2)}
|
|
183
|
+
self.cross[2] = {(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)}
|
|
184
|
+
self.cross[3] = {(2, 0), (2, 1), (2, 2), (0, 2), (1, 2)}
|
|
185
|
+
self.cross[4] = {(0, 0), (0, 1), (0, 2), (1, 1), (2, 1)}
|
|
186
|
+
self.cross[5] = {(0, 0), (1, 0), (2, 0), (1, 1), (1, 2)}
|
|
187
|
+
self.cross[6] = {(1, 0), (1, 1), (1, 2), (0, 2), (2, 2)}
|
|
188
|
+
self.cross[7] = {(0, 1), (1, 1), (2, 1), (2, 0), (2, 2)}
|
|
189
|
+
self.cross[8] = {(0, 0), (0, 1), (1, 0), (1, 1), (2, 2)}
|
|
190
|
+
self.cross[9] = {(0, 0), (1, 1), (1, 2), (2, 1), (2, 2)}
|
|
191
|
+
self.cross[10] = {(2, 0), (2, 1), (1, 0), (1, 1), (0, 2)}
|
|
192
|
+
self.cross[11] = {(0, 1), (0, 2), (1, 1), (1, 2), (2, 0)}
|
|
193
|
+
self.cross[12] = {(0, 0), (1, 0), (0, 2), (1, 2), (2, 1)}
|
|
194
|
+
self.cross[13] = {(1, 0), (0, 1), (0, 2), (2, 1), (2, 2)}
|
|
195
|
+
self.cross[14] = {(0, 1), (1, 0), (1, 2), (2, 0), (2, 2)}
|
|
196
|
+
self.cross[15] = {(0, 0), (0, 1), (1, 2), (2, 0), (2, 1)}
|
|
197
|
+
self.cross[16] = {(1, 0), (1, 1), (1, 2), (0, 1), (2, 1)}
|
|
198
|
+
self.cross[17] = {(0, 0), (0, 2), (1, 1), (2, 0), (2, 2)}
|
|
199
|
+
self.box = {(i, j) for i in range(3) for j in range(3)}
|
|
200
|
+
self.square = [set() for i in range(18)]
|
|
201
|
+
for i in range(18):
|
|
202
|
+
self.square[i] = self.box - self.cross[i]
|
|
203
|
+
|
|
204
|
+
MS34_GF3 = MatrixSpace(GF(2), 3, 4)
|
|
205
|
+
cols = {}
|
|
206
|
+
cols[1] = MS34_GF3([[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]])
|
|
207
|
+
cols[2] = MS34_GF3([[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0]])
|
|
208
|
+
cols[3] = MS34_GF3([[0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0]])
|
|
209
|
+
cols[4] = MS34_GF3([[0, 0, 0, 1], [0, 0, 0, 1], [0, 0, 0, 1]])
|
|
210
|
+
self.col = cols
|
|
211
|
+
|
|
212
|
+
tets = {}
|
|
213
|
+
tets[1] = MS34_GF3([[1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]])
|
|
214
|
+
tets[2] = MS34_GF3([[1, 0, 0, 0], [0, 1, 1, 1], [0, 0, 0, 0]])
|
|
215
|
+
tets[3] = MS34_GF3([[1, 0, 0, 0], [0, 0, 0, 0], [0, 1, 1, 1]])
|
|
216
|
+
tets[4] = MS34_GF3([[0, 1, 0, 0], [1, 0, 1, 0], [0, 0, 0, 1]])
|
|
217
|
+
tets[5] = MS34_GF3([[0, 0, 0, 1], [1, 1, 0, 0], [0, 0, 1, 0]])
|
|
218
|
+
tets[6] = MS34_GF3([[0, 0, 1, 0], [1, 0, 0, 1], [0, 1, 0, 0]])
|
|
219
|
+
tets[7] = MS34_GF3([[0, 1, 0, 0], [0, 0, 0, 1], [1, 0, 1, 0]])
|
|
220
|
+
tets[8] = MS34_GF3([[0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 1]])
|
|
221
|
+
tets[9] = MS34_GF3([[0, 0, 0, 1], [0, 0, 1, 0], [1, 1, 0, 0]])
|
|
222
|
+
self.tet = tets
|
|
223
|
+
|
|
224
|
+
def __repr__(self) -> str:
|
|
225
|
+
"""
|
|
226
|
+
Return a string representation of ``self``.
|
|
227
|
+
|
|
228
|
+
EXAMPLES::
|
|
229
|
+
|
|
230
|
+
sage: M = Minimog(type='modulo11')
|
|
231
|
+
sage: M
|
|
232
|
+
Minimog of type modulo11
|
|
233
|
+
"""
|
|
234
|
+
return "Minimog of type %s" % self.type
|
|
235
|
+
|
|
236
|
+
def __str__(self) -> str:
|
|
237
|
+
"""
|
|
238
|
+
EXAMPLES::
|
|
239
|
+
|
|
240
|
+
sage: M = Minimog(type='modulo11')
|
|
241
|
+
sage: print(M)
|
|
242
|
+
Minimog of type modulo11 associated to
|
|
243
|
+
[ 0 3 +Infinity 2]
|
|
244
|
+
[ 5 9 8 10]
|
|
245
|
+
[ 4 1 6 7]
|
|
246
|
+
"""
|
|
247
|
+
return f"Minimog of type {self.type} associated to\n {self.minimog}"
|
|
248
|
+
|
|
249
|
+
def _latex_(self):
|
|
250
|
+
r"""
|
|
251
|
+
Print latex code.
|
|
252
|
+
|
|
253
|
+
EXAMPLES::
|
|
254
|
+
|
|
255
|
+
sage: M = Minimog(type='modulo11')
|
|
256
|
+
sage: latex(M)
|
|
257
|
+
Minimog of type modulo11 associated to
|
|
258
|
+
$\left(\begin{array}{rrrr}
|
|
259
|
+
0 & 3 & +\infty & 2 \\
|
|
260
|
+
5 & 9 & 8 & 10 \\
|
|
261
|
+
4 & 1 & 6 & 7
|
|
262
|
+
\end{array}\right)$
|
|
263
|
+
"""
|
|
264
|
+
from sage.misc.latex import latex
|
|
265
|
+
return f"Minimog of type {self.type} associated to\n ${latex(self.minimog)}$"
|
|
266
|
+
|
|
267
|
+
def print_kitten(self):
|
|
268
|
+
"""
|
|
269
|
+
This simply prints the "kitten" (expressed as a triangular diagram
|
|
270
|
+
of symbols).
|
|
271
|
+
|
|
272
|
+
EXAMPLES::
|
|
273
|
+
|
|
274
|
+
sage: from sage.games.hexad import *
|
|
275
|
+
sage: M = Minimog("shuffle")
|
|
276
|
+
sage: M.print_kitten()
|
|
277
|
+
0
|
|
278
|
+
<BLANKLINE>
|
|
279
|
+
8
|
|
280
|
+
9 10
|
|
281
|
+
5 11 3
|
|
282
|
+
8 2 4 8
|
|
283
|
+
9 10 7 9 10
|
|
284
|
+
<BLANKLINE>
|
|
285
|
+
6 1
|
|
286
|
+
sage: M = Minimog("modulo11")
|
|
287
|
+
sage: M.print_kitten()
|
|
288
|
+
+Infinity
|
|
289
|
+
<BLANKLINE>
|
|
290
|
+
6
|
|
291
|
+
2 10
|
|
292
|
+
5 7 3
|
|
293
|
+
6 9 4 6
|
|
294
|
+
2 10 8 2 10
|
|
295
|
+
<BLANKLINE>
|
|
296
|
+
0 1
|
|
297
|
+
"""
|
|
298
|
+
MINIMOG = self.minimog
|
|
299
|
+
kitten = f' {MINIMOG[0][2]}'
|
|
300
|
+
kitten += '\n '
|
|
301
|
+
kitten += f'\n {MINIMOG[2][2]}'
|
|
302
|
+
kitten += f'\n {MINIMOG[0][3]} {MINIMOG[1][3]}'
|
|
303
|
+
kitten += f'\n {MINIMOG[1][0]} {MINIMOG[2][3]} {MINIMOG[0][1]}'
|
|
304
|
+
kitten += '\n {0} {1} {2} {0}'.format(MINIMOG[2][2], MINIMOG[1][1], MINIMOG[2][0])
|
|
305
|
+
kitten += '\n {0} {1} {2} {0} {1}'.format(MINIMOG[0][3], MINIMOG[1][3], MINIMOG[1][2])
|
|
306
|
+
kitten += '\n \n'
|
|
307
|
+
kitten += f'{MINIMOG[0][0]} {MINIMOG[2][1]}'
|
|
308
|
+
print(kitten)
|
|
309
|
+
|
|
310
|
+
def find_hexad0(self, pts):
|
|
311
|
+
"""
|
|
312
|
+
Find a hexad of type 0.
|
|
313
|
+
|
|
314
|
+
INPUT:
|
|
315
|
+
|
|
316
|
+
- ``pts`` -- set of 2 distinct elements of MINIMOG, but not
|
|
317
|
+
including the "points at infinity"
|
|
318
|
+
|
|
319
|
+
OUTPUT:
|
|
320
|
+
|
|
321
|
+
hexad containing ``pts`` and of type 0 (the 3 points "at
|
|
322
|
+
infinity" union a line)
|
|
323
|
+
|
|
324
|
+
.. NOTE::
|
|
325
|
+
|
|
326
|
+
The 3 points "at infinity" are
|
|
327
|
+
``{MINIMOG[0][2], MINIMOG[2][1], MINIMOG[0][0]}``.
|
|
328
|
+
|
|
329
|
+
EXAMPLES::
|
|
330
|
+
|
|
331
|
+
sage: from sage.games.hexad import *
|
|
332
|
+
sage: M = Minimog(type='shuffle')
|
|
333
|
+
sage: M.find_hexad0(set([2, 4]))
|
|
334
|
+
([0, 1, 2, 4, 6, 8], ['line 1', 'picture 1'])
|
|
335
|
+
"""
|
|
336
|
+
MINIMOG = self.minimog
|
|
337
|
+
L = set(pts)
|
|
338
|
+
H = {MINIMOG[0][2], MINIMOG[2][1], MINIMOG[0][0]}
|
|
339
|
+
for i in range(12):
|
|
340
|
+
if L <= picture_set(self.picture02, self.line[i]):
|
|
341
|
+
WHAT = ["line " + str(i), "picture " + str(1)]
|
|
342
|
+
H = H | picture_set(self.picture02, self.line[i])
|
|
343
|
+
return list(H), WHAT
|
|
344
|
+
if L <= picture_set(self.picture21, self.line[i]):
|
|
345
|
+
WHAT = ["line " + str(i), "picture " + str(0)]
|
|
346
|
+
H = H | picture_set(self.picture21, self.line[i])
|
|
347
|
+
return list(H), WHAT
|
|
348
|
+
if L <= picture_set(self.picture00, self.line[i]):
|
|
349
|
+
WHAT = ["line " + str(i), "picture " + str(6)]
|
|
350
|
+
H = H | picture_set(self.picture00, self.line[i])
|
|
351
|
+
return list(H), WHAT
|
|
352
|
+
return [], []
|
|
353
|
+
|
|
354
|
+
def find_hexad1(self, pts):
|
|
355
|
+
"""
|
|
356
|
+
Find a hexad of type 1.
|
|
357
|
+
|
|
358
|
+
INPUT:
|
|
359
|
+
|
|
360
|
+
- ``pts`` -- set of 5 distinct elements of MINIMOG
|
|
361
|
+
|
|
362
|
+
OUTPUT:
|
|
363
|
+
|
|
364
|
+
hexad containing ``pts`` and of type 1 (union of 2 parallel
|
|
365
|
+
lines -- *no* points "at infinity")
|
|
366
|
+
|
|
367
|
+
.. NOTE::
|
|
368
|
+
|
|
369
|
+
The 3 points "at infinity" are
|
|
370
|
+
``{MINIMOG[0][2], MINIMOG[2][1], MINIMOG[0][0]}``.
|
|
371
|
+
|
|
372
|
+
EXAMPLES::
|
|
373
|
+
|
|
374
|
+
sage: from sage.games.hexad import *
|
|
375
|
+
sage: M = Minimog(type='shuffle')
|
|
376
|
+
sage: M.find_hexad1(set([2, 3, 4, 5, 8]))
|
|
377
|
+
([2, 3, 4, 5, 8, 11], ['lines (1, 2)', 'picture 1'])
|
|
378
|
+
"""
|
|
379
|
+
H = set(pts)
|
|
380
|
+
L = set(pts)
|
|
381
|
+
linez = [(1, 2), (1, 3), (2, 3), (4, 5), (4, 6), (5, 6),
|
|
382
|
+
(7, 8), (7, 9), (8, 9), (10, 11), (10, 12), (11, 12)]
|
|
383
|
+
for x in linez:
|
|
384
|
+
x1 = int(x[0] - 1)
|
|
385
|
+
x2 = int(x[1] - 1) # (recall | is union)
|
|
386
|
+
if L <= (picture_set(self.picture02, self.line[x1]) | picture_set(self.picture02, self.line[x2])):
|
|
387
|
+
WHAT = ["lines " + str(x), "picture " + str(1)]
|
|
388
|
+
H = picture_set(self.picture02, self.line[x1]) | picture_set(self.picture02, self.line[x2])
|
|
389
|
+
return list(H), WHAT
|
|
390
|
+
if L <= (picture_set(self.picture21, self.line[x1]) | picture_set(self.picture21, self.line[x2])):
|
|
391
|
+
WHAT = ["lines " + str(x), "picture " + str(0)]
|
|
392
|
+
H = picture_set(self.picture21, self.line[x1]) | picture_set(self.picture21, self.line[x2])
|
|
393
|
+
return list(H), WHAT
|
|
394
|
+
if L <= (picture_set(self.picture00, self.line[x1]) | picture_set(self.picture00, self.line[x2])):
|
|
395
|
+
WHAT = ["lines " + str(x), "picture " + str(6)]
|
|
396
|
+
H = picture_set(self.picture00, self.line[x1]) | picture_set(self.picture00, self.line[x2])
|
|
397
|
+
return list(H), WHAT
|
|
398
|
+
return [], []
|
|
399
|
+
|
|
400
|
+
def find_hexad2(self, pts, x0):
|
|
401
|
+
r"""
|
|
402
|
+
Find a hexad of type 2.
|
|
403
|
+
|
|
404
|
+
INPUT:
|
|
405
|
+
|
|
406
|
+
- ``pts`` -- list S of 4 elements of MINIMOG, not including
|
|
407
|
+
any "points at infinity"
|
|
408
|
+
- ``x0`` -- in ``{MINIMOG[0][2], MINIMOG[2][1], MINIMOG[0][0]}``
|
|
409
|
+
|
|
410
|
+
OUTPUT: hexad containing `S \cup \{x0\}` of type 2
|
|
411
|
+
|
|
412
|
+
EXAMPLES::
|
|
413
|
+
|
|
414
|
+
sage: from sage.games.hexad import *
|
|
415
|
+
sage: M = Minimog(type='shuffle')
|
|
416
|
+
sage: M.find_hexad2([2, 3, 4, 5], 1)
|
|
417
|
+
([], [])
|
|
418
|
+
|
|
419
|
+
The above output indicates that there is no hexad of type 2
|
|
420
|
+
containing `\{2, 3, 4, 5\}`. However, there is one containing
|
|
421
|
+
`\{2, 3, 4, 8\}`::
|
|
422
|
+
|
|
423
|
+
sage: M.find_hexad2([2, 3, 4, 8], 0)
|
|
424
|
+
([0, 2, 3, 4, 8, 9], ['cross 12', 'picture 0'])
|
|
425
|
+
"""
|
|
426
|
+
MINIMOG = self.minimog
|
|
427
|
+
L = set(pts)
|
|
428
|
+
H = {x0}
|
|
429
|
+
for i in range(18):
|
|
430
|
+
if (x0 == MINIMOG[2][1] and L <= picture_set(self.picture02, self.cross[i])):
|
|
431
|
+
WHAT = ["cross " + str(i), "picture " + str(1)]
|
|
432
|
+
H = H | picture_set(self.picture02, self.cross[i])
|
|
433
|
+
return list(H), WHAT
|
|
434
|
+
if (x0 == MINIMOG[0][2] and L <= picture_set(self.picture21, self.cross[i])):
|
|
435
|
+
WHAT = ["cross " + str(i), "picture " + str(MINIMOG[0][2])]
|
|
436
|
+
H = H | picture_set(self.picture21, self.cross[i])
|
|
437
|
+
return list(H), WHAT
|
|
438
|
+
if (x0 == MINIMOG[0][0] and L <= picture_set(self.picture00, self.cross[i])):
|
|
439
|
+
WHAT = ["cross " + str(i), "picture " + str(6)]
|
|
440
|
+
H = H | picture_set(self.picture00, self.cross[i])
|
|
441
|
+
return list(H), WHAT
|
|
442
|
+
return [], []
|
|
443
|
+
|
|
444
|
+
def find_hexad3(self, pts, x0, x1):
|
|
445
|
+
r"""
|
|
446
|
+
Find a hexad of type 3.
|
|
447
|
+
|
|
448
|
+
INPUT:
|
|
449
|
+
|
|
450
|
+
- ``pts`` -- list of 3 elements of MINIMOG, not including any
|
|
451
|
+
"points at infinity"
|
|
452
|
+
- ``x0``, ``x1`` -- in ``{MINIMOG[0][2], MINIMOG[2][1],
|
|
453
|
+
MINIMOG[0][0]}``
|
|
454
|
+
|
|
455
|
+
OUTPUT:
|
|
456
|
+
|
|
457
|
+
hexad containing pts union \{x0, x1\} of type 3 (square at
|
|
458
|
+
picture of "omitted point at infinity")
|
|
459
|
+
|
|
460
|
+
EXAMPLES::
|
|
461
|
+
|
|
462
|
+
sage: from sage.games.hexad import *
|
|
463
|
+
sage: M = Minimog(type='shuffle')
|
|
464
|
+
sage: M.find_hexad3([2, 3, 4], 0, 1)
|
|
465
|
+
([0, 1, 2, 3, 4, 11], ['square 2', 'picture 6'])
|
|
466
|
+
"""
|
|
467
|
+
MINIMOG = self.minimog
|
|
468
|
+
L = set(pts)
|
|
469
|
+
H = {x0, x1}
|
|
470
|
+
for i in range(18):
|
|
471
|
+
if (MINIMOG[0][2] not in H and L <= picture_set(self.picture21, self.square[i])):
|
|
472
|
+
WHAT = ["square " + str(i), "picture " + str(MINIMOG[0][2])]
|
|
473
|
+
H = H | picture_set(self.picture21, self.square[i])
|
|
474
|
+
return list(H), WHAT
|
|
475
|
+
if (MINIMOG[2][1] not in H and L <= picture_set(self.picture02, self.square[i])):
|
|
476
|
+
WHAT = ["square " + str(i), "picture " + str(MINIMOG[2][1])]
|
|
477
|
+
H = H | picture_set(self.picture02, self.square[i])
|
|
478
|
+
return list(H), WHAT
|
|
479
|
+
if (MINIMOG[0][0] not in H and L <= picture_set(self.picture00, self.square[i])):
|
|
480
|
+
WHAT = ["square " + str(i), "picture " + str(MINIMOG[0][0])]
|
|
481
|
+
H = H | picture_set(self.picture00, self.square[i])
|
|
482
|
+
return list(H), WHAT
|
|
483
|
+
return [], []
|
|
484
|
+
|
|
485
|
+
def find_hexad(self, pts):
|
|
486
|
+
r"""
|
|
487
|
+
Find a hexad of some type.
|
|
488
|
+
|
|
489
|
+
INPUT:
|
|
490
|
+
|
|
491
|
+
- ``pts`` -- list S of 5 elements of MINIMOG
|
|
492
|
+
|
|
493
|
+
OUTPUT: hexad containing `S \cup \{x0\}` of some type
|
|
494
|
+
|
|
495
|
+
.. NOTE::
|
|
496
|
+
|
|
497
|
+
The 3 "points at infinity" are
|
|
498
|
+
``{MINIMOG[0][2], MINIMOG[2][1], MINIMOG[0][0]}``.
|
|
499
|
+
|
|
500
|
+
Theorem ([Cu1984]_, [Co1984]_): Each hexads is of exactly one
|
|
501
|
+
of the following types:
|
|
502
|
+
|
|
503
|
+
0. {3 "points at infinity"} union {any line},
|
|
504
|
+
1. the union of any two (distinct) parallel lines in the same
|
|
505
|
+
picture,
|
|
506
|
+
2. one "point at infinity" union a cross in the corresponding
|
|
507
|
+
picture, or
|
|
508
|
+
3. two "points at infinity" union a square in the picture
|
|
509
|
+
corresponding to the omitted point at infinity.
|
|
510
|
+
|
|
511
|
+
More precisely, there are 132 such hexads (12 of type 0,
|
|
512
|
+
12 of type 1, 54 of type 2, and 54 of type 3).
|
|
513
|
+
They form a Steiner system of type `(5, 6, 12)`.
|
|
514
|
+
|
|
515
|
+
EXAMPLES::
|
|
516
|
+
|
|
517
|
+
sage: from sage.games.hexad import *
|
|
518
|
+
sage: M = Minimog(type='shuffle')
|
|
519
|
+
sage: M.find_hexad([0, 1, 2, 3, 4])
|
|
520
|
+
([0, 1, 2, 3, 4, 11], ['square 2', 'picture 6'])
|
|
521
|
+
sage: M.find_hexad([1, 2, 3, 4, 5])
|
|
522
|
+
([1, 2, 3, 4, 5, 6], ['square 8', 'picture 0'])
|
|
523
|
+
sage: M.find_hexad([2, 3, 4, 5, 8])
|
|
524
|
+
([2, 3, 4, 5, 8, 11], ['lines (1, 2)', 'picture 1'])
|
|
525
|
+
sage: M.find_hexad([0, 1, 2, 4, 6])
|
|
526
|
+
([0, 1, 2, 4, 6, 8], ['line 1', 'picture 1'])
|
|
527
|
+
sage: M = Minimog(type='modulo11')
|
|
528
|
+
sage: M.find_hexad([1, 2, 3, 4, SR(infinity)]) # random (machine dependent?) order
|
|
529
|
+
([+Infinity, 2, 3, 4, 1, 10], ['square 8', 'picture 0'])
|
|
530
|
+
|
|
531
|
+
AUTHOR:
|
|
532
|
+
|
|
533
|
+
David Joyner (2006-05)
|
|
534
|
+
|
|
535
|
+
REFERENCES: [Cu1984]_, [Co1984]_
|
|
536
|
+
"""
|
|
537
|
+
MINIMOG = self.minimog
|
|
538
|
+
L = set(pts)
|
|
539
|
+
LL = L.copy()
|
|
540
|
+
pts_at_infty = {MINIMOG[0][2], MINIMOG[2][1], MINIMOG[0][0]}
|
|
541
|
+
# recall & means intersection
|
|
542
|
+
L2 = LL & pts_at_infty
|
|
543
|
+
if len(L2) == 3: # must be type 0 (line + pts at infty)
|
|
544
|
+
H, WHAT = self.find_hexad0(LL - pts_at_infty)
|
|
545
|
+
return H, WHAT
|
|
546
|
+
if len(L2) == 2: # type 0 or 3
|
|
547
|
+
if (MINIMOG[0][2] in LL and MINIMOG[2][1] in LL):
|
|
548
|
+
H, WHAT = self.find_hexad3(LL - {MINIMOG[0][2], MINIMOG[2][1]},
|
|
549
|
+
MINIMOG[0][2], MINIMOG[2][1])
|
|
550
|
+
if H: # must be type 3
|
|
551
|
+
return list(H), WHAT
|
|
552
|
+
# could be type 0
|
|
553
|
+
H, WHAT = self.find_hexad0(LL - L2)
|
|
554
|
+
if H: # must be type 0
|
|
555
|
+
return list(H), WHAT
|
|
556
|
+
if (MINIMOG[2][1] in LL and MINIMOG[0][0] in LL):
|
|
557
|
+
H, WHAT = self.find_hexad3(LL - {MINIMOG[2][1], MINIMOG[0][0]},
|
|
558
|
+
MINIMOG[2][1], MINIMOG[0][0])
|
|
559
|
+
if H: # must be type 3
|
|
560
|
+
return list(H), WHAT
|
|
561
|
+
# could be type 0
|
|
562
|
+
H, WHAT = self.find_hexad0(LL - L2)
|
|
563
|
+
if H: # must be type 0
|
|
564
|
+
return list(H), WHAT
|
|
565
|
+
if (MINIMOG[0][2] in LL and MINIMOG[0][0] in LL):
|
|
566
|
+
H, WHAT = self.find_hexad3(LL - {MINIMOG[0][2], MINIMOG[0][0]},
|
|
567
|
+
MINIMOG[0][2], MINIMOG[0][0])
|
|
568
|
+
if H: # must be type 3
|
|
569
|
+
return list(H), WHAT
|
|
570
|
+
# could be type 0
|
|
571
|
+
H, WHAT = self.find_hexad0(LL - L2)
|
|
572
|
+
if H: # must be type 0
|
|
573
|
+
return list(H), WHAT
|
|
574
|
+
if len(L2) == 1:
|
|
575
|
+
H, WHAT = self.find_hexad2(LL - L2, list(L2)[0])
|
|
576
|
+
if not H: # not a cross in picture at infinity
|
|
577
|
+
if list(L2)[0] == MINIMOG[2][1]:
|
|
578
|
+
L1 = LL - L2
|
|
579
|
+
H, WHAT = self.find_hexad3(L1, MINIMOG[0][0], MINIMOG[2][1])
|
|
580
|
+
if H:
|
|
581
|
+
return list(H), WHAT
|
|
582
|
+
L1 = LL - L2
|
|
583
|
+
H, WHAT = self.find_hexad3(L1, MINIMOG[0][2], MINIMOG[2][1])
|
|
584
|
+
if H:
|
|
585
|
+
return list(H), WHAT
|
|
586
|
+
if list(L2)[0] == MINIMOG[0][0]:
|
|
587
|
+
L1 = (LL - L2)
|
|
588
|
+
H, WHAT = self.find_hexad3(L1, MINIMOG[0][0], MINIMOG[2][1])
|
|
589
|
+
if H:
|
|
590
|
+
return list(H), WHAT
|
|
591
|
+
L1 = (LL - L2)
|
|
592
|
+
H, WHAT = self.find_hexad3(L1, MINIMOG[0][0], MINIMOG[0][2])
|
|
593
|
+
if H:
|
|
594
|
+
return list(H), WHAT
|
|
595
|
+
if list(L2)[0] == MINIMOG[0][2]:
|
|
596
|
+
L1 = (LL - L2)
|
|
597
|
+
H, WHAT = self.find_hexad3(L1, MINIMOG[0][0], MINIMOG[0][2])
|
|
598
|
+
if H:
|
|
599
|
+
return list(H), WHAT
|
|
600
|
+
L1 = (LL - L2)
|
|
601
|
+
H, WHAT = self.find_hexad3(L1, MINIMOG[2][1], MINIMOG[0][2])
|
|
602
|
+
if H:
|
|
603
|
+
return list(H), WHAT
|
|
604
|
+
return list(H), WHAT
|
|
605
|
+
# a cross in a pic at infty
|
|
606
|
+
if not L2: # L is either a union of 2 lines or a cross
|
|
607
|
+
for i in LL:
|
|
608
|
+
for j in pts_at_infty:
|
|
609
|
+
H, WHAT = self.find_hexad2(LL - {i}, j)
|
|
610
|
+
if (H and i in H):
|
|
611
|
+
return list(H), WHAT # L is in a cross
|
|
612
|
+
H, WHAT = self.find_hexad1(LL) # L is a union of lines
|
|
613
|
+
return H, WHAT
|
|
614
|
+
|
|
615
|
+
def blackjack_move(self, L0):
|
|
616
|
+
r"""
|
|
617
|
+
Perform a blackjack move.
|
|
618
|
+
|
|
619
|
+
INPUT:
|
|
620
|
+
|
|
621
|
+
- ``L0`` -- list of cards of length 6, taken
|
|
622
|
+
from `\{0, 1, ..., 11\}`
|
|
623
|
+
|
|
624
|
+
.. RUBRIC:: MATHEMATICAL BLACKJACK
|
|
625
|
+
|
|
626
|
+
Mathematical blackjack is played with 12 cards, labeled `0, ..., 11`
|
|
627
|
+
(for example: king, ace, `2`, `3`, ..., `10`, jack, where the
|
|
628
|
+
king is `0` and the jack is `11`). Divide the 12 cards into two
|
|
629
|
+
piles of `6` (to be fair, this should be done randomly). Each of
|
|
630
|
+
the `6` cards of one of these piles are to be placed face up on
|
|
631
|
+
the table. The remaining cards are in a stack which is shared
|
|
632
|
+
and visible to both players. If the sum of the cards face up on
|
|
633
|
+
the table is less than 21 then no legal move is possible so you
|
|
634
|
+
must shuffle the cards and deal a new game. (Conway calls such
|
|
635
|
+
a game `*={0|0}`, where `0={|}`; in this game the first player
|
|
636
|
+
automatically wins.)
|
|
637
|
+
|
|
638
|
+
* Players alternate moves.
|
|
639
|
+
* A move consists of exchanging a card on the table with a
|
|
640
|
+
lower card from the other pile.
|
|
641
|
+
* The player whose move makes the sum of the cards on the table
|
|
642
|
+
under 21 loses.
|
|
643
|
+
|
|
644
|
+
The winning strategy (given below) for this game is due to
|
|
645
|
+
Conway and Ryba. There is a Steiner system `S(5, 6, 12)` of hexads
|
|
646
|
+
in the set `\{0, 1, ..., 11\}`. This Steiner system is associated
|
|
647
|
+
to the MINIMOG of in the "shuffle numbering" rather than the
|
|
648
|
+
"modulo `11` labeling".
|
|
649
|
+
|
|
650
|
+
**Proposition** ([KR2001]_) For this Steiner system, the
|
|
651
|
+
winning strategy is to choose a move which is a hexad from
|
|
652
|
+
this system.
|
|
653
|
+
|
|
654
|
+
EXAMPLES::
|
|
655
|
+
|
|
656
|
+
sage: M = Minimog(type='modulo11')
|
|
657
|
+
sage: M.blackjack_move([0, 2, 3, 6, 1, 10])
|
|
658
|
+
'6 --> 5. The total went from 22 to 21.'
|
|
659
|
+
sage: M = Minimog(type='shuffle')
|
|
660
|
+
sage: M.blackjack_move([0, 2, 4, 6, 7, 11])
|
|
661
|
+
'4 --> 3. The total went from 30 to 29.'
|
|
662
|
+
|
|
663
|
+
Is this really a hexad? ::
|
|
664
|
+
|
|
665
|
+
sage: M.find_hexad([11, 2, 3, 6, 7])
|
|
666
|
+
([0, 2, 3, 6, 7, 11], ['square 9', 'picture 1'])
|
|
667
|
+
|
|
668
|
+
So, yes it is, but here is further confirmation::
|
|
669
|
+
|
|
670
|
+
sage: M.blackjack_move([0, 2, 3, 6, 7, 11])
|
|
671
|
+
This is a hexad.
|
|
672
|
+
There is no winning move, so make a random legal move.
|
|
673
|
+
[0, 2, 3, 6, 7, 11]
|
|
674
|
+
|
|
675
|
+
Now, suppose player 2 replaced the 11 by a 9. Your next move::
|
|
676
|
+
|
|
677
|
+
sage: M.blackjack_move([0, 2, 3, 6, 7, 9])
|
|
678
|
+
'7 --> 1. The total went from 27 to 21.'
|
|
679
|
+
|
|
680
|
+
You have now won. Sage will even tell you so::
|
|
681
|
+
|
|
682
|
+
sage: M.blackjack_move([0, 2, 3, 6, 1, 9])
|
|
683
|
+
'No move possible. Shuffle the deck and redeal.'
|
|
684
|
+
|
|
685
|
+
AUTHOR:
|
|
686
|
+
|
|
687
|
+
David Joyner (2006-05)
|
|
688
|
+
|
|
689
|
+
REFERENCES: [CS1986]_, [KR2001]_
|
|
690
|
+
"""
|
|
691
|
+
total = sum(L0)
|
|
692
|
+
if total < 22:
|
|
693
|
+
return "No move possible. Shuffle the deck and redeal."
|
|
694
|
+
L = set(L0)
|
|
695
|
+
for x in L:
|
|
696
|
+
h, WHAT = self.find_hexad(L - {x})
|
|
697
|
+
if list(L0) == list(h):
|
|
698
|
+
print(" This is a hexad. \n There is no winning move, so make a random legal move.")
|
|
699
|
+
return L0
|
|
700
|
+
y = list(set(h) - (L - {x}))[0]
|
|
701
|
+
if y < x:
|
|
702
|
+
return str(x) + ' --> ' + str(y) + ". The total went from " + str(total) + " to " + str(total - x + y) + "."
|
|
703
|
+
print("This is a hexad. \n There is no winning move, so make a random legal move.")
|
|
704
|
+
return L0
|