public override Task <CollatzResponse> FindLongestSequence(CollatzRequest request, ServerCallContext context) { var tasks = new List <Task <(BigInteger value, int sequenceLength)> >(); var range = request.Start..request.End; var ranges = range.Partition(Environment.ProcessorCount); for (var i = 0; i < Environment.ProcessorCount; i++) { var r = ranges[i]; tasks.Add(Task.Run(() => FindLongestSequence(r))); } Task.WaitAll(tasks.ToArray()); (BigInteger value, int sequenceLength)result = (BigInteger.Zero, 0); foreach (var task in tasks) { var taskResult = task.Result; if (taskResult.sequenceLength > result.sequenceLength) { result = taskResult; } } var response = new CollatzResponse() { Value = ByteString.CopyFrom(result.value.ToByteArray()), Length = result.sequenceLength }; return(Task.FromResult(response)); }
public override Task <CollatzResponse> Calculate( CollatzRequest request, ServerCallContext context) { var requestBytes = request.Number.ToArray(); var start = new BigInteger(requestBytes); if (start <= BigInteger.One) { throw new ArgumentException( "Must provide a starting value greater than one.", nameof(start)); } var sequence = new List <byte[]> { start.ToByteArray() }; while (start > 1) { start = start % 2 == 0 ? start / 2 : ((3 * start) + 1) / 2; sequence.Add(start.ToByteArray()); } var result = new CollatzResponse() { Number = ByteString.CopyFrom(requestBytes), }; result.Sequence.AddRange(sequence.Select(_ => ByteString.CopyFrom(_))); return(Task.FromResult(result)); }
private static async Task CalculateWithStreaming(CollatzGrpc.Collatz.CollatzClient client) { var request = new CollatzRequest() { Number = ByteString.CopyFrom(new BigInteger(55).ToByteArray()) }; using var responseCall = client.CalculateStream(request); await foreach (var response in responseCall.ResponseStream.ReadAllAsync()) { await Console.Out.WriteLineAsync(string.Join(", ", response.Sequence.Select(_ => new BigInteger(_.ToByteArray()).ToString()))); } }
public override async Task CalculateStream(CollatzRequest request, IServerStreamWriter <CollatzResponse> responseStream, ServerCallContext context) { var random = new Random(); var bytes = request.Number.ToArray(); var start = new BigInteger(request.Number.ToArray()); if (start <= BigInteger.One) { throw new ArgumentException( "Must provide a starting value greater than one.", nameof(start)); } var sequence = new List <byte[]> { start.ToByteArray() }; while (start > 1) { await Task.Delay(random.Next(250, 1000)); start = start % 2 == 0 ? start / 2 : ((3 * start) + 1) / 2; sequence.Add(start.ToByteArray()); if (sequence.Count >= 3) { var result = new CollatzResponse() { Number = ByteString.CopyFrom(start.ToByteArray()), }; result.Sequence.AddRange(sequence.Select(_ => ByteString.CopyFrom(_))); await responseStream.WriteAsync(result); sequence.Clear(); } } }