Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
johnW-ret committed Aug 10, 2023
0 parents commit c867c49
Show file tree
Hide file tree
Showing 2 changed files with 238 additions and 0 deletions.
20 changes: 20 additions & 0 deletions README.md
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.
218 changes: 218 additions & 0 deletions notebooks/strings.ipynb
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
}

0 comments on commit c867c49

Please sign in to comment.