From b22d4f32894692efa88ce3ad452f0997a799101c Mon Sep 17 00:00:00 2001 From: pingings <56961474+pingings@users.noreply.github.com> Date: Thu, 24 Oct 2019 16:43:04 +0100 Subject: [PATCH 01/29] Create sol1.py --- project_euler/problem_33/sol1.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 project_euler/problem_33/sol1.py diff --git a/project_euler/problem_33/sol1.py b/project_euler/problem_33/sol1.py new file mode 100644 index 000000000000..747f6faf3933 --- /dev/null +++ b/project_euler/problem_33/sol1.py @@ -0,0 +1,23 @@ +def isDigitCancelling(num,den): + if num != den: + if num % 10 == den // 10: + if (num // 10) / (den % 10) == num/den: + return True + +def solve(): + solutions = [] + den = 11 + for num in range(11,99): + while den <= 99: + if (num != den) and (num % 10 == den // 10) and (den%10 != 0): + if isDigitCancelling(num,den): + solutions.append("{}/{}".format(num,den)) + den += 1 + num += 1 + den = 10 + return solutions + + +if __name__ == "__main__": + print(*solve(),sep=" , ") + From 3e3f178f23f557abb530e5e1cc8b846ce9a0712a Mon Sep 17 00:00:00 2001 From: pingings <56961474+pingings@users.noreply.github.com> Date: Thu, 24 Oct 2019 16:43:19 +0100 Subject: [PATCH 02/29] Create __init__.py --- project_euler/problem_33/__init__.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 project_euler/problem_33/__init__.py diff --git a/project_euler/problem_33/__init__.py b/project_euler/problem_33/__init__.py new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/project_euler/problem_33/__init__.py @@ -0,0 +1 @@ + From a8a3c8b2ad3282810dede60ed578d5b7adfc0444 Mon Sep 17 00:00:00 2001 From: pingings <56961474+pingings@users.noreply.github.com> Date: Thu, 24 Oct 2019 16:44:00 +0100 Subject: [PATCH 03/29] Update sol1.py --- project_euler/problem_33/sol1.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/project_euler/problem_33/sol1.py b/project_euler/problem_33/sol1.py index 747f6faf3933..cfb19f74b76f 100644 --- a/project_euler/problem_33/sol1.py +++ b/project_euler/problem_33/sol1.py @@ -1,3 +1,23 @@ +""" + +Problem: + +The fraction 49/98 is a curious fraction, as an inexperienced +mathematician in attempting to simplify it may incorrectly believe +that 49/98 = 4/8, which is correct, is obtained by cancelling the 9s. + +We shall consider fractions like, 30/50 = 3/5, to be trivial examples. + +There are exactly four non-trivial examples of this type of fraction, +less than one in value, and containing two digits in the numerator +and denominator. + +If the product of these four fractions is given in its lowest common +terms, find the value of the denominator. + +""" + + def isDigitCancelling(num,den): if num != den: if num % 10 == den // 10: From 7903c926d604a4d35551f09a967441f383671648 Mon Sep 17 00:00:00 2001 From: pingings <56961474+pingings@users.noreply.github.com> Date: Thu, 24 Oct 2019 16:47:24 +0100 Subject: [PATCH 04/29] corrected range --- project_euler/problem_33/sol1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project_euler/problem_33/sol1.py b/project_euler/problem_33/sol1.py index cfb19f74b76f..98ff65d79aa3 100644 --- a/project_euler/problem_33/sol1.py +++ b/project_euler/problem_33/sol1.py @@ -27,7 +27,7 @@ def isDigitCancelling(num,den): def solve(): solutions = [] den = 11 - for num in range(11,99): + for num in range(11,100): while den <= 99: if (num != den) and (num % 10 == den // 10) and (den%10 != 0): if isDigitCancelling(num,den): From 03ffa62564b4c6a10ad99662ea395ed5368ac45e Mon Sep 17 00:00:00 2001 From: RitwickGhosh <56272528+RitwickGhosh@users.noreply.github.com> Date: Fri, 25 Oct 2019 20:41:05 +0530 Subject: [PATCH 05/29] Add files via upload --- machine_learning/isotonic.py | 953 +++++++++++++++++++++++++++++++++++ 1 file changed, 953 insertions(+) create mode 100644 machine_learning/isotonic.py diff --git a/machine_learning/isotonic.py b/machine_learning/isotonic.py new file mode 100644 index 000000000000..b76003f67206 --- /dev/null +++ b/machine_learning/isotonic.py @@ -0,0 +1,953 @@ +import numpy as np + +from scipy import interpolate + +from scipy.stats import spearmanr + +from .base import BaseEstimator, TransformerMixin, RegressorMixin + +from .utils import check_array, check_consistent_length + + +import warnings + +import math + +cimport numpy as np + +cimport cython + +from cython cimport floating + + + + + +def _inplace_contiguous_isotonic_regression(floating[::1] y, floating[::1] w): + + cdef: + + Py_ssize_t n = y.shape[0], i, k + + floating prev_y, sum_wy, sum_w + + Py_ssize_t[::1] target = np.arange(n, dtype=np.intp) + + + + # target describes a list of blocks. At any time, if [i..j] (inclusive) is + + # an active block, then target[i] := j and target[j] := i. + + + + # For "active" indices (block starts): + + # w[i] := sum{w_orig[j], j=[i..target[i]]} + + # y[i] := sum{y_orig[j]*w_orig[j], j=[i..target[i]]} / w[i] + + + + with nogil: + + i = 0 + + while i < n: + + k = target[i] + 1 + + if k == n: + + break + + if y[i] < y[k]: + + i = k + + continue + + sum_wy = w[i] * y[i] + + sum_w = w[i] + + while True: + + # We are within a decreasing subsequence. + + prev_y = y[k] + + sum_wy += w[k] * y[k] + + sum_w += w[k] + + k = target[k] + 1 + + if k == n or prev_y < y[k]: + + # Non-singleton decreasing subsequence is finished, + + # update first entry. + + y[i] = sum_wy / sum_w + + w[i] = sum_w + + target[i] = k - 1 + + target[k - 1] = i + + if i > 0: + + # Backtrack if we can. This makes the algorithm + + # single-pass and ensures O(n) complexity. + + i = target[i - 1] + + # Otherwise, restart from the same point. + + break + + # Reconstruct the solution. + + i = 0 + + while i < n: + + k = target[i] + 1 + + y[i + 1 : k] = y[i] + + i = k + + + + + +def _make_unique(np.ndarray[dtype=floating] X, + + np.ndarray[dtype=floating] y, + + np.ndarray[dtype=floating] sample_weights): + + """Average targets for duplicate X, drop duplicates. + + + + Aggregates duplicate X values into a single X value where + + the target y is a (sample_weighted) average of the individual + + targets. + + + + +__all__ = ['check_increasing', 'isotonic_regression', + + 'IsotonicRegression'] + + + + + +def check_increasing(x, y): + + """Determine whether y is monotonically correlated with x. + + + + y is found increasing or decreasing with respect to x based on a Spearman + + correlation test. + + + + Parameters + + ---------- + + x : array-like, shape=(n_samples,) + + Training data. + + + + y : array-like, shape=(n_samples,) + + Training target. + + + + Returns + + ------- + + increasing_bool : boolean + + Whether the relationship is increasing or decreasing. + + + + Notes + + ----- + + The Spearman correlation coefficient is estimated from the data, and the + + sign of the resulting estimate is used as the result. + + + + In the event that the 95% confidence interval based on Fisher transform + + spans zero, a warning is raised. + + + + References + + ---------- + + Fisher transformation. Wikipedia. + + https://en.wikipedia.org/wiki/Fisher_transformation + + """ + + + + # Calculate Spearman rho estimate and set return accordingly. + + rho, _ = spearmanr(x, y) + + increasing_bool = rho >= 0 + + + + # Run Fisher transform to get the rho CI, but handle rho=+/-1 + + if rho not in [-1.0, 1.0] and len(x) > 3: + + F = 0.5 * math.log((1. + rho) / (1. - rho)) + + F_se = 1 / math.sqrt(len(x) - 3) + + + + # Use a 95% CI, i.e., +/-1.96 S.E. + + # https://en.wikipedia.org/wiki/Fisher_transformation + + rho_0 = math.tanh(F - 1.96 * F_se) + + rho_1 = math.tanh(F + 1.96 * F_se) + + + + # Warn if the CI spans zero. + + if np.sign(rho_0) != np.sign(rho_1): + + warnings.warn("Confidence interval of the Spearman " + + "correlation coefficient spans zero. " + + "Determination of ``increasing`` may be " + + "suspect.") + + + + return increasing_bool + + + + + +def isotonic_regression(y, sample_weight=None, y_min=None, y_max=None, + + increasing=True): + + """Solve the isotonic regression model:: + + + + min sum w[i] (y[i] - y_[i]) ** 2 + + + + subject to y_min = y_[1] <= y_[2] ... <= y_[n] = y_max + + + + where: + + - y[i] are inputs (real numbers) + + - y_[i] are fitted + + - w[i] are optional strictly positive weights (default to 1.0) + + + + Read more in the :ref:`User Guide `. + + + + Parameters + + ---------- + + y : iterable of floats + + The data. + + + + sample_weight : iterable of floats, optional, default: None + + Weights on each point of the regression. + + If None, weight is set to 1 (equal weights). + + + + y_min : optional, default: None + + If not None, set the lowest value of the fit to y_min. + + + + y_max : optional, default: None + + If not None, set the highest value of the fit to y_max. + + + + increasing : boolean, optional, default: True + + Whether to compute ``y_`` is increasing (if set to True) or decreasing + + (if set to False) + + + + Returns + + ------- + + y_ : list of floats + + Isotonic fit of y. + + + + References + + ---------- + + "Active set algorithms for isotonic regression; A unifying framework" + + by Michael J. Best and Nilotpal Chakravarti, section 3. + + """ + + order = np.s_[:] if increasing else np.s_[::-1] + + y = check_array(y, ensure_2d=False, dtype=[np.float64, np.float32]) + + y = np.array(y[order], dtype=y.dtype) + + if sample_weight is None: + + sample_weight = np.ones(len(y), dtype=y.dtype) + + else: + + sample_weight = np.array(sample_weight[order], dtype=y.dtype) + + + + _inplace_contiguous_isotonic_regression(y, sample_weight) + + if y_min is not None or y_max is not None: + + # Older versions of np.clip don't accept None as a bound, so use np.inf + + if y_min is None: + + y_min = -np.inf + + if y_max is None: + + y_max = np.inf + + np.clip(y, y_min, y_max, y) + + return y[order] + + + + + +class IsotonicRegression(BaseEstimator, TransformerMixin, RegressorMixin): + + """Isotonic regression model. + + + + The isotonic regression optimization problem is defined by:: + + + + min sum w_i (y[i] - y_[i]) ** 2 + + + + subject to y_[i] <= y_[j] whenever X[i] <= X[j] + + and min(y_) = y_min, max(y_) = y_max + + + + where: + + - ``y[i]`` are inputs (real numbers) + + - ``y_[i]`` are fitted + + - ``X`` specifies the order. + + If ``X`` is non-decreasing then ``y_`` is non-decreasing. + + - ``w[i]`` are optional strictly positive weights (default to 1.0) + + + + Read more in the :ref:`User Guide `. + + + + Parameters + + ---------- + + y_min : optional, default: None + + If not None, set the lowest value of the fit to y_min. + + + + y_max : optional, default: None + + If not None, set the highest value of the fit to y_max. + + + + increasing : boolean or string, optional, default: True + + If boolean, whether or not to fit the isotonic regression with y + + increasing or decreasing. + + + + The string value "auto" determines whether y should + + increase or decrease based on the Spearman correlation estimate's + + sign. + + + + out_of_bounds : string, optional, default: "nan" + + The ``out_of_bounds`` parameter handles how x-values outside of the + + training domain are handled. When set to "nan", predicted y-values + + will be NaN. When set to "clip", predicted y-values will be + + set to the value corresponding to the nearest train interval endpoint. + + When set to "raise", allow ``interp1d`` to throw ValueError. + + + + + + Attributes + + ---------- + + X_min_ : float + + Minimum value of input array `X_` for left bound. + + + + X_max_ : float + + Maximum value of input array `X_` for right bound. + + + + f_ : function + + The stepwise interpolating function that covers the input domain ``X``. + + + + Notes + + ----- + + Ties are broken using the secondary method from Leeuw, 1977. + + + + References + + ---------- + + Isotonic Median Regression: A Linear Programming Approach + + Nilotpal Chakravarti + + Mathematics of Operations Research + + Vol. 14, No. 2 (May, 1989), pp. 303-308 + + + + Isotone Optimization in R : Pool-Adjacent-Violators + + Algorithm (PAVA) and Active Set Methods + + Leeuw, Hornik, Mair + + Journal of Statistical Software 2009 + + + + Correctness of Kruskal's algorithms for monotone regression with ties + + Leeuw, Psychometrica, 1977 + + + + Examples + + -------- + + >>> from sklearn.datasets import make_regression + + >>> from sklearn.isotonic import IsotonicRegression + + >>> X, y = make_regression(n_samples=10, n_features=1, random_state=41) + + >>> iso_reg = IsotonicRegression().fit(X.flatten(), y) + + >>> iso_reg.predict([.1, .2]) # doctest: +ELLIPSIS + + array([1.8628..., 3.7256...]) + + """ + + def __init__(self, y_min=None, y_max=None, increasing=True, + + out_of_bounds='nan'): + + self.y_min = y_min + + self.y_max = y_max + + self.increasing = increasing + + self.out_of_bounds = out_of_bounds + + + + def _check_fit_data(self, X, y, sample_weight=None): + + if len(X.shape) != 1: + + raise ValueError("X should be a 1d array") + + + + def _build_f(self, X, y): + + """Build the f_ interp1d function.""" + + + + # Handle the out_of_bounds argument by setting bounds_error + + if self.out_of_bounds not in ["raise", "nan", "clip"]: + + raise ValueError("The argument ``out_of_bounds`` must be in " + + "'nan', 'clip', 'raise'; got {0}" + + .format(self.out_of_bounds)) + + + + bounds_error = self.out_of_bounds == "raise" + + if len(y) == 1: + + # single y, constant prediction + + self.f_ = lambda x: y.repeat(x.shape) + + else: + + self.f_ = interpolate.interp1d(X, y, kind='linear', + + bounds_error=bounds_error) + + + + def _build_y(self, X, y, sample_weight, trim_duplicates=True): + + """Build the y_ IsotonicRegression.""" + + self._check_fit_data(X, y, sample_weight) + + + + # Determine increasing if auto-determination requested + + if self.increasing == 'auto': + + self.increasing_ = check_increasing(X, y) + + else: + + self.increasing_ = self.increasing + + + + # If sample_weights is passed, removed zero-weight values and clean + + # order + + if sample_weight is not None: + + sample_weight = check_array(sample_weight, ensure_2d=False, + + dtype=X.dtype) + + mask = sample_weight > 0 + + X, y, sample_weight = X[mask], y[mask], sample_weight[mask] + + else: + + sample_weight = np.ones(len(y), dtype=X.dtype) + + + + order = np.lexsort((y, X)) + + X, y, sample_weight = [array[order] for array in [X, y, sample_weight]] + + unique_X, unique_y, unique_sample_weight = _make_unique( + + X, y, sample_weight) + + + + # Store _X_ and _y_ to maintain backward compat during the deprecation + + # period of X_ and y_ + + self._X_ = X = unique_X + + self._y_ = y = isotonic_regression(unique_y, unique_sample_weight, + + self.y_min, self.y_max, + + increasing=self.increasing_) + + + + # Handle the left and right bounds on X + + self.X_min_, self.X_max_ = np.min(X), np.max(X) + + + + if trim_duplicates: + + # Remove unnecessary points for faster prediction + + keep_data = np.ones((len(y),), dtype=bool) + + # Aside from the 1st and last point, remove points whose y values + + # are equal to both the point before and the point after it. + + keep_data[1:-1] = np.logical_or( + + np.not_equal(y[1:-1], y[:-2]), + + np.not_equal(y[1:-1], y[2:]) + + ) + + return X[keep_data], y[keep_data] + + else: + + # The ability to turn off trim_duplicates is only used to it make + + # easier to unit test that removing duplicates in y does not have + + # any impact the resulting interpolation function (besides + + # prediction speed). + + return X, y + + + + def fit(self, X, y, sample_weight=None): + + """Fit the model using X, y as training data. + + + + Parameters + + ---------- + + X : array-like, shape=(n_samples,) + + Training data. + + + + y : array-like, shape=(n_samples,) + + Training target. + + + + sample_weight : array-like, shape=(n_samples,), optional, default: None + + Weights. If set to None, all weights will be set to 1 (equal + + weights). + + + + Returns + + ------- + + self : object + + Returns an instance of self. + + + + Notes + + ----- + + X is stored for future use, as `transform` needs X to interpolate + + new input data. + + """ + + check_params = dict(accept_sparse=False, ensure_2d=False, + + dtype=[np.float64, np.float32]) + + X = check_array(X, **check_params) + + y = check_array(y, **check_params) + + check_consistent_length(X, y, sample_weight) + + + + # Transform y by running the isotonic regression algorithm and + + # transform X accordingly. + + X, y = self._build_y(X, y, sample_weight) + + + + # It is necessary to store the non-redundant part of the training set + + # on the model to make it possible to support model persistence via + + # the pickle module as the object built by scipy.interp1d is not + + # picklable directly. + + self._necessary_X_, self._necessary_y_ = X, y + + + + # Build the interpolation function + + self._build_f(X, y) + + return self + + + + def transform(self, T): + + """Transform new data by linear interpolation + + + + Parameters + + ---------- + + T : array-like, shape=(n_samples,) + + Data to transform. + + + + Returns + + ------- + + T_ : array, shape=(n_samples,) + + The transformed data + + """ + + + + if hasattr(self, '_necessary_X_'): + + dtype = self._necessary_X_.dtype + + else: + + dtype = np.float64 + + + + T = check_array(T, dtype=dtype, ensure_2d=False) + + + + if len(T.shape) != 1: + + raise ValueError("Isotonic regression input should be a 1d array") + + + + # Handle the out_of_bounds argument by clipping if needed + + if self.out_of_bounds not in ["raise", "nan", "clip"]: + + raise ValueError("The argument ``out_of_bounds`` must be in " + + "'nan', 'clip', 'raise'; got {0}" + + .format(self.out_of_bounds)) + + + + if self.out_of_bounds == "clip": + + T = np.clip(T, self.X_min_, self.X_max_) + + + + res = self.f_(T) + + + + # on scipy 0.17, interp1d up-casts to float64, so we cast back + + res = res.astype(T.dtype) + + + + return res + + + + def predict(self, T): + + """Predict new data by linear interpolation. + + + + Parameters + + ---------- + + T : array-like, shape=(n_samples,) + + Data to transform. + + + + Returns + + ------- + + T_ : array, shape=(n_samples,) + + Transformed data. + + """ + + return self.transform(T) + + + + def __getstate__(self): + + """Pickle-protocol - return state of the estimator. """ + + state = super().__getstate__() + + # remove interpolation method + + state.pop('f_', None) + + return state + + + + def __setstate__(self, state): + + """Pickle-protocol - set state of the estimator. + + + + We need to rebuild the interpolation function. + + """ + + super().__setstate__(state) + + if hasattr(self, '_necessary_X_') and hasattr(self, '_necessary_y_'): + + self._build_f(self._necessary_X_, self._necessary_y_) + + + + def _more_tags(self): + + return {'X_types': ['1darray']} \ No newline at end of file From 7b5fbaaebe2fabf69ce2a0451e77e871feaffd1b Mon Sep 17 00:00:00 2001 From: RitwickGhosh <56272528+RitwickGhosh@users.noreply.github.com> Date: Fri, 25 Oct 2019 20:44:22 +0530 Subject: [PATCH 06/29] Update DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index a4838d24dab7..b2d21ccfa395 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -207,6 +207,7 @@ - [knn sklearn](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/knn_sklearn.py) - [linear regression](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/linear_regression.py) - [logistic regression](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/logistic_regression.py) +- [Isotonic regression](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/isotonic.py) - [naive bayes](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/naive_bayes.ipynb) - Random Forest Classification - [random forest classification](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/random_forest_classification/random_forest_classification.py) From 264615bfb4a810f4fd53c9bc4ecaf500cab87bec Mon Sep 17 00:00:00 2001 From: RitwickGhosh <56272528+RitwickGhosh@users.noreply.github.com> Date: Sat, 26 Oct 2019 12:17:16 +0530 Subject: [PATCH 07/29] Create sol1.py --- project_euler/Problem_27/sol1.py | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 project_euler/Problem_27/sol1.py diff --git a/project_euler/Problem_27/sol1.py b/project_euler/Problem_27/sol1.py new file mode 100644 index 000000000000..2961c6ff4c7a --- /dev/null +++ b/project_euler/Problem_27/sol1.py @@ -0,0 +1,39 @@ +""" +Euler discovered the remarkable quadratic formula: +n2 + n + 41 +It turns out that the formula will produce 40 primes for the consecutive values n = 0 to 39. However, when n = 40, 402 + 40 + 41 = 40(40 + 1) + 41 is divisible by 41, and certainly when n = 41, 412 + 41 + 41 is clearly divisible by 41. +The incredible formula n2 − 79n + 1601 was discovered, which produces 80 primes for the consecutive values n = 0 to 79. The product of the coefficients, −79 and 1601, is −126479. +Considering quadratics of the form: +n² + an + b, where |a| < 1000 and |b| < 1000 +where |n| is the modulus/absolute value of ne.g. |11| = 11 and |−4| = 4 +Find the product of the coefficients, a and b, for the quadratic expression that produces the maximum number of primes for consecutive values of n, starting with n = 0. +""" +def isPrime(input): + if (input == 2): + return True + if (input <= 1): + return False + if (input % 2 == 0): + return False + for (int i = input - 2; i >= math.sqrt(input); i -= 2): + if (input % i == 0): + return False + return True + +def findMaxN(a,b): + max = 0 + n = 2 + while (isPrime(n*n + a*n + b)==True): + if (n > max): + max = n++ + return max + + +def findMaxN(a,b): + max = 0 + n = 2 + while (isPrime(n*n + a*n + b)==True): + if (n > max): + max = n++ + return max + From e802182151e320fe5c23d2f39bc40cad655b2127 Mon Sep 17 00:00:00 2001 From: RitwickGhosh <56272528+RitwickGhosh@users.noreply.github.com> Date: Sat, 26 Oct 2019 12:19:51 +0530 Subject: [PATCH 08/29] Update sol1.py --- project_euler/Problem_27/sol1.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/project_euler/Problem_27/sol1.py b/project_euler/Problem_27/sol1.py index 2961c6ff4c7a..c090a10e0ed5 100644 --- a/project_euler/Problem_27/sol1.py +++ b/project_euler/Problem_27/sol1.py @@ -36,4 +36,7 @@ def findMaxN(a,b): if (n > max): max = n++ return max + +if __name__ == "__main__": + print(solution(int(input().strip()))) From 8f2f0bec74603fd804754e0eaf31d111e6bbd16d Mon Sep 17 00:00:00 2001 From: RitwickGhosh <56272528+RitwickGhosh@users.noreply.github.com> Date: Sat, 26 Oct 2019 12:21:43 +0530 Subject: [PATCH 09/29] Create __init__.py --- project_euler/Problem_27/__init__.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 project_euler/Problem_27/__init__.py diff --git a/project_euler/Problem_27/__init__.py b/project_euler/Problem_27/__init__.py new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/project_euler/Problem_27/__init__.py @@ -0,0 +1 @@ + From 568d4083402391bfd434171fd3f93e86681122e8 Mon Sep 17 00:00:00 2001 From: RitwickGhosh <56272528+RitwickGhosh@users.noreply.github.com> Date: Sat, 26 Oct 2019 12:24:51 +0530 Subject: [PATCH 10/29] Update DIRECTORY.md --- DIRECTORY.md | 1 - 1 file changed, 1 deletion(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index b2d21ccfa395..a4838d24dab7 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -207,7 +207,6 @@ - [knn sklearn](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/knn_sklearn.py) - [linear regression](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/linear_regression.py) - [logistic regression](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/logistic_regression.py) -- [Isotonic regression](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/isotonic.py) - [naive bayes](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/naive_bayes.ipynb) - Random Forest Classification - [random forest classification](https://github.com/TheAlgorithms/Python/blob/master/machine_learning/random_forest_classification/random_forest_classification.py) From 8eaf27ff20061366dd2aaec0a59dea4a84377912 Mon Sep 17 00:00:00 2001 From: RitwickGhosh <56272528+RitwickGhosh@users.noreply.github.com> Date: Sat, 26 Oct 2019 12:26:32 +0530 Subject: [PATCH 11/29] Delete isotonic.py --- machine_learning/isotonic.py | 953 ----------------------------------- 1 file changed, 953 deletions(-) delete mode 100644 machine_learning/isotonic.py diff --git a/machine_learning/isotonic.py b/machine_learning/isotonic.py deleted file mode 100644 index b76003f67206..000000000000 --- a/machine_learning/isotonic.py +++ /dev/null @@ -1,953 +0,0 @@ -import numpy as np - -from scipy import interpolate - -from scipy.stats import spearmanr - -from .base import BaseEstimator, TransformerMixin, RegressorMixin - -from .utils import check_array, check_consistent_length - - -import warnings - -import math - -cimport numpy as np - -cimport cython - -from cython cimport floating - - - - - -def _inplace_contiguous_isotonic_regression(floating[::1] y, floating[::1] w): - - cdef: - - Py_ssize_t n = y.shape[0], i, k - - floating prev_y, sum_wy, sum_w - - Py_ssize_t[::1] target = np.arange(n, dtype=np.intp) - - - - # target describes a list of blocks. At any time, if [i..j] (inclusive) is - - # an active block, then target[i] := j and target[j] := i. - - - - # For "active" indices (block starts): - - # w[i] := sum{w_orig[j], j=[i..target[i]]} - - # y[i] := sum{y_orig[j]*w_orig[j], j=[i..target[i]]} / w[i] - - - - with nogil: - - i = 0 - - while i < n: - - k = target[i] + 1 - - if k == n: - - break - - if y[i] < y[k]: - - i = k - - continue - - sum_wy = w[i] * y[i] - - sum_w = w[i] - - while True: - - # We are within a decreasing subsequence. - - prev_y = y[k] - - sum_wy += w[k] * y[k] - - sum_w += w[k] - - k = target[k] + 1 - - if k == n or prev_y < y[k]: - - # Non-singleton decreasing subsequence is finished, - - # update first entry. - - y[i] = sum_wy / sum_w - - w[i] = sum_w - - target[i] = k - 1 - - target[k - 1] = i - - if i > 0: - - # Backtrack if we can. This makes the algorithm - - # single-pass and ensures O(n) complexity. - - i = target[i - 1] - - # Otherwise, restart from the same point. - - break - - # Reconstruct the solution. - - i = 0 - - while i < n: - - k = target[i] + 1 - - y[i + 1 : k] = y[i] - - i = k - - - - - -def _make_unique(np.ndarray[dtype=floating] X, - - np.ndarray[dtype=floating] y, - - np.ndarray[dtype=floating] sample_weights): - - """Average targets for duplicate X, drop duplicates. - - - - Aggregates duplicate X values into a single X value where - - the target y is a (sample_weighted) average of the individual - - targets. - - - - -__all__ = ['check_increasing', 'isotonic_regression', - - 'IsotonicRegression'] - - - - - -def check_increasing(x, y): - - """Determine whether y is monotonically correlated with x. - - - - y is found increasing or decreasing with respect to x based on a Spearman - - correlation test. - - - - Parameters - - ---------- - - x : array-like, shape=(n_samples,) - - Training data. - - - - y : array-like, shape=(n_samples,) - - Training target. - - - - Returns - - ------- - - increasing_bool : boolean - - Whether the relationship is increasing or decreasing. - - - - Notes - - ----- - - The Spearman correlation coefficient is estimated from the data, and the - - sign of the resulting estimate is used as the result. - - - - In the event that the 95% confidence interval based on Fisher transform - - spans zero, a warning is raised. - - - - References - - ---------- - - Fisher transformation. Wikipedia. - - https://en.wikipedia.org/wiki/Fisher_transformation - - """ - - - - # Calculate Spearman rho estimate and set return accordingly. - - rho, _ = spearmanr(x, y) - - increasing_bool = rho >= 0 - - - - # Run Fisher transform to get the rho CI, but handle rho=+/-1 - - if rho not in [-1.0, 1.0] and len(x) > 3: - - F = 0.5 * math.log((1. + rho) / (1. - rho)) - - F_se = 1 / math.sqrt(len(x) - 3) - - - - # Use a 95% CI, i.e., +/-1.96 S.E. - - # https://en.wikipedia.org/wiki/Fisher_transformation - - rho_0 = math.tanh(F - 1.96 * F_se) - - rho_1 = math.tanh(F + 1.96 * F_se) - - - - # Warn if the CI spans zero. - - if np.sign(rho_0) != np.sign(rho_1): - - warnings.warn("Confidence interval of the Spearman " - - "correlation coefficient spans zero. " - - "Determination of ``increasing`` may be " - - "suspect.") - - - - return increasing_bool - - - - - -def isotonic_regression(y, sample_weight=None, y_min=None, y_max=None, - - increasing=True): - - """Solve the isotonic regression model:: - - - - min sum w[i] (y[i] - y_[i]) ** 2 - - - - subject to y_min = y_[1] <= y_[2] ... <= y_[n] = y_max - - - - where: - - - y[i] are inputs (real numbers) - - - y_[i] are fitted - - - w[i] are optional strictly positive weights (default to 1.0) - - - - Read more in the :ref:`User Guide `. - - - - Parameters - - ---------- - - y : iterable of floats - - The data. - - - - sample_weight : iterable of floats, optional, default: None - - Weights on each point of the regression. - - If None, weight is set to 1 (equal weights). - - - - y_min : optional, default: None - - If not None, set the lowest value of the fit to y_min. - - - - y_max : optional, default: None - - If not None, set the highest value of the fit to y_max. - - - - increasing : boolean, optional, default: True - - Whether to compute ``y_`` is increasing (if set to True) or decreasing - - (if set to False) - - - - Returns - - ------- - - y_ : list of floats - - Isotonic fit of y. - - - - References - - ---------- - - "Active set algorithms for isotonic regression; A unifying framework" - - by Michael J. Best and Nilotpal Chakravarti, section 3. - - """ - - order = np.s_[:] if increasing else np.s_[::-1] - - y = check_array(y, ensure_2d=False, dtype=[np.float64, np.float32]) - - y = np.array(y[order], dtype=y.dtype) - - if sample_weight is None: - - sample_weight = np.ones(len(y), dtype=y.dtype) - - else: - - sample_weight = np.array(sample_weight[order], dtype=y.dtype) - - - - _inplace_contiguous_isotonic_regression(y, sample_weight) - - if y_min is not None or y_max is not None: - - # Older versions of np.clip don't accept None as a bound, so use np.inf - - if y_min is None: - - y_min = -np.inf - - if y_max is None: - - y_max = np.inf - - np.clip(y, y_min, y_max, y) - - return y[order] - - - - - -class IsotonicRegression(BaseEstimator, TransformerMixin, RegressorMixin): - - """Isotonic regression model. - - - - The isotonic regression optimization problem is defined by:: - - - - min sum w_i (y[i] - y_[i]) ** 2 - - - - subject to y_[i] <= y_[j] whenever X[i] <= X[j] - - and min(y_) = y_min, max(y_) = y_max - - - - where: - - - ``y[i]`` are inputs (real numbers) - - - ``y_[i]`` are fitted - - - ``X`` specifies the order. - - If ``X`` is non-decreasing then ``y_`` is non-decreasing. - - - ``w[i]`` are optional strictly positive weights (default to 1.0) - - - - Read more in the :ref:`User Guide `. - - - - Parameters - - ---------- - - y_min : optional, default: None - - If not None, set the lowest value of the fit to y_min. - - - - y_max : optional, default: None - - If not None, set the highest value of the fit to y_max. - - - - increasing : boolean or string, optional, default: True - - If boolean, whether or not to fit the isotonic regression with y - - increasing or decreasing. - - - - The string value "auto" determines whether y should - - increase or decrease based on the Spearman correlation estimate's - - sign. - - - - out_of_bounds : string, optional, default: "nan" - - The ``out_of_bounds`` parameter handles how x-values outside of the - - training domain are handled. When set to "nan", predicted y-values - - will be NaN. When set to "clip", predicted y-values will be - - set to the value corresponding to the nearest train interval endpoint. - - When set to "raise", allow ``interp1d`` to throw ValueError. - - - - - - Attributes - - ---------- - - X_min_ : float - - Minimum value of input array `X_` for left bound. - - - - X_max_ : float - - Maximum value of input array `X_` for right bound. - - - - f_ : function - - The stepwise interpolating function that covers the input domain ``X``. - - - - Notes - - ----- - - Ties are broken using the secondary method from Leeuw, 1977. - - - - References - - ---------- - - Isotonic Median Regression: A Linear Programming Approach - - Nilotpal Chakravarti - - Mathematics of Operations Research - - Vol. 14, No. 2 (May, 1989), pp. 303-308 - - - - Isotone Optimization in R : Pool-Adjacent-Violators - - Algorithm (PAVA) and Active Set Methods - - Leeuw, Hornik, Mair - - Journal of Statistical Software 2009 - - - - Correctness of Kruskal's algorithms for monotone regression with ties - - Leeuw, Psychometrica, 1977 - - - - Examples - - -------- - - >>> from sklearn.datasets import make_regression - - >>> from sklearn.isotonic import IsotonicRegression - - >>> X, y = make_regression(n_samples=10, n_features=1, random_state=41) - - >>> iso_reg = IsotonicRegression().fit(X.flatten(), y) - - >>> iso_reg.predict([.1, .2]) # doctest: +ELLIPSIS - - array([1.8628..., 3.7256...]) - - """ - - def __init__(self, y_min=None, y_max=None, increasing=True, - - out_of_bounds='nan'): - - self.y_min = y_min - - self.y_max = y_max - - self.increasing = increasing - - self.out_of_bounds = out_of_bounds - - - - def _check_fit_data(self, X, y, sample_weight=None): - - if len(X.shape) != 1: - - raise ValueError("X should be a 1d array") - - - - def _build_f(self, X, y): - - """Build the f_ interp1d function.""" - - - - # Handle the out_of_bounds argument by setting bounds_error - - if self.out_of_bounds not in ["raise", "nan", "clip"]: - - raise ValueError("The argument ``out_of_bounds`` must be in " - - "'nan', 'clip', 'raise'; got {0}" - - .format(self.out_of_bounds)) - - - - bounds_error = self.out_of_bounds == "raise" - - if len(y) == 1: - - # single y, constant prediction - - self.f_ = lambda x: y.repeat(x.shape) - - else: - - self.f_ = interpolate.interp1d(X, y, kind='linear', - - bounds_error=bounds_error) - - - - def _build_y(self, X, y, sample_weight, trim_duplicates=True): - - """Build the y_ IsotonicRegression.""" - - self._check_fit_data(X, y, sample_weight) - - - - # Determine increasing if auto-determination requested - - if self.increasing == 'auto': - - self.increasing_ = check_increasing(X, y) - - else: - - self.increasing_ = self.increasing - - - - # If sample_weights is passed, removed zero-weight values and clean - - # order - - if sample_weight is not None: - - sample_weight = check_array(sample_weight, ensure_2d=False, - - dtype=X.dtype) - - mask = sample_weight > 0 - - X, y, sample_weight = X[mask], y[mask], sample_weight[mask] - - else: - - sample_weight = np.ones(len(y), dtype=X.dtype) - - - - order = np.lexsort((y, X)) - - X, y, sample_weight = [array[order] for array in [X, y, sample_weight]] - - unique_X, unique_y, unique_sample_weight = _make_unique( - - X, y, sample_weight) - - - - # Store _X_ and _y_ to maintain backward compat during the deprecation - - # period of X_ and y_ - - self._X_ = X = unique_X - - self._y_ = y = isotonic_regression(unique_y, unique_sample_weight, - - self.y_min, self.y_max, - - increasing=self.increasing_) - - - - # Handle the left and right bounds on X - - self.X_min_, self.X_max_ = np.min(X), np.max(X) - - - - if trim_duplicates: - - # Remove unnecessary points for faster prediction - - keep_data = np.ones((len(y),), dtype=bool) - - # Aside from the 1st and last point, remove points whose y values - - # are equal to both the point before and the point after it. - - keep_data[1:-1] = np.logical_or( - - np.not_equal(y[1:-1], y[:-2]), - - np.not_equal(y[1:-1], y[2:]) - - ) - - return X[keep_data], y[keep_data] - - else: - - # The ability to turn off trim_duplicates is only used to it make - - # easier to unit test that removing duplicates in y does not have - - # any impact the resulting interpolation function (besides - - # prediction speed). - - return X, y - - - - def fit(self, X, y, sample_weight=None): - - """Fit the model using X, y as training data. - - - - Parameters - - ---------- - - X : array-like, shape=(n_samples,) - - Training data. - - - - y : array-like, shape=(n_samples,) - - Training target. - - - - sample_weight : array-like, shape=(n_samples,), optional, default: None - - Weights. If set to None, all weights will be set to 1 (equal - - weights). - - - - Returns - - ------- - - self : object - - Returns an instance of self. - - - - Notes - - ----- - - X is stored for future use, as `transform` needs X to interpolate - - new input data. - - """ - - check_params = dict(accept_sparse=False, ensure_2d=False, - - dtype=[np.float64, np.float32]) - - X = check_array(X, **check_params) - - y = check_array(y, **check_params) - - check_consistent_length(X, y, sample_weight) - - - - # Transform y by running the isotonic regression algorithm and - - # transform X accordingly. - - X, y = self._build_y(X, y, sample_weight) - - - - # It is necessary to store the non-redundant part of the training set - - # on the model to make it possible to support model persistence via - - # the pickle module as the object built by scipy.interp1d is not - - # picklable directly. - - self._necessary_X_, self._necessary_y_ = X, y - - - - # Build the interpolation function - - self._build_f(X, y) - - return self - - - - def transform(self, T): - - """Transform new data by linear interpolation - - - - Parameters - - ---------- - - T : array-like, shape=(n_samples,) - - Data to transform. - - - - Returns - - ------- - - T_ : array, shape=(n_samples,) - - The transformed data - - """ - - - - if hasattr(self, '_necessary_X_'): - - dtype = self._necessary_X_.dtype - - else: - - dtype = np.float64 - - - - T = check_array(T, dtype=dtype, ensure_2d=False) - - - - if len(T.shape) != 1: - - raise ValueError("Isotonic regression input should be a 1d array") - - - - # Handle the out_of_bounds argument by clipping if needed - - if self.out_of_bounds not in ["raise", "nan", "clip"]: - - raise ValueError("The argument ``out_of_bounds`` must be in " - - "'nan', 'clip', 'raise'; got {0}" - - .format(self.out_of_bounds)) - - - - if self.out_of_bounds == "clip": - - T = np.clip(T, self.X_min_, self.X_max_) - - - - res = self.f_(T) - - - - # on scipy 0.17, interp1d up-casts to float64, so we cast back - - res = res.astype(T.dtype) - - - - return res - - - - def predict(self, T): - - """Predict new data by linear interpolation. - - - - Parameters - - ---------- - - T : array-like, shape=(n_samples,) - - Data to transform. - - - - Returns - - ------- - - T_ : array, shape=(n_samples,) - - Transformed data. - - """ - - return self.transform(T) - - - - def __getstate__(self): - - """Pickle-protocol - return state of the estimator. """ - - state = super().__getstate__() - - # remove interpolation method - - state.pop('f_', None) - - return state - - - - def __setstate__(self, state): - - """Pickle-protocol - set state of the estimator. - - - - We need to rebuild the interpolation function. - - """ - - super().__setstate__(state) - - if hasattr(self, '_necessary_X_') and hasattr(self, '_necessary_y_'): - - self._build_f(self._necessary_X_, self._necessary_y_) - - - - def _more_tags(self): - - return {'X_types': ['1darray']} \ No newline at end of file From a91f13cfdba4546d0b14c6b32ed8cb7e19af5135 Mon Sep 17 00:00:00 2001 From: RitwickGhosh <56272528+RitwickGhosh@users.noreply.github.com> Date: Sat, 26 Oct 2019 13:08:43 +0530 Subject: [PATCH 12/29] Update sol1.py --- project_euler/Problem_27/sol1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project_euler/Problem_27/sol1.py b/project_euler/Problem_27/sol1.py index c090a10e0ed5..798e276a56bd 100644 --- a/project_euler/Problem_27/sol1.py +++ b/project_euler/Problem_27/sol1.py @@ -25,7 +25,7 @@ def findMaxN(a,b): n = 2 while (isPrime(n*n + a*n + b)==True): if (n > max): - max = n++ + max = n+1 return max @@ -34,7 +34,7 @@ def findMaxN(a,b): n = 2 while (isPrime(n*n + a*n + b)==True): if (n > max): - max = n++ + max = n+1 return max if __name__ == "__main__": From 34a2715c006312fdd34d240266267ef757180132 Mon Sep 17 00:00:00 2001 From: itsvinayak Date: Wed, 30 Oct 2019 23:07:25 +0530 Subject: [PATCH 13/29] Problem_27_project_euler --- project_euler/Problem_27/sol1.py | 66 +++++++++++++++++--------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/project_euler/Problem_27/sol1.py b/project_euler/Problem_27/sol1.py index 798e276a56bd..9b2dc773aa37 100644 --- a/project_euler/Problem_27/sol1.py +++ b/project_euler/Problem_27/sol1.py @@ -8,35 +8,41 @@ where |n| is the modulus/absolute value of ne.g. |11| = 11 and |−4| = 4 Find the product of the coefficients, a and b, for the quadratic expression that produces the maximum number of primes for consecutive values of n, starting with n = 0. """ -def isPrime(input): - if (input == 2): - return True - if (input <= 1): - return False - if (input % 2 == 0): - return False - for (int i = input - 2; i >= math.sqrt(input); i -= 2): - if (input % i == 0): - return False - return True - -def findMaxN(a,b): - max = 0 - n = 2 - while (isPrime(n*n + a*n + b)==True): - if (n > max): - max = n+1 - return max - - -def findMaxN(a,b): - max = 0 - n = 2 - while (isPrime(n*n + a*n + b)==True): - if (n > max): - max = n+1 - return max + +import math + +def isPrime(k): + # checks if a number is prime + if k < 2: return False + elif k == 2: return True + elif k % 2 == 0: return False + else: + for x in range(3, int(math.sqrt(k)+1), 2): + if k % x == 0: return False + + return True + + +def solution(a_limit, b_limit): + longest = [0, 0, 0] + # length, a, b + for a in range((a_limit * -1) + 1, a_limit): + for b in range(2, b_limit): + if isPrime(b): + count = 0 + n = 0 + while isPrime((n**2) + (a*n) + b): + count += 1 + n += 1 + + if count > longest[0]: + longest = [count, a, b] + + ans=longest[1]*longest[2] + return ans + + + if __name__ == "__main__": - print(solution(int(input().strip()))) - + print(solution(1000, 1000)) From ff5713733463d15091057818fa48059d23e7e217 Mon Sep 17 00:00:00 2001 From: itsvinayak Date: Thu, 31 Oct 2019 09:40:25 +0530 Subject: [PATCH 14/29] project_euler/Problem_27/sol1.py --- project_euler/Problem_27/sol1.py | 42 +++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/project_euler/Problem_27/sol1.py b/project_euler/Problem_27/sol1.py index 9b2dc773aa37..0134a67d0690 100644 --- a/project_euler/Problem_27/sol1.py +++ b/project_euler/Problem_27/sol1.py @@ -11,38 +11,52 @@ import math + def isPrime(k): - # checks if a number is prime - if k < 2: return False - elif k == 2: return True - elif k % 2 == 0: return False - else: - for x in range(3, int(math.sqrt(k)+1), 2): - if k % x == 0: return False + # checks if a number is prime + if k < 2: + return False + elif k == 2: + return True + elif k % 2 == 0: + return False + else: + for x in range(3, int(math.sqrt(k) + 1), 2): + if k % x == 0: + return False - return True + return True def solution(a_limit, b_limit): + """ + >>> solution(1000, 1000) + -59231 + >>> solution(2000, 2000) + -126479 + >>> solution(-1000, 1000) + 0 + >>> solution(-1000, -1000) + 0 + + """ longest = [0, 0, 0] - # length, a, b + # length, a, b for a in range((a_limit * -1) + 1, a_limit): for b in range(2, b_limit): if isPrime(b): count = 0 n = 0 - while isPrime((n**2) + (a*n) + b): + while isPrime((n ** 2) + (a * n) + b): count += 1 n += 1 if count > longest[0]: longest = [count, a, b] - ans=longest[1]*longest[2] + ans = longest[1] * longest[2] return ans - - if __name__ == "__main__": - print(solution(1000, 1000)) + print(solution(1000, 1000)) From aef684f8f8f06f4ad574df59a370964f49883185 Mon Sep 17 00:00:00 2001 From: itsvinayak Date: Thu, 31 Oct 2019 10:04:59 +0530 Subject: [PATCH 15/29] project_euler/Problem_27/sol1.py --- project_euler/Problem_27/sol1.py | 67 +++++++++++++++----------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/project_euler/Problem_27/sol1.py b/project_euler/Problem_27/sol1.py index 0134a67d0690..d0b86dc1a025 100644 --- a/project_euler/Problem_27/sol1.py +++ b/project_euler/Problem_27/sol1.py @@ -11,25 +11,23 @@ import math - -def isPrime(k): - # checks if a number is prime - if k < 2: - return False - elif k == 2: - return True - elif k % 2 == 0: - return False - else: - for x in range(3, int(math.sqrt(k) + 1), 2): - if k % x == 0: - return False - - return True - +def isprime(k): + # checks if a number is prime + if k < 2: + return False + elif k == 2: + return True + elif k % 2 == 0: + return False + else: + for x in range(3, int(math.sqrt(k) + 1), 2): + if k % x == 0: + return False + + return True def solution(a_limit, b_limit): - """ + """ >>> solution(1000, 1000) -59231 >>> solution(2000, 2000) @@ -40,23 +38,22 @@ def solution(a_limit, b_limit): 0 """ - longest = [0, 0, 0] - # length, a, b - for a in range((a_limit * -1) + 1, a_limit): - for b in range(2, b_limit): - if isPrime(b): - count = 0 - n = 0 - while isPrime((n ** 2) + (a * n) + b): - count += 1 - n += 1 - - if count > longest[0]: - longest = [count, a, b] - - ans = longest[1] * longest[2] - return ans - + longest = [0, 0, 0] + # length, a, b + for a in range((a_limit * -1) + 1, a_limit): + for b in range(2, b_limit): + if isprime(b): + count = 0 + n = 0 + while isprime((n ** 2) + (a * n) + b): + count += 1 + n += 1 + + if count > longest[0]: + longest = [count, a, b] + + ans = longest[1] * longest[2] + return ans if __name__ == "__main__": - print(solution(1000, 1000)) + print(solution(1000, 1000)) From e9fe8cbb6609da132aa6edceae5fa530ac2efe55 Mon Sep 17 00:00:00 2001 From: itsvinayak Date: Thu, 31 Oct 2019 10:24:38 +0530 Subject: [PATCH 16/29] project_euler/problem_27/ --- project_euler/problem_27/__init__.py | 1 + project_euler/problem_27/sol1.py | 59 ++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 project_euler/problem_27/__init__.py create mode 100644 project_euler/problem_27/sol1.py diff --git a/project_euler/problem_27/__init__.py b/project_euler/problem_27/__init__.py new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/project_euler/problem_27/__init__.py @@ -0,0 +1 @@ + diff --git a/project_euler/problem_27/sol1.py b/project_euler/problem_27/sol1.py new file mode 100644 index 000000000000..d0b86dc1a025 --- /dev/null +++ b/project_euler/problem_27/sol1.py @@ -0,0 +1,59 @@ +""" +Euler discovered the remarkable quadratic formula: +n2 + n + 41 +It turns out that the formula will produce 40 primes for the consecutive values n = 0 to 39. However, when n = 40, 402 + 40 + 41 = 40(40 + 1) + 41 is divisible by 41, and certainly when n = 41, 412 + 41 + 41 is clearly divisible by 41. +The incredible formula n2 − 79n + 1601 was discovered, which produces 80 primes for the consecutive values n = 0 to 79. The product of the coefficients, −79 and 1601, is −126479. +Considering quadratics of the form: +n² + an + b, where |a| < 1000 and |b| < 1000 +where |n| is the modulus/absolute value of ne.g. |11| = 11 and |−4| = 4 +Find the product of the coefficients, a and b, for the quadratic expression that produces the maximum number of primes for consecutive values of n, starting with n = 0. +""" + +import math + +def isprime(k): + # checks if a number is prime + if k < 2: + return False + elif k == 2: + return True + elif k % 2 == 0: + return False + else: + for x in range(3, int(math.sqrt(k) + 1), 2): + if k % x == 0: + return False + + return True + +def solution(a_limit, b_limit): + """ + >>> solution(1000, 1000) + -59231 + >>> solution(2000, 2000) + -126479 + >>> solution(-1000, 1000) + 0 + >>> solution(-1000, -1000) + 0 + + """ + longest = [0, 0, 0] + # length, a, b + for a in range((a_limit * -1) + 1, a_limit): + for b in range(2, b_limit): + if isprime(b): + count = 0 + n = 0 + while isprime((n ** 2) + (a * n) + b): + count += 1 + n += 1 + + if count > longest[0]: + longest = [count, a, b] + + ans = longest[1] * longest[2] + return ans + +if __name__ == "__main__": + print(solution(1000, 1000)) From bd47691bb46226c002a5317b09be34253d473dc4 Mon Sep 17 00:00:00 2001 From: itsvinayak Date: Thu, 31 Oct 2019 10:33:30 +0530 Subject: [PATCH 17/29] project_euler/problem_27 --- project_euler/Problem_27/__init__.py | 1 - project_euler/Problem_27/sol1.py | 59 ---------------------------- 2 files changed, 60 deletions(-) delete mode 100644 project_euler/Problem_27/__init__.py delete mode 100644 project_euler/Problem_27/sol1.py diff --git a/project_euler/Problem_27/__init__.py b/project_euler/Problem_27/__init__.py deleted file mode 100644 index 8b137891791f..000000000000 --- a/project_euler/Problem_27/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/project_euler/Problem_27/sol1.py b/project_euler/Problem_27/sol1.py deleted file mode 100644 index d0b86dc1a025..000000000000 --- a/project_euler/Problem_27/sol1.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -Euler discovered the remarkable quadratic formula: -n2 + n + 41 -It turns out that the formula will produce 40 primes for the consecutive values n = 0 to 39. However, when n = 40, 402 + 40 + 41 = 40(40 + 1) + 41 is divisible by 41, and certainly when n = 41, 412 + 41 + 41 is clearly divisible by 41. -The incredible formula n2 − 79n + 1601 was discovered, which produces 80 primes for the consecutive values n = 0 to 79. The product of the coefficients, −79 and 1601, is −126479. -Considering quadratics of the form: -n² + an + b, where |a| < 1000 and |b| < 1000 -where |n| is the modulus/absolute value of ne.g. |11| = 11 and |−4| = 4 -Find the product of the coefficients, a and b, for the quadratic expression that produces the maximum number of primes for consecutive values of n, starting with n = 0. -""" - -import math - -def isprime(k): - # checks if a number is prime - if k < 2: - return False - elif k == 2: - return True - elif k % 2 == 0: - return False - else: - for x in range(3, int(math.sqrt(k) + 1), 2): - if k % x == 0: - return False - - return True - -def solution(a_limit, b_limit): - """ - >>> solution(1000, 1000) - -59231 - >>> solution(2000, 2000) - -126479 - >>> solution(-1000, 1000) - 0 - >>> solution(-1000, -1000) - 0 - - """ - longest = [0, 0, 0] - # length, a, b - for a in range((a_limit * -1) + 1, a_limit): - for b in range(2, b_limit): - if isprime(b): - count = 0 - n = 0 - while isprime((n ** 2) + (a * n) + b): - count += 1 - n += 1 - - if count > longest[0]: - longest = [count, a, b] - - ans = longest[1] * longest[2] - return ans - -if __name__ == "__main__": - print(solution(1000, 1000)) From 10e64cfe0d6a8f46409ae850c4b84a17a1788e0c Mon Sep 17 00:00:00 2001 From: itsvinayak Date: Thu, 31 Oct 2019 10:37:09 +0530 Subject: [PATCH 18/29] project_euler/problem_27 --- project_euler/Problem_27/__init__.py | 1 - project_euler/Problem_27/sol1.py | 59 ---------------------------- 2 files changed, 60 deletions(-) delete mode 100644 project_euler/Problem_27/__init__.py delete mode 100644 project_euler/Problem_27/sol1.py diff --git a/project_euler/Problem_27/__init__.py b/project_euler/Problem_27/__init__.py deleted file mode 100644 index 8b137891791f..000000000000 --- a/project_euler/Problem_27/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/project_euler/Problem_27/sol1.py b/project_euler/Problem_27/sol1.py deleted file mode 100644 index d0b86dc1a025..000000000000 --- a/project_euler/Problem_27/sol1.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -Euler discovered the remarkable quadratic formula: -n2 + n + 41 -It turns out that the formula will produce 40 primes for the consecutive values n = 0 to 39. However, when n = 40, 402 + 40 + 41 = 40(40 + 1) + 41 is divisible by 41, and certainly when n = 41, 412 + 41 + 41 is clearly divisible by 41. -The incredible formula n2 − 79n + 1601 was discovered, which produces 80 primes for the consecutive values n = 0 to 79. The product of the coefficients, −79 and 1601, is −126479. -Considering quadratics of the form: -n² + an + b, where |a| < 1000 and |b| < 1000 -where |n| is the modulus/absolute value of ne.g. |11| = 11 and |−4| = 4 -Find the product of the coefficients, a and b, for the quadratic expression that produces the maximum number of primes for consecutive values of n, starting with n = 0. -""" - -import math - -def isprime(k): - # checks if a number is prime - if k < 2: - return False - elif k == 2: - return True - elif k % 2 == 0: - return False - else: - for x in range(3, int(math.sqrt(k) + 1), 2): - if k % x == 0: - return False - - return True - -def solution(a_limit, b_limit): - """ - >>> solution(1000, 1000) - -59231 - >>> solution(2000, 2000) - -126479 - >>> solution(-1000, 1000) - 0 - >>> solution(-1000, -1000) - 0 - - """ - longest = [0, 0, 0] - # length, a, b - for a in range((a_limit * -1) + 1, a_limit): - for b in range(2, b_limit): - if isprime(b): - count = 0 - n = 0 - while isprime((n ** 2) + (a * n) + b): - count += 1 - n += 1 - - if count > longest[0]: - longest = [count, a, b] - - ans = longest[1] * longest[2] - return ans - -if __name__ == "__main__": - print(solution(1000, 1000)) From e6a2a006933f728da1f06d9f1dd4b6539807b6dc Mon Sep 17 00:00:00 2001 From: itsvinayak Date: Thu, 31 Oct 2019 11:57:27 +0530 Subject: [PATCH 19/29] update sol1 of Euler Problem 27 solution script Added --- project_euler/problem_27/sol1.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/project_euler/problem_27/sol1.py b/project_euler/problem_27/sol1.py index d0b86dc1a025..379f7ff9630b 100644 --- a/project_euler/problem_27/sol1.py +++ b/project_euler/problem_27/sol1.py @@ -11,14 +11,12 @@ import math -def isprime(k): +def is_prime(k): # checks if a number is prime - if k < 2: + if k < 2 or k % 2 == 0: return False elif k == 2: return True - elif k % 2 == 0: - return False else: for x in range(3, int(math.sqrt(k) + 1), 2): if k % x == 0: @@ -36,16 +34,15 @@ def solution(a_limit, b_limit): 0 >>> solution(-1000, -1000) 0 - """ longest = [0, 0, 0] # length, a, b for a in range((a_limit * -1) + 1, a_limit): for b in range(2, b_limit): - if isprime(b): + if is_prime(b): count = 0 n = 0 - while isprime((n ** 2) + (a * n) + b): + while is_prime((n ** 2) + (a * n) + b): count += 1 n += 1 From 2f0d1884cf46753df342be0adec8c44ac11af0da Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Thu, 31 Oct 2019 08:06:15 +0100 Subject: [PATCH 20/29] Remove slow test, wrap long comments, format with psf/black --- project_euler/problem_27/sol1.py | 71 ++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/project_euler/problem_27/sol1.py b/project_euler/problem_27/sol1.py index 379f7ff9630b..ce12e40f0778 100644 --- a/project_euler/problem_27/sol1.py +++ b/project_euler/problem_27/sol1.py @@ -1,56 +1,63 @@ """ Euler discovered the remarkable quadratic formula: n2 + n + 41 -It turns out that the formula will produce 40 primes for the consecutive values n = 0 to 39. However, when n = 40, 402 + 40 + 41 = 40(40 + 1) + 41 is divisible by 41, and certainly when n = 41, 412 + 41 + 41 is clearly divisible by 41. -The incredible formula n2 − 79n + 1601 was discovered, which produces 80 primes for the consecutive values n = 0 to 79. The product of the coefficients, −79 and 1601, is −126479. +It turns out that the formula will produce 40 primes for the consecutive values +n = 0 to 39. However, when n = 40, 402 + 40 + 41 = 40(40 + 1) + 41 is divisible +by 41, and certainly when n = 41, 412 + 41 + 41 is clearly divisible by 41. +The incredible formula n2 − 79n + 1601 was discovered, which produces 80 primes +for the consecutive values n = 0 to 79. The product of the coefficients, −79 and +1601, is −126479. Considering quadratics of the form: n² + an + b, where |a| < 1000 and |b| < 1000 where |n| is the modulus/absolute value of ne.g. |11| = 11 and |−4| = 4 -Find the product of the coefficients, a and b, for the quadratic expression that produces the maximum number of primes for consecutive values of n, starting with n = 0. +Find the product of the coefficients, a and b, for the quadratic expression that +produces the maximum number of primes for consecutive values of n, starting with +n = 0. """ import math + def is_prime(k): - # checks if a number is prime - if k < 2 or k % 2 == 0: - return False - elif k == 2: - return True - else: - for x in range(3, int(math.sqrt(k) + 1), 2): - if k % x == 0: - return False + # checks if a number is prime + if k < 2 or k % 2 == 0: + return False + elif k == 2: + return True + else: + for x in range(3, int(math.sqrt(k) + 1), 2): + if k % x == 0: + return False + return True - return True def solution(a_limit, b_limit): - """ + """ >>> solution(1000, 1000) -59231 - >>> solution(2000, 2000) - -126479 + >>> solution(200, 1000) + -59231 + >>> solution(200, 200) + -4925 >>> solution(-1000, 1000) 0 >>> solution(-1000, -1000) 0 """ - longest = [0, 0, 0] - # length, a, b - for a in range((a_limit * -1) + 1, a_limit): - for b in range(2, b_limit): - if is_prime(b): - count = 0 - n = 0 - while is_prime((n ** 2) + (a * n) + b): - count += 1 - n += 1 - - if count > longest[0]: - longest = [count, a, b] + longest = [0, 0, 0] # length, a, b + for a in range((a_limit * -1) + 1, a_limit): + for b in range(2, b_limit): + if is_prime(b): + count = 0 + n = 0 + while is_prime((n ** 2) + (a * n) + b): + count += 1 + n += 1 + if count > longest[0]: + longest = [count, a, b] + ans = longest[1] * longest[2] + return ans - ans = longest[1] * longest[2] - return ans if __name__ == "__main__": - print(solution(1000, 1000)) + print(solution(1000, 1000)) From 4a9d42c7f94d687890ab8ecbb72acaba0c7601f0 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Thu, 31 Oct 2019 08:06:45 +0100 Subject: [PATCH 21/29] Delete __init__.py --- project_euler/problem_27/__init__.py | 1 - 1 file changed, 1 deletion(-) delete mode 100644 project_euler/problem_27/__init__.py diff --git a/project_euler/problem_27/__init__.py b/project_euler/problem_27/__init__.py deleted file mode 100644 index 8b137891791f..000000000000 --- a/project_euler/problem_27/__init__.py +++ /dev/null @@ -1 +0,0 @@ - From 5d98bc45e3cec1ee39a6a342775fb829f178030f Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Thu, 31 Oct 2019 08:08:11 +0100 Subject: [PATCH 22/29] Add type hints --- project_euler/problem_27/sol1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project_euler/problem_27/sol1.py b/project_euler/problem_27/sol1.py index ce12e40f0778..4bfc26643653 100644 --- a/project_euler/problem_27/sol1.py +++ b/project_euler/problem_27/sol1.py @@ -18,7 +18,7 @@ import math -def is_prime(k): +def is_prime(k: int) -> bool: # checks if a number is prime if k < 2 or k % 2 == 0: return False @@ -31,7 +31,7 @@ def is_prime(k): return True -def solution(a_limit, b_limit): +def solution(a_limit: int, b_limit: int) -> int: """ >>> solution(1000, 1000) -59231 From e18154fbcca27068700ee5eb2f35fafc5c08d9a3 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Thu, 31 Oct 2019 08:10:26 +0100 Subject: [PATCH 23/29] Add doctests to function is_prime() --- project_euler/problem_27/sol1.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/project_euler/problem_27/sol1.py b/project_euler/problem_27/sol1.py index 4bfc26643653..dbd07f81b713 100644 --- a/project_euler/problem_27/sol1.py +++ b/project_euler/problem_27/sol1.py @@ -19,7 +19,13 @@ def is_prime(k: int) -> bool: - # checks if a number is prime + """ + Determine if a number is prime + >>> is_prime(10) + False + >>> is_prime(11) + True + """ if k < 2 or k % 2 == 0: return False elif k == 2: From bb790078744e4063fa8ca912911ccba82bd86f6e Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Thu, 31 Oct 2019 08:13:55 +0100 Subject: [PATCH 24/29] Rename project_euler/problem_27/project_euler/problem_27/sol1.pysol1.py to project_euler/problem_27/problem_27_sol1.py --- project_euler/problem_27/{sol1.py => problem_27_sol1.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename project_euler/problem_27/{sol1.py => problem_27_sol1.py} (100%) diff --git a/project_euler/problem_27/sol1.py b/project_euler/problem_27/problem_27_sol1.py similarity index 100% rename from project_euler/problem_27/sol1.py rename to project_euler/problem_27/problem_27_sol1.py From 2f8caf8671511e11db332798680e1321a3104454 Mon Sep 17 00:00:00 2001 From: itsvinayak Date: Thu, 31 Oct 2019 17:34:31 +0530 Subject: [PATCH 25/29] Added Problem 33 --- project_euler/problem_33/sol1.py | 48 ++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/project_euler/problem_33/sol1.py b/project_euler/problem_33/sol1.py index 98ff65d79aa3..0992c96935f5 100644 --- a/project_euler/problem_33/sol1.py +++ b/project_euler/problem_33/sol1.py @@ -1,43 +1,55 @@ """ - Problem: -The fraction 49/98 is a curious fraction, as an inexperienced -mathematician in attempting to simplify it may incorrectly believe +The fraction 49/98 is a curious fraction, as an inexperienced +mathematician in attempting to simplify it may incorrectly believe that 49/98 = 4/8, which is correct, is obtained by cancelling the 9s. We shall consider fractions like, 30/50 = 3/5, to be trivial examples. -There are exactly four non-trivial examples of this type of fraction, -less than one in value, and containing two digits in the numerator +There are exactly four non-trivial examples of this type of fraction, +less than one in value, and containing two digits in the numerator and denominator. -If the product of these four fractions is given in its lowest common +If the product of these four fractions is given in its lowest common terms, find the value of the denominator. - """ -def isDigitCancelling(num,den): +def isDigitCancelling(num, den): if num != den: if num % 10 == den // 10: - if (num // 10) / (den % 10) == num/den: + if (num // 10) / (den % 10) == num / den: return True -def solve(): + +def solve(digit_len: int) -> str: + """ + >>> solve(2) + '16/64 , 19/95 , 26/65 , 49/98' + >>> solve(3) + '16/64 , 19/95 , 26/65 , 49/98' + >>> solve(4) + '16/64 , 19/95 , 26/65 , 49/98' + >>> solve(0) + '' + >>> solve(5) + '16/64 , 19/95 , 26/65 , 49/98' + """ solutions = [] - den = 11 - for num in range(11,100): + den = 11 + last_digit = int("1" + "0" * digit_len) + for num in range(den, last_digit): while den <= 99: - if (num != den) and (num % 10 == den // 10) and (den%10 != 0): - if isDigitCancelling(num,den): - solutions.append("{}/{}".format(num,den)) + if (num != den) and (num % 10 == den // 10) and (den % 10 != 0): + if isDigitCancelling(num, den): + solutions.append("{}/{}".format(num, den)) den += 1 num += 1 - den = 10 + den = 10 + solutions = " , ".join(solutions) return solutions if __name__ == "__main__": - print(*solve(),sep=" , ") - + print(solve(2)) From 871a6cbd67056fe547b9d3ac3ad7044cdc60fc17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kadir=20Bayt=C4=B1n?= <46162640+kadirbaytin@users.noreply.github.com> Date: Sat, 26 Oct 2019 15:25:49 +0300 Subject: [PATCH 26/29] added solution 1 for problem_99 --- project_euler/problem_99/base_exp.txt | 1000 +++++++++++++++++++++++++ project_euler/problem_99/sol1.py | 21 + 2 files changed, 1021 insertions(+) create mode 100644 project_euler/problem_99/base_exp.txt create mode 100644 project_euler/problem_99/sol1.py diff --git a/project_euler/problem_99/base_exp.txt b/project_euler/problem_99/base_exp.txt new file mode 100644 index 000000000000..abe95aa86036 --- /dev/null +++ b/project_euler/problem_99/base_exp.txt @@ -0,0 +1,1000 @@ +519432,525806 +632382,518061 +78864,613712 +466580,530130 +780495,510032 +525895,525320 +15991,714883 +960290,502358 +760018,511029 +166800,575487 +210884,564478 +555151,523163 +681146,515199 +563395,522587 +738250,512126 +923525,503780 +595148,520429 +177108,572629 +750923,511482 +440902,532446 +881418,505504 +422489,534197 +979858,501616 +685893,514935 +747477,511661 +167214,575367 +234140,559696 +940238,503122 +728969,512609 +232083,560102 +900971,504694 +688801,514772 +189664,569402 +891022,505104 +445689,531996 +119570,591871 +821453,508118 +371084,539600 +911745,504251 +623655,518600 +144361,582486 +352442,541775 +420726,534367 +295298,549387 +6530,787777 +468397,529976 +672336,515696 +431861,533289 +84228,610150 +805376,508857 +444409,532117 +33833,663511 +381850,538396 +402931,536157 +92901,604930 +304825,548004 +731917,512452 +753734,511344 +51894,637373 +151578,580103 +295075,549421 +303590,548183 +333594,544123 +683952,515042 +60090,628880 +951420,502692 +28335,674991 +714940,513349 +343858,542826 +549279,523586 +804571,508887 +260653,554881 +291399,549966 +402342,536213 +408889,535550 +40328,652524 +375856,539061 +768907,510590 +165993,575715 +976327,501755 +898500,504795 +360404,540830 +478714,529095 +694144,514472 +488726,528258 +841380,507226 +328012,544839 +22389,690868 +604053,519852 +329514,544641 +772965,510390 +492798,527927 +30125,670983 +895603,504906 +450785,531539 +840237,507276 +380711,538522 +63577,625673 +76801,615157 +502694,527123 +597706,520257 +310484,547206 +944468,502959 +121283,591152 +451131,531507 +566499,522367 +425373,533918 +40240,652665 +39130,654392 +714926,513355 +469219,529903 +806929,508783 +287970,550487 +92189,605332 +103841,599094 +671839,515725 +452048,531421 +987837,501323 +935192,503321 +88585,607450 +613883,519216 +144551,582413 +647359,517155 +213902,563816 +184120,570789 +258126,555322 +502546,527130 +407655,535678 +401528,536306 +477490,529193 +841085,507237 +732831,512408 +833000,507595 +904694,504542 +581435,521348 +455545,531110 +873558,505829 +94916,603796 +720176,513068 +545034,523891 +246348,557409 +556452,523079 +832015,507634 +173663,573564 +502634,527125 +250732,556611 +569786,522139 +216919,563178 +521815,525623 +92304,605270 +164446,576167 +753413,511364 +11410,740712 +448845,531712 +925072,503725 +564888,522477 +7062,780812 +641155,517535 +738878,512100 +636204,517828 +372540,539436 +443162,532237 +571192,522042 +655350,516680 +299741,548735 +581914,521307 +965471,502156 +513441,526277 +808682,508700 +237589,559034 +543300,524025 +804712,508889 +247511,557192 +543486,524008 +504383,526992 +326529,545039 +792493,509458 +86033,609017 +126554,589005 +579379,521481 +948026,502823 +404777,535969 +265767,554022 +266876,553840 +46631,643714 +492397,527958 +856106,506581 +795757,509305 +748946,511584 +294694,549480 +409781,535463 +775887,510253 +543747,523991 +210592,564536 +517119,525990 +520253,525751 +247926,557124 +592141,520626 +346580,542492 +544969,523902 +506501,526817 +244520,557738 +144745,582349 +69274,620858 +292620,549784 +926027,503687 +736320,512225 +515528,526113 +407549,535688 +848089,506927 +24141,685711 +9224,757964 +980684,501586 +175259,573121 +489160,528216 +878970,505604 +969546,502002 +525207,525365 +690461,514675 +156510,578551 +659778,516426 +468739,529945 +765252,510770 +76703,615230 +165151,575959 +29779,671736 +928865,503569 +577538,521605 +927555,503618 +185377,570477 +974756,501809 +800130,509093 +217016,563153 +365709,540216 +774508,510320 +588716,520851 +631673,518104 +954076,502590 +777828,510161 +990659,501222 +597799,520254 +786905,509727 +512547,526348 +756449,511212 +869787,505988 +653747,516779 +84623,609900 +839698,507295 +30159,670909 +797275,509234 +678136,515373 +897144,504851 +989554,501263 +413292,535106 +55297,633667 +788650,509637 +486748,528417 +150724,580377 +56434,632490 +77207,614869 +588631,520859 +611619,519367 +100006,601055 +528924,525093 +190225,569257 +851155,506789 +682593,515114 +613043,519275 +514673,526183 +877634,505655 +878905,505602 +1926,914951 +613245,519259 +152481,579816 +841774,507203 +71060,619442 +865335,506175 +90244,606469 +302156,548388 +399059,536557 +478465,529113 +558601,522925 +69132,620966 +267663,553700 +988276,501310 +378354,538787 +529909,525014 +161733,576968 +758541,511109 +823425,508024 +149821,580667 +269258,553438 +481152,528891 +120871,591322 +972322,501901 +981350,501567 +676129,515483 +950860,502717 +119000,592114 +392252,537272 +191618,568919 +946699,502874 +289555,550247 +799322,509139 +703886,513942 +194812,568143 +261823,554685 +203052,566221 +217330,563093 +734748,512313 +391759,537328 +807052,508777 +564467,522510 +59186,629748 +113447,594545 +518063,525916 +905944,504492 +613922,519213 +439093,532607 +445946,531981 +230530,560399 +297887,549007 +459029,530797 +403692,536075 +855118,506616 +963127,502245 +841711,507208 +407411,535699 +924729,503735 +914823,504132 +333725,544101 +176345,572832 +912507,504225 +411273,535308 +259774,555036 +632853,518038 +119723,591801 +163902,576321 +22691,689944 +402427,536212 +175769,572988 +837260,507402 +603432,519893 +313679,546767 +538165,524394 +549026,523608 +61083,627945 +898345,504798 +992556,501153 +369999,539727 +32847,665404 +891292,505088 +152715,579732 +824104,507997 +234057,559711 +730507,512532 +960529,502340 +388395,537687 +958170,502437 +57105,631806 +186025,570311 +993043,501133 +576770,521664 +215319,563513 +927342,503628 +521353,525666 +39563,653705 +752516,511408 +110755,595770 +309749,547305 +374379,539224 +919184,503952 +990652,501226 +647780,517135 +187177,570017 +168938,574877 +649558,517023 +278126,552016 +162039,576868 +658512,516499 +498115,527486 +896583,504868 +561170,522740 +747772,511647 +775093,510294 +652081,516882 +724905,512824 +499707,527365 +47388,642755 +646668,517204 +571700,522007 +180430,571747 +710015,513617 +435522,532941 +98137,602041 +759176,511070 +486124,528467 +526942,525236 +878921,505604 +408313,535602 +926980,503640 +882353,505459 +566887,522345 +3326,853312 +911981,504248 +416309,534800 +392991,537199 +622829,518651 +148647,581055 +496483,527624 +666314,516044 +48562,641293 +672618,515684 +443676,532187 +274065,552661 +265386,554079 +347668,542358 +31816,667448 +181575,571446 +961289,502320 +365689,540214 +987950,501317 +932299,503440 +27388,677243 +746701,511701 +492258,527969 +147823,581323 +57918,630985 +838849,507333 +678038,515375 +27852,676130 +850241,506828 +818403,508253 +131717,587014 +850216,506834 +904848,504529 +189758,569380 +392845,537217 +470876,529761 +925353,503711 +285431,550877 +454098,531234 +823910,508003 +318493,546112 +766067,510730 +261277,554775 +421530,534289 +694130,514478 +120439,591498 +213308,563949 +854063,506662 +365255,540263 +165437,575872 +662240,516281 +289970,550181 +847977,506933 +546083,523816 +413252,535113 +975829,501767 +361540,540701 +235522,559435 +224643,561577 +736350,512229 +328303,544808 +35022,661330 +307838,547578 +474366,529458 +873755,505819 +73978,617220 +827387,507845 +670830,515791 +326511,545034 +309909,547285 +400970,536363 +884827,505352 +718307,513175 +28462,674699 +599384,520150 +253565,556111 +284009,551093 +343403,542876 +446557,531921 +992372,501160 +961601,502308 +696629,514342 +919537,503945 +894709,504944 +892201,505051 +358160,541097 +448503,531745 +832156,507636 +920045,503924 +926137,503675 +416754,534757 +254422,555966 +92498,605151 +826833,507873 +660716,516371 +689335,514746 +160045,577467 +814642,508425 +969939,501993 +242856,558047 +76302,615517 +472083,529653 +587101,520964 +99066,601543 +498005,527503 +709800,513624 +708000,513716 +20171,698134 +285020,550936 +266564,553891 +981563,501557 +846502,506991 +334,1190800 +209268,564829 +9844,752610 +996519,501007 +410059,535426 +432931,533188 +848012,506929 +966803,502110 +983434,501486 +160700,577267 +504374,526989 +832061,507640 +392825,537214 +443842,532165 +440352,532492 +745125,511776 +13718,726392 +661753,516312 +70500,619875 +436952,532814 +424724,533973 +21954,692224 +262490,554567 +716622,513264 +907584,504425 +60086,628882 +837123,507412 +971345,501940 +947162,502855 +139920,584021 +68330,621624 +666452,516038 +731446,512481 +953350,502619 +183157,571042 +845400,507045 +651548,516910 +20399,697344 +861779,506331 +629771,518229 +801706,509026 +189207,569512 +737501,512168 +719272,513115 +479285,529045 +136046,585401 +896746,504860 +891735,505067 +684771,514999 +865309,506184 +379066,538702 +503117,527090 +621780,518717 +209518,564775 +677135,515423 +987500,501340 +197049,567613 +329315,544673 +236756,559196 +357092,541226 +520440,525733 +213471,563911 +956852,502490 +702223,514032 +404943,535955 +178880,572152 +689477,514734 +691351,514630 +866669,506128 +370561,539656 +739805,512051 +71060,619441 +624861,518534 +261660,554714 +366137,540160 +166054,575698 +601878,519990 +153445,579501 +279899,551729 +379166,538691 +423209,534125 +675310,515526 +145641,582050 +691353,514627 +917468,504026 +284778,550976 +81040,612235 +161699,576978 +616394,519057 +767490,510661 +156896,578431 +427408,533714 +254849,555884 +737217,512182 +897133,504851 +203815,566051 +270822,553189 +135854,585475 +778805,510111 +784373,509847 +305426,547921 +733418,512375 +732087,512448 +540668,524215 +702898,513996 +628057,518328 +640280,517587 +422405,534204 +10604,746569 +746038,511733 +839808,507293 +457417,530938 +479030,529064 +341758,543090 +620223,518824 +251661,556451 +561790,522696 +497733,527521 +724201,512863 +489217,528217 +415623,534867 +624610,518548 +847541,506953 +432295,533249 +400391,536421 +961158,502319 +139173,584284 +421225,534315 +579083,521501 +74274,617000 +701142,514087 +374465,539219 +217814,562985 +358972,540995 +88629,607424 +288597,550389 +285819,550812 +538400,524385 +809930,508645 +738326,512126 +955461,502535 +163829,576343 +826475,507891 +376488,538987 +102234,599905 +114650,594002 +52815,636341 +434037,533082 +804744,508880 +98385,601905 +856620,506559 +220057,562517 +844734,507078 +150677,580387 +558697,522917 +621751,518719 +207067,565321 +135297,585677 +932968,503404 +604456,519822 +579728,521462 +244138,557813 +706487,513800 +711627,513523 +853833,506674 +497220,527562 +59428,629511 +564845,522486 +623621,518603 +242689,558077 +125091,589591 +363819,540432 +686453,514901 +656813,516594 +489901,528155 +386380,537905 +542819,524052 +243987,557841 +693412,514514 +488484,528271 +896331,504881 +336730,543721 +728298,512647 +604215,519840 +153729,579413 +595687,520398 +540360,524240 +245779,557511 +924873,503730 +509628,526577 +528523,525122 +3509,847707 +522756,525555 +895447,504922 +44840,646067 +45860,644715 +463487,530404 +398164,536654 +894483,504959 +619415,518874 +966306,502129 +990922,501212 +835756,507474 +548881,523618 +453578,531282 +474993,529410 +80085,612879 +737091,512193 +50789,638638 +979768,501620 +792018,509483 +665001,516122 +86552,608694 +462772,530469 +589233,520821 +891694,505072 +592605,520594 +209645,564741 +42531,649269 +554376,523226 +803814,508929 +334157,544042 +175836,572970 +868379,506051 +658166,516520 +278203,551995 +966198,502126 +627162,518387 +296774,549165 +311803,547027 +843797,507118 +702304,514032 +563875,522553 +33103,664910 +191932,568841 +543514,524006 +506835,526794 +868368,506052 +847025,506971 +678623,515342 +876139,505726 +571997,521984 +598632,520198 +213590,563892 +625404,518497 +726508,512738 +689426,514738 +332495,544264 +411366,535302 +242546,558110 +315209,546555 +797544,509219 +93889,604371 +858879,506454 +124906,589666 +449072,531693 +235960,559345 +642403,517454 +720567,513047 +705534,513858 +603692,519870 +488137,528302 +157370,578285 +63515,625730 +666326,516041 +619226,518883 +443613,532186 +597717,520257 +96225,603069 +86940,608450 +40725,651929 +460976,530625 +268875,553508 +270671,553214 +363254,540500 +384248,538137 +762889,510892 +377941,538833 +278878,551890 +176615,572755 +860008,506412 +944392,502967 +608395,519571 +225283,561450 +45095,645728 +333798,544090 +625733,518476 +995584,501037 +506135,526853 +238050,558952 +557943,522972 +530978,524938 +634244,517949 +177168,572616 +85200,609541 +953043,502630 +523661,525484 +999295,500902 +840803,507246 +961490,502312 +471747,529685 +380705,538523 +911180,504275 +334149,544046 +478992,529065 +325789,545133 +335884,543826 +426976,533760 +749007,511582 +667067,516000 +607586,519623 +674054,515599 +188534,569675 +565185,522464 +172090,573988 +87592,608052 +907432,504424 +8912,760841 +928318,503590 +757917,511138 +718693,513153 +315141,546566 +728326,512645 +353492,541647 +638429,517695 +628892,518280 +877286,505672 +620895,518778 +385878,537959 +423311,534113 +633501,517997 +884833,505360 +883402,505416 +999665,500894 +708395,513697 +548142,523667 +756491,511205 +987352,501340 +766520,510705 +591775,520647 +833758,507563 +843890,507108 +925551,503698 +74816,616598 +646942,517187 +354923,541481 +256291,555638 +634470,517942 +930904,503494 +134221,586071 +282663,551304 +986070,501394 +123636,590176 +123678,590164 +481717,528841 +423076,534137 +866246,506145 +93313,604697 +783632,509880 +317066,546304 +502977,527103 +141272,583545 +71708,618938 +617748,518975 +581190,521362 +193824,568382 +682368,515131 +352956,541712 +351375,541905 +505362,526909 +905165,504518 +128645,588188 +267143,553787 +158409,577965 +482776,528754 +628896,518282 +485233,528547 +563606,522574 +111001,595655 +115920,593445 +365510,540237 +959724,502374 +938763,503184 +930044,503520 +970959,501956 +913658,504176 +68117,621790 +989729,501253 +567697,522288 +820427,508163 +54236,634794 +291557,549938 +124961,589646 +403177,536130 +405421,535899 +410233,535417 +815111,508403 +213176,563974 +83099,610879 +998588,500934 +513640,526263 +129817,587733 +1820,921851 +287584,550539 +299160,548820 +860621,506386 +529258,525059 +586297,521017 +953406,502616 +441234,532410 +986217,501386 +781938,509957 +461247,530595 +735424,512277 +146623,581722 +839838,507288 +510667,526494 +935085,503327 +737523,512167 +303455,548204 +992779,501145 +60240,628739 +939095,503174 +794368,509370 +501825,527189 +459028,530798 +884641,505363 +512287,526364 +835165,507499 +307723,547590 +160587,577304 +735043,512300 +493289,527887 +110717,595785 +306480,547772 +318593,546089 +179810,571911 +200531,566799 +314999,546580 +197020,567622 +301465,548487 +237808,559000 +131944,586923 +882527,505449 +468117,530003 +711319,513541 +156240,578628 +965452,502162 +992756,501148 +437959,532715 +739938,512046 +614249,519196 +391496,537356 +62746,626418 +688215,514806 +75501,616091 +883573,505412 +558824,522910 +759371,511061 +173913,573489 +891351,505089 +727464,512693 +164833,576051 +812317,508529 +540320,524243 +698061,514257 +69149,620952 +471673,529694 +159092,577753 +428134,533653 +89997,606608 +711061,513557 +779403,510081 +203327,566155 +798176,509187 +667688,515963 +636120,517833 +137410,584913 +217615,563034 +556887,523038 +667229,515991 +672276,515708 +325361,545187 +172115,573985 +13846,725685 \ No newline at end of file diff --git a/project_euler/problem_99/sol1.py b/project_euler/problem_99/sol1.py new file mode 100644 index 000000000000..7bd68b25f505 --- /dev/null +++ b/project_euler/problem_99/sol1.py @@ -0,0 +1,21 @@ +""" +Problem: + +Comparing two numbers written in index form like 2'11 and 3'7 is not difficult, as any calculator would confirm that 2^11 = 2048 < 3^7 = 2187. + +However, confirming that 632382^518061 > 519432^525806 would be much more difficult, as both numbers contain over three million digits. + +Using base_exp.txt (right click and 'Save Link/Target As...'), a 22K text file containing one thousand lines with a base/exponent pair on each line, determine which line number has the greatest numerical value. + +NOTE: The first two lines in the file represent the numbers in the example given above. +""" + +#!/usr/bin/env python +import os +from math import log10 +largest = [0, 0] +for i, line in enumerate(open(os.path.join(os.path.dirname(__file__), 'base_exp.txt'))): + a, x = list(map(int, line.split(','))) + if x * log10(a) > largest[0]: + largest = [x * log10(a), i+1] +print(largest[1]) From 742d919c13e24e091a6263783ae9d7a5810633a3 Mon Sep 17 00:00:00 2001 From: itsvinayak Date: Fri, 1 Nov 2019 12:43:14 +0530 Subject: [PATCH 27/29] update added solution 1 for problem_99 --- project_euler/problem_99/sol1.py | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/project_euler/problem_99/sol1.py b/project_euler/problem_99/sol1.py index 7bd68b25f505..156d56ed81ec 100644 --- a/project_euler/problem_99/sol1.py +++ b/project_euler/problem_99/sol1.py @@ -5,17 +5,29 @@ However, confirming that 632382^518061 > 519432^525806 would be much more difficult, as both numbers contain over three million digits. -Using base_exp.txt (right click and 'Save Link/Target As...'), a 22K text file containing one thousand lines with a base/exponent pair on each line, determine which line number has the greatest numerical value. +Using base_exp.txt, a 22K text file containing one thousand lines with a base/exponent pair on each line, determine which line number has the greatest numerical value. NOTE: The first two lines in the file represent the numbers in the example given above. """ -#!/usr/bin/env python import os from math import log10 -largest = [0, 0] -for i, line in enumerate(open(os.path.join(os.path.dirname(__file__), 'base_exp.txt'))): - a, x = list(map(int, line.split(','))) - if x * log10(a) > largest[0]: - largest = [x * log10(a), i+1] -print(largest[1]) + + +def find_largest() -> int: + """ + >>> find_largest() + 709 + """ + largest = [0, 0] + for i, line in enumerate( + open(os.path.join(os.path.dirname(__file__), "base_exp.txt")) + ): + a, x = list(map(int, line.split(","))) + if x * log10(a) > largest[0]: + largest = [x * log10(a), i + 1] + return largest[1] + + +if __name__ == "__main__": + print(find_largest()) From 1405d0b97a6f4d4c5e7b8e9dab42abcce888e003 Mon Sep 17 00:00:00 2001 From: itsvinayak Date: Fri, 1 Nov 2019 13:08:25 +0530 Subject: [PATCH 28/29] update --- project_euler/problem_99/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 project_euler/problem_99/__init__.py diff --git a/project_euler/problem_99/__init__.py b/project_euler/problem_99/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 From 60c029d788bf0248c6e13f1cd2b3f39383959b4e Mon Sep 17 00:00:00 2001 From: vinayak Date: Fri, 1 Nov 2019 13:54:41 +0530 Subject: [PATCH 29/29] Update sol1.py --- project_euler/problem_99/sol1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project_euler/problem_99/sol1.py b/project_euler/problem_99/sol1.py index 156d56ed81ec..6729927dfa63 100644 --- a/project_euler/problem_99/sol1.py +++ b/project_euler/problem_99/sol1.py @@ -14,14 +14,14 @@ from math import log10 -def find_largest() -> int: +def find_largest(data_file: str="base_exp.txt") -> int: """ >>> find_largest() 709 """ largest = [0, 0] for i, line in enumerate( - open(os.path.join(os.path.dirname(__file__), "base_exp.txt")) + open(os.path.join(os.path.dirname(__file__), data_file)) ): a, x = list(map(int, line.split(","))) if x * log10(a) > largest[0]: