The problem in brief
You get between 1000 and 4000 points in the plane, with coordinates up to in absolute value, each labelled or , and a promise that some straight line separates the two classes. You must print a line . A point is classified when and otherwise. The statement asks for the line of a support vector machine: among all the lines that separate the classes, the one that stays as far as possible from the nearest points on each side. It suggests finding it by gradient descent on a loss it defines.
How you are scored
On each hidden test the judge measures the accuracy of your line on the points, and the score is
averaged over the tests. Since the data is separable, 100 is reachable on every test. The official tests are hidden, so we use the sample and 100 random separable tests of our own, generated in the allowed ranges with class gaps from 10 to 5000.
A warning about the sample. The sample answer 1 1 0 classifies only 1 of the 10 sample points correctly (for example gives , so , but its label is ). The opposite line -1 -1 0 gets 9 of 10, and -1 -1 -3 gets all 10: the printed answer has the wrong sign (and the wrong offset). Do not use it to check your sign convention. The real max-margin line for the sample is about , which classifies all 10 points correctly.
The key idea
The margin. Write . The distance from a point to the line is , so the geometric margin of a separating line is
The SVM line maximises . Rescaling does not change the line, so we can fix the numerator: require for every point, so that . Maximising the margin then becomes
Why the statement's loss cannot work as written. It only charges the misclassified points, , plus . Take : every point is classified , the misclassified ones cost , and the regulariser is 0 too. The loss is exactly 0, its global minimum, and the "classifier" says to everyone. The loss must demand a margin, not just the right side. The standard fix is the hinge loss, the soft version of the constraint above:
A point now costs nothing only once it lies beyond the margin.
The geometric shortcut. In two dimensions the hard-margin problem has an exact geometric answer: the SVM line is the perpendicular bisector of the closest pair of points between the convex hulls of the two classes, and the margin is half the distance between the hulls. Intuitively, any separating strip must fit between the two hulls, and the widest one is set by the two hulls' nearest points. Formally, this is the dual of the problem above: the optimal is proportional to , where and are the closest points of the two hulls.
A first baseline: gradient descent
Following the statement, we minimise the hinge loss by full-batch (sub)gradient descent:
Scale the data first. With coordinates near , the gradient in is times larger than the gradient in , and no single learning rate suits both. We centre the points and divide both axes by the same factor (the largest absolute coordinate). A common factor keeps angles and distance ratios, so the max-margin line is unchanged, and we map the result back at the end: , , .
With , 3000 steps and a step size of , this gets a score of 99.73 on our 100 tests. Every test clears the 97 % bar, but only 39 are at 100 %, and the worst one stops at 98.9 %. The failures are the tests where the gap between the classes is tiny compared with the spread of the points (10 units out of 200 000). To push every point past the margin, must grow to about in scaled units, which takes a very long time with a decaying step and fights against the regulariser.
The full solution
- Convex hulls of the points and of the points (Andrew's monotone chain, ).
- Closest pair , : the minimum over all vertex-to-edge distances, in both directions (vectorised with numpy, at most a few million distance computations).
- The line: normal (pointing towards the class) through the midpoint, .
p, q = closest_points(convex_hull(X[l == 1]), convex_hull(X[l == -1]))
a, b = p - q
c = -(p - q) @ (p + q) / 2

Both lines separate this example. The exact one has a margin of 8164 (scikit-learn's SVC solver finds 8163), while gradient descent stopped at 6183: close, but not centred in the gap.
Results
100 random separable tests in the allowed ranges, compared with scikit-learn's SVC(kernel="linear", C=1e8) as the reference max-margin solver.
| method | min accuracy | tests at 100 % | score | margin / optimal (median) |
|---|---|---|---|---|
| statement's loss, at its minimum | about 0.5 | 0 | 0 | |
| gradient descent on the hinge loss (scaled data) | 0.989 | 39 | 99.73 | negative (some points stay inside the margin) |
| exact: closest points of the convex hulls | 1.000 | 100 | 100.00 | 1.000 |
What to remember
- A loss must reward what you actually want: if correct points cost nothing and the regulariser shrinks , the zero vector wins. The hinge loss builds the margin into the objective.
- Max margin = minimum under : fixing the scale of the line turns a max-min problem into a clean quadratic program.
- Rescale before gradient descent, with the same factor on every axis when geometry matters, and map the parameters back.
- Geometry gives the exact answer in 2-D: the SVM separates the convex hulls through the bisector of their closest points. In higher dimensions the same duality is what SVM solvers exploit.
- Do not trust a sample output blindly: check it against the statement's own conventions.