diff --git a/LeetCodeSharp.Fetcher/LeetCodeSharp.Fetcher.csproj b/LeetCodeSharp.Fetcher/LeetCodeSharp.Fetcher.csproj
index 2150e37..fd4bd08 100644
--- a/LeetCodeSharp.Fetcher/LeetCodeSharp.Fetcher.csproj
+++ b/LeetCodeSharp.Fetcher/LeetCodeSharp.Fetcher.csproj
@@ -2,7 +2,7 @@
Exe
- net8.0
+ net9.0
enable
enable
diff --git a/LeetCodeSharp.Tests/LeetCodeSharp.Tests.csproj b/LeetCodeSharp.Tests/LeetCodeSharp.Tests.csproj
index a65736f..6f0ce56 100644
--- a/LeetCodeSharp.Tests/LeetCodeSharp.Tests.csproj
+++ b/LeetCodeSharp.Tests/LeetCodeSharp.Tests.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net9.0
enable
enable
diff --git a/LeetCodeSharp.Tests/P2296Tests.cs b/LeetCodeSharp.Tests/P2296Tests.cs
new file mode 100644
index 0000000..8325381
--- /dev/null
+++ b/LeetCodeSharp.Tests/P2296Tests.cs
@@ -0,0 +1,24 @@
+using LeetCodeSharp.Problems2296;
+
+namespace LeetCodeSharp.Tests;
+
+public sealed class P2296Tests
+{
+ [Fact]
+ public void Test1()
+ {
+ TextEditor editor = new();
+
+ editor.AddText("leetcode");
+ Assert.Equal(4, editor.DeleteText(4));
+ editor.AddText("practice");
+
+ Assert.Equal("etpractice", editor.CursorRight(3));
+ Assert.Equal("leet", editor.CursorLeft(8));
+
+ Assert.Equal(4, editor.DeleteText(4));
+ Assert.Equal(string.Empty, editor.CursorLeft(2));
+
+ Assert.Equal("practi", editor.CursorRight(6));
+ }
+}
\ No newline at end of file
diff --git a/LeetCodeSharp/Problems/Solution2296.cs b/LeetCodeSharp/Problems/Solution2296.cs
new file mode 100644
index 0000000..01feabb
--- /dev/null
+++ b/LeetCodeSharp/Problems/Solution2296.cs
@@ -0,0 +1,131 @@
+// [2296] Design a Text Editor
+
+
+namespace LeetCodeSharp.Problems2296
+{
+ // Submission codes start here
+
+ using System.Collections.Generic;
+ using System.Linq;
+
+ public class TextEditor
+ {
+ private readonly LinkedList _text = new LinkedList();
+
+ // 让游标就是光标左边的字符
+ private LinkedListNode _cursor;
+
+ public TextEditor()
+ {
+ _cursor = _text.First;
+ }
+
+ public void AddText(string text)
+ {
+ // 说明光标位于起始位置
+ // 右边可能有字符可能没有字符
+ if (_cursor is null)
+ {
+ _cursor = _text.AddFirst(text[0]);
+
+ foreach (int i in Enumerable.Range(1, text.Length - 1))
+ {
+ _cursor = _text.AddAfter(_cursor, text[i]);
+ }
+
+ return;
+ }
+
+ foreach (char c in text)
+ {
+ _cursor = _text.AddAfter(_cursor, c);
+ }
+ }
+
+ public int DeleteText(int k)
+ {
+ int result = 0;
+
+ foreach (int _ in Enumerable.Range(0, k))
+ {
+ if (_cursor is null)
+ {
+ break;
+ }
+
+ LinkedListNode lastNode = _cursor.Previous;
+ _text.Remove(_cursor);
+ result += 1;
+
+ _cursor = lastNode;
+ }
+
+ return result;
+ }
+
+ public string CursorLeft(int k)
+ {
+ foreach (int _ in Enumerable.Range(0, k))
+ {
+ // 前进的时候倒是可以移动出去
+ if (_cursor is null)
+ {
+ break;
+ }
+
+ _cursor = _cursor.Previous;
+ }
+
+ return GetLeftStringOfCursor(_cursor);
+ }
+
+ public string CursorRight(int k)
+ {
+ foreach (int _ in Enumerable.Range(0, k))
+ {
+ // 如果游标为空
+ // 此时位于文本的起始
+ if (_cursor is null)
+ {
+ _cursor = _text.First;
+ if (_cursor is null)
+ {
+ return string.Empty;
+ }
+
+ continue;
+ }
+
+ // 移动的时候不能移动出去了
+ if (_cursor.Next is null)
+ {
+ break;
+ }
+
+ _cursor = _cursor.Next;
+ }
+
+ return GetLeftStringOfCursor(_cursor);
+ }
+
+ private string GetLeftStringOfCursor(LinkedListNode node)
+ {
+ List buffer = new List();
+
+ while (node != null)
+ {
+ if (buffer.Count >= 10)
+ {
+ break;
+ }
+
+ buffer.Add(node.Value);
+ node = node.Previous;
+ }
+
+ return buffer.AsEnumerable().Reverse().Aggregate(string.Empty, (str, c) => str + c);
+ }
+ }
+
+ // Submission codes end here
+}
\ No newline at end of file