指定された最大値に達するまで昇順のシーケンスを返し、その後再び降順を返す整数値の関数が必要です。私はそれをジッグラトと呼んでいます:
0 1 2 3 4 5 6 6 5 4 3 2 1 0
手順はすべて1つです。最大値(シーケンスの途中)は2回表示する必要があります。ゼロから最大2*の範囲外では、何が起こるかは気にしません。
関数を高速にしたい-分岐しない。私はビット演算が好きです。
動作しない例として、ピラミッド関数と絶対値の実装を次に示します。
private static readonly int LONG_ABS_MASK_SHIFT = sizeof(long) * 8 - 1;
/// <summary>
/// Compute the Absolute value of a long without branching.
///
/// Note: This will deviate from Math.Abs for Int64.MinValue, where the .NET library would throw an exception.
/// The most negative number cannot be made positive.
/// </summary>
/// <param name="v">Number to transform.</param>
/// <returns>Absolute value of v.</returns>
public static long Abs(this long v)
{
long mask = v >> LONG_ABS_MASK_SHIFT;
return (v ^ mask) - mask;
}
public static long Pyramid(this long N, long max)
{
return max - (max - N).Abs();
}
このピラミッド関数は、0 1 2 3 4 5 6 5 4 3 210のようなシーケンスを作成します
真ん中の数字は1回だけ発生することに注意してください。
ルックアップテーブルをlongまたはBigInteger内のビットの連続ブロックとして格納し、それらをシフトしてマスクすることを考えましたが、長いシリーズではメモリを大量に消費します。ただし、使用する命令はごくわずかです。