{"id":16120426,"url":"https://github.com/nadvolod/algorithms","last_synced_at":"2026-02-01T20:06:02.102Z","repository":{"id":147944261,"uuid":"466592221","full_name":"nadvolod/algorithms","owner":"nadvolod","description":"Algorithms and data-structures exercises","archived":false,"fork":false,"pushed_at":"2022-03-10T17:43:28.000Z","size":93,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-27T06:41:04.709Z","etag":null,"topics":["algorithms","data-structures"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nadvolod.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-05T23:39:09.000Z","updated_at":"2022-03-06T00:20:26.000Z","dependencies_parsed_at":"2023-05-28T02:00:23.983Z","dependency_job_id":null,"html_url":"https://github.com/nadvolod/algorithms","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/nadvolod/algorithms","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nadvolod%2Falgorithms","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nadvolod%2Falgorithms/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nadvolod%2Falgorithms/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nadvolod%2Falgorithms/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nadvolod","download_url":"https://codeload.github.com/nadvolod/algorithms/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nadvolod%2Falgorithms/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28988518,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-01T18:17:03.387Z","status":"ssl_error","status_checked_at":"2026-02-01T18:16:57.287Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorithms","data-structures"],"created_at":"2024-10-09T20:58:21.836Z","updated_at":"2026-02-01T20:06:02.065Z","avatar_url":"https://github.com/nadvolod.png","language":null,"readme":"# algorithms\n\nLet's practice coding algorithms together!\n\n## Caesar Cipher Encryptor\n\n### Prompt\n\nGiven a non-empty string of lowercase letters and a non-negative integer\n  representing a key, write a function that returns a new string obtained by\n  shifting every letter in the input string by k positions in the alphabet,\n  where k is the key.\n  \nMake sure you wrap around the alphabet\n  \n### Sample input\n\n```c#\nstring = \"xyz\"\nkey = 2\n```\n\n### Sample output\n\n```c#\n\"zab\"\n```\n\n### Initial planning\n\n1. way to implement this function is to use ASCII values. For example\n\n```c#\nint asciCode = (int)'a';\nstring asciStr = asciCode.ToString();\n//output is 97\n// z would be 122\n```\n\nSo to shift the letter by your key, we can do\n\n```c#\nint shiftedLetter = ((int)'a') + 2;\n// this will return 99\n```\n\nHowever, the crux is the wrapping that has to happen to return to the start of the alphabet. The solution would look like this.\n\n```c#\nint asciCode = ((int)'z') + 2;\nif(asciCode \u003c= 122)\n\treturn asciCode.ToString();\nelse\n\treturn ((char)(96 + asciCode % 122)).ToString();\n```\n\n`asciCode % 122` means that we're dividing something like 124/122 and getting a remainder of 2. Wrapping 2 means that our letter is going to be `b`. Hence, we\nneed to add the 2 to 96 to get to `b`.\n\n#### What happens if the `key` is a really large number like 54?\n\n54 = 26 + 26 + 2. So this means that the answer should be the same as above. But, `((int)'z') + 54 = 176`. \n\n`176 % 122 = 54` which is still greater than the 2 that we want to get to `b`.\n\nHence, our first step needs to be to mod the key, like this\n\n```c#\n// now the key will return the remainder, which is what we want\nint key = key % 26;\nint asciCode = ((int)'z') + key;\nif(asciCode \u003c= 122)\n\treturn asciCode.ToString();\nelse\n\treturn ((char)(96 + asciCode % 122)).ToString();\n```\n\n### Solution\n\n```c#\npublic static string getShiftedValue(char character, int key)\n{\n\tint asciCode = ((int)character) + key;\n\tif(asciCode \u003c= 122)\n\t\treturn ((char)asciCode).ToString();\n\telse\n\t\treturn ((char)(96 + asciCode % 122)).ToString();\n}\npublic static string CaesarCypherEncryptor(string str, int key) {\n\t// Write your code here.\n\tstring newStr=\"\";\n\tkey = key % 26;\n\tvar charArray = str.ToCharArray();\n\tforeach(var character in charArray){\n\t\tnewStr += getShiftedValue(character, key);\n\t}\n\treturn newStr;\n}\n```\n\n### Solution B\n\nWhat if we didn't want to use the `char` cast? Well we could create an array of values ourselves like this\n\n```c#\nvar letterDictionary = new Dictionary\u003cchar letter, int index\u003e();\nletterDictionary.Add('a', 0);\nletterDictionary.Add('b', 1);\n...\nletterDictionary.Add('z', 25);\n```\n\nHence, we'd need to update our algorithm a bit to look like this\n\nℹ️ Let's revisit this implementation in the future as it's not fully finished\n\n```c#\npublic static string getShiftedValue(char character, int key)\n{\n\tint incrementedChar = letterDictionary[character] + key;\n\tif(incrementedChar \u003c= 25)\n\t\treturn letterDictionary[character].ToString();\n\telse\n\t\treturn letterDictionary[character % 26].ToString();\n}\n\npublic static string CaesarCypherEncryptor(string str, int key) {\n\t// Write your code here.\n\tstring newStr=\"\";\n\tkey = key % 26;\n\tvar charArray = str.ToCharArray();\n\tforeach(var character in charArray){\n\t\tnewStr += getShiftedValue(character, key);\n\t}\n\treturn newStr;\n}\n```\n\nTime= O(n) where n is the length of the string\n\nSpace= O(n) \n\nWith an alphabet, our length is only 26. If our alphabet size changed, then we would have an O(m).\n\n## Subarray Sort\n\n### Prompt\n\n  Write a function that takes in an array of at least two integers and that\n  returns an array of the starting and ending indices of the smallest subarray\n  in the input array that needs to be sorted in place in order for the entire\n  input array to be sorted (in ascending order).\n\n### Sample input\n\n```c#\n[1,2,4,7,10,11,7,12,6,7,16,18,19]\n```\n\n### Sample output\n\n```c#\n[3,9]\n```\n\nIf we sort the input array above starting at index 3 aka 7 to index 9 aka 7, then the entire array will be sorted.\n\n### Input/output table\n\n| Input  | Expected output  |\n|---|---|\n| [1, 2, 4, 7, 10, 11, 7, 12, 6, 7, 16, 18, 19]  | [3, 9]  |\n| [1, 2]  | [-1, -1]  |\n| [2, 1]  | [0, 1]  |\n| [1, 2, 4, 7, 10, 11, 7, 12, 13, 14, 16, 18, 19]  | [4, 6]  |\n\n### Notes\n\n* There are always at least 2 numbers that are not sorted if 1 number is out of place. For example, [1,2,3,10,5,7], the 10 and the 5 need to move even though only the 10 is out of place.\n* Just having a single number out of place could force a huge sub-array to need sorting. For example [1,2,3,4,-1]. The -1 is out of place here. If we wanted to move it to the correct location of -1, then we would need to sort the entire array.\n\n[1,2,3,4,-1,7,10] - what part of this array would need to be sorted? Still the same as before [1,2,3,4,-1]. It's the [size of the smallest unsorted value and it's correct position, the value of the largest unsorted number]\n\nSo:\n\n1. We need to find all of the unsorted values\n2. Find the smallest unsorted value and it's sorted position in the array\n3. Find the largest unsorted value and it's final position in the array\n4. This will help to create the start and end of the array that needs to be sorted\n\n### An algorithm attempt\n\n```\n[0,1,2,3,4,  5,6,7, 8,9,10,11,12]\n[1,2,4,7,10,11,7,12,6,7,16,18,19]\n```\n ✅✅✅ ✅ ✅ ❌ ❌❌ ❌ ✅ ✅ ✅ ✅\n\nSorted (✅) means that the number before is smaller and the number after is bigger.\n\nUnsorted (❌)\n\nNow, we need to get the lowest and highest values that are unsorted. So, starting from the left 6 should come between [4,7]. Next, starting from the right, 12 should come between [7,16]. Hence, this gives us indices 3 to 9 that need to be sorted.\n\nSpace= O(1), it's constant space\nTime= O(n), where n is the length of the input array. We just need a single pass through the array\n\n### Solution A\n\n```c#\nusing System;\n\npublic class Program {\n\tpublic static int[] SubarraySort(int[] array) {\n\t\t// Write your code here.\n\t\tint minOutOfOrder = Int32.MaxValue;\n\t\tint maxOutOfOrder = Int32.MinValue;\n\t\t\n\t\t// this for loop is O(n) operation, n is the length of the array\n\t\tfor(int i=0; i \u003c array.Length; i++){\n\t\t\tint num = array[i];\n\t\t\tif(isOutOfOrder(i, num, array)){\n\t\t\t\t// we wanted to have the max value here initially so that any number evaluates to less than that\n\t\t\t\t// Min() returns the min from 2 ints\n\t\t\t\tminOutOfOrder = Math.Min(minOutOfOrder, num);\n\t\t\t\t//we wanted the min value so that on the first pass, any value will be larger \n\t\t\t\t//than initial maxOutOfOrder\n\t\t\t\tmaxOutOfOrder = Math.Max(maxOutOfOrder, num);\n\t\t\t}\n\t\t}\n\t\t// our array is already sorted if our default values haven't changed\n\t\tif (minOutOfOrder == Int32.MaxValue){\n\t\t\treturn new int[] {-1, -1};\n\t\t}\n\t\tint subarrayLeftIdx = 0;\n\t\t// 6 is our minOutOfOrder\n\t\t// starting at index 0 we move right while the condition is true\n\t\t// at one point, we reach 7 at index 3, so subarrayLeftIdx=3\n\t\t// because it's incremented at 1,2,4 and exits while loop at 7\n\t\t// O(n) operation as it's only dependent on array length\n\t\twhile (minOutOfOrder \u003e= array[subarrayLeftIdx]){\n\t\t\tsubarrayLeftIdx++;\n\t\t}\n\t\t// same logic as for the minOutOfOrder but we start on the right and work our way left\n\t\tint subarrayRightIdx = array.Length - 1;\n\t\t// O(n) operation as it's only dependent on array length\n\t\twhile (maxOutOfOrder \u003c= array[subarrayRightIdx]){\n\t\t\tsubarrayRightIdx--;\n\t\t}\n\t\t\n\t\treturn new int[] {subarrayLeftIdx, subarrayRightIdx};\n\t}\n\t\n\tpublic static bool isOutOfOrder(int i, int num, int[] array){\n\t\t// assert that the number is greater than the next one in the array\n\t\t// if so, then it's outOfOrder\n\t\tif(i==0){\n\t\t\treturn num \u003e array[i+1];\n\t\t}\n\t\t// if i is the last one in the array\n\t\tif(i==array.Length -1){\n\t\t\treturn num \u003c array[i-1];\n\t\t}\n\t\t// return true if our num is greater than the num on the right, or less than the num on the left\n\t\treturn num \u003e array[i+1] || num \u003c array[i-1];\n\t}\n}\n\n```\n\n### Test cases using above algorithm\n\nInput\n```\n{\n  \"array\": [1, 2, 4, 7, 10, 11, 7, 12, 6, 7, 16, 18, 19]\n}\n```\nOutput\n```\n[3, 9]\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnadvolod%2Falgorithms","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnadvolod%2Falgorithms","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnadvolod%2Falgorithms/lists"}