Reconcile a payment ledger without losing a cent.

Exact decimal amounts, duplicate records and a report that stays consistent when the input order changes.

All work examples

The brief

Build a small reconciliation function that groups entries by account, adds amounts exactly and produces a stable report. Repeated entries should count once. Conflicting records should be rejected.

Why this case matters

A replayed transaction should not change an account balance. This exercise combines exact money handling with duplicate detection, so reviewers can inspect both the calculation and the rules around the input.

Input and output contract

The accepted fields and returned values are defined before the implementation is checked.

Input fieldRequirement
idA non-empty record ID used to detect repeats.
accountA non-empty account name used to group amounts.
amountA decimal string with exactly two places; negative values represent deductions.
Output fieldMeaning
accountsAccount names sorted alphabetically, each with an exact net amount.
totalThe net sum across all accounts, formatted to two decimal places.
unique_entriesThe number of distinct accepted record IDs.

An input-to-output example

This example was checked against the included Python reference implementation.

Input records

[
  {
    "id": "entry-1",
    "account": "main",
    "amount": "0.10"
  },
  {
    "id": "entry-2",
    "account": "main",
    "amount": "0.20"
  },
  {
    "id": "entry-1",
    "account": "main",
    "amount": "0.10"
  },
  {
    "id": "refund-1",
    "account": "main",
    "amount": "-0.05"
  }
]

Returned result

{
  "accounts": [
    {
      "account": "main",
      "net": "0.25"
    }
  ],
  "total": "0.25",
  "unique_entries": 3
}

The second entry-1 row is an identical replay, so it does not add another 0.10. The accepted amounts are 0.10 + 0.20 − 0.05, producing 0.25 from three unique IDs.

A case that should fail

If entry-1 appears again with an amount of 0.20, the function raises an error instead of choosing one version silently.

How it works

The reference solution converts two-decimal amounts to integer cents. It tracks records by ID, rejects conflicts and sorts the final account list. This keeps arithmetic exact and makes the report independent of input order.

  1. Validate the rows

    Require an object with an ID, account and correctly formatted decimal amount. Reject incomplete or malformed entries.

  2. Reconcile by record ID

    Convert each amount to integer cents. Skip an identical repeat, but reject an ID if its account or amount changes.

  3. Produce the report

    Add accepted amounts by account, sort account names and format the totals back to decimal strings.

What we checked

The verifier includes malformed amounts, missing fields, empty input, very large values and cancellation to zero. It also rearranges the input to check that the final report stays the same.

CheckReference result
Exact decimal additionPassed
Signed amounts and refundsPassed
Duplicate IDs counted oncePassed
Conflicting IDs rejectedPassed
Input-order independencePassed
Invalid amounts rejectedPassed
Missing fields rejectedPassed
Empty inputPassed
Large amounts remain exactPassed
Cancellation without negative zeroPassed

The reference implementation passed all 10 checks. The verifier also rejected a deliberately empty implementation. This confirms that the checks can detect that incorrect submission; it does not prove that every possible incorrect solution will be caught.

Run it yourself

Download and unzip the package. From its folder, run:

python verify.py

To check another implementation, use python verify.py path/to/candidate.py. No external packages or network access are required.

Scope and limitations

This is a finite engineering exercise. It is not an accounting product, an exhaustive proof of correctness or a measurement of AI model performance.

The recorded run used Python 3.12.14. A Dockerfile is included for convenience, but Docker was not used for the published verification run and its base image is not digest-pinned.

Tell us what needs doing.

Share the scope, the expected volume and your timeline.
We’ll work out where our team can help.