diff --git a/problems/3227-vowels-game-in-a-string/3227-vowels-game-in-a-string.sln b/problems/3227-vowels-game-in-a-string/3227-vowels-game-in-a-string.sln
new file mode 100644
index 0000000..3213b7e
--- /dev/null
+++ b/problems/3227-vowels-game-in-a-string/3227-vowels-game-in-a-string.sln
@@ -0,0 +1,30 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.2.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csharp", "csharp\csharp.csproj", "{CF022C7B-CAF3-706D-67E1-FB93518229B7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProject", "test\TestProject.csproj", "{C670389A-9CE7-B456-51E5-A79D56E199CF}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {CF022C7B-CAF3-706D-67E1-FB93518229B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CF022C7B-CAF3-706D-67E1-FB93518229B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CF022C7B-CAF3-706D-67E1-FB93518229B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CF022C7B-CAF3-706D-67E1-FB93518229B7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C670389A-9CE7-B456-51E5-A79D56E199CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C670389A-9CE7-B456-51E5-A79D56E199CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C670389A-9CE7-B456-51E5-A79D56E199CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C670389A-9CE7-B456-51E5-A79D56E199CF}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {15EA9854-706B-456C-B6A2-6AF4670868DE}
+ EndGlobalSection
+EndGlobal
diff --git a/problems/3227-vowels-game-in-a-string/README.md b/problems/3227-vowels-game-in-a-string/README.md
new file mode 100644
index 0000000..5aae5cc
--- /dev/null
+++ b/problems/3227-vowels-game-in-a-string/README.md
@@ -0,0 +1,82 @@
+# [3227] Vowels Game In A String
+
+## 題目資訊
+- **難度**: Medium
+- **標籤**: Math, String, Brainteaser, Game Theory
+- **題目連結**: https://leetcode.com/problems/vowels-game-in-a-string/
+- **練習日期**: 2025-09-12
+- **目標複雜度**: 時間 O(n)、空間 O(1)
+
+## 題目描述
+Alice and Bob are playing a game on a string.
+
+You are given a string `s`, Alice and Bob will take turns playing the following game where Alice starts **first**:
+
+On Alice's turn, she has to remove any **non-empty** substring from `s` that contains an odd number of vowels.
+On Bob's turn, he has to remove any non-empty substring from `s` that contains an even number of vowels.
+The first player who cannot make a move on their turn loses the game. We assume that both Alice and Bob play optimally.
+
+Return `true` if Alice wins the game, and `false` otherwise.
+
+The English vowels are: `a`, `e`, `i`, `o`, and `u`.
+
+## 先備條件與限制
+- 輸入限制:n ∈ [?, ?]、值域 ∈ [?, ?]
+- 回傳/輸出格式:...
+- 其他:是否允許排序/就地修改
+
+## 解題思路
+
+### 初步分析
+- 類型:雙指針 / 滑動視窗 / 排序 / DP / 貪心 / 圖論 ...
+- 關鍵觀察:
+- 複雜度目標理由:
+
+### 解法比較
+1. 解法A(基準/暴力):
+ - 思路:
+ - 正確性:
+ - 複雜度:O(?) / O(?)
+2. 解法B(優化):
+ - 思路:
+ - 正確性:
+ - 複雜度:O(?) / O(?)
+
+### 乾跑(Dry Run)
+- 範例:...
+
+### 常見陷阱
+- 邊界:空/單一/極值/全相等
+- 去重:排序後跳重複、集合
+- 溢位:使用 64-bit
+
+## 測試案例
+
+### 範例輸入輸出
+```
+Input: ...
+Output: ...
+Explanation: ...
+```
+
+### 邊界清單
+- [ ] 空陣列/空字串
+- [ ] 單一元素 / 全相同
+- [ ] 含負數/0/大數
+- [ ] 去重
+- [ ] 大資料壓力
+
+## 複雜度分析
+- 最壞:時間 O(?)、空間 O(?)
+
+## 相關題目 / Follow-up
+-
+
+## 學習筆記
+- 今天學到:
+- 卡住與修正:
+- 待優化:
+
+---
+**總結**:這題的核心在於 ______,適合練習 ______。
+
diff --git a/problems/3227-vowels-game-in-a-string/csharp/Program.cs b/problems/3227-vowels-game-in-a-string/csharp/Program.cs
new file mode 100644
index 0000000..6076c43
--- /dev/null
+++ b/problems/3227-vowels-game-in-a-string/csharp/Program.cs
@@ -0,0 +1,24 @@
+// LeetCode 3227: Vowels Game In A String
+// 難度: Medium
+// 日期: 2025-09-12
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+public class Solution {
+ public bool DoesAliceWin(string s)
+ {
+ string vowels = "aeiou";
+
+ foreach (var character in s)
+ {
+ if (vowels.Contains(character))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
diff --git a/problems/3227-vowels-game-in-a-string/csharp/csharp.csproj b/problems/3227-vowels-game-in-a-string/csharp/csharp.csproj
new file mode 100644
index 0000000..e8cd599
--- /dev/null
+++ b/problems/3227-vowels-game-in-a-string/csharp/csharp.csproj
@@ -0,0 +1,7 @@
+
+
+ net8.0
+ enable
+ enable
+
+
diff --git a/problems/3227-vowels-game-in-a-string/go.mod b/problems/3227-vowels-game-in-a-string/go.mod
new file mode 100644
index 0000000..5ea7f9d
--- /dev/null
+++ b/problems/3227-vowels-game-in-a-string/go.mod
@@ -0,0 +1,4 @@
+module leetcode/3227-vowels-game-in-a-string
+
+go 1.18
+
diff --git a/problems/3227-vowels-game-in-a-string/go/main.go b/problems/3227-vowels-game-in-a-string/go/main.go
new file mode 100644
index 0000000..f6d25f1
--- /dev/null
+++ b/problems/3227-vowels-game-in-a-string/go/main.go
@@ -0,0 +1,19 @@
+// LeetCode 3227: Vowels Game In A String
+// 難度: Medium
+// 日期: 2025-09-12
+
+package vowels
+
+import "strings"
+
+// DoesAliceWin returns true if the string contains any vowel.
+// Game theory reduces to: Alice wins iff there exists at least one vowel.
+func DoesAliceWin(s string) bool {
+ const vowels = "aeiou"
+ for _, ch := range s {
+ if strings.ContainsRune(vowels, ch) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/problems/3227-vowels-game-in-a-string/test/SolutionTests.cs b/problems/3227-vowels-game-in-a-string/test/SolutionTests.cs
new file mode 100644
index 0000000..a47d454
--- /dev/null
+++ b/problems/3227-vowels-game-in-a-string/test/SolutionTests.cs
@@ -0,0 +1,168 @@
+// LeetCode 3227: Vowels Game in a String 單元測試(xUnit)
+// Problem: Alice and Bob play a game. Alice removes substrings with odd vowels,
+// Bob removes substrings with even vowels. Alice wins if string has any vowels.
+
+using Xunit;
+
+public class SolutionTests
+{
+ private readonly Solution _s = new Solution();
+
+ [Fact]
+ public void Example1_StringWithVowels_AliceWins()
+ {
+ // Arrange
+ var input = "leetcode"; // contains vowels: e,e,o,e
+ var expected = true; // Alice wins
+
+ // Act
+ var got = _s.DoesAliceWin(input);
+
+ // Assert
+ Assert.Equal(expected, got);
+ }
+
+ [Fact]
+ public void Example2_StringWithoutVowels_BobWins()
+ {
+ // Arrange
+ var input = "bcdf"; // no vowels
+ var expected = false; // Bob wins (Alice can't make first move)
+
+ // Act
+ var got = _s.DoesAliceWin(input);
+
+ // Assert
+ Assert.Equal(expected, got);
+ }
+
+ [Fact]
+ public void AllVowels_AliceWins()
+ {
+ // Arrange
+ var input = "aeiou"; // all vowels (odd count = 5)
+ var expected = true; // Alice removes entire string
+
+ // Act
+ var got = _s.DoesAliceWin(input);
+
+ // Assert
+ Assert.Equal(expected, got);
+ }
+
+ [Fact]
+ public void SingleVowel_AliceWins()
+ {
+ // Arrange
+ var input = "a"; // single vowel
+ var expected = true; // Alice removes it immediately
+
+ // Act
+ var got = _s.DoesAliceWin(input);
+
+ // Assert
+ Assert.Equal(expected, got);
+ }
+
+ [Fact]
+ public void SingleConsonant_BobWins()
+ {
+ // Arrange
+ var input = "b"; // single consonant, no vowels
+ var expected = false; // Alice can't move
+
+ // Act
+ var got = _s.DoesAliceWin(input);
+
+ // Assert
+ Assert.Equal(expected, got);
+ }
+
+ [Fact]
+ public void MixedString_EvenVowelCount_AliceWins()
+ {
+ // Arrange
+ var input = "programming"; // vowels: o,a,i (3 vowels, odd)
+ var expected = true; // Alice can remove all vowels at once
+
+ // Act
+ var got = _s.DoesAliceWin(input);
+
+ // Assert
+ Assert.Equal(expected, got);
+ }
+
+ [Fact]
+ public void LongStringNoVowels_BobWins()
+ {
+ // Arrange
+ var input = "bcdfghjklmnpqrstvwxyz"; // all consonants
+ var expected = false; // No vowels = Bob wins
+
+ // Act
+ var got = _s.DoesAliceWin(input);
+
+ // Assert
+ Assert.Equal(expected, got);
+ }
+
+ [Fact]
+ public void RepeatedVowels_AliceWins()
+ {
+ // Arrange
+ var input = "aaaa"; // 4 vowels (even count)
+ var expected = true; // Alice can remove 3, leaving 1 (Bob can't move)
+
+ // Act
+ var got = _s.DoesAliceWin(input);
+
+ // Assert
+ Assert.Equal(expected, got);
+ }
+
+ [Fact]
+ public void EdgeCases()
+ {
+ // Single character tests
+ Assert.True(_s.DoesAliceWin("e")); // vowel
+ Assert.False(_s.DoesAliceWin("x")); // consonant
+
+ // Two character tests
+ Assert.True(_s.DoesAliceWin("ab")); // has vowel 'a'
+ Assert.False(_s.DoesAliceWin("xy")); // no vowels
+
+ // Vowel at different positions
+ Assert.True(_s.DoesAliceWin("xabc")); // vowel at start-middle
+ Assert.True(_s.DoesAliceWin("abcx")); // vowel in middle
+ Assert.True(_s.DoesAliceWin("xbca")); // vowel at end
+ }
+
+ [Fact]
+ public void GameTheoryValidation()
+ {
+ // Test cases that validate the game theory logic:
+ // If total vowels = 0: Alice loses (can't make first move)
+ Assert.False(_s.DoesAliceWin("bcdfg"));
+
+ // If total vowels = odd: Alice wins (removes all vowels in one move)
+ Assert.True(_s.DoesAliceWin("hello")); // e,o = 2 vowels (even), but Alice still wins
+ Assert.True(_s.DoesAliceWin("beautiful")); // e,a,u,i,u = 5 vowels (odd)
+
+ // If total vowels = even > 0: Alice wins (leaves exactly 1 vowel for Bob)
+ Assert.True(_s.DoesAliceWin("code")); // o,e = 2 vowels (even)
+ Assert.True(_s.DoesAliceWin("education")); // e,u,a,i,o = 5 vowels, but any vowels = Alice wins
+ }
+
+ [Theory]
+ [InlineData("", false)] // empty string - no vowels
+ [InlineData("aeiou", true)] // all vowels
+ [InlineData("bcdfg", false)] // all consonants
+ [InlineData("hello", true)] // mixed with vowels
+ [InlineData("rhythm", false)] // no vowels (y not considered vowel)
+ [InlineData("queue", true)] // multiple same vowels
+ public void ParameterizedTests(string input, bool expected)
+ {
+ // Act & Assert
+ Assert.Equal(expected, _s.DoesAliceWin(input));
+ }
+}
\ No newline at end of file
diff --git a/problems/3227-vowels-game-in-a-string/test/TestProject.csproj b/problems/3227-vowels-game-in-a-string/test/TestProject.csproj
new file mode 100644
index 0000000..e2d8b41
--- /dev/null
+++ b/problems/3227-vowels-game-in-a-string/test/TestProject.csproj
@@ -0,0 +1,19 @@
+
+
+ net8.0
+ enable
+ false
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
diff --git a/problems/3227-vowels-game-in-a-string/test/edge_cases.md b/problems/3227-vowels-game-in-a-string/test/edge_cases.md
new file mode 100644
index 0000000..a45b86a
--- /dev/null
+++ b/problems/3227-vowels-game-in-a-string/test/edge_cases.md
@@ -0,0 +1,20 @@
+# 邊界情況清單(3227 Vowels Game In A String)
+
+## 需要測試的邊界
+- [ ] 空輸入 / 單一元素
+- [ ] 重複元素 / 全相同
+- [ ] 極值(最小/最大)
+- [ ] 含負數 / 0 / 大數
+- [ ] 大資料量(接近上限)
+
+## 額外案例
+### 案例 1
+- 輸入:
+- 預期:
+- 說明:
+
+### 案例 2
+- 輸入:
+- 預期:
+- 說明:
+
diff --git a/problems/3227-vowels-game-in-a-string/test/main_test.go b/problems/3227-vowels-game-in-a-string/test/main_test.go
new file mode 100644
index 0000000..8cf1402
--- /dev/null
+++ b/problems/3227-vowels-game-in-a-string/test/main_test.go
@@ -0,0 +1,188 @@
+// LeetCode 3227: Vowels Game in a String 單元測試(Go testing)
+// Problem: Alice and Bob play a game. Alice removes substrings with odd vowels,
+// Bob removes substrings with even vowels. Alice wins if string has any vowels.
+package vowels_test
+
+import (
+ "fmt"
+ "testing"
+ vowels "leetcode/3227-vowels-game-in-a-string/go"
+)
+
+func TestExample1(t *testing.T) {
+ // "leetcode" contains vowels: e,e,o,e
+ input := "leetcode"
+ got := vowels.DoesAliceWin(input)
+ want := true // Alice wins
+ if got != want {
+ t.Fatalf("input %q: want %v got %v", input, want, got)
+ }
+}
+
+func TestExample2(t *testing.T) {
+ // "bcdf" has no vowels
+ input := "bcdf"
+ got := vowels.DoesAliceWin(input)
+ want := false // Bob wins (Alice can't make first move)
+ if got != want {
+ t.Fatalf("input %q: want %v got %v", input, want, got)
+ }
+}
+
+func TestAllVowels(t *testing.T) {
+ // All vowels string - Alice removes entire string
+ input := "aeiou"
+ got := vowels.DoesAliceWin(input)
+ want := true
+ if got != want {
+ t.Fatalf("input %q: want %v got %v", input, want, got)
+ }
+}
+
+func TestSingleVowel(t *testing.T) {
+ // Single vowel - Alice removes it immediately
+ input := "a"
+ got := vowels.DoesAliceWin(input)
+ want := true
+ if got != want {
+ t.Fatalf("input %q: want %v got %v", input, want, got)
+ }
+}
+
+func TestSingleConsonant(t *testing.T) {
+ // Single consonant - Alice can't move
+ input := "b"
+ got := vowels.DoesAliceWin(input)
+ want := false
+ if got != want {
+ t.Fatalf("input %q: want %v got %v", input, want, got)
+ }
+}
+
+func TestMixedString(t *testing.T) {
+ // "programming" has vowels: o,a,i
+ input := "programming"
+ got := vowels.DoesAliceWin(input)
+ want := true // Alice can remove vowels
+ if got != want {
+ t.Fatalf("input %q: want %v got %v", input, want, got)
+ }
+}
+
+func TestLongStringNoVowels(t *testing.T) {
+ // All consonants - no vowels means Bob wins
+ input := "bcdfghjklmnpqrstvwxyz"
+ got := vowels.DoesAliceWin(input)
+ want := false
+ if got != want {
+ t.Fatalf("input %q: want %v got %v", input, want, got)
+ }
+}
+
+func TestRepeatedVowels(t *testing.T) {
+ // Even number of same vowels - Alice can leave 1 for Bob
+ input := "aaaa"
+ got := vowels.DoesAliceWin(input)
+ want := true
+ if got != want {
+ t.Fatalf("input %q: want %v got %v", input, want, got)
+ }
+}
+
+func TestEdgeCases(t *testing.T) {
+ testCases := []struct {
+ input string
+ want bool
+ desc string
+ }{
+ {"e", true, "single vowel"},
+ {"x", false, "single consonant"},
+ {"ab", true, "has vowel 'a'"},
+ {"xy", false, "no vowels"},
+ {"xabc", true, "vowel in middle"},
+ {"abcx", true, "vowel at start"},
+ {"xbca", true, "vowel at end"},
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.desc, func(t *testing.T) {
+ got := vowels.DoesAliceWin(tc.input)
+ if got != tc.want {
+ t.Fatalf("input %q (%s): want %v got %v", tc.input, tc.desc, tc.want, got)
+ }
+ })
+ }
+}
+
+func TestGameTheoryValidation(t *testing.T) {
+ testCases := []struct {
+ input string
+ want bool
+ desc string
+ }{
+ // If total vowels = 0: Alice loses
+ {"bcdfg", false, "no vowels - Alice can't move"},
+ {"rhythm", false, "no vowels (y not counted)"},
+
+ // Any vowels > 0: Alice wins
+ {"hello", true, "e,o vowels - Alice wins"},
+ {"beautiful", true, "e,a,u,i,u vowels - Alice wins"},
+ {"code", true, "o,e vowels - Alice wins"},
+ {"education", true, "e,u,a,i,o vowels - Alice wins"},
+ {"queue", true, "u,e,u,e vowels - Alice wins"},
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.desc, func(t *testing.T) {
+ got := vowels.DoesAliceWin(tc.input)
+ if got != tc.want {
+ t.Fatalf("input %q (%s): want %v got %v", tc.input, tc.desc, tc.want, got)
+ }
+ })
+ }
+}
+
+func TestParameterized(t *testing.T) {
+ testCases := []struct {
+ input string
+ want bool
+ }{
+ {"", false}, // empty string
+ {"aeiou", true}, // all vowels
+ {"bcdfg", false}, // all consonants
+ {"hello", true}, // mixed with vowels
+ {"rhythm", false}, // no vowels
+ {"queue", true}, // multiple same vowels
+ {"xyz", false}, // short no vowels
+ {"programming", true}, // longer mixed
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.input, func(t *testing.T) {
+ got := vowels.DoesAliceWin(tc.input)
+ if got != tc.want {
+ t.Errorf("doesAliceWin(%q) = %v, want %v", tc.input, got, tc.want)
+ }
+ })
+ }
+}
+
+// Benchmark test
+func BenchmarkDoesAliceWin(b *testing.B) {
+ testString := "abcdefghijklmnopqrstuvwxyz"
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ vowels.DoesAliceWin(testString)
+ }
+}
+
+// Example test for documentation
+func ExampleDoesAliceWin() {
+ result1 := vowels.DoesAliceWin("leetcode")
+ result2 := vowels.DoesAliceWin("bcdf")
+ fmt.Println(result1)
+ fmt.Println(result2)
+ // Output:
+ // true
+ // false
+}