Beginner · logic
Sort Three Numbers
There are six possible orders and only one is right. You can write them all out with nested ifs — or you can compare-and-swap three times and let the order emerge, which is the same trick every real sort uses.
At a glanceThree compare-and-swaps: make <code>a ≤ b</code>, then <code>a ≤ c</code>, then <code>b ≤ c</code>; print <code>a b c</code>.
Problem
Input: Three integers (each −1000 to 1000), separated by spaces. Equal values are allowed.
Output: The same three numbers in non-decreasing order, separated by single spaces.
Samples:
| Input | Output |
|---|---|
3 1 2 | 1 2 3 |
5 5 1 | 1 5 5 |
Equal values are the test that separates real sorting from sloppy sorting: 5 5 1 must give 1 5 5, and a strict < chain still handles it — but a chain with the wrong order does not.
Your solution
Custom input for "Run my input"
Judging runs in your browser against hidden tests. A runaway loop is cut off after 3 seconds — still, make sure every loop has an exit. Your code is saved in this browser as you type.
Stuck? Hints
Hint 1 — Write the swap once, reuse it
The same three lines from Swap Two Numbers appear three times: if (a > b) { int t = a; a = b; b = t; } and likewise for a, c and b, c. Same block, different pair.
Hint 2 — Why that order works
After the first comparison a holds the smaller of the original a, b. After the second, a also beats c — so a is the global minimum and is finished. The third comparison only has to order the remaining two. Once you see the invariant, the three lines stop looking arbitrary.
Hint 3 — The nested-if alternative
You can enumerate all six orders with if (a <= b && b <= c) ... else if ..., and it will pass. It is also six branches that each duplicate the three couts — and it stops scaling the moment there is a fourth number. Compare-and-swap is the version that grows.
Solution (try it first!)
#include <iostream>
using namespace std;
int main() {
int a, b, c;
cin >> a >> b >> c;
if (a > b) { int t = a; a = b; b = t; }
if (a > c) { int t = a; a = c; c = t; }
if (b > c) { int t = b; b = c; c = t; }
cout << a << " " << b << " " << c << endl;
return 0;
}
Three compare-and-swaps is bubble sort with the loops unrolled — see Bubble Sort for the general version, and Merge Intervals for sorting two arrays that must stay paired. The instinct to swap repeatedly instead of enumerating cases is worth keeping.
Deep dive
Why this works
Three compare-and-swaps in the order (a,b), (a,c), (b,c) establish the invariant a ≤ b ≤ c: after the first two comparisons a is the minimum of all three, so the third only has to order the remaining pair. This is bubble sort with the loops unrolled.
The cost
O(1) — at most three comparisons and three swaps; the general problem needs O(n²) with bubble sort or O(n log n) with a good sort.
Where it goes wrong
- Wrong comparison order. Doing (b,c) first then (a,b) leaves
aunverified againstc— the classic partial-sort bug. - Enumerating all six orders with nested ifs: correct but six duplicated print blocks that stop scaling at four numbers.
- Losing the temporary in the swap, so one value is duplicated and another vanishes.
Next step
Unroll-in-reverse is exactly Bubble Sort; sorting paired arrays without breaking the pairing is Merge Intervals.
Two things to remember
- Three compare-and-swaps in the right order sort three values — that is bubble sort unrolled.
- After the first two comparisons,
ais the global minimum, so the third only orders the rest.
🐞 This version fails — open it and try
Compares (b,c) before (a,c) — a is never verified against the largest
#include <iostream>
using namespace std;
int main() {
int a, b, c;
cin >> a >> b >> c;
if (b > c) { int t = b; b = c; c = t; } // bug: wrong order
if (a > b) { int t = a; a = b; b = t; }
cout << a << " " << b << " " << c << endl;
return 0;
}