1
0

00-开关与错开的时钟.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #!/usr/bin/env python3
  2. """课前零食:追踪 XOR 高斯消元与非互质 CRT 合并。"""
  3. from __future__ import annotations
  4. from math import gcd
  5. MATRIX = [
  6. [1, 1, 0, 1], # x1 xor x2 = 1
  7. [0, 1, 1, 0], # x2 xor x3 = 0
  8. [1, 0, 1, 1], # x1 xor x3 = 1(依赖前两行)
  9. ]
  10. def ask(prompt: str, default: str) -> str:
  11. try:
  12. return input(prompt).strip() or default
  13. except EOFError:
  14. return default
  15. def print_matrix(matrix: list[list[int]]) -> None:
  16. for row in matrix:
  17. print(" ", " ".join(map(str, row[:-1])), "|", row[-1])
  18. def xor_lab() -> None:
  19. matrix = [row[:] for row in MATRIX]
  20. variables = len(matrix[0]) - 1
  21. pivot_row = 0
  22. print("\n增广矩阵(最后一列为右侧常数):")
  23. print_matrix(matrix)
  24. for column in range(variables):
  25. pivot = next((r for r in range(pivot_row, len(matrix)) if matrix[r][column]), None)
  26. if pivot is None:
  27. print(f"第 {column + 1} 列没有主元:对应变量暂时自由。")
  28. continue
  29. matrix[pivot_row], matrix[pivot] = matrix[pivot], matrix[pivot_row]
  30. print(f"\n选第 {column + 1} 列主元,放到第 {pivot_row + 1} 行。")
  31. for row in range(len(matrix)):
  32. if row != pivot_row and matrix[row][column]:
  33. matrix[row] = [a ^ b for a, b in zip(matrix[row], matrix[pivot_row])]
  34. print(f" 第 {row + 1} 行 XOR 主元行")
  35. print_matrix(matrix)
  36. pivot_row += 1
  37. contradiction = any(not any(row[:-1]) and row[-1] for row in matrix)
  38. print("\n秩 =", pivot_row)
  39. if contradiction:
  40. print("出现 0=1:无解。")
  41. elif pivot_row < variables:
  42. print("相容但有自由变量:多解。")
  43. else:
  44. print("每个变量有主元:唯一解。")
  45. def exgcd(a: int, b: int) -> tuple[int, int, int]:
  46. if b == 0:
  47. return a, 1, 0
  48. g, x, y = exgcd(b, a % b)
  49. return g, y, x - (a // b) * y
  50. def merge(a: int, m: int, b: int, n: int) -> tuple[int, int] | None:
  51. g = gcd(m, n)
  52. print(f"gcd({m},{n})={g},差 b-a={b - a}")
  53. if (b - a) % g:
  54. return None
  55. reduced_m, reduced_n = m // g, n // g
  56. _, inverse, _ = exgcd(reduced_m, reduced_n)
  57. t = ((b - a) // g * inverse) % reduced_n
  58. modulus = m * reduced_n
  59. value = (a + m * t) % modulus
  60. print(f"解出 t={t},所以 x={value} (mod {modulus})")
  61. return value, modulus
  62. def crt_lab() -> None:
  63. raw = ask("输入 a m b n(回车为 1 4 3 6): ", "1 4 3 6")
  64. try:
  65. a, m, b, n = map(int, raw.split())
  66. if m <= 0 or n <= 0:
  67. raise ValueError
  68. except ValueError:
  69. print("格式应为四个整数 a m b n;使用预设。")
  70. a, m, b, n = 1, 4, 3, 6
  71. print(f"\n合并 x≡{a} (mod {m}) 与 x≡{b} (mod {n})")
  72. result = merge(a, m, b, n)
  73. if result is None:
  74. print("不兼容:两只时钟永远不会同时指向这些余数。")
  75. else:
  76. value, modulus = result
  77. print(f"验算:{value}%{m}={value % m},{value}%{n}={value % n};以后每隔 {modulus} 重复。")
  78. def main() -> None:
  79. choice = ask("选择 x=XOR 消元,c=CRT 合并(回车为 x): ", "x").lower()
  80. if choice == "c":
  81. crt_lab()
  82. else:
  83. xor_lab()
  84. if __name__ == "__main__":
  85. main()