DEV Community

Suraj Panda
Suraj Panda

Posted on

From Mathematical Equations to Financial Modeling: My HackerRank Hackathon Experience

Recently, I participated in the HackerRank Orchestrate hackathon. The challenge was to design a financial affordability decision engine called Buy or Wait?
The system had to decide whether a person should:

  • Pay for something now
  • Pay partially
  • Use installments
  • Wait until a later date
  • Not make the payment

When I first read the problem, I thought it was mainly a mathematical calculation:
Current balance - minimum safety balance

I initially thought the answer would simply be the amount left after keeping some money aside. But after analyzing the dataset and the problem statement, I understood that it was actually a financial modeling problem.

Understanding the actual problem

A person may have enough money in their account today, but that does not always mean they can safely afford a purchase.
They may have rent due in a few days, pending debits, subscriptions, future salary, or other recurring expenses. They may also want to maintain a minimum balance for emergencies.
So the real question became:
Can this person make the payment and still remain above their minimum safety balance during the future forecast period?

That changed the way I designed the solution.

How I structured the system

I divided the code into separate stages.
First, the system loads the financial profiles, events, requests, payment options, messages, images, and exchange rates. Then it builds the user’s financial state.
During this process, the engine:

  • Converts foreign-currency transactions
  • Reserves pending debits
  • Ignores failed, cancelled, and unrealized events
  • Detects recurring income and expenses
  • Applies relevant evidence from messages and images
  • Respects protected spending categories
  • Uses the user’s payment preferences

After that, the engine creates a future balance projection.

Each event changes the balance on a particular date. Income increases the balance, expenses reduce it, and proposed payment plans are also added to the projection.

The engine then finds the lowest projected balance. The safe amount is based on that lowest point, not only on the current balance.

Recurring expenses were not as simple as they looked

Another difficult part was identifying recurring expenses.
Repeated transactions do not automatically mean that something is recurring. A person might make two similar purchases by coincidence.
I used settled historical transactions and checked:

  • Whether there were enough occurrences
  • The gap between transaction dates
  • Whether the cadence was reasonably consistent
  • Whether the amounts were stable
  • Whether the description suggested a one-time transaction
  • Whether an amount was an extreme outlier A single transaction was never treated as a recurring pattern. For example, rent or a regular subscription could be forecast, but a refund, bonus, reversal, annual payment, or one-time purchase should not automatically be projected into the future. This made me realize that financial modeling is not only about writing formulas. It is also about deciding which data should influence the future.

Choosing a payment plan

The engine generates different types of plans:

  • Full payment today
  • Full payment at a later date
  • Partial payment
  • Installments For installments, I made sure the engine only uses payment options supplied by the provider. It does not create a custom installment schedule. Every plan is passed through the same balance simulation. If the balance falls below the user’s minimum safety balance at any point, that plan is rejected.

Spending changes

If a payment plan is not affordable, the engine checks whether the user has allowed certain expenses to be stopped or reduced.

At first, I considered using a greedy approach. That would mean applying one change at a time and selecting the first change that improved the situation.

However, greedy search can miss a solution where two smaller changes are needed together. Because of that, I changed the logic to search combinations of up to three spending changes.
The search:

  • Tries one change
  • Then tries pairs
  • Then tries triples
  • Rejects stopping and reducing the same event
  • Prefers the solution with the fewest changes

This is more reliable than simply choosing the largest individual saving.

Why I kept the decision deterministic

Although AI was part of the project, I did not let the LLM make the affordability decision.
The affordability calculation involves money, dates, constraints, and safety limits. It needs to be reproducible and auditable.

The core engine must reliably answer questions such as:

  • Does the balance fall below the minimum?
  • Is the payment option actually available?
  • Does the plan finish before the deadline?
  • Is the spending category protected?
  • Is the user willing to stop or reduce that expense?

An LLM could give a reasonable-sounding answer but still make an arithmetic error or overlook an event.

I used AI for implementation assistance, unstructured evidence, and explanation generation. But the final financial decision is produced by deterministic Python logic.

What I learned from the dataset

One of the most important things I learned was that the dataset did not always follow one obvious mathematical pattern.

Some decisions depended on how pending events were interpreted, when income was considered available, how recurring expenses were forecast, or how same-day transactions were ordered.

This is why I spent time checking the output, comparing the results, and asking what rule was actually influencing each decision.

I also learned that it is easy to overfit a system to sample rows. A rule may make one row correct but create incorrect behavior for other users. So I tried to keep the logic general and use the sample data to identify edge cases and guardrails rather than hardcoding individual answers.

Top comments (0)