public static string Solve2(string[] lines) { const int ChunkSize = 800000; string prefix = lines[0]; char[] password = new char[8]; int passwordChars = 0; int i = 0; while (passwordChars < 8) { ValidHashResult[] results = TryGenerateResultsChunk(prefix, i, i + ChunkSize, null, ParallelWorkers); for (int j = 0; passwordChars < 8 && j < results.Length; j++) { ValidHashResult result = results[j]; if (password[result.Position] == '\0') { password[result.Position] = result.Value; passwordChars++; } } i += ChunkSize; } return(new string(password)); }
private static ValidHashResult[] TryGenerateResultsChunk( string prefix, int startIdxInc, int endIdxExc, int?pos, int parallel) { int totalToCalc = endIdxExc - startIdxInc; int workSize = totalToCalc / parallel; if (workSize * parallel != totalToCalc) { throw new InvalidOperationException("Make sure range is divisible by parallel"); } ValidHashResult[] arr = new ValidHashResult[totalToCalc]; List <Tuple <int, int> > ranges = new(); for (int i = 0; i < parallel; i++) { int start = startIdxInc + (i * workSize); int end = start + workSize; ranges.Add(Tuple.Create(start, end)); } Parallel.For(0, parallel, i => { int arrOffset = i * workSize; ComputeHashResultsSingleWorker(arr, prefix, arrOffset, ranges[i].Item1, ranges[i].Item2, pos); }); return(arr.Where(a => a != null).ToArray()); }
public static string Solve1(string[] lines) { string prefix = lines[0]; string password = ""; int i = 0; while (password.Length < 8) { ValidHashResult[] results = TryGenerateResultsChunk(prefix, i, i + ChunkSize, password.Length, ParallelWorkers); for (int j = 0; password.Length < 8 && j < results.Length; j++) { ValidHashResult result = results[j]; password = password + result.Value; } i += ChunkSize; } return(password); }