diff --git a/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/Palindrom.sln b/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/Palindrom.sln
new file mode 100644
index 00000000..813d2a48
--- /dev/null
+++ b/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/Palindrom.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31112.23
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Palindrom", "Palindrom\Palindrom.csproj", "{87FAE52E-8A5E-4E2C-80FC-1B82110F86BA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PalindromTest", "PalindromTest\PalindromTest.csproj", "{7FD235E0-F63F-4653-BC54-CC002E15BA19}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {87FAE52E-8A5E-4E2C-80FC-1B82110F86BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {87FAE52E-8A5E-4E2C-80FC-1B82110F86BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {87FAE52E-8A5E-4E2C-80FC-1B82110F86BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {87FAE52E-8A5E-4E2C-80FC-1B82110F86BA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7FD235E0-F63F-4653-BC54-CC002E15BA19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7FD235E0-F63F-4653-BC54-CC002E15BA19}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7FD235E0-F63F-4653-BC54-CC002E15BA19}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7FD235E0-F63F-4653-BC54-CC002E15BA19}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {D30751F1-D037-4D14-8F26-2D5CBFA3FC47}
+ EndGlobalSection
+EndGlobal
diff --git a/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/Palindrom/Palindrom.csproj b/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/Palindrom/Palindrom.csproj
new file mode 100644
index 00000000..c73e0d16
--- /dev/null
+++ b/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/Palindrom/Palindrom.csproj
@@ -0,0 +1,8 @@
+
+
+
+ Exe
+ netcoreapp3.1
+
+
+
diff --git a/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/Palindrom/Palindrome.cs b/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/Palindrom/Palindrome.cs
new file mode 100644
index 00000000..5cfa87f5
--- /dev/null
+++ b/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/Palindrom/Palindrome.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Linq;
+
+namespace Palindrom
+{
+ public static class Palindrome
+ {
+ public static bool IsPalindrome(string input, bool ignoreCaseSensitivity = false)
+ {
+ if (string.IsNullOrWhiteSpace(input))
+ return false;
+
+ if (input.Any(char.IsPunctuation) || input.Any(char.IsWhiteSpace))
+ {
+ input = new string(input.Where(x => !(char.IsPunctuation(x) || char.IsWhiteSpace(x))).ToArray());
+ }
+
+ var firstHalfLength = (int)Math.Floor(input.Length / 2d);
+ var secondHalfStartIndex = (int)Math.Ceiling(input.Length / 2d);
+
+ var firstHalf = input[0..firstHalfLength];
+ var secondHalf = ReverseString(input[secondHalfStartIndex..]);
+
+ return ignoreCaseSensitivity
+ ? firstHalf.ToLower() == secondHalf.ToLower()
+ : firstHalf == secondHalf;
+ }
+
+ private static string ReverseString(string s)
+ {
+ var array = s.ToCharArray();
+ Array.Reverse(array);
+ return new string(array);
+ }
+ }
+}
diff --git a/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/Palindrom/PalindromeExamples.cs b/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/Palindrom/PalindromeExamples.cs
new file mode 100644
index 00000000..aff969b5
--- /dev/null
+++ b/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/Palindrom/PalindromeExamples.cs
@@ -0,0 +1,55 @@
+using System.Collections.Generic;
+
+namespace Palindrom
+{
+ public static class PalindromeExamples
+ {
+ public static List PalindromesCaseInsensitive { get; } = new List
+ {
+ "Abba",
+ "Lagerregal",
+ "Reliefpfeiler",
+ "Rentner",
+ "Dienstmannamtsneid",
+ };
+
+ public static List PalindromesCaseSensitive { get; } = new List
+ {
+ "abba",
+ "lagerregal",
+ "reliefpfeiler",
+ "rentner",
+ "dienstmannamtsneid",
+ };
+
+ public static List NoPalindromes { get; } = new List
+ {
+ "Aufgabe",
+ "Palindromsätze",
+ "Satzzeichen",
+ "vernachlässigen",
+ "Zeichenkette",
+ };
+
+ public static List PalindromeSentencesCaseInsensitive { get; } = new List
+ {
+ "Tarne nie deinen Rat!",
+ "Eine güldne, gute Tugend: Lüge nie!",
+ "Ein agiler Hit reizt sie. Geist?! Biertrunk nur treibt sie. Geist ziert ihre Liga nie!"
+ };
+
+ public static List PalindromeSentencesCaseSensitive { get; } = new List
+ {
+ "tarne nie deinen rat!",
+ "eine güldne, gute tugend: lüge nie!",
+ "ein agiler hit reizt sie. geist?! biertrunk nur treibt sie. geist ziert ihre liga nie!"
+ };
+
+ public static List NoPalindromeSentences { get; } = new List
+ {
+ "lorem ipsum dolor sit amet consectetur adipisicing elit.",
+ "Künstliche neuronale Netze haben, ebenso wie künstliche Neuronen, ein biologisches Vorbild.",
+ "An engine or motor is a machine designed to convert one or more forms of energy into mechanical energy."
+ };
+ }
+}
diff --git a/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/Palindrom/Program.cs b/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/Palindrom/Program.cs
new file mode 100644
index 00000000..2b2d3c90
--- /dev/null
+++ b/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/Palindrom/Program.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Linq;
+
+namespace Palindrom
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("'Palindrom'");
+ Process();
+ }
+
+ private static void Process()
+ {
+ Console.WriteLine("Would you like to ignore case sensitivity for the palindrome checks? (y)es / (n)o");
+
+ var keyPressed = Console.ReadKey();
+
+ Console.WriteLine();
+
+ var ignoreCaseSensitivity = false;
+ if (keyPressed.Key == ConsoleKey.Y)
+ {
+ ignoreCaseSensitivity = true;
+ }
+ else if (keyPressed.Key != ConsoleKey.N)
+ {
+ Console.WriteLine("Error: Invalid input detected!");
+ Process();
+ return;
+ }
+
+ var testInput = PalindromeExamples.PalindromesCaseInsensitive
+ .Concat(PalindromeExamples.PalindromesCaseSensitive)
+ .Concat(PalindromeExamples.NoPalindromes)
+ .Concat(PalindromeExamples.PalindromeSentencesCaseInsensitive)
+ .Concat(PalindromeExamples.PalindromeSentencesCaseSensitive)
+ .Concat(PalindromeExamples.NoPalindromeSentences);
+
+ foreach (var input in testInput)
+ {
+ var result = Palindrome.IsPalindrome(input, ignoreCaseSensitivity) ? "IS" : "Is NOT";
+
+ Console.WriteLine("{0} >> {1} a palindrome", input, result);
+ }
+ }
+
+ }
+}
diff --git a/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/PalindromTest/PalindromTest.csproj b/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/PalindromTest/PalindromTest.csproj
new file mode 100644
index 00000000..dce462c0
--- /dev/null
+++ b/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/PalindromTest/PalindromTest.csproj
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp3.1
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/PalindromTest/PalindromeTest.cs b/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/PalindromTest/PalindromeTest.cs
new file mode 100644
index 00000000..108e8fbb
--- /dev/null
+++ b/katas/Palindrom/solutions/MarcelSchmidt/Palindrom/PalindromTest/PalindromeTest.cs
@@ -0,0 +1,126 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Palindrom;
+using System.Collections.Generic;
+
+namespace PalindromTest
+{
+ [TestClass]
+ public class PalindromeTest
+ {
+ [TestMethod]
+ public void IsPalindrome_CaseInsensitiveCheck_WordCaseInsensitive_ReturnsTrue()
+ {
+ CaseInsensitiveCheckSucceed(PalindromeExamples.PalindromesCaseInsensitive);
+ }
+
+ [TestMethod]
+ public void IsPalindrome_CaseSensitiveCheck_WordCaseInsensitive_ReturnsFalse()
+ {
+ CaseSensitiveCheckFail(PalindromeExamples.PalindromesCaseInsensitive);
+ }
+
+ [TestMethod]
+ public void IsPalindrome_CaseInsensitiveCheck_WordCaseSensitive_ReturnsTrue()
+ {
+ CaseInsensitiveCheckSucceed(PalindromeExamples.PalindromesCaseSensitive);
+ }
+
+ [TestMethod]
+ public void IsPalindrome_CaseSensitiveCheck_WordCaseSensitive_ReturnsTrue()
+ {
+ CaseSensitiveCheckSucceed(PalindromeExamples.PalindromesCaseSensitive);
+ }
+
+ [TestMethod]
+ public void IsPalindrome_CaseSensitiveCheck_WordNoPalindrome_ReturnsFalse()
+ {
+ CaseSensitiveCheckFail(PalindromeExamples.NoPalindromes);
+ }
+
+ [TestMethod]
+ public void IsPalindrome_CaseInsensitiveCheck_WordNoPalindrome_ReturnsFalse()
+ {
+ CaseInsensitiveCheckFail(PalindromeExamples.NoPalindromes);
+ }
+
+ [TestMethod]
+ public void IsPalindrome_CaseInsensitiveCheck_SentenceCaseInsensitive_ReturnsTrue()
+ {
+ CaseInsensitiveCheckSucceed(PalindromeExamples.PalindromeSentencesCaseInsensitive);
+ }
+
+ [TestMethod]
+ public void IsPalindrome_CaseSensitiveCheck_SentenceCaseInsensitive_ReturnsFalse()
+ {
+ CaseSensitiveCheckFail(PalindromeExamples.PalindromeSentencesCaseInsensitive);
+ }
+
+ [TestMethod]
+ public void IsPalindrome_CaseInsensitiveCheck_SentenceCaseSensitive_ReturnsTrue()
+ {
+ CaseInsensitiveCheckSucceed(PalindromeExamples.PalindromeSentencesCaseSensitive);
+ }
+
+ [TestMethod]
+ public void IsPalindrome_CaseSensitiveCheck_SentenceCaseSensitive_ReturnsTrue()
+ {
+ CaseSensitiveCheckSucceed(PalindromeExamples.PalindromeSentencesCaseSensitive);
+ }
+
+ [TestMethod]
+ public void IsPalindrome_CaseSensitiveCheck_SentenceNoPalindrome_ReturnsFalse()
+ {
+ CaseSensitiveCheckFail(PalindromeExamples.NoPalindromeSentences);
+ }
+
+ [TestMethod]
+ public void IsPalindrome_CaseInsensitiveCheck_SentenceNoPalindrome_ReturnsFalse()
+ {
+ CaseInsensitiveCheckFail(PalindromeExamples.NoPalindromeSentences);
+ }
+
+ private static void CaseInsensitiveCheckFail(IEnumerable palindromes)
+ {
+ foreach (var palindrome in palindromes)
+ {
+ if (Palindrome.IsPalindrome(palindrome, true))
+ {
+ Assert.Fail("{0} is for some reason classified as a palindrome", palindrome);
+ }
+ }
+ }
+
+ private static void CaseInsensitiveCheckSucceed(IEnumerable palindromes)
+ {
+ foreach (var palindrome in palindromes)
+ {
+ if (!Palindrome.IsPalindrome(palindrome, true))
+ {
+ Assert.Fail("{0} is no palindrome", palindrome);
+ }
+ }
+ }
+
+ private static void CaseSensitiveCheckFail(IEnumerable palindromes)
+ {
+ foreach (var palindrome in palindromes)
+ {
+ if (Palindrome.IsPalindrome(palindrome))
+ {
+ Assert.Fail("{0} is for some reason classified as a palindrome", palindrome);
+ }
+ }
+ }
+
+ private static void CaseSensitiveCheckSucceed(IEnumerable palindromes)
+ {
+ foreach (var palindrome in palindromes)
+ {
+ if (!Palindrome.IsPalindrome(palindrome))
+ {
+ Assert.Fail("{0} is no palindrome", palindrome);
+ }
+ }
+ }
+ }
+}
diff --git "a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Bin\303\244rsuche/Bin\303\244rsuche.csproj" "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Bin\303\244rsuche/Bin\303\244rsuche.csproj"
new file mode 100644
index 00000000..d224b7b9
--- /dev/null
+++ "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Bin\303\244rsuche/Bin\303\244rsuche.csproj"
@@ -0,0 +1,11 @@
+
+
+
+ netcoreapp3.1
+
+
+
+
+
+
+
diff --git "a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Bin\303\244rsuche/DivideAndConquer.cs" "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Bin\303\244rsuche/DivideAndConquer.cs"
new file mode 100644
index 00000000..6a909c53
--- /dev/null
+++ "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Bin\303\244rsuche/DivideAndConquer.cs"
@@ -0,0 +1,97 @@
+using Infrastructure.Module;
+using System;
+using System.Linq;
+
+namespace Binärsuche
+{
+ public class DivideAndConquer : BaseModule
+ {
+ public DivideAndConquer(string moduleName) : base(moduleName)
+ {
+ }
+
+ protected override void Process()
+ {
+ var searchArea = DivideAndConquerHelper.GetSearchAreaAlphabet();
+ DisplaySearchArea(searchArea);
+
+ var selectedChar = ' ';
+ while (selectedChar == ' ')
+ {
+ Console.WriteLine("Enter the alphabetical letter you want to search for");
+
+ var input = Console.ReadKey();
+ if (searchArea.Contains(char.ToUpper(input.KeyChar)))
+ {
+ selectedChar = char.ToUpper(input.KeyChar);
+ continue;
+ }
+
+ Console.WriteLine("Error: Invalid input detected! Choose and press a character from >> {0}", DivideAndConquerHelper.Alphabet);
+ }
+
+ if (Search(searchArea, selectedChar, false))
+ {
+ DisplaySearchFound(selectedChar);
+ }
+ else
+ {
+ DisplaySearchNotFound(selectedChar);
+ }
+ }
+
+ public static bool Search(char[] searchArea, char searchChar, bool ordered = true)
+ {
+ if (!ordered)
+ {
+ searchArea = searchArea.OrderBy(x => x).ToArray();
+ }
+
+ DisplaySearchArea(searchArea);
+
+ if (searchArea.Length == 1)
+ {
+ return searchArea[0] == searchChar;
+ }
+
+ var found = false;
+ var middle = (int)Math.Floor(searchArea.Length / 2d);
+ if (searchArea[middle] == searchChar)
+ {
+ return true;
+ }
+ else
+ {
+ if (searchChar > searchArea[middle])
+ {
+ if (searchArea.Length <= 2)
+ return false;
+
+ found = Search(searchArea[(middle + 1)..], searchChar);
+ }
+ else
+ {
+ found = Search(searchArea[0..middle], searchChar);
+ }
+ }
+
+ return found;
+ }
+
+ private static void DisplaySearchArea(char[] searchArea)
+ {
+ Console.WriteLine("\nSearch area:");
+ Console.WriteLine(string.Join(" ", searchArea));
+ }
+
+ private static void DisplaySearchFound(char searchChar)
+ {
+ Console.WriteLine("\nSuccess: Found character! >> {0}", searchChar);
+ }
+
+ private static void DisplaySearchNotFound(char searchChar)
+ {
+ Console.WriteLine("\nError: Selected character could not be found! >> {0}", searchChar);
+ }
+ }
+}
diff --git "a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Bin\303\244rsuche/DivideAndConquerHelper.cs" "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Bin\303\244rsuche/DivideAndConquerHelper.cs"
new file mode 100644
index 00000000..1d63dea9
--- /dev/null
+++ "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Bin\303\244rsuche/DivideAndConquerHelper.cs"
@@ -0,0 +1,16 @@
+using Infrastructure;
+
+namespace Binärsuche
+{
+ public class DivideAndConquerHelper
+ {
+ public static string Alphabet { get; } = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ public static char[] GetSearchAreaAlphabet()
+ {
+ var searchArea = Alphabet.ToCharArray();
+ searchArea.Shuffle();
+ return searchArea;
+ }
+ }
+}
diff --git "a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Bin\303\244rsucheTest/Bin\303\244rsucheTest.csproj" "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Bin\303\244rsucheTest/Bin\303\244rsucheTest.csproj"
new file mode 100644
index 00000000..7f536088
--- /dev/null
+++ "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Bin\303\244rsucheTest/Bin\303\244rsucheTest.csproj"
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp3.1
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git "a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Bin\303\244rsucheTest/DivideAndConquerTest.cs" "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Bin\303\244rsucheTest/DivideAndConquerTest.cs"
new file mode 100644
index 00000000..d3b0c30b
--- /dev/null
+++ "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Bin\303\244rsucheTest/DivideAndConquerTest.cs"
@@ -0,0 +1,82 @@
+using Binärsuche;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace BinärsucheTest
+{
+ [TestClass]
+ public class DivideAndConquerTest
+ {
+ [TestMethod]
+ public void Search_LetterA_ReturnsTrue()
+ {
+ if (!DivideAndConquer.Search(DivideAndConquerHelper.GetSearchAreaAlphabet(), 'A', false))
+ {
+ Assert.Fail("Character 'A' could not be found!");
+ }
+ }
+
+ [TestMethod]
+ public void Search_LetterZ_ReturnsTrue()
+ {
+ if (!DivideAndConquer.Search(DivideAndConquerHelper.GetSearchAreaAlphabet(), 'Z', false))
+ {
+ Assert.Fail("Character 'Z' could not be found!");
+ }
+ }
+
+ [TestMethod]
+ public void Search_LetterN_ReturnsTrue()
+ {
+ if (!DivideAndConquer.Search(DivideAndConquerHelper.GetSearchAreaAlphabet(), 'N', false))
+ {
+ Assert.Fail("Character 'N' could not be found!");
+ }
+ }
+
+ [TestMethod]
+ public void Search_LetterO_ReturnsTrue()
+ {
+ if (!DivideAndConquer.Search(DivideAndConquerHelper.GetSearchAreaAlphabet(), 'O', false))
+ {
+ Assert.Fail("Character 'O' could not be found!");
+ }
+ }
+
+ [TestMethod]
+ public void Search_LetterL_ReturnsTrue()
+ {
+ if (!DivideAndConquer.Search(DivideAndConquerHelper.GetSearchAreaAlphabet(), 'L', false))
+ {
+ Assert.Fail("Character 'L' could not be found!");
+ }
+ }
+
+ [TestMethod]
+ public void Search_LetterLowerA_ReturnsFalse()
+ {
+ if (DivideAndConquer.Search(DivideAndConquerHelper.GetSearchAreaAlphabet(), 'a', false))
+ {
+ Assert.Fail("Character 'a' was found!");
+ }
+ }
+
+ [TestMethod]
+ public void Search_LetterLowerN_ReturnsFalse()
+ {
+ if (DivideAndConquer.Search(DivideAndConquerHelper.GetSearchAreaAlphabet(), 'n', false))
+ {
+ Assert.Fail("Character 'n' was found!");
+ }
+ }
+
+
+ [TestMethod]
+ public void Search_Numeric1_ReturnsFalse()
+ {
+ if (DivideAndConquer.Search(DivideAndConquerHelper.GetSearchAreaAlphabet(), '1', false))
+ {
+ Assert.Fail("Character '1' was found!");
+ }
+ }
+ }
+}
diff --git "a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Fakult\303\244t/Factorial.cs" "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Fakult\303\244t/Factorial.cs"
new file mode 100644
index 00000000..8696003f
--- /dev/null
+++ "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Fakult\303\244t/Factorial.cs"
@@ -0,0 +1,38 @@
+using Infrastructure.Module;
+using System;
+
+namespace Fakultät
+{
+ public class Factorial : BaseModule
+ {
+ public Factorial(string moduleName) : base(moduleName)
+ {
+ }
+
+ protected override void Process()
+ {
+ Console.WriteLine("Enter your number to calculate the factorial");
+ var numberInput = Console.ReadLine();
+
+ var isValidNumber = int.TryParse(numberInput, out int number);
+ if (!isValidNumber || number < 0)
+ {
+ Console.WriteLine("Error: Invalid input detected! Enter a single non-negative integer number.");
+ Process();
+ return;
+ }
+
+ var result = CalculateFactorial(number);
+ Console.WriteLine("The factorial of {0} is {1}", number, result);
+ }
+
+ public static int CalculateFactorial(int number)
+ {
+ if (number <= 1)
+ return 1;
+
+ return number * CalculateFactorial(number - 1);
+ }
+ }
+}
+
diff --git "a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Fakult\303\244t/Fakult\303\244t.csproj" "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Fakult\303\244t/Fakult\303\244t.csproj"
new file mode 100644
index 00000000..d224b7b9
--- /dev/null
+++ "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Fakult\303\244t/Fakult\303\244t.csproj"
@@ -0,0 +1,11 @@
+
+
+
+ netcoreapp3.1
+
+
+
+
+
+
+
diff --git "a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Fakult\303\244tTest/FactorialTest.cs" "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Fakult\303\244tTest/FactorialTest.cs"
new file mode 100644
index 00000000..0ab45de1
--- /dev/null
+++ "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Fakult\303\244tTest/FactorialTest.cs"
@@ -0,0 +1,59 @@
+using Fakultät;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace FakultätTest
+{
+ [TestClass]
+ public class FactorialTest
+ {
+ [TestMethod]
+ public void CalculateFactorial_5Is120_ReturnsTrue()
+ {
+ var result = Factorial.CalculateFactorial(5);
+ if (result != 120)
+ {
+ Assert.Fail("Factorial of result {0} is not {1} but {2} which is wrong.", 5, 120, result);
+ }
+ }
+
+ [TestMethod]
+ public void CalculateFactorial_9Is362880_ReturnsTrue()
+ {
+ var result = Factorial.CalculateFactorial(9);
+ if (result != 362880)
+ {
+ Assert.Fail("Factorial result of {0} is not {1} but {2} which is wrong.", 9, 362880, result);
+ }
+ }
+
+ [TestMethod]
+ public void CalculateFactorial_1Is1_ReturnsTrue()
+ {
+ var result = Factorial.CalculateFactorial(1);
+ if (result != 1)
+ {
+ Assert.Fail("Factorial result of {0} is not {1} but {2} which is wrong.", 1, 1, result);
+ }
+ }
+
+ [TestMethod]
+ public void CalculateFactorial_0Is1_ReturnsTrue()
+ {
+ var result = Factorial.CalculateFactorial(0);
+ if (result != 1)
+ {
+ Assert.Fail("Factorial result of {0} is not {1} but {2} which is wrong.", 0, 1, result);
+ }
+ }
+
+ [TestMethod]
+ public void CalculateFactorial_3Is1231321_ReturnsFalse()
+ {
+ var result = Factorial.CalculateFactorial(3);
+ if (result == 1231321)
+ {
+ Assert.Fail("Factorial result of {0} is not {1}.", 3, 1231321);
+ }
+ }
+ }
+}
diff --git "a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Fakult\303\244tTest/Fakult\303\244tTest.csproj" "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Fakult\303\244tTest/Fakult\303\244tTest.csproj"
new file mode 100644
index 00000000..4db51e54
--- /dev/null
+++ "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Fakult\303\244tTest/Fakult\303\244tTest.csproj"
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp3.1
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Infrastructure/Extensions.cs b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Infrastructure/Extensions.cs
new file mode 100644
index 00000000..f8afc766
--- /dev/null
+++ b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Infrastructure/Extensions.cs
@@ -0,0 +1,33 @@
+using System.Collections.Generic;
+
+namespace Infrastructure
+{
+ public static class StackExtensions
+ {
+ public static void AddRange(this Stack stack, IEnumerable range)
+ {
+ if (range is null)
+ return;
+
+ foreach (var item in range)
+ {
+ stack.Push(item);
+ }
+ }
+ }
+
+ public static class ArrayExtensions
+ {
+ public static void Shuffle(this T[] array)
+ {
+ var n = array.Length;
+ while (n > 1)
+ {
+ var k = Helper.Rng.Next(n--);
+ var temp = array[n];
+ array[n] = array[k];
+ array[k] = temp;
+ }
+ }
+ }
+}
diff --git a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Infrastructure/Helper.cs b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Infrastructure/Helper.cs
new file mode 100644
index 00000000..e5060fe5
--- /dev/null
+++ b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Infrastructure/Helper.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Infrastructure
+{
+ public static class Helper
+ {
+ public static Random Rng { get; } = new Random((int)(DateTime.Now - new DateTime(1994, 7, 8)).TotalMilliseconds);
+ }
+}
diff --git a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Infrastructure/Infrastructure.csproj b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Infrastructure/Infrastructure.csproj
new file mode 100644
index 00000000..cb631906
--- /dev/null
+++ b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Infrastructure/Infrastructure.csproj
@@ -0,0 +1,7 @@
+
+
+
+ netcoreapp3.1
+
+
+
diff --git a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Infrastructure/Module/BaseModule.cs b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Infrastructure/Module/BaseModule.cs
new file mode 100644
index 00000000..61bd14e6
--- /dev/null
+++ b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Infrastructure/Module/BaseModule.cs
@@ -0,0 +1,29 @@
+using System;
+
+namespace Infrastructure.Module
+{
+ public abstract class BaseModule : IModule
+ {
+ public string ModuleName { get; set; } = "Module name not set";
+
+ public BaseModule(string moduleName)
+ {
+ ModuleName = moduleName;
+ }
+
+ public void Run()
+ {
+ Console.WriteLine("\n{0}", ModuleName);
+
+ Process();
+
+ Console.WriteLine("Press any key to return to main menu...");
+ Console.ReadKey();
+ }
+
+ protected virtual void Process()
+ {
+ throw new NotImplementedException("Process has not been implemented!");
+ }
+ }
+}
diff --git a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Infrastructure/Module/IModule.cs b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Infrastructure/Module/IModule.cs
new file mode 100644
index 00000000..0054fa0f
--- /dev/null
+++ b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Infrastructure/Module/IModule.cs
@@ -0,0 +1,7 @@
+namespace Infrastructure.Module
+{
+ public interface IModule
+ {
+ void Run();
+ }
+}
diff --git a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Rekursion.sln b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Rekursion.sln
new file mode 100644
index 00000000..c1d81bfd
--- /dev/null
+++ b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Rekursion.sln
@@ -0,0 +1,80 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31112.23
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Rekursion", "Rekursion\Rekursion.csproj", "{748BBCB5-2CA5-4571-9530-1D06104BE2C6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fakultät", "Fakultät\Fakultät.csproj", "{95FF8E7A-3726-4ADB-94F2-3FDA64F52B3D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Binärsuche", "Binärsuche\Binärsuche.csproj", "{E12CC3CF-56C4-4299-B248-BC4308C828E9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TürmeVonHanoi", "TürmeVonHanoi\TürmeVonHanoi.csproj", "{4DB20433-2B2B-4086-800A-99019A89D5C7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Infrastructure", "Infrastructure\Infrastructure.csproj", "{E64CDFA2-8417-4F0D-9C0D-35CBA5F5C477}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FakultätTest", "FakultätTest\FakultätTest.csproj", "{578BB47D-FB88-4A6D-B681-7B089DB6B14E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BinärsucheTest", "BinärsucheTest\BinärsucheTest.csproj", "{9419840B-1994-4D25-9396-FBB7F677A2D6}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{539B0966-C6E0-4F8B-B48F-81E167A7C3E4}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTests", "UnitTests", "{C4278130-82C3-4600-8260-D7881E201D77}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TürmeVonHanoiTest", "TürmeVonHanoiTest\TürmeVonHanoiTest.csproj", "{4D3AFF0A-5AF6-4781-8380-03978628A9A6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {748BBCB5-2CA5-4571-9530-1D06104BE2C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {748BBCB5-2CA5-4571-9530-1D06104BE2C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {748BBCB5-2CA5-4571-9530-1D06104BE2C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {748BBCB5-2CA5-4571-9530-1D06104BE2C6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {95FF8E7A-3726-4ADB-94F2-3FDA64F52B3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {95FF8E7A-3726-4ADB-94F2-3FDA64F52B3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {95FF8E7A-3726-4ADB-94F2-3FDA64F52B3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {95FF8E7A-3726-4ADB-94F2-3FDA64F52B3D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E12CC3CF-56C4-4299-B248-BC4308C828E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E12CC3CF-56C4-4299-B248-BC4308C828E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E12CC3CF-56C4-4299-B248-BC4308C828E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E12CC3CF-56C4-4299-B248-BC4308C828E9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4DB20433-2B2B-4086-800A-99019A89D5C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4DB20433-2B2B-4086-800A-99019A89D5C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4DB20433-2B2B-4086-800A-99019A89D5C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4DB20433-2B2B-4086-800A-99019A89D5C7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E64CDFA2-8417-4F0D-9C0D-35CBA5F5C477}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E64CDFA2-8417-4F0D-9C0D-35CBA5F5C477}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E64CDFA2-8417-4F0D-9C0D-35CBA5F5C477}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E64CDFA2-8417-4F0D-9C0D-35CBA5F5C477}.Release|Any CPU.Build.0 = Release|Any CPU
+ {578BB47D-FB88-4A6D-B681-7B089DB6B14E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {578BB47D-FB88-4A6D-B681-7B089DB6B14E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {578BB47D-FB88-4A6D-B681-7B089DB6B14E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {578BB47D-FB88-4A6D-B681-7B089DB6B14E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9419840B-1994-4D25-9396-FBB7F677A2D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9419840B-1994-4D25-9396-FBB7F677A2D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9419840B-1994-4D25-9396-FBB7F677A2D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9419840B-1994-4D25-9396-FBB7F677A2D6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4D3AFF0A-5AF6-4781-8380-03978628A9A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4D3AFF0A-5AF6-4781-8380-03978628A9A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4D3AFF0A-5AF6-4781-8380-03978628A9A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4D3AFF0A-5AF6-4781-8380-03978628A9A6}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {95FF8E7A-3726-4ADB-94F2-3FDA64F52B3D} = {539B0966-C6E0-4F8B-B48F-81E167A7C3E4}
+ {E12CC3CF-56C4-4299-B248-BC4308C828E9} = {539B0966-C6E0-4F8B-B48F-81E167A7C3E4}
+ {4DB20433-2B2B-4086-800A-99019A89D5C7} = {539B0966-C6E0-4F8B-B48F-81E167A7C3E4}
+ {578BB47D-FB88-4A6D-B681-7B089DB6B14E} = {C4278130-82C3-4600-8260-D7881E201D77}
+ {9419840B-1994-4D25-9396-FBB7F677A2D6} = {C4278130-82C3-4600-8260-D7881E201D77}
+ {C4278130-82C3-4600-8260-D7881E201D77} = {539B0966-C6E0-4F8B-B48F-81E167A7C3E4}
+ {4D3AFF0A-5AF6-4781-8380-03978628A9A6} = {C4278130-82C3-4600-8260-D7881E201D77}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {F309A75B-6FE5-4066-A324-58BB482B1684}
+ EndGlobalSection
+EndGlobal
diff --git a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Rekursion/Program.cs b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Rekursion/Program.cs
new file mode 100644
index 00000000..4a510338
--- /dev/null
+++ b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Rekursion/Program.cs
@@ -0,0 +1,63 @@
+using Binärsuche;
+using Fakultät;
+using System;
+using TürmeVonHanoi;
+
+namespace Rekursion
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ var moduleFactorial = new Factorial("1 - Fakultät");
+ var moduleDivideAndConquer = new DivideAndConquer("2 - Binärsuche");
+ var moduleTowerOfHanoi = new TowerOfHanoi("3 - Türme von Hanoi");
+
+ var run = true;
+ while (run)
+ {
+ Console.Clear();
+ Console.WriteLine("Welcome to 'Rekursion'. Please select a module:");
+ Console.WriteLine("F: '{0}'", moduleFactorial.ModuleName);
+ Console.WriteLine("B: '{0}'", moduleDivideAndConquer.ModuleName);
+ Console.WriteLine("T: '{0}'", moduleTowerOfHanoi.ModuleName);
+ Console.WriteLine("Q: Quit program");
+
+ var input = Console.ReadKey();
+ switch (input.Key)
+ {
+ case ConsoleKey.NumPad1:
+ case ConsoleKey.D1:
+ case ConsoleKey.F:
+ {
+ moduleFactorial.Run();
+ break;
+ }
+ case ConsoleKey.NumPad2:
+ case ConsoleKey.D2:
+ case ConsoleKey.B:
+ {
+ moduleDivideAndConquer.Run();
+ break;
+ }
+ case ConsoleKey.NumPad3:
+ case ConsoleKey.D3:
+ case ConsoleKey.T:
+ {
+ moduleTowerOfHanoi.Run();
+ break;
+ }
+ case ConsoleKey.Q:
+ {
+ run = false;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Rekursion/Rekursion.csproj b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Rekursion/Rekursion.csproj
new file mode 100644
index 00000000..0e47b22e
--- /dev/null
+++ b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/Rekursion/Rekursion.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ netcoreapp3.1
+
+
+
+
+
+
+
+
+
diff --git "a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoi/GameDisk.cs" "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoi/GameDisk.cs"
new file mode 100644
index 00000000..029a92b4
--- /dev/null
+++ "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoi/GameDisk.cs"
@@ -0,0 +1,12 @@
+namespace TürmeVonHanoi
+{
+ public class GameDisk
+ {
+ public int Size { get; set; }
+
+ public GameDisk(int size)
+ {
+ Size = size;
+ }
+ }
+}
diff --git "a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoi/GameStack.cs" "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoi/GameStack.cs"
new file mode 100644
index 00000000..56887d1b
--- /dev/null
+++ "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoi/GameStack.cs"
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace TürmeVonHanoi
+{
+ public class GameStack
+ {
+ public Stack Content = new Stack();
+ }
+}
diff --git "a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoi/TowerOfHanoi.cs" "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoi/TowerOfHanoi.cs"
new file mode 100644
index 00000000..573a964c
--- /dev/null
+++ "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoi/TowerOfHanoi.cs"
@@ -0,0 +1,156 @@
+using Infrastructure;
+using Infrastructure.Module;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace TürmeVonHanoi
+{
+ public class TowerOfHanoi : BaseModule
+ {
+ public TowerOfHanoi(string moduleName, bool solved = false) : base(moduleName)
+ {
+ if (solved)
+ {
+ // Init last stack with all disks in correct order
+ _gameStacks[^1].Content.AddRange(_gameDisks.OrderByDescending(x => x.Size).ToList());
+ }
+ }
+
+ private readonly List _gameStacks = new List()
+ {
+ new GameStack(),
+ new GameStack(),
+ new GameStack(),
+ };
+
+ private readonly List _gameDisks = new List()
+ {
+ new GameDisk(1),
+ new GameDisk(2),
+ new GameDisk(3),
+ new GameDisk(4),
+ new GameDisk(5),
+ new GameDisk(6),
+ new GameDisk(7),
+ new GameDisk(8),
+ };
+
+ protected override void Process()
+ {
+ // Init first stack with all disks
+ _gameStacks[0].Content.AddRange(_gameDisks.OrderByDescending(x => x.Size).ToList());
+
+ ProcessGame();
+ }
+
+ private void ProcessGame()
+ {
+ DisplayGameBoard();
+
+ if (!EvaluateUserInput())
+ {
+ Console.WriteLine("Press any key to try again...");
+ Console.ReadKey();
+ }
+
+ if (CheckWinCondition())
+ {
+ DisplayGameBoard();
+ Console.WriteLine("-------------------------");
+ Console.WriteLine("Congratulations you won!");
+ Console.WriteLine("-------------------------");
+ return;
+ }
+
+ ProcessGame();
+ }
+
+ private bool EvaluateUserInput()
+ {
+ Console.WriteLine("\nSelect a stack to take from (1/2/3...)");
+ var input = Console.ReadLine();
+
+ var isValidInput = int.TryParse(input, out int selectedStackTake);
+ if (!isValidInput || selectedStackTake < 1 || selectedStackTake > _gameStacks.Count)
+ {
+ Console.WriteLine("Error: Invalid input detected! >> {0}", input);
+ return false;
+ }
+
+ if (!_gameStacks[selectedStackTake - 1].Content.Any())
+ {
+ Console.WriteLine("Error: Invalid operation detected >> Stack {0} is empty!", selectedStackTake);
+ return false;
+ }
+
+ var selectedDisk = _gameStacks[selectedStackTake - 1].Content.Peek();
+
+ Console.WriteLine("Select a stack (1/2/3...) to place selected disk (size {0})", selectedDisk.Size);
+ input = Console.ReadLine();
+
+ isValidInput = int.TryParse(input, out int selectedStackPlace);
+ if (!isValidInput || selectedStackPlace < 1 || selectedStackPlace > _gameStacks.Count)
+ {
+ Console.WriteLine("Error: Invalid input detected! >> {0}", input);
+ return false;
+ }
+
+ if (selectedStackPlace == selectedStackTake)
+ {
+ Console.WriteLine("Error: Invalid operation detected. >> Same stack selected {0}!", selectedStackTake);
+ return false;
+ }
+
+ var selectedStackPlaceContent = _gameStacks[selectedStackPlace - 1].Content;
+ if (selectedStackPlaceContent.Any() && selectedStackPlaceContent.Peek().Size < selectedDisk.Size)
+ {
+ Console.WriteLine("Error: Invalid operation detected. >> Stack already contains a smaller disk! {0} > {1}",
+ selectedDisk.Size,
+ selectedStackPlaceContent.Peek().Size);
+ return false;
+ }
+
+ var gameDisk = _gameStacks[selectedStackTake - 1].Content.Pop();
+ _gameStacks[selectedStackPlace - 1].Content.Push(gameDisk);
+
+ return true;
+ }
+
+ private void DisplayGameBoard()
+ {
+ Console.Clear();
+ Console.WriteLine(ModuleName);
+
+ for (var i = 0; i < _gameStacks.Count; i++)
+ {
+ Console.Write("\nStack {0}:", i + 1);
+
+ foreach (var disk in _gameStacks[i].Content.Reverse())
+ {
+ Console.Write("|-{0}-|", disk.Size);
+ }
+ }
+
+ Console.WriteLine();
+ }
+
+ private bool CheckWinCondition()
+ {
+ var lastStackDisks = _gameStacks.Last().Content;
+ if (lastStackDisks.Count != _gameDisks.Count)
+ return false;
+
+ var expectedSize = _gameDisks.Max(x => x.Size);
+ foreach (var disk in lastStackDisks.Reverse())
+ {
+ if (disk.Size != expectedSize)
+ return false;
+
+ expectedSize--;
+ }
+
+ return true;
+ }
+ }
+}
diff --git "a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoi/T\303\274rmeVonHanoi.csproj" "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoi/T\303\274rmeVonHanoi.csproj"
new file mode 100644
index 00000000..d224b7b9
--- /dev/null
+++ "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoi/T\303\274rmeVonHanoi.csproj"
@@ -0,0 +1,11 @@
+
+
+
+ netcoreapp3.1
+
+
+
+
+
+
+
diff --git "a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoiTest/TowerOfHanoiTest.cs" "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoiTest/TowerOfHanoiTest.cs"
new file mode 100644
index 00000000..b079a399
--- /dev/null
+++ "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoiTest/TowerOfHanoiTest.cs"
@@ -0,0 +1,38 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Reflection;
+using TürmeVonHanoi;
+
+namespace TürmeVonHanoiTest
+{
+ [TestClass]
+ public class TowerOfHanoiTest
+ {
+ [TestMethod]
+ public void CheckWinCondition_ConditionMet_ReturnsTrue()
+ {
+ var towerOfHanoi = new TowerOfHanoi("Tower of Hanoi test", true);
+
+ var checkWinConditionMethod = typeof(TowerOfHanoi).GetMethod("CheckWinCondition", BindingFlags.NonPublic | BindingFlags.Instance);
+
+ var result = (bool)checkWinConditionMethod.Invoke(towerOfHanoi, new object[] { });
+ if (!result)
+ {
+ Assert.Fail("Win condition is not met for some reason!");
+ }
+ }
+
+ [TestMethod]
+ public void CheckWinCondition_ConditionNotMet_ReturnsFalse()
+ {
+ var towerOfHanoi = new TowerOfHanoi("Tower of Hanoi test");
+
+ var checkWinConditionMethod = typeof(TowerOfHanoi).GetMethod("CheckWinCondition", BindingFlags.NonPublic | BindingFlags.Instance);
+
+ var result = (bool)checkWinConditionMethod.Invoke(towerOfHanoi, new object[] { });
+ if (result)
+ {
+ Assert.Fail("Win condition is met for some reason!");
+ }
+ }
+ }
+}
diff --git "a/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoiTest/T\303\274rmeVonHanoiTest.csproj" "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoiTest/T\303\274rmeVonHanoiTest.csproj"
new file mode 100644
index 00000000..06113f18
--- /dev/null
+++ "b/katas/Rekursion/solutions/MarcelSchmidt/Rekursion/T\303\274rmeVonHanoiTest/T\303\274rmeVonHanoiTest.csproj"
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp3.1
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+