puzzle contents
Contents
raw puzzle

Original Problem

Goal

In this puzzle that shows a real-life phenomenon, you have to detect whether a bank account have a high risk to contain fraudulent transactions.

The Benford law is used on real anti-fraud systems to detect frauds about government accounting fraud, fiscal fraud, or even election cheating.

Your program receives in input a list of transactions, like:

+1122.85 $<br />-10.69 $<br />-21.79 $<br />+12.08 $


You have to count how much transactions start with "1", "2", ...

For example:
"+1122.85 $" starts with 1
"-0.50" starts with 5
"$ 242.00" starts with 2

And you must output "true" if the bank account seems fraudulent, or "false" if it seems regular.

For this puzzle, your program will naively output whether a bank account seems fraudulent or not. You will be given the Benford law percentages:

1: 30.1%<br />2: 17.6%<br />3: 12.5%<br />4: 9.7%<br />5: 7.9%<br />6: 6.7%<br />7: 5.8%<br />8: 5.1%<br />9: 4.6%


An account is considered regular if the account starting numbers percentage follow these percentages, with a margin of 10 percent. Which means that you may find:

transactions starting with 1: 30.1%, so between 20.1% and 40.1%
transactions starting with 2: 17.6%, so between 7.6% and 27.6%
...

If at least one of these percentage is outside the expected range, the account is considered as fraudulent, you must then output "true".

Note that transactions may be formatted like this:

-48.12$<br />- 5,00 &euro;<br />+0.99<br />350.10<br />-25 &euro;<br />$ 500.00<br />42 &pound;


It can be any currency.

Input
Line 1: The number of transactions N.
Next N lines: The transaction. Can be formatted like "-48.12$", "- 5,00 €", "+0.99", "350.10", "-25 €", ...
Output
One line: "true" if the account seems fraudulent, "false" if it seems regular.
Constraints
0 < N ≤ 1000

Solution

The only problem on this task is the corrupted input format. I wanted to extract the first digit with \(d = \left\lfloor n \cdot 10^{-\lfloor\log_{10}(n)\rfloor}\right\rfloor\), but the most reliable way is to search for the first digit in the string.

After solving the input, it's just a comparision if the frequecy is within the required 10% interval:

let res = false;

const N = +readline();
const cnt = new Uint32Array(10);
const bnf = [
 .0,
 .301,
 .176,
 .125,
 .097,
 .079,
 .067,
 .058,
 .051,
 .046
];

for (let i = 0; i < N; i++) {
  cnt[readline().match(/\d/)[0]]++;
}

for (let i = 1; i < 10; i++) {
  if (Math.abs(bnf[i] - cnt[i] / N) > .1) {
    res = true;
    break;
  }
}
print(res);