From 26f2df762248e947638ffdb61a9d7c9f5d5f0592 Mon Sep 17 00:00:00 2001 From: Kunwar Preet Singh <75082218+Enkryp@users.noreply.github.com> Date: Mon, 2 May 2022 19:42:18 +0530 Subject: [PATCH] Add sol for P104 Project Euler (#5257) * Hacktoberfest: added sol for P104 Project Euler * bot requests resolved * pre-commit * Update sol.py * Update sol.py * remove trailing zeroes * Update sol.py * Update sol.py * Update sol.py Co-authored-by: John Law --- project_euler/problem_104/__init__.py | 0 project_euler/problem_104/sol.py | 137 ++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 project_euler/problem_104/__init__.py create mode 100644 project_euler/problem_104/sol.py diff --git a/project_euler/problem_104/__init__.py b/project_euler/problem_104/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/project_euler/problem_104/sol.py b/project_euler/problem_104/sol.py new file mode 100644 index 000000000..0818ac401 --- /dev/null +++ b/project_euler/problem_104/sol.py @@ -0,0 +1,137 @@ +""" +Project Euler Problem 104 : https://projecteuler.net/problem=104 + +The Fibonacci sequence is defined by the recurrence relation: + +Fn = Fn−1 + Fn−2, where F1 = 1 and F2 = 1. +It turns out that F541, which contains 113 digits, is the first Fibonacci number +for which the last nine digits are 1-9 pandigital (contain all the digits 1 to 9, +but not necessarily in order). And F2749, which contains 575 digits, is the first +Fibonacci number for which the first nine digits are 1-9 pandigital. + +Given that Fk is the first Fibonacci number for which the first nine digits AND +the last nine digits are 1-9 pandigital, find k. +""" + + +def check(number: int) -> bool: + """ + Takes a number and checks if it is pandigital both from start and end + + + >>> check(123456789987654321) + True + + >>> check(120000987654321) + False + + >>> check(1234567895765677987654321) + True + + """ + + check_last = [0] * 11 + check_front = [0] * 11 + + # mark last 9 numbers + for x in range(9): + check_last[int(number % 10)] = 1 + number = number // 10 + # flag + f = True + + # check last 9 numbers for pandigitality + + for x in range(9): + if not check_last[x + 1]: + f = False + if not f: + return f + + # mark first 9 numbers + number = int(str(number)[:9]) + + for x in range(9): + check_front[int(number % 10)] = 1 + number = number // 10 + + # check first 9 numbers for pandigitality + + for x in range(9): + if not check_front[x + 1]: + f = False + return f + + +def check1(number: int) -> bool: + """ + Takes a number and checks if it is pandigital from END + + >>> check1(123456789987654321) + True + + >>> check1(120000987654321) + True + + >>> check1(12345678957656779870004321) + False + + """ + + check_last = [0] * 11 + + # mark last 9 numbers + for x in range(9): + check_last[int(number % 10)] = 1 + number = number // 10 + # flag + f = True + + # check last 9 numbers for pandigitality + + for x in range(9): + if not check_last[x + 1]: + f = False + return f + + +def solution() -> int: + """ + Outputs the answer is the least Fibonacci number pandigital from both sides. + >>> solution() + 329468 + """ + + a = 1 + b = 1 + c = 2 + # temporary Fibonacci numbers + + a1 = 1 + b1 = 1 + c1 = 2 + # temporary Fibonacci numbers mod 1e9 + + # mod m=1e9, done for fast optimisation + tocheck = [0] * 1000000 + m = 1000000000 + + for x in range(1000000): + c1 = (a1 + b1) % m + a1 = b1 % m + b1 = c1 % m + if check1(b1): + tocheck[x + 3] = 1 + + for x in range(1000000): + c = a + b + a = b + b = c + # perform check only if in tocheck + if tocheck[x + 3] and check(b): + return x + 3 # first 2 already done + return -1 + + +if __name__ == "__main__": + print(f"{solution() = }")