diff --git a/weeks/week-18/solutions/1114405055/ai_log_q3_digital_root.md b/weeks/week-18/solutions/1114405055/ai_log_q3_digital_root.md
new file mode 100644
index 000000000..cc3920037
--- /dev/null
+++ b/weeks/week-18/solutions/1114405055/ai_log_q3_digital_root.md
@@ -0,0 +1,24 @@
+# AI 協作紀錄 — 第三題:任意進位的數字根
+
+## 需求確認
+- 學號 1114405055 末兩碼 55 → 個位 u=5 → 查表 base=7(依使用者明確指定,不可混用其他題目的終止邏輯)
+- 輸入:每行一個十進位非負整數 x,讀到 EOF 結束(與第二題相同,但不同於第一題的 n=0 終止)
+- x=0 的數字根規定為 0,不能套一般迭代公式硬算
+
+## 設計決策(先問後做)
+- **base 是否做成命令列/環境變數參數?** 已詢問使用者,選擇直接寫死 `BASE = 7` 常數,理由是題目已用學號決定 base,做成可帶參數屬於題目未要求的額外設計(違反「最小化、不過度設計」原則)。
+- **函式拆兩個(digit_sum_in_base / digital_root)而非合成一個?**
+ 因為測試需要分別驗證「兩位數但只迭代一次就收斂」與「需要兩輪才收斂」這兩種邊界情境,若合成一個函式無法在測試中檢查中間結果,故拆開。
+
+## 開發流程(TDD:紅燈 → 綠燈)
+1. 先寫 `test_digital_root.py`,涵蓋使用者列出的所有 edge case(x=0、x int:
+ """把 x 換算成 base 進位,將各位數字相加,回傳十進位整數。"""
+ total = 0
+ while x > 0:
+ total += x % base
+ x //= base
+ return total
+
+
+def digital_root(x: int, base: int) -> int:
+ """重複對 base 進位下的各位數字相加,直到結果是一位數(< base)。"""
+ if x == 0:
+ return 0
+ while x >= base:
+ x = digit_sum_in_base(x, base)
+ return x
+
+
+def main() -> None:
+ import sys
+
+ for line in sys.stdin:
+ line = line.strip()
+ if not line:
+ continue
+ x = int(line)
+ print(digital_root(x, BASE))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/weeks/week-18/solutions/1114405055/test_digital_root.py b/weeks/week-18/solutions/1114405055/test_digital_root.py
new file mode 100644
index 000000000..b8cee1d1d
--- /dev/null
+++ b/weeks/week-18/solutions/1114405055/test_digital_root.py
@@ -0,0 +1,74 @@
+# 第三題:任意進位的數字根 -- 測試
+# 學號 1114405055 末兩碼 55,個位 u=5,查表得 base=7
+#
+# digit_sum_in_base(x, base):x 換算成 base 進位後,把各位數字加總,回傳十進位整數
+# digital_root(x, base):重複呼叫 digit_sum_in_base 直到結果是 base 進位下的一位數
+# x=0 時題目規定直接回傳 0,不套公式硬算
+
+import pytest
+
+from digital_root import digit_sum_in_base, digital_root
+
+BASE = 7
+
+
+def test_zero_is_zero_by_definition():
+ # 題目明文規定 x=0 的數字根固定是 0,不能用一般迭代公式去算
+ assert digital_root(0, BASE) == 0
+
+
+def test_already_single_digit_no_iteration_needed():
+ # x < base 時,本身在 base 進位下就是一位數,不需要任何累加迭代
+ for x in range(1, BASE):
+ assert digital_root(x, BASE) == x
+
+
+def test_sample_8_one_iteration_to_converge():
+ # 8 在 7 進位是 11 -> 1+1=2,2 < 7 已是一位數,迭代一次即收斂
+ assert digit_sum_in_base(8, BASE) == 2
+ assert digital_root(8, BASE) == 2
+
+
+def test_sample_63_needs_two_iterations_to_converge():
+ # 63 在 7 進位是 120 -> 1+2+0=3,3 < 7 已是一位數
+ # 這組驗證「相加一次後仍可能不是一位數,需再轉一次進位再加一次」的收斂邊界
+ assert digit_sum_in_base(63, BASE) == 3
+ assert digital_root(63, BASE) == 3
+
+
+def test_needs_multiple_rounds_to_converge_to_single_digit():
+ # 自行驗算:x=1000000 在 7 進位是 11333311
+ # 第一輪:1+1+3+3+3+3+1+1 = 16,16 在 7 進位是 22(兩位數,尚未收斂)
+ # 第二輪:2+2 = 4,4 < 7 已是一位數
+ # 證明 digital_root 必須是「迴圈直到一位數」而非只做固定一次相加
+ x = 1_000_000
+ first_round = digit_sum_in_base(x, BASE)
+ assert first_round == 16
+ assert first_round >= BASE # 第一次相加後仍是兩位數,尚未收斂
+ second_round = digit_sum_in_base(first_round, BASE)
+ assert second_round == 4
+ assert digital_root(x, BASE) == 4
+
+
+def test_large_value_terminates_quickly():
+ # x 接近上限 1e9,確認迴圈會收斂且不會死迴圈或效能爆炸
+ x = 10**9
+ result = digital_root(x, BASE)
+ assert 0 <= result < BASE
+
+
+@pytest.mark.parametrize("x", [0, 1, 6, 7, 8, 63, 1_000_000, 10**9])
+def test_digital_root_always_single_digit_in_base(x):
+ # 數字根定義上必須落在 [0, base) 之間(在 base 進位下是一位數)
+ assert 0 <= digital_root(x, BASE) < BASE
+
+
+def test_base_16_conversion_not_hardcoded_for_small_base():
+ # 題目特別提醒 base 可能是 16,確認進位轉換/輸出邏輯沒有寫死成只服務小 base
+ # 255 在 16 進位是 FF -> 十進位數字相加 15+15=30,30 在 16 進位是 1E -> 1+14=15
+ base16 = 16
+ assert digit_sum_in_base(255, base16) == 30
+ assert digital_root(255, base16) == 15
+ # 16 進位下剛好一位數的情況
+ assert digital_root(15, base16) == 15
+ assert digital_root(0, base16) == 0
diff --git a/weeks/week-18/solutions/1114405055/test_log_q3_green.txt b/weeks/week-18/solutions/1114405055/test_log_q3_green.txt
new file mode 100644
index 000000000..dfde15351
--- /dev/null
+++ b/weeks/week-18/solutions/1114405055/test_log_q3_green.txt
@@ -0,0 +1,24 @@
+============================= test session starts =============================
+platform win32 -- Python 3.13.9, pytest-8.4.2, pluggy-1.5.0 -- C:\Users\User\anaconda3\python.exe
+cachedir: .pytest_cache
+rootdir: C:\Users\User\Desktop\0622-3\2026-python\weeks\week-18\solutions\1114405055
+plugins: anyio-4.10.0
+collecting ... collected 15 items
+
+test_digital_root.py::test_zero_is_zero_by_definition PASSED [ 6%]
+test_digital_root.py::test_already_single_digit_no_iteration_needed PASSED [ 13%]
+test_digital_root.py::test_sample_8_one_iteration_to_converge PASSED [ 20%]
+test_digital_root.py::test_sample_63_needs_two_iterations_to_converge PASSED [ 26%]
+test_digital_root.py::test_needs_multiple_rounds_to_converge_to_single_digit PASSED [ 33%]
+test_digital_root.py::test_large_value_terminates_quickly PASSED [ 40%]
+test_digital_root.py::test_digital_root_always_single_digit_in_base[0] PASSED [ 46%]
+test_digital_root.py::test_digital_root_always_single_digit_in_base[1] PASSED [ 53%]
+test_digital_root.py::test_digital_root_always_single_digit_in_base[6] PASSED [ 60%]
+test_digital_root.py::test_digital_root_always_single_digit_in_base[7] PASSED [ 66%]
+test_digital_root.py::test_digital_root_always_single_digit_in_base[8] PASSED [ 73%]
+test_digital_root.py::test_digital_root_always_single_digit_in_base[63] PASSED [ 80%]
+test_digital_root.py::test_digital_root_always_single_digit_in_base[1000000] PASSED [ 86%]
+test_digital_root.py::test_digital_root_always_single_digit_in_base[1000000000] PASSED [ 93%]
+test_digital_root.py::test_base_16_conversion_not_hardcoded_for_small_base PASSED [100%]
+
+============================= 15 passed in 0.02s ==============================
diff --git a/weeks/week-18/solutions/1114405055/test_log_q3_red.txt b/weeks/week-18/solutions/1114405055/test_log_q3_red.txt
new file mode 100644
index 000000000..28ade1cc3
--- /dev/null
+++ b/weeks/week-18/solutions/1114405055/test_log_q3_red.txt
@@ -0,0 +1,22 @@
+============================= test session starts =============================
+platform win32 -- Python 3.13.9, pytest-8.4.2, pluggy-1.5.0 -- C:\Users\User\anaconda3\python.exe
+cachedir: .pytest_cache
+rootdir: C:\Users\User\Desktop\0622-3\2026-python\weeks\week-18\solutions\1114405055
+plugins: anyio-4.10.0
+collecting ... collected 0 items / 1 error
+
+=================================== ERRORS ====================================
+____________________ ERROR collecting test_digital_root.py ____________________
+ImportError while importing test module 'C:\Users\User\Desktop\0622-3\2026-python\weeks\week-18\solutions\1114405055\test_digital_root.py'.
+Hint: make sure your test modules/packages have valid Python names.
+Traceback:
+C:\Users\User\anaconda3\Lib\importlib\__init__.py:88: in import_module
+ return _bootstrap._gcd_import(name[level:], package, level)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+test_digital_root.py:10: in
+ from digital_root import digit_sum_in_base, digital_root
+E ModuleNotFoundError: No module named 'digital_root'
+=========================== short test summary info ===========================
+ERROR test_digital_root.py
+!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!
+============================== 1 error in 0.08s ===============================