From e82e93ac0df910b45accd21976f1a50dd103125e Mon Sep 17 00:00:00 2001 From: Reniz Shah <95038253+reniz-shah@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:19:54 +0530 Subject: [PATCH 01/12] add algorithm to check if given string is valid number or not Add a new file string_is_valid_number.py in string directory --- strings/string_is_valid_number.py | 134 ++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 strings/string_is_valid_number.py diff --git a/strings/string_is_valid_number.py b/strings/string_is_valid_number.py new file mode 100644 index 000000000..5a547bc98 --- /dev/null +++ b/strings/string_is_valid_number.py @@ -0,0 +1,134 @@ +""" +Solution By: Reniz Shah +Topic: Deterministic Finite Automaton (DFA) +Given a string s, return whether s is a valid number or not +Input: s = -90E3 +Output: True +Leetcode link: https://leetcode.com/problems/valid-number/description/ +""" + + +def classify_char(char): + """ + Classifies a character into one of the following categories: + + - 'numeric': if the character is a digit (0-9) + - 'ign': if the character is a plus sign (+) or a minus sign (-) + - 'exponent': if the character is an 'e' or 'E' (used in exponential notation) + - 'decimal': if the character is a decimal point (.) + - None: if the character does not fit into any of the above categories + + Parameters: + char (str): The character to be classified + + Returns: + str: The classification of the character + + >>> classify_char('2') + 'numeric' + >>> classify_char('-') + 'sign' + >>> classify_char('e') + 'exponent' + >>> classify_char('.') + 'decimal' + >>> classify_char('r') + + """ + + if char.isdigit(): + return "numeric" + if char in "+-": + return "sign" + if char in "eE": + return "exponent" + if char == ".": + return "decimal" + return None + + +def is_valid_number(s: str) -> bool: + """ + This function checks if the input string represents a valid number. + + It uses a finite state machine to parse the input string, + transitioning between states based on the character type. + The function returns True if the input string represents a valid number, + and False otherwise. + + A valid number is defined as a string that can be parsed into an + integer, decimal, or exponent. + + >>> is_valid_number("2") + True + >>> is_valid_number("0089") + True + >>> is_valid_number("-0.1") + True + >>> is_valid_number("+3.14") + True + >>> is_valid_number("4.") + True + >>> is_valid_number("-.9") + True + >>> is_valid_number("2e10") + True + >>> is_valid_number("-90E3") + True + >>> is_valid_number("3e+7") + True + >>> is_valid_number("+6e-1") + True + >>> is_valid_number("53.5e93") + True + >>> is_valid_number("-123.456e789") + True + + + >>> is_valid_number("abc") + False + >>> is_valid_number("1a") + False + >>> is_valid_number("1e") + False + >>> is_valid_number("e3") + False + >>> is_valid_number("99e2.5") + False + >>> is_valid_number("--6") + False + >>> is_valid_number("-+3") + False + >>> is_valid_number("95a54e53") + False + >>> is_valid_number(".") + False + """ + + state_machine = { + "initial": {"numeric": "whole", "sign": "signed", "decimal": "fractional"}, + "signed": {"numeric": "whole", "decimal": "fractional"}, + "whole": {"numeric": "whole", "decimal": "Fraction", "exponent": "exponential"}, + "fractional": {"numeric": "Fraction"}, + "Fraction": {"numeric": "Fraction", "exponent": "exponential"}, + "exponential": {"numeric": "Exp_number", "sign": "Exp_sign"}, + "Exp_sign": {"numeric": "Exp_number"}, + "Exp_number": {"numeric": "Exp_number"}, + } + + valid_final_states = {"whole", "Fraction", "Exp_number"} + current_state = "initial" + + for char in s: + char_type = classify_char(char) + if char_type is None or char_type not in state_machine[current_state]: + return False + current_state = state_machine[current_state][char_type] + + return current_state in valid_final_states + + +if __name__ == "__main__": + import doctest + + doctest.testmod() From eed534f95180daaa0ea0761e7f8d71d92aa18218 Mon Sep 17 00:00:00 2001 From: reniz-shah Date: Wed, 7 Aug 2024 17:52:07 +0530 Subject: [PATCH 02/12] resolve comments which is create enum for states and char types extract state machine outside function --- strings/string_is_valid_number.py | 83 ++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 30 deletions(-) diff --git a/strings/string_is_valid_number.py b/strings/string_is_valid_number.py index 5a547bc98..80011ec7b 100644 --- a/strings/string_is_valid_number.py +++ b/strings/string_is_valid_number.py @@ -6,44 +6,78 @@ Input: s = -90E3 Output: True Leetcode link: https://leetcode.com/problems/valid-number/description/ """ +from enum import Enum +from typing import Dict + +class CharType(Enum): + NUMERIC = 'NUMERIC' + SIGN = 'SIGN' + EXPONENT = 'EXPONENT' + DECIMAL = 'DECIMAL' + +class State(Enum): + INITIAL = 'INITIAL' + SIGNED = 'SIGNED' + WHOLE = 'WHOLE' + FRACTIONAL = 'FRACTIONAL' + FRACTION = 'FRACTION' + EXPONENTIAL = 'EXPONENTIAL' + EXP_SIGN = 'EXP_SIGN' + EXP_NUMBER = 'EXP_NUMBER' + +state_machine : Dict[State, Dict[CharType, State]] = { + State.INITIAL: {CharType.NUMERIC: State.WHOLE, CharType.SIGN: State.SIGNED, CharType.DECIMAL: State.FRACTIONAL}, + State.SIGNED: {CharType.NUMERIC: State.WHOLE, CharType.DECIMAL: State.FRACTIONAL}, + State.WHOLE: {CharType.NUMERIC: State.WHOLE, CharType.DECIMAL: State.FRACTION, CharType.EXPONENT: State.EXPONENTIAL}, + State.FRACTIONAL: {CharType.NUMERIC: State.FRACTION}, + State.FRACTION: {CharType.NUMERIC: State.FRACTION, CharType.EXPONENT: State.EXPONENTIAL}, + State.EXPONENTIAL: {CharType.NUMERIC: State.EXP_NUMBER, CharType.SIGN: State.EXP_SIGN}, + State.EXP_SIGN: {CharType.NUMERIC: State.EXP_NUMBER}, + State.EXP_NUMBER: {CharType.NUMERIC: State.EXP_NUMBER}, +} -def classify_char(char): +def classify_char(char: str) -> CharType | None: """ Classifies a character into one of the following categories: - - 'numeric': if the character is a digit (0-9) - - 'ign': if the character is a plus sign (+) or a minus sign (-) - - 'exponent': if the character is an 'e' or 'E' (used in exponential notation) - - 'decimal': if the character is a decimal point (.) - - None: if the character does not fit into any of the above categories + - 'CharType.NUMERIC': if the character is a digit (0-9) + - 'CharType.SIGN': if the character is a plus sign (+) or a minus sign (-) + - 'CharType.EXPONENT': if the character is an 'e' or 'E' (used in exponential notation) + - 'CharType.DECIMAL': if the character is a decimal point (.) + - None: if the character does not fit into any of the above categories or size of char is not 1 Parameters: char (str): The character to be classified Returns: - str: The classification of the character + CharType: The classification of the character >>> classify_char('2') - 'numeric' + >>> classify_char('-') - 'sign' + >>> classify_char('e') - 'exponent' + >>> classify_char('.') - 'decimal' - >>> classify_char('r') + + >>> classify_char('') + + >>> classify_char('0') + + >>> classify_char('01') """ - + if len(char) != 1: + return None if char.isdigit(): - return "numeric" + return CharType.NUMERIC if char in "+-": - return "sign" + return CharType.SIGN if char in "eE": - return "exponent" + return CharType.EXPONENT if char == ".": - return "decimal" + return CharType.DECIMAL return None @@ -105,19 +139,8 @@ def is_valid_number(s: str) -> bool: False """ - state_machine = { - "initial": {"numeric": "whole", "sign": "signed", "decimal": "fractional"}, - "signed": {"numeric": "whole", "decimal": "fractional"}, - "whole": {"numeric": "whole", "decimal": "Fraction", "exponent": "exponential"}, - "fractional": {"numeric": "Fraction"}, - "Fraction": {"numeric": "Fraction", "exponent": "exponential"}, - "exponential": {"numeric": "Exp_number", "sign": "Exp_sign"}, - "Exp_sign": {"numeric": "Exp_number"}, - "Exp_number": {"numeric": "Exp_number"}, - } - - valid_final_states = {"whole", "Fraction", "Exp_number"} - current_state = "initial" + valid_final_states = {State.WHOLE, State.FRACTION, State.EXP_NUMBER} + current_state = State.INITIAL for char in s: char_type = classify_char(char) From ab442394d15d302c41dee7dcd877c966f6a71be7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 12:22:54 +0000 Subject: [PATCH 03/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- strings/string_is_valid_number.py | 54 ++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/strings/string_is_valid_number.py b/strings/string_is_valid_number.py index 80011ec7b..d9d4bfa8e 100644 --- a/strings/string_is_valid_number.py +++ b/strings/string_is_valid_number.py @@ -6,32 +6,50 @@ Input: s = -90E3 Output: True Leetcode link: https://leetcode.com/problems/valid-number/description/ """ + from enum import Enum from typing import Dict + class CharType(Enum): - NUMERIC = 'NUMERIC' - SIGN = 'SIGN' - EXPONENT = 'EXPONENT' - DECIMAL = 'DECIMAL' + NUMERIC = "NUMERIC" + SIGN = "SIGN" + EXPONENT = "EXPONENT" + DECIMAL = "DECIMAL" + class State(Enum): - INITIAL = 'INITIAL' - SIGNED = 'SIGNED' - WHOLE = 'WHOLE' - FRACTIONAL = 'FRACTIONAL' - FRACTION = 'FRACTION' - EXPONENTIAL = 'EXPONENTIAL' - EXP_SIGN = 'EXP_SIGN' - EXP_NUMBER = 'EXP_NUMBER' + INITIAL = "INITIAL" + SIGNED = "SIGNED" + WHOLE = "WHOLE" + FRACTIONAL = "FRACTIONAL" + FRACTION = "FRACTION" + EXPONENTIAL = "EXPONENTIAL" + EXP_SIGN = "EXP_SIGN" + EXP_NUMBER = "EXP_NUMBER" -state_machine : Dict[State, Dict[CharType, State]] = { - State.INITIAL: {CharType.NUMERIC: State.WHOLE, CharType.SIGN: State.SIGNED, CharType.DECIMAL: State.FRACTIONAL}, + +state_machine: Dict[State, Dict[CharType, State]] = { + State.INITIAL: { + CharType.NUMERIC: State.WHOLE, + CharType.SIGN: State.SIGNED, + CharType.DECIMAL: State.FRACTIONAL, + }, State.SIGNED: {CharType.NUMERIC: State.WHOLE, CharType.DECIMAL: State.FRACTIONAL}, - State.WHOLE: {CharType.NUMERIC: State.WHOLE, CharType.DECIMAL: State.FRACTION, CharType.EXPONENT: State.EXPONENTIAL}, + State.WHOLE: { + CharType.NUMERIC: State.WHOLE, + CharType.DECIMAL: State.FRACTION, + CharType.EXPONENT: State.EXPONENTIAL, + }, State.FRACTIONAL: {CharType.NUMERIC: State.FRACTION}, - State.FRACTION: {CharType.NUMERIC: State.FRACTION, CharType.EXPONENT: State.EXPONENTIAL}, - State.EXPONENTIAL: {CharType.NUMERIC: State.EXP_NUMBER, CharType.SIGN: State.EXP_SIGN}, + State.FRACTION: { + CharType.NUMERIC: State.FRACTION, + CharType.EXPONENT: State.EXPONENTIAL, + }, + State.EXPONENTIAL: { + CharType.NUMERIC: State.EXP_NUMBER, + CharType.SIGN: State.EXP_SIGN, + }, State.EXP_SIGN: {CharType.NUMERIC: State.EXP_NUMBER}, State.EXP_NUMBER: {CharType.NUMERIC: State.EXP_NUMBER}, } @@ -62,7 +80,7 @@ def classify_char(char: str) -> CharType | None: >>> classify_char('.') >>> classify_char('') - + >>> classify_char('0') >>> classify_char('01') From 42c24d6f3c17869f69dbb1f70162f3d61a65cd7b Mon Sep 17 00:00:00 2001 From: reniz-shah Date: Wed, 7 Aug 2024 17:52:07 +0530 Subject: [PATCH 04/12] resolve comments which is create enum for states and char types extract state machine outside function --- strings/string_is_valid_number.py | 84 ++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/strings/string_is_valid_number.py b/strings/string_is_valid_number.py index d9d4bfa8e..9e2ac663f 100644 --- a/strings/string_is_valid_number.py +++ b/strings/string_is_valid_number.py @@ -6,6 +6,82 @@ Input: s = -90E3 Output: True Leetcode link: https://leetcode.com/problems/valid-number/description/ """ +from enum import Enum +from typing import Dict + +class CharType(Enum): + NUMERIC = 'NUMERIC' + SIGN = 'SIGN' + EXPONENT = 'EXPONENT' + DECIMAL = 'DECIMAL' + +class State(Enum): + INITIAL = 'INITIAL' + SIGNED = 'SIGNED' + WHOLE = 'WHOLE' + FRACTIONAL = 'FRACTIONAL' + FRACTION = 'FRACTION' + EXPONENTIAL = 'EXPONENTIAL' + EXP_SIGN = 'EXP_SIGN' + EXP_NUMBER = 'EXP_NUMBER' + +state_machine : Dict[State, Dict[CharType, State]] = { + State.INITIAL: {CharType.NUMERIC: State.WHOLE, CharType.SIGN: State.SIGNED, CharType.DECIMAL: State.FRACTIONAL}, + State.SIGNED: {CharType.NUMERIC: State.WHOLE, CharType.DECIMAL: State.FRACTIONAL}, + State.WHOLE: {CharType.NUMERIC: State.WHOLE, CharType.DECIMAL: State.FRACTION, CharType.EXPONENT: State.EXPONENTIAL}, + State.FRACTIONAL: {CharType.NUMERIC: State.FRACTION}, + State.FRACTION: {CharType.NUMERIC: State.FRACTION, CharType.EXPONENT: State.EXPONENTIAL}, + State.EXPONENTIAL: {CharType.NUMERIC: State.EXP_NUMBER, CharType.SIGN: State.EXP_SIGN}, + State.EXP_SIGN: {CharType.NUMERIC: State.EXP_NUMBER}, + State.EXP_NUMBER: {CharType.NUMERIC: State.EXP_NUMBER}, +} + +from enum import Enum +from typing import Dict + + +class CharType(Enum): + NUMERIC = "NUMERIC" + SIGN = "SIGN" + EXPONENT = "EXPONENT" + DECIMAL = "DECIMAL" + + +class State(Enum): + INITIAL = "INITIAL" + SIGNED = "SIGNED" + WHOLE = "WHOLE" + FRACTIONAL = "FRACTIONAL" + FRACTION = "FRACTION" + EXPONENTIAL = "EXPONENTIAL" + EXP_SIGN = "EXP_SIGN" + EXP_NUMBER = "EXP_NUMBER" + + +state_machine: Dict[State, Dict[CharType, State]] = { + State.INITIAL: { + CharType.NUMERIC: State.WHOLE, + CharType.SIGN: State.SIGNED, + CharType.DECIMAL: State.FRACTIONAL, + }, + State.SIGNED: {CharType.NUMERIC: State.WHOLE, CharType.DECIMAL: State.FRACTIONAL}, + State.WHOLE: { + CharType.NUMERIC: State.WHOLE, + CharType.DECIMAL: State.FRACTION, + CharType.EXPONENT: State.EXPONENTIAL, + }, + State.FRACTIONAL: {CharType.NUMERIC: State.FRACTION}, + State.FRACTION: { + CharType.NUMERIC: State.FRACTION, + CharType.EXPONENT: State.EXPONENTIAL, + }, + State.EXPONENTIAL: { + CharType.NUMERIC: State.EXP_NUMBER, + CharType.SIGN: State.EXP_SIGN, + }, + State.EXP_SIGN: {CharType.NUMERIC: State.EXP_NUMBER}, + State.EXP_NUMBER: {CharType.NUMERIC: State.EXP_NUMBER}, +} from enum import Enum from typing import Dict @@ -78,12 +154,8 @@ def classify_char(char: str) -> CharType | None: >>> classify_char('e') >>> classify_char('.') - - >>> classify_char('') - - >>> classify_char('0') - - >>> classify_char('01') + 'decimal' + >>> classify_char('r') """ if len(char) != 1: From aaf90cdb3871e36ad128d2d8a7656099b697758e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 12:22:54 +0000 Subject: [PATCH 05/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- strings/string_is_valid_number.py | 58 ++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/strings/string_is_valid_number.py b/strings/string_is_valid_number.py index 9e2ac663f..696fb78c5 100644 --- a/strings/string_is_valid_number.py +++ b/strings/string_is_valid_number.py @@ -6,32 +6,50 @@ Input: s = -90E3 Output: True Leetcode link: https://leetcode.com/problems/valid-number/description/ """ + from enum import Enum from typing import Dict + class CharType(Enum): - NUMERIC = 'NUMERIC' - SIGN = 'SIGN' - EXPONENT = 'EXPONENT' - DECIMAL = 'DECIMAL' + NUMERIC = "NUMERIC" + SIGN = "SIGN" + EXPONENT = "EXPONENT" + DECIMAL = "DECIMAL" + class State(Enum): - INITIAL = 'INITIAL' - SIGNED = 'SIGNED' - WHOLE = 'WHOLE' - FRACTIONAL = 'FRACTIONAL' - FRACTION = 'FRACTION' - EXPONENTIAL = 'EXPONENTIAL' - EXP_SIGN = 'EXP_SIGN' - EXP_NUMBER = 'EXP_NUMBER' + INITIAL = "INITIAL" + SIGNED = "SIGNED" + WHOLE = "WHOLE" + FRACTIONAL = "FRACTIONAL" + FRACTION = "FRACTION" + EXPONENTIAL = "EXPONENTIAL" + EXP_SIGN = "EXP_SIGN" + EXP_NUMBER = "EXP_NUMBER" -state_machine : Dict[State, Dict[CharType, State]] = { - State.INITIAL: {CharType.NUMERIC: State.WHOLE, CharType.SIGN: State.SIGNED, CharType.DECIMAL: State.FRACTIONAL}, + +state_machine: Dict[State, Dict[CharType, State]] = { + State.INITIAL: { + CharType.NUMERIC: State.WHOLE, + CharType.SIGN: State.SIGNED, + CharType.DECIMAL: State.FRACTIONAL, + }, State.SIGNED: {CharType.NUMERIC: State.WHOLE, CharType.DECIMAL: State.FRACTIONAL}, - State.WHOLE: {CharType.NUMERIC: State.WHOLE, CharType.DECIMAL: State.FRACTION, CharType.EXPONENT: State.EXPONENTIAL}, + State.WHOLE: { + CharType.NUMERIC: State.WHOLE, + CharType.DECIMAL: State.FRACTION, + CharType.EXPONENT: State.EXPONENTIAL, + }, State.FRACTIONAL: {CharType.NUMERIC: State.FRACTION}, - State.FRACTION: {CharType.NUMERIC: State.FRACTION, CharType.EXPONENT: State.EXPONENTIAL}, - State.EXPONENTIAL: {CharType.NUMERIC: State.EXP_NUMBER, CharType.SIGN: State.EXP_SIGN}, + State.FRACTION: { + CharType.NUMERIC: State.FRACTION, + CharType.EXPONENT: State.EXPONENTIAL, + }, + State.EXPONENTIAL: { + CharType.NUMERIC: State.EXP_NUMBER, + CharType.SIGN: State.EXP_SIGN, + }, State.EXP_SIGN: {CharType.NUMERIC: State.EXP_NUMBER}, State.EXP_NUMBER: {CharType.NUMERIC: State.EXP_NUMBER}, } @@ -154,6 +172,12 @@ def classify_char(char: str) -> CharType | None: >>> classify_char('e') >>> classify_char('.') + + >>> classify_char('') + + >>> classify_char('0') + + >>> classify_char('01') 'decimal' >>> classify_char('r') From 0b4271a5d76af82d188b31a8f7c533d0392992ef Mon Sep 17 00:00:00 2001 From: reniz-shah Date: Wed, 7 Aug 2024 18:05:08 +0530 Subject: [PATCH 06/12] resolve ruff check failing --- strings/string_is_valid_number.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/strings/string_is_valid_number.py b/strings/string_is_valid_number.py index 696fb78c5..6928c72ce 100644 --- a/strings/string_is_valid_number.py +++ b/strings/string_is_valid_number.py @@ -8,7 +8,6 @@ Leetcode link: https://leetcode.com/problems/valid-number/description/ """ from enum import Enum -from typing import Dict class CharType(Enum): @@ -29,7 +28,7 @@ class State(Enum): EXP_NUMBER = "EXP_NUMBER" -state_machine: Dict[State, Dict[CharType, State]] = { +state_machine: dict[State, dict[CharType, State]] = { State.INITIAL: { CharType.NUMERIC: State.WHOLE, CharType.SIGN: State.SIGNED, @@ -155,9 +154,11 @@ def classify_char(char: str) -> CharType | None: - 'CharType.NUMERIC': if the character is a digit (0-9) - 'CharType.SIGN': if the character is a plus sign (+) or a minus sign (-) - - 'CharType.EXPONENT': if the character is an 'e' or 'E' (used in exponential notation) + - 'CharType.EXPONENT': if the character is an 'e' or 'E' + (used in exponential notation) - 'CharType.DECIMAL': if the character is a decimal point (.) - - None: if the character does not fit into any of the above categories or size of char is not 1 + - None: if the character does not fit into any of the above categories + - None: if size of char is not 1 Parameters: char (str): The character to be classified From 3faf2cd53e67f6f7fc4628b1ecc8b2dae46eea90 Mon Sep 17 00:00:00 2001 From: reniz-shah Date: Wed, 7 Aug 2024 18:11:57 +0530 Subject: [PATCH 07/12] change variable name from s to number_string as it is more descriptive --- strings/string_is_valid_number.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/strings/string_is_valid_number.py b/strings/string_is_valid_number.py index 6928c72ce..db78b46c2 100644 --- a/strings/string_is_valid_number.py +++ b/strings/string_is_valid_number.py @@ -196,7 +196,7 @@ def classify_char(char: str) -> CharType | None: return None -def is_valid_number(s: str) -> bool: +def is_valid_number(number_string: str) -> bool: """ This function checks if the input string represents a valid number. @@ -257,7 +257,7 @@ def is_valid_number(s: str) -> bool: valid_final_states = {State.WHOLE, State.FRACTION, State.EXP_NUMBER} current_state = State.INITIAL - for char in s: + for char in number_string: char_type = classify_char(char) if char_type is None or char_type not in state_machine[current_state]: return False From 13d5527a5ef3e308b39391fc07a27b67ed8ae327 Mon Sep 17 00:00:00 2001 From: reniz-shah Date: Thu, 8 Aug 2024 10:16:15 +0530 Subject: [PATCH 08/12] rebase branch with master --- strings/string_is_valid_number.py | 102 ------------------------------ 1 file changed, 102 deletions(-) diff --git a/strings/string_is_valid_number.py b/strings/string_is_valid_number.py index db78b46c2..cfd941630 100644 --- a/strings/string_is_valid_number.py +++ b/strings/string_is_valid_number.py @@ -2,8 +2,6 @@ Solution By: Reniz Shah Topic: Deterministic Finite Automaton (DFA) Given a string s, return whether s is a valid number or not -Input: s = -90E3 -Output: True Leetcode link: https://leetcode.com/problems/valid-number/description/ """ @@ -53,100 +51,6 @@ state_machine: dict[State, dict[CharType, State]] = { State.EXP_NUMBER: {CharType.NUMERIC: State.EXP_NUMBER}, } -from enum import Enum -from typing import Dict - - -class CharType(Enum): - NUMERIC = "NUMERIC" - SIGN = "SIGN" - EXPONENT = "EXPONENT" - DECIMAL = "DECIMAL" - - -class State(Enum): - INITIAL = "INITIAL" - SIGNED = "SIGNED" - WHOLE = "WHOLE" - FRACTIONAL = "FRACTIONAL" - FRACTION = "FRACTION" - EXPONENTIAL = "EXPONENTIAL" - EXP_SIGN = "EXP_SIGN" - EXP_NUMBER = "EXP_NUMBER" - - -state_machine: Dict[State, Dict[CharType, State]] = { - State.INITIAL: { - CharType.NUMERIC: State.WHOLE, - CharType.SIGN: State.SIGNED, - CharType.DECIMAL: State.FRACTIONAL, - }, - State.SIGNED: {CharType.NUMERIC: State.WHOLE, CharType.DECIMAL: State.FRACTIONAL}, - State.WHOLE: { - CharType.NUMERIC: State.WHOLE, - CharType.DECIMAL: State.FRACTION, - CharType.EXPONENT: State.EXPONENTIAL, - }, - State.FRACTIONAL: {CharType.NUMERIC: State.FRACTION}, - State.FRACTION: { - CharType.NUMERIC: State.FRACTION, - CharType.EXPONENT: State.EXPONENTIAL, - }, - State.EXPONENTIAL: { - CharType.NUMERIC: State.EXP_NUMBER, - CharType.SIGN: State.EXP_SIGN, - }, - State.EXP_SIGN: {CharType.NUMERIC: State.EXP_NUMBER}, - State.EXP_NUMBER: {CharType.NUMERIC: State.EXP_NUMBER}, -} - -from enum import Enum -from typing import Dict - - -class CharType(Enum): - NUMERIC = "NUMERIC" - SIGN = "SIGN" - EXPONENT = "EXPONENT" - DECIMAL = "DECIMAL" - - -class State(Enum): - INITIAL = "INITIAL" - SIGNED = "SIGNED" - WHOLE = "WHOLE" - FRACTIONAL = "FRACTIONAL" - FRACTION = "FRACTION" - EXPONENTIAL = "EXPONENTIAL" - EXP_SIGN = "EXP_SIGN" - EXP_NUMBER = "EXP_NUMBER" - - -state_machine: Dict[State, Dict[CharType, State]] = { - State.INITIAL: { - CharType.NUMERIC: State.WHOLE, - CharType.SIGN: State.SIGNED, - CharType.DECIMAL: State.FRACTIONAL, - }, - State.SIGNED: {CharType.NUMERIC: State.WHOLE, CharType.DECIMAL: State.FRACTIONAL}, - State.WHOLE: { - CharType.NUMERIC: State.WHOLE, - CharType.DECIMAL: State.FRACTION, - CharType.EXPONENT: State.EXPONENTIAL, - }, - State.FRACTIONAL: {CharType.NUMERIC: State.FRACTION}, - State.FRACTION: { - CharType.NUMERIC: State.FRACTION, - CharType.EXPONENT: State.EXPONENTIAL, - }, - State.EXPONENTIAL: { - CharType.NUMERIC: State.EXP_NUMBER, - CharType.SIGN: State.EXP_SIGN, - }, - State.EXP_SIGN: {CharType.NUMERIC: State.EXP_NUMBER}, - State.EXP_NUMBER: {CharType.NUMERIC: State.EXP_NUMBER}, -} - def classify_char(char: str) -> CharType | None: """ @@ -179,9 +83,6 @@ def classify_char(char: str) -> CharType | None: >>> classify_char('0') >>> classify_char('01') - 'decimal' - >>> classify_char('r') - """ if len(char) != 1: return None @@ -199,15 +100,12 @@ def classify_char(char: str) -> CharType | None: def is_valid_number(number_string: str) -> bool: """ This function checks if the input string represents a valid number. - It uses a finite state machine to parse the input string, transitioning between states based on the character type. The function returns True if the input string represents a valid number, and False otherwise. - A valid number is defined as a string that can be parsed into an integer, decimal, or exponent. - >>> is_valid_number("2") True >>> is_valid_number("0089") From 2d5eebf84244d0cf52eebaa247c07dce7baa4532 Mon Sep 17 00:00:00 2001 From: reniz-shah Date: Wed, 7 Aug 2024 17:52:07 +0530 Subject: [PATCH 09/12] resolve comments which is create enum for states and char types extract state machine outside function --- strings/string_is_valid_number.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/strings/string_is_valid_number.py b/strings/string_is_valid_number.py index cfd941630..073240733 100644 --- a/strings/string_is_valid_number.py +++ b/strings/string_is_valid_number.py @@ -4,6 +4,35 @@ Topic: Deterministic Finite Automaton (DFA) Given a string s, return whether s is a valid number or not Leetcode link: https://leetcode.com/problems/valid-number/description/ """ +from enum import Enum +from typing import Dict + +class CharType(Enum): + NUMERIC = 'NUMERIC' + SIGN = 'SIGN' + EXPONENT = 'EXPONENT' + DECIMAL = 'DECIMAL' + +class State(Enum): + INITIAL = 'INITIAL' + SIGNED = 'SIGNED' + WHOLE = 'WHOLE' + FRACTIONAL = 'FRACTIONAL' + FRACTION = 'FRACTION' + EXPONENTIAL = 'EXPONENTIAL' + EXP_SIGN = 'EXP_SIGN' + EXP_NUMBER = 'EXP_NUMBER' + +state_machine : Dict[State, Dict[CharType, State]] = { + State.INITIAL: {CharType.NUMERIC: State.WHOLE, CharType.SIGN: State.SIGNED, CharType.DECIMAL: State.FRACTIONAL}, + State.SIGNED: {CharType.NUMERIC: State.WHOLE, CharType.DECIMAL: State.FRACTIONAL}, + State.WHOLE: {CharType.NUMERIC: State.WHOLE, CharType.DECIMAL: State.FRACTION, CharType.EXPONENT: State.EXPONENTIAL}, + State.FRACTIONAL: {CharType.NUMERIC: State.FRACTION}, + State.FRACTION: {CharType.NUMERIC: State.FRACTION, CharType.EXPONENT: State.EXPONENTIAL}, + State.EXPONENTIAL: {CharType.NUMERIC: State.EXP_NUMBER, CharType.SIGN: State.EXP_SIGN}, + State.EXP_SIGN: {CharType.NUMERIC: State.EXP_NUMBER}, + State.EXP_NUMBER: {CharType.NUMERIC: State.EXP_NUMBER}, +} from enum import Enum From 1b1df64534126ba1ef430f42589a475b925a5906 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 12:22:54 +0000 Subject: [PATCH 10/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- strings/string_is_valid_number.py | 52 +++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/strings/string_is_valid_number.py b/strings/string_is_valid_number.py index 073240733..6ebee8942 100644 --- a/strings/string_is_valid_number.py +++ b/strings/string_is_valid_number.py @@ -4,32 +4,50 @@ Topic: Deterministic Finite Automaton (DFA) Given a string s, return whether s is a valid number or not Leetcode link: https://leetcode.com/problems/valid-number/description/ """ + from enum import Enum from typing import Dict + class CharType(Enum): - NUMERIC = 'NUMERIC' - SIGN = 'SIGN' - EXPONENT = 'EXPONENT' - DECIMAL = 'DECIMAL' + NUMERIC = "NUMERIC" + SIGN = "SIGN" + EXPONENT = "EXPONENT" + DECIMAL = "DECIMAL" + class State(Enum): - INITIAL = 'INITIAL' - SIGNED = 'SIGNED' - WHOLE = 'WHOLE' - FRACTIONAL = 'FRACTIONAL' - FRACTION = 'FRACTION' - EXPONENTIAL = 'EXPONENTIAL' - EXP_SIGN = 'EXP_SIGN' - EXP_NUMBER = 'EXP_NUMBER' + INITIAL = "INITIAL" + SIGNED = "SIGNED" + WHOLE = "WHOLE" + FRACTIONAL = "FRACTIONAL" + FRACTION = "FRACTION" + EXPONENTIAL = "EXPONENTIAL" + EXP_SIGN = "EXP_SIGN" + EXP_NUMBER = "EXP_NUMBER" -state_machine : Dict[State, Dict[CharType, State]] = { - State.INITIAL: {CharType.NUMERIC: State.WHOLE, CharType.SIGN: State.SIGNED, CharType.DECIMAL: State.FRACTIONAL}, + +state_machine: Dict[State, Dict[CharType, State]] = { + State.INITIAL: { + CharType.NUMERIC: State.WHOLE, + CharType.SIGN: State.SIGNED, + CharType.DECIMAL: State.FRACTIONAL, + }, State.SIGNED: {CharType.NUMERIC: State.WHOLE, CharType.DECIMAL: State.FRACTIONAL}, - State.WHOLE: {CharType.NUMERIC: State.WHOLE, CharType.DECIMAL: State.FRACTION, CharType.EXPONENT: State.EXPONENTIAL}, + State.WHOLE: { + CharType.NUMERIC: State.WHOLE, + CharType.DECIMAL: State.FRACTION, + CharType.EXPONENT: State.EXPONENTIAL, + }, State.FRACTIONAL: {CharType.NUMERIC: State.FRACTION}, - State.FRACTION: {CharType.NUMERIC: State.FRACTION, CharType.EXPONENT: State.EXPONENTIAL}, - State.EXPONENTIAL: {CharType.NUMERIC: State.EXP_NUMBER, CharType.SIGN: State.EXP_SIGN}, + State.FRACTION: { + CharType.NUMERIC: State.FRACTION, + CharType.EXPONENT: State.EXPONENTIAL, + }, + State.EXPONENTIAL: { + CharType.NUMERIC: State.EXP_NUMBER, + CharType.SIGN: State.EXP_SIGN, + }, State.EXP_SIGN: {CharType.NUMERIC: State.EXP_NUMBER}, State.EXP_NUMBER: {CharType.NUMERIC: State.EXP_NUMBER}, } From 272b0caf6a8beb32bb82ef1ed4957d476559e3d5 Mon Sep 17 00:00:00 2001 From: reniz-shah Date: Wed, 7 Aug 2024 18:05:08 +0530 Subject: [PATCH 11/12] resolve ruff check failing --- strings/string_is_valid_number.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/strings/string_is_valid_number.py b/strings/string_is_valid_number.py index 6ebee8942..ac35e88b8 100644 --- a/strings/string_is_valid_number.py +++ b/strings/string_is_valid_number.py @@ -6,7 +6,6 @@ Leetcode link: https://leetcode.com/problems/valid-number/description/ """ from enum import Enum -from typing import Dict class CharType(Enum): @@ -27,7 +26,7 @@ class State(Enum): EXP_NUMBER = "EXP_NUMBER" -state_machine: Dict[State, Dict[CharType, State]] = { +state_machine: dict[State, dict[CharType, State]] = { State.INITIAL: { CharType.NUMERIC: State.WHOLE, CharType.SIGN: State.SIGNED, From 914b0b052866558cde2482eb0903b3e50b483ad2 Mon Sep 17 00:00:00 2001 From: reniz-shah Date: Thu, 8 Aug 2024 10:38:10 +0530 Subject: [PATCH 12/12] resolve ruff check failing --- strings/string_is_valid_number.py | 46 ------------------------------- 1 file changed, 46 deletions(-) diff --git a/strings/string_is_valid_number.py b/strings/string_is_valid_number.py index ac35e88b8..cfd941630 100644 --- a/strings/string_is_valid_number.py +++ b/strings/string_is_valid_number.py @@ -8,52 +8,6 @@ Leetcode link: https://leetcode.com/problems/valid-number/description/ from enum import Enum -class CharType(Enum): - NUMERIC = "NUMERIC" - SIGN = "SIGN" - EXPONENT = "EXPONENT" - DECIMAL = "DECIMAL" - - -class State(Enum): - INITIAL = "INITIAL" - SIGNED = "SIGNED" - WHOLE = "WHOLE" - FRACTIONAL = "FRACTIONAL" - FRACTION = "FRACTION" - EXPONENTIAL = "EXPONENTIAL" - EXP_SIGN = "EXP_SIGN" - EXP_NUMBER = "EXP_NUMBER" - - -state_machine: dict[State, dict[CharType, State]] = { - State.INITIAL: { - CharType.NUMERIC: State.WHOLE, - CharType.SIGN: State.SIGNED, - CharType.DECIMAL: State.FRACTIONAL, - }, - State.SIGNED: {CharType.NUMERIC: State.WHOLE, CharType.DECIMAL: State.FRACTIONAL}, - State.WHOLE: { - CharType.NUMERIC: State.WHOLE, - CharType.DECIMAL: State.FRACTION, - CharType.EXPONENT: State.EXPONENTIAL, - }, - State.FRACTIONAL: {CharType.NUMERIC: State.FRACTION}, - State.FRACTION: { - CharType.NUMERIC: State.FRACTION, - CharType.EXPONENT: State.EXPONENTIAL, - }, - State.EXPONENTIAL: { - CharType.NUMERIC: State.EXP_NUMBER, - CharType.SIGN: State.EXP_SIGN, - }, - State.EXP_SIGN: {CharType.NUMERIC: State.EXP_NUMBER}, - State.EXP_NUMBER: {CharType.NUMERIC: State.EXP_NUMBER}, -} - -from enum import Enum - - class CharType(Enum): NUMERIC = "NUMERIC" SIGN = "SIGN"