using System.Diagnostics.Contracts; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using StitchATon2.Infra.Buffers; namespace StitchATon2.Domain; public static class Utils { [Pure] public static string GetSBSNotation(int row) => row <= 26 ? new string([(char)(row + 'A' - 1)]) : new string(['A', (char)(row + 'A' - 27)]); [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)] private static int DivCeil(int a, int b) { return (a + b - 1) / b; } public static (int Column, int Row) GetSBSCoordinate(string coordinate) { var column = coordinate[^1] - '0'; if(char.IsDigit(coordinate[^2])) column += 10 * (coordinate[^2] - '0'); var row = char.IsLetter(coordinate[1]) ? 26 + coordinate[1] - 'A' + 1 : coordinate[0] - 'A' + 1; return (column, row); } public static IBuffer BoundsMatrix(float scaleFactor, int length, int max, int offset) { var vectorSize = DivCeil(length, Vector.Count); using var buffer = MemoryAllocator.Allocate>(vectorSize); var span = buffer.Span; var vectorMin = Vector.Zero; var vectorOffset = new Vector(offset - 1); var vectorMax = new Vector(max - 1); var vectorScale = new Vector(scaleFactor); var vectorSequence = SequenceVector(0f, 1f); var seq = 0f; for (var i = 0; i < vectorSize; i++, seq += Vector.Count) { var sequence = new Vector(seq) + vectorSequence; span[i] = Vector.Multiply(sequence, vectorScale); span[i] = Vector.Add(span[i], vectorScale); span[i] = Vector.Ceiling(span[i]); } var result = MemoryAllocator.Allocate(vectorSize * Vector.Count); var resultSpan = MemoryMarshal.Cast>(result.Span); for (var i = 0; i < vectorSize; i++) { resultSpan[i] = Vector.ConvertToInt32(span[i]); resultSpan[i] = Vector.Add(resultSpan[i], vectorOffset); resultSpan[i] = Vector.Min(resultSpan[i], vectorMax); resultSpan[i] = Vector.Max(resultSpan[i], vectorMin); } return result; } private static Vector SequenceVector(float start, float step) { var vector = Vector.Zero; ref var reference = ref Unsafe.As, float>(ref vector); for (var i = 0; i < Vector.Count; i++) { ref var current = ref Unsafe.Add(ref reference, i); current = start + step * i; } return vector; } }