Last active
March 1, 2019 15:25
-
-
Save Ilchert/1605b071eb18d4e8c595fc4db237f565 to your computer and use it in GitHub Desktop.
Combination task on long
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 System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Linq; | |
using System.Runtime.ConstrainedExecution; | |
using System.Runtime.InteropServices; | |
using System.Security; | |
using System.Text; | |
using System.Threading; | |
using System.Threading.Tasks; | |
namespace ConsoleApp | |
{ | |
class Program | |
{ | |
private const int DataSize = 80000; | |
private const int DataItemSize = 20; | |
static void Main() | |
{ | |
var sw = new Stopwatch(); | |
sw.Start(); | |
var comparer = Comparer<long>.Default; | |
var data = PrepareData(comparer); | |
sw.Stop(); | |
Console.WriteLine(sw.Elapsed); | |
sw.Restart(); | |
const int firstIndex = 0; | |
const int lastIndex = DataItemSize - 1; | |
for (int leftIndex = 0; leftIndex < DataSize - 1; leftIndex++) | |
{ | |
var boundsExceed = false; | |
for (int rightIndex = leftIndex + 1; rightIndex < DataSize; rightIndex++) | |
{ | |
var resultItem = new ResultItem(leftIndex, rightIndex); | |
var left = data[leftIndex]; | |
var right = data[rightIndex]; | |
if (boundsExceed) | |
{ | |
Out(resultItem); | |
continue; | |
} | |
//hot path | |
var boundComp = left[lastIndex].CompareTo(right[firstIndex]); | |
if (boundComp < 0) | |
{ | |
Out(resultItem); | |
boundsExceed = true; | |
continue; | |
} | |
if (boundComp == 0) | |
{ | |
resultItem.ItemsCount = 1; | |
Out(resultItem); | |
continue; | |
} | |
//main comparison | |
var startLeft = InternalBinarySearch(left, right[firstIndex]); | |
if (startLeft < 0) | |
startLeft = ~startLeft; | |
var endRight = InternalBinarySearch(right, left[lastIndex]); | |
if (endRight < 0) | |
{ | |
endRight = Math.Min(~endRight, lastIndex); | |
} | |
byte itemsCount = 0; | |
var startRight = 0; | |
while (startLeft < DataItemSize && startRight <= endRight) | |
{ | |
var cmp = left[startLeft].CompareTo(right[startRight]); | |
if (cmp < 0) | |
{ | |
startLeft++; | |
} | |
else if (cmp > 0) | |
{ | |
startRight++; | |
} | |
else | |
{ | |
itemsCount++; | |
startLeft++; | |
startRight++; | |
} | |
} | |
resultItem.ItemsCount = itemsCount; | |
Out(resultItem); | |
} | |
} | |
Console.WriteLine(sw.Elapsed); | |
} | |
private static void Out(ResultItem item) | |
{ | |
} | |
internal static int InternalBinarySearch<T>( | |
long[] array, | |
T value) | |
{ | |
int index = 0; | |
int length = array.Length; | |
int num1 = index; | |
int num2 = index + length - 1; | |
while (num1 <= num2) | |
{ | |
int index1 = num1 + (num2 - num1 >> 1); | |
int num3 = array[index1].CompareTo(value); | |
if (num3 == 0) | |
return index1; | |
if (num3 < 0) | |
num1 = index1 + 1; | |
else | |
num2 = index1 - 1; | |
} | |
return ~num1; | |
} | |
public static long[][] PrepareData(IComparer<long> comparer) | |
{ | |
//prepare data | |
var data = new long[DataSize][]; | |
for (int i = 0; i < DataSize; i++) | |
{ | |
data[i] = new long[DataItemSize]; | |
for (int j = 0; j < DataItemSize; j++) | |
data[i][j] = RandomLong(); | |
} | |
//sort items | |
for (int i = 0; i < DataSize; i++) | |
Array.Sort(data[i], comparer); | |
//again sort | |
Array.Sort(data, (l, r) => comparer.Compare(l[0], r[0])); | |
return data; | |
} | |
public struct ResultItem | |
{ | |
public int LeftIndex; | |
public int RightIndex; | |
public byte ItemsCount; | |
public ResultItem(int leftIndex, int rightIndex) | |
{ | |
LeftIndex = leftIndex; | |
RightIndex = rightIndex; | |
ItemsCount = 0; | |
} | |
} | |
private static readonly Random random = new Random(); | |
public static long RandomLong() | |
{ | |
Span<byte> data = stackalloc byte[8]; | |
random.NextBytes(data); | |
return BitConverter.ToInt64(data) % 281474976710656; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment