Created
February 24, 2023 08:46
-
-
Save savaged/bea80a7a930777b7c45e9f07a897f616 to your computer and use it in GitHub Desktop.
Fun C# Caesar Cipher command line tool in a functional programming style
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using CaesarCipher; | |
if (args?.Length > 0) | |
Console.WriteLine(args[0].Rot13()); | |
else | |
{ | |
Console.WriteLine("Start typing (Return key to exit)"); | |
PresentUntilReturnKey(); | |
} | |
static void PresentUntilReturnKey(char output = '\0') | |
{ | |
if (output != 0) | |
{ | |
if (output == '\r') return; | |
Present( | |
output, | |
Console.Write, | |
Console.GetCursorPosition, | |
Console.SetCursorPosition); | |
} | |
PresentUntilReturnKey(Console.ReadKey().Rot13()); | |
} | |
static void Present( | |
char output, | |
Action<string> writer, | |
Func<(int Left, int Top)> cursorPositionGetter, | |
Action<int, int> cursorPositionSetter) => | |
KeyPressPresenter.Present( | |
output, writer, cursorPositionGetter, cursorPositionSetter); | |
internal class KeyPressPresenter | |
{ | |
public static void Present( | |
char output, | |
Action<string> writer, | |
Func<(int Left, int Top)>? cursorPositionGetter = null, | |
Action<int, int>? cursorPositionSetter = null) | |
{ | |
if (output == 127) | |
{ | |
writer($"\b\b"); | |
return; | |
} | |
if (cursorPositionGetter == null | |
|| cursorPositionSetter == null) | |
{ | |
writer($"\b{output}"); | |
return; | |
} | |
Write(output, | |
cursorPositionGetter(), | |
writer, | |
cursorPositionSetter); | |
} | |
private static void Write( | |
char output, | |
(int Left, int Top) origPos, | |
Action<string> writer, | |
Action<int, int> cursorPositionSetter) | |
{ | |
SetPosition(cursorPositionSetter, origPos); | |
writer($"{output}"); | |
ResetPosition(cursorPositionSetter, origPos); | |
} | |
private static void SetPosition( | |
Action<int, int> cursorPositionSetter, | |
(int Left, int Top) origPos) | |
{ | |
try | |
{ | |
cursorPositionSetter(origPos.Left - 1, origPos.Top + 1); | |
} | |
catch (ArgumentOutOfRangeException) | |
{ | |
cursorPositionSetter(1, 1); | |
} | |
} | |
private static void ResetPosition( | |
Action<int, int> cursorPositionSetter, | |
(int Left, int Top) origPos) | |
{ | |
cursorPositionSetter(origPos.Left, origPos.Top); | |
} | |
} | |
namespace CaesarCipher | |
{ | |
public static class Extensions | |
{ | |
public static char[] Rot13(this string self) => | |
self.ToCharArray().Rot13(); | |
public static char Rot13(this ConsoleKeyInfo self) => | |
self.KeyChar.Rot13(); | |
private static char[] Rot13(this IEnumerable<char> self) => | |
self.Select(c => c.Rot13()).ToArray(); | |
private static char Rot13(this char self) => | |
self switch | |
{ | |
>= 'a' and <= 'm' or >= 'A' and <= 'M' => (char)(self + 13), | |
>= 'n' and <= 'z' or >= 'N' and <= 'Z' => (char)(self - 13), | |
_ => self | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment