The french Sécurité Sociale identification numbers end with a check code of two digits. I have verified that every possible common transcription error can be detected, and found some other kinds of errors (e.g., rolling three consecutive digits) that may stay undetected.
def check_code(number): return 97 - int(number) % 97def single_digit_generator(number): for i in range(len(number)): for wrong_digit in "0123456789": yield number[:i] + wrong_digit + number[i+1:]def roll_generator(number): for i in range(len(number) - 2): yield number[:i] + number[i+2] + number[i] + number[i+1] + number[i+3:] yield number[:i] + number[i+1] + number[i+2] + number[i] + number[i+3:]def find_error(generator, number): control = check_code(number) for wrong_number in generator(number): if number != wrong_number and check_code(wrong_number) == control: return (number, wrong_number)assert find_error(single_digit_generator, "0149517490979") is Noneassert find_error(roll_generator, "0149517490979") == ('0149517490979', '0149517499709')
My Python 2.7 code (working fragment above) makes heavy use of generators. I was wondering how I could adapt them in OCaml. I surely can write a function maintaining some internal state, but I'm looking for a purely functional solution. May I study the library lazy
, which I'm not too familiar with? I'm not asking for code, just directions.