Two pointers use sorted order to rule out pairs
The task is to find two distinct array positions whose values sum to ten. The array is sorted ascending, so a low endpoint and high endpoint provide information about which direction can improve the current sum. Sorted-order elimination is what makes the pointer movement valid. The example is not a general pair search over arbitrary unsorted input, and it does not promise every possible matching pair. It returns one found pair under its particular movement and starting policy.
The baseline finds a pair immediately
The left pointer begins at one and the right pointer at nine. Their sum is ten, so found becomes true and the loop breaks on its first iteration. The conditional print then produces 1+9. This easy baseline verifies the success path but does not exercise either pointer-advance branch. A careful test plan therefore needs additional target or input variations before concluding that the algorithm’s movement rules are correct. The printed values are the selected pair, not their indices or a count of all solutions.
var total = (long)values[left] + values[right];Each comparison discards impossible endpoint choices
If the current sum is below the target, pairing the current left value with any smaller right value cannot help, so left advances. If the sum is too large, pairing the current right value with any larger left value cannot help, so right retreats. The loop condition left less than right prevents reusing one array position twice. Each step shrinks the candidate interval, which gives linear pointer progress after the sorted input is available. The reasoning depends on the array’s ascending order.
Widen before addition and keep position identity
The cast to long applies before the addition, allowing both int values to be added in a wider type. Casting an already computed int sum afterward would be too late to prevent an int overflow from affecting that sum. Also distinguish equal values from the same position: two different positions containing five can form ten, but one isolated five cannot be reused twice. The loop’s strict pointer inequality expresses that positional requirement even though the output prints only values.
Practice: force both pointer movement branches
Change the target to eleven consistently in the comparison logic and predict the route through candidate sums: one plus nine is too small, three plus nine is too large, three plus seven is too small, and four plus seven matches. The printed pair should be 4+7. Then test target fifteen and predict missing. Keep a pointer-state table for each iteration so a correct final answer cannot hide a branch that moved in the wrong direction but happened to recover on one convenient input.
- Update every target comparison together when exploring a new target, or introduce one named target variable.
- Preserve the sorted input contract while testing pointer movement; unsorted input is a different invalid-precondition case.
Practice: test absence and repeated values
For an independent boundary exercise, test an empty array, one value equal to five, two fives, and values that have no matching pair. Predict missing for the one-element case and five plus five only when two positions exist. Then try large positive and negative integers in sorted order to inspect why the wider intermediate sum matters. Distinguish a valid missing result from a malformed input or violated ordering precondition; they should not become interchangeable merely because both can produce surprising output.
- Only read values through the pointers on the successful branch that established a valid pair.
- Decide separately whether callers need one pair, unique value pairs, or every matching index pair.
Let the invariant justify the optimization
The linear search is justified because sorted values make each discarded endpoint impossible for the remaining opposite choices. Tests should cover both movements, success, absence, duplicate values, and positional boundaries. If sorting is needed first, account for that preprocessing cost and whether rearranging the source is permitted. The sample uses local managed arrays and a wider numeric intermediate available in this runtime. Its strength is a precise pair contract, not a blanket promise that two pointers solve every two-value problem without additional assumptions.
- Baseline prints
1+9because the initial endpoints already sum to ten. - The pointers must refer to distinct positions, though their stored values may be equal.
- Sorted input and widening before arithmetic are separate correctness requirements.
A working example
using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
var values = new[] { 1, 3, 4, 7, 9 };
var left = 0; var right = values.Length - 1; var found = false;
while (left < right)
{
var total = (long)values[left] + values[right];
if (total == 10) { found = true; break; }
if (total < 10) left++; else right--;
}
Console.WriteLine(found ? $"{values[left]}+{values[right]}" : "missing");
Expected output
1+9
The sorted order justifies which pointer can move safely.