-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit c867c49
Showing
2 changed files
with
238 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
ToyProblems | ||
=== | ||
|
||
This is a repository consisting of answers and explanations to potential interview questions and novel computer science problems. | ||
|
||
The purpose of this repository is not to provide a comprehensive collection of "prep work" nor to discover the most optimal solution to a problem, but to store and organize solutions I come up with that I find interesting so that I don't lose them. As such, | ||
- the organization and structure of this repository is subject to change | ||
- while the average problem is meant to be a novel or "bite-sized" programming problem which are common in interviews, you may find problems unlikely to appear on any interview | ||
|
||
# Table of Contents | ||
- [notebooks/](notebooks/) | ||
|
||
[Polyglot Notebooks](https://code.visualstudio.com/docs/languages/polyglot). Loosely organized by topic, for example | ||
|
||
- strings.ipynb | ||
- trees.dib | ||
- ... | ||
|
||
Some notebooks may be dedicated to an entire problem. Otherwise I will attempt to name problems in a notebook with the naming scheme `00 Name1`, `01 Name2`... etc. | ||
> **Note:** Notebooks can render an [`HtmlString`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.html.htmlstring) object in the output of the cell. It might be fun to define some .NET types in a dll that provide an `HtmlString` in some fashion and import them into a notebook. Therefore, this may affect the project structure and whether certain notebooks can run without colocated dependencies in the future. |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Strings\n", | ||
"===\n", | ||
"\n", | ||
"Problems where text parsing and maniuplation play a considerable role in the problem.\n", | ||
"\n", | ||
"You may note that, along with `string`s, you will often find `Span<char>` and `ReadOnlySpan<char>` littered around or entirely replacing `string`s in the problems. `Span<T>` types represent a strongly-typed (`T`) contiguous memory region that can be sliced into a new `Span<T>` and passed around around the stack, which makes them convenient for performing `string` manipulation without allocation overhead." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## 00 Longest Substring Palindrome in a String\n", | ||
"### Description\n", | ||
"...\n", | ||
"\n", | ||
"### Solution\n", | ||
"The general idea is to scan over the array once, checking for the centers of odd-length and even-length palindromes and expanding them as far out as we can. The bounds of the palindrome is kept instead of the `string` so that we don't have to keep reallocating when we find a longer one.\n", | ||
"\n", | ||
"You could optimize this by, if you have found a palindrome of length `m`, by not checking the (this might be slightly off) last `m` characters since you know anything you find won't be longer than what you have - but the general idea stays the same. " | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 1, | ||
"metadata": { | ||
"dotnet_interactive": { | ||
"language": "csharp" | ||
}, | ||
"polyglot_notebook": { | ||
"kernelName": "csharp" | ||
} | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"ReadOnlySpan<char> FindLongestPalindrome(ReadOnlySpan<char> maybePalindrome)\n", | ||
"{\n", | ||
" ReadOnlySpan<char> lookingGlass = stackalloc char[3]; // how many characters we scan at once\n", | ||
" var longestPalindromeBounds = (lower: 0, upper: 0); // bounds of longest string\n", | ||
" // so that we don't have to keep reallocating strings every time we find a longer one\n", | ||
"\n", | ||
" // shift lookingGlass through string, offsetting 1 at a time\n", | ||
" for (int i = 0;\n", | ||
" i < maybePalindrome.Length - lookingGlass.Length + 1;\n", | ||
" i++)\n", | ||
" {\n", | ||
" lookingGlass = maybePalindrome[i..(i + lookingGlass.Length)]; // shift glass\n", | ||
"\n", | ||
" // 2-ple palindrome\n", | ||
" if (lookingGlass[0] == lookingGlass[1])\n", | ||
" {\n", | ||
" TryFindLongestPalindrome((i, i + 1), maybePalindrome);\n", | ||
" }\n", | ||
" // 3-ple palindrome\n", | ||
" else if (lookingGlass[0] == lookingGlass[2])\n", | ||
" {\n", | ||
" TryFindLongestPalindrome((i, i + 2), maybePalindrome);\n", | ||
" }\n", | ||
" }\n", | ||
"\n", | ||
" // last 2-ple case gets skipped\n", | ||
" if (maybePalindrome.Length > 1\n", | ||
" && longestPalindromeBounds.upper - longestPalindromeBounds.lower < 2\n", | ||
" && lookingGlass[1] == lookingGlass[2])\n", | ||
" {\n", | ||
" longestPalindromeBounds = (maybePalindrome.Length - 2, maybePalindrome.Length);\n", | ||
" }\n", | ||
"\n", | ||
" void TryFindLongestPalindrome((int lower, int upper) bounds, ReadOnlySpan<char> maybePalindrome)\n", | ||
" {\n", | ||
" // get number of times palindrome could be expanded\n", | ||
" int len = GetCountOfPalindromeExpansion(bounds, maybePalindrome);\n", | ||
" // expand the bounds by larger size, adding 1 to capture ending bound as inclusive\n", | ||
" bounds = (bounds.lower - len, bounds.upper + len + 1);\n", | ||
"\n", | ||
" // if string longer\n", | ||
" if (bounds.upper - bounds.lower > longestPalindromeBounds.upper - longestPalindromeBounds.lower)\n", | ||
" longestPalindromeBounds = bounds; // set\n", | ||
"\n", | ||
" /// <summary>\n", | ||
" /// Try to expand a palindrome from its starting point until it is no longer symmetrical, then return the number of expansion steps we made\n", | ||
" /// </summary>\n", | ||
" static int GetCountOfPalindromeExpansion((int, int) start, ReadOnlySpan<char> str)\n", | ||
" {\n", | ||
" var (left, right) = start;\n", | ||
"\n", | ||
" int len = 0;\n", | ||
" // expand once\n", | ||
" left--;\n", | ||
" right++;\n", | ||
"\n", | ||
" for (; // increase length as long as symmetry is maintained\n", | ||
" left >= 0\n", | ||
" && right < str.Length\n", | ||
" && str[left] == str[right];\n", | ||
"\n", | ||
" left--, right++, len++) ;\n", | ||
"\n", | ||
" return len;\n", | ||
" }\n", | ||
" }\n", | ||
"\n", | ||
" return maybePalindrome[longestPalindromeBounds.lower..longestPalindromeBounds.upper];\n", | ||
"}" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"metadata": { | ||
"dotnet_interactive": { | ||
"language": "csharp" | ||
}, | ||
"polyglot_notebook": { | ||
"kernelName": "csharp" | ||
} | ||
}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/csv": [ | ||
"Source,Final\r\n", | ||
"wesleyracecarobama,racecar\r\n", | ||
",\r\n", | ||
"abcde,\r\n", | ||
"catcacrat,cac\r\n", | ||
"catracecarcacrat,racecar\r\n", | ||
"inevitable,\r\n", | ||
"llorange,ll\r\n", | ||
"0cn824gnmm,mm\r\n" | ||
], | ||
"text/html": [ | ||
"<table><thead><tr><td><span>Source</span></td><td><span>Final</span></td></tr></thead><tbody><tr><td>wesleyracecarobama</td><td>racecar</td></tr><tr><td></td><td></td></tr><tr><td>abcde</td><td></td></tr><tr><td>catcacrat</td><td>cac</td></tr><tr><td>catracecarcacrat</td><td>racecar</td></tr><tr><td>inevitable</td><td></td></tr><tr><td>llorange</td><td>ll</td></tr><tr><td>0cn824gnmm</td><td>mm</td></tr></tbody></table><style>\r\n", | ||
".dni-code-hint {\r\n", | ||
" font-style: italic;\r\n", | ||
" overflow: hidden;\r\n", | ||
" white-space: nowrap;\r\n", | ||
"}\r\n", | ||
".dni-treeview {\r\n", | ||
" white-space: nowrap;\r\n", | ||
"}\r\n", | ||
".dni-treeview td {\r\n", | ||
" vertical-align: top;\r\n", | ||
" text-align: start;\r\n", | ||
"}\r\n", | ||
"details.dni-treeview {\r\n", | ||
" padding-left: 1em;\r\n", | ||
"}\r\n", | ||
"table td {\r\n", | ||
" text-align: start;\r\n", | ||
"}\r\n", | ||
"table tr { \r\n", | ||
" vertical-align: top; \r\n", | ||
" margin: 0em 0px;\r\n", | ||
"}\r\n", | ||
"table tr td pre \r\n", | ||
"{ \r\n", | ||
" vertical-align: top !important; \r\n", | ||
" margin: 0em 0px !important;\r\n", | ||
"} \r\n", | ||
"table th {\r\n", | ||
" text-align: start;\r\n", | ||
"}\r\n", | ||
"</style>" | ||
] | ||
}, | ||
"metadata": {}, | ||
"output_type": "display_data" | ||
} | ||
], | ||
"source": [ | ||
"new List<string>()\n", | ||
"{\n", | ||
" \"wesleyracecarobama\",\n", | ||
" \"\",\n", | ||
" \"abcde\",\n", | ||
" \"catcacrat\",\n", | ||
" \"catracecarcacrat\",\n", | ||
" \"inevitable\",\n", | ||
" \"llorange\",\n", | ||
" \"0cn824gnmm\"\n", | ||
"}\n", | ||
".Select(s => new { Source = s, Final = FindLongestPalindrome(s).ToString() })\n", | ||
".DisplayTable()" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": ".NET (C#)", | ||
"language": "C#", | ||
"name": ".net-csharp" | ||
}, | ||
"language_info": { | ||
"name": "polyglot-notebook" | ||
}, | ||
"polyglot_notebook": { | ||
"kernelInfo": { | ||
"defaultKernelName": "csharp", | ||
"items": [ | ||
{ | ||
"aliases": [], | ||
"languageName": "csharp", | ||
"name": "csharp" | ||
} | ||
] | ||
} | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |