Open Source · 7 Languages · 900+ Problems

Project Euler Solutions

Complete solutions in C++, Python & Java — with step-by-step mathematical explanations

All Problems

Problem 203: Squarefree Binomial Coefficients

View on Project Euler

Project Euler Problem 203 Solution

EulerSolve provides an optimized solution for Project Euler Problem 203, Squarefree Binomial Coefficients, with C++, Python, Java, and a step-by-step mathematical explanation.

Problem Summary We work with the first 51 rows of Pascal's triangle, so the row index runs from \(n=0\) through \(n=50\). From those rows we collect all binomial coefficients \(\binom{n}{k}\), keep only distinct values, and then add the ones that are squarefree. Define $B=\left\{\binom{n}{k}:0\le n\le 50,\ 0\le k\le n\right\}.$ Let \(Q\subseteq B\) be the subset of squarefree values. The required quantity is $A=\sum_{v\in Q} v.$ The implementations avoid factorial formulas and avoid full prime factorizations. They generate each row multiplicatively, store coefficients in a set so duplicates disappear automatically, and then reject every value that has a square divisor greater than 1. Mathematical Approach The problem has only two real mathematical ingredients: how to enumerate binomial coefficients exactly, and how to recognize whether a positive integer is squarefree. Once those are clear, the final sum is just a filtered set sum. The distinct coefficient set Pascal's triangle contains many repeated numbers. Some repeats are internal to one row because of the symmetry $\binom{n}{k}=\binom{n}{n-k}.$ Other repeats occur across different rows, for example $\binom{5}{2}=10=\binom{10}{1}.$ Therefore the problem is not asking for a sum over positions \((n,k)\), but over the distinct numerical values that appear....

Detailed mathematical approach

Problem Summary

We work with the first 51 rows of Pascal's triangle, so the row index runs from \(n=0\) through \(n=50\). From those rows we collect all binomial coefficients \(\binom{n}{k}\), keep only distinct values, and then add the ones that are squarefree.

Define

$B=\left\{\binom{n}{k}:0\le n\le 50,\ 0\le k\le n\right\}.$

Let \(Q\subseteq B\) be the subset of squarefree values. The required quantity is

$A=\sum_{v\in Q} v.$

The implementations avoid factorial formulas and avoid full prime factorizations. They generate each row multiplicatively, store coefficients in a set so duplicates disappear automatically, and then reject every value that has a square divisor greater than 1.

Mathematical Approach

The problem has only two real mathematical ingredients: how to enumerate binomial coefficients exactly, and how to recognize whether a positive integer is squarefree. Once those are clear, the final sum is just a filtered set sum.

The distinct coefficient set

Pascal's triangle contains many repeated numbers. Some repeats are internal to one row because of the symmetry

$\binom{n}{k}=\binom{n}{n-k}.$

Other repeats occur across different rows, for example

$\binom{5}{2}=10=\binom{10}{1}.$

Therefore the problem is not asking for a sum over positions \((n,k)\), but over the distinct numerical values that appear. Using the set \(B\) is the mathematically correct way to state that requirement.

Generating one row without factorials

For a fixed row \(n\), the coefficients begin with

$\binom{n}{0}=1.$

From there we can move across the row by the multiplicative recurrence

$\binom{n}{k+1}=\binom{n}{k}\frac{n-k}{k+1},\qquad 0\le k<n.$

Equivalently, if the update is written before the current coefficient is stored, then

$\binom{n}{k}=\binom{n}{k-1}\frac{n-k+1}{k},\qquad 1\le k\le n.$

These are the two equivalent forms used by the implementations. The key invariant is that the current integer always equals the current binomial coefficient, so every division is exact and no floating-point arithmetic is needed. This is much cleaner than computing \(n!\), \(k!\), and \((n-k)!\) separately for every position.

Why the squarefree test works

A positive integer \(v\) is squarefree exactly when no prime square divides it. In other words, \(v\) is rejected if there exists a prime \(p\) such that

$p^2\mid v.$

The implementations first test whether

$4\mid v,$

which handles the only even prime, namely \(p=2\). After that they scan odd values \(p=3,5,7,\dots\) while \(p^2\le v\), and reject \(v\) as soon as \(p^2\mid v\). Mathematically it would be enough to scan odd primes only, but testing all odd \(p\) is still correct: if \(v\) has any odd square divisor, then it has an odd prime-square divisor, and that divisor will be found during the scan.

Worked example: the first eight rows

The checkpoint built into one implementation uses the first 8 rows, meaning \(n=0,1,\dots,7\). The distinct coefficients appearing there are

$\{1,2,3,4,5,6,7,10,15,20,21,35\}.$

Among these, \(4\) is not squarefree because \(4\mid 4\), and \(20\) is not squarefree because \(4\mid 20\). The remaining values

$\{1,2,3,5,6,7,10,15,21,35\}$

are all squarefree, so their sum is

$1+2+3+5+6+7+10+15+21+35=105.$

This example shows the entire method on a smaller input: generate coefficients, deduplicate them, remove values having a square divisor, and sum what remains.

How the Code Works

Building the distinct coefficient set

The C++, Python, and Java implementations sweep through the rows one by one. For each row they maintain the current coefficient, insert it into a set, and update it by the multiplicative recurrence to obtain the next coefficient in the row. Because the container stores unique integers, repeated values from row symmetry or from different rows are automatically collapsed into one entry.

Filtering squarefree values and summing

After the set has been built, the implementation iterates through its stored coefficients. A defensive zero check appears in the squarefree routine, although every actual binomial coefficient here is positive. Then the algorithm rejects multiples of \(4\), checks odd squares up to \(\sqrt{v}\), and adds \(v\) to the running total only if no square divisor is found. One implementation also verifies the 8-row checkpoint \(105\) before solving the full 51-row case.

Complexity Analysis

If the first \(R\) rows are processed, coefficient generation touches

$\sum_{n=0}^{R-1}(n+1)=\frac{R(R+1)}{2}$

positions, so the row sweep is \(O(R^2)\). Let \(U\) be the number of distinct coefficients collected and let \(M\) be the largest such coefficient. The squarefree filtering stage costs \(O(U\sqrt{M})\) trial divisions in the worst case, because each test scans odd candidates up to \(\sqrt{v}\).

Memory usage is \(O(U)\) for the set of distinct coefficients. For the actual problem, \(R=51\), so only 1326 coefficient positions are visited, and the largest values still fit comfortably in 64-bit integer arithmetic. That is why the direct set-and-test approach is entirely sufficient here.

Footnotes and References

  1. Problem page: https://projecteuler.net/problem=203
  2. Pascal's triangle: Wikipedia - Pascal's triangle
  3. Binomial coefficient: Wikipedia - Binomial coefficient
  4. Square-free integer: Wikipedia - Square-free integer

Mathematical approach · C++ solution · Python solution · Java solution

Previous: Problem 202 · All Project Euler solutions · Next: Problem 204

Need help with a problem? Ask me! 💡
e
✦ Euler GLM 5.2
Hi! I'm Euler. Ask me anything about Project Euler problems, math concepts, or solution approaches! 🧮