Skip to content

Instantly share code, notes, and snippets.

@kunitsyn
Last active April 25, 2020 11:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kunitsyn/7f5fdbe17771fa4ec5c8b169017eef41 to your computer and use it in GitHub Desktop.
Save kunitsyn/7f5fdbe17771fa4ec5c8b169017eef41 to your computer and use it in GitHub Desktop.
Binary searching imaginary sorted merge of two sorted arrays
using System;
using System.Diagnostics;
using System.Linq;
namespace BinarySearchOlymp
{
class Program
{
enum ResultType { FOUND, NOT_FOUND };
struct BinarySearchResult { public ResultType type; public int index; };
private static int? FindIndexByValue(int[] array1, int[] array2, int targetValue)
{
var res1 = BinarySearch(array1, targetValue);
var res2 = BinarySearch(array2, targetValue);
if (res1.type == ResultType.FOUND || res2.type == ResultType.FOUND)
{
return res1.index + res2.index;
}
return null;
}
// returns found index or, if not found, how many elements are less than targetValue
private static BinarySearchResult BinarySearch(int[] array, int targetValue)
{
if (array.Length == 0)
{
return new BinarySearchResult() { type = ResultType.NOT_FOUND, index = 0 };
}
int l = 0;
int r = array.Length - 1;
while (l <= r)
{
int i = (l + r) / 2;
if (array[i] < targetValue) l = i + 1;
else if (array[i] > targetValue) r = i - 1;
else return new BinarySearchResult() { type = ResultType.FOUND, index = i };
}
if (l == array.Length)
{
return new BinarySearchResult() { type = ResultType.NOT_FOUND, index = array.Length };
}
if (array[l] < targetValue)
{
return new BinarySearchResult() { type = ResultType.NOT_FOUND, index = l + 1 };
}
return new BinarySearchResult() { type = ResultType.NOT_FOUND, index = l };
}
static void Main(string[] args)
{
Test(
new int[] { },
new int[] { },
33);
Test(
new int[] { 12, 17, 34, 42, 44, 46, 47, 51, 67, 89, 111, 116, 118, 163, 164, 177, 189, 192, 195, 197, 214, 217, 242, 244, 276, 280, 286, 291, 305, 308, 309 },
new int[] { 0, 0, 16, 17, 26, 29, 34, 41, 45, 66, 86, 89, 100, 103, 139, 164, 172, 184, 191, 192 },
163);
Test(
new int[] { 4 },
new int[] { 15, 42, 48, 56, 58, 74, 77, 80, 92, 93, 100, 102 },
92);
var r = new Random();
for (int i = 0; i < 200; i++)
{
int length1 = r.Next(50);
int length2 = r.Next(50);
int[] array1 = Enumerable.Range(1, length1).Select(x => r.Next(length1)).OrderBy(x => x).ToArray();
int[] array2 = Enumerable.Range(1, length2).Select(x => r.Next(length2)).OrderBy(x => x).ToArray();
int targetExistingValue = array1.Concat(array2).ElementAt(r.Next(length1 + length2));
Test(array1, array2, targetExistingValue);
int targetMissingValue = Enumerable.Range(1, length1 + length2 + 1).First(x => Array.IndexOf(array1, x) == -1 && Array.IndexOf(array2, x) == -1);
Test(array1, array2, targetMissingValue);
}
}
private static void Test(int[] array1, int[] array2, int targetValue)
{
int[] truth = FindIndexByValueGroundTruth(array1, array2, targetValue);
int? test = FindIndexByValue(array1, array2, targetValue);
if (test == null && truth.Length > 0)
{
Debug.WriteLine("not found where was supposed to find");
Debug.WriteLine("array1 = " + p(array1) + " array2 = " + p(array2) + " targetValue = " + targetValue + " truth = " + p(truth));
}
if (test != null && truth.Length == 0)
{
Debug.WriteLine("found where not supposed to find");
Debug.WriteLine("array1 = " + p(array1) + " array2 = " + p(array2) + " targetValue = " + targetValue + " test = " + test);
}
if (test != null && Array.IndexOf(truth, test) == -1)
{
Debug.WriteLine("found not correct");
Debug.WriteLine("array1 = " + p(array1) + " array2 = " + p(array2) + " targetValue = " + targetValue + " truth = " + p(truth) + " test = " + test);
}
}
private static int[] FindIndexByValueGroundTruth(int[] array1, int[] array2, int targetValue)
{
return array1.Concat(array2).OrderBy(x => x).Select((x, i) => new int[] { x, i }).Where((x, i) => x[0] == targetValue).Select(x => x[1]).ToArray();
}
private static string p(int[] array)
{
return string.Join(", ", array);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment