diff options
| author | leshe4ka46 <alex9102naid1@ya.ru> | 2025-12-13 19:41:40 +0300 |
|---|---|---|
| committer | leshe4ka46 <alex9102naid1@ya.ru> | 2025-12-13 19:41:40 +0300 |
| commit | 175ac10904d0f31c3ffeeeed507c8914f13d0b15 (patch) | |
| tree | 671c68a03354c5084470c5cfcfd4fe87aae2aff8 /R_LogR | |
| parent | 72b4edeadeafc9c54b3db9b0961a45da3d07b77c (diff) | |
linr, logr
Diffstat (limited to 'R_LogR')
| -rw-r--r-- | R_LogR/Rplots.pdf | bin | 0 -> 11835 bytes | |||
| -rw-r--r-- | R_LogR/asset-v1_MEPhIx+CSA12AI+2019Spring+type@asset+block@mlclass-ex2.zip | bin | 0 -> 245817 bytes | |||
| -rw-r--r-- | R_LogR/ex2.pdf | bin | 0 -> 258794 bytes | |||
| -rwxr-xr-x | R_LogR/main.r | 41 | ||||
| -rw-r--r-- | R_LogR/mlclass-ex2/costFunction.m | 35 | ||||
| -rw-r--r-- | R_LogR/mlclass-ex2/costFunctionReg.m | 36 | ||||
| -rw-r--r-- | R_LogR/mlclass-ex2/ex2.m | 135 | ||||
| -rw-r--r-- | R_LogR/mlclass-ex2/ex2_reg.m | 117 | ||||
| -rw-r--r-- | R_LogR/mlclass-ex2/mapFeature.m | 21 | ||||
| -rw-r--r-- | R_LogR/mlclass-ex2/plotData.m | 33 | ||||
| -rw-r--r-- | R_LogR/mlclass-ex2/plotDecisionBoundary.m | 49 | ||||
| -rw-r--r-- | R_LogR/mlclass-ex2/predict.m | 32 | ||||
| -rw-r--r-- | R_LogR/mlclass-ex2/sigmoid.m | 18 | ||||
| -rw-r--r-- | R_LogR/mlclass-ex2/submit.m | 333 | ||||
| -rw-r--r-- | R_LogR/mlclass-ex2/submitWeb.m | 349 | ||||
| -rw-r--r-- | R_LogR/survey.csv | 751 |
16 files changed, 1950 insertions, 0 deletions
diff --git a/R_LogR/Rplots.pdf b/R_LogR/Rplots.pdf Binary files differnew file mode 100644 index 0000000..5a71719 --- /dev/null +++ b/R_LogR/Rplots.pdf diff --git a/R_LogR/asset-v1_MEPhIx+CSA12AI+2019Spring+type@asset+block@mlclass-ex2.zip b/R_LogR/asset-v1_MEPhIx+CSA12AI+2019Spring+type@asset+block@mlclass-ex2.zip Binary files differnew file mode 100644 index 0000000..36ed86a --- /dev/null +++ b/R_LogR/asset-v1_MEPhIx+CSA12AI+2019Spring+type@asset+block@mlclass-ex2.zip diff --git a/R_LogR/ex2.pdf b/R_LogR/ex2.pdf Binary files differnew file mode 100644 index 0000000..78d3d35 --- /dev/null +++ b/R_LogR/ex2.pdf diff --git a/R_LogR/main.r b/R_LogR/main.r new file mode 100755 index 0000000..748b0f4 --- /dev/null +++ b/R_LogR/main.r @@ -0,0 +1,41 @@ +#!/usr/bin/env Rscript + +# https://www.r-bloggers.com/2015/09/how-to-perform-a-logistic-regression-in-r/ + +data <- read.csv("survey.csv") + + +str(data) +head(data) + +data$price20 <- ifelse(data$Price == 20, 1, 0) +data$price30 <- ifelse(data$Price == 30, 1, 0) +head(data) + +model <- glm( + MYDEPV ~ Income + Age + price20 + price30, + family = binomial(link = "logit"), + data = data +) +summary(model) + +coef(model) + +plot(data$Income, data$MYDEPV) + + +test_dat <- data.frame(Income = seq(20, 100, 1), Age = 20, price20 = 1, price30 = 0) +pred <- predict(model, newdata = test_dat, type = "response") + +lines(test_dat$Income, pred, col = "blue", lwd = 2) + + +new_data3 <- data.frame( + Income = c(58), + Age = c(25), + price20 = c(1), + price30 = c(0) +) + +predicted <- predict(model, newdata = new_data3) +print(1 / (1 + exp(-predicted))) diff --git a/R_LogR/mlclass-ex2/costFunction.m b/R_LogR/mlclass-ex2/costFunction.m new file mode 100644 index 0000000..6e6118c --- /dev/null +++ b/R_LogR/mlclass-ex2/costFunction.m @@ -0,0 +1,35 @@ +function [J, grad] = costFunction(theta, X, y) +%COSTFUNCTION Compute cost and gradient for logistic regression +% J = COSTFUNCTION(theta, X, y) computes the cost of using theta as the +% parameter for logistic regression and the gradient of the cost +% w.r.t. to the parameters. + +% Initialize some useful values +m = length(y); % number of training examples + +% You need to return the following variables correctly +% J = 0; +% grad = zeros(size(theta)); + +% ====================== YOUR CODE HERE ====================== +% Instructions: Compute the cost of a particular choice of theta. +% You should set J to the cost. +% Compute the partial derivatives and set grad to the partial +% derivatives of the cost w.r.t. each parameter in theta +% +% Note: grad should have the same dimensions as theta +% + +pred = sigmoid(X*theta); + +% J = 1 /m .* sum(-y .* log(pred) - (1-y) .* log(1-pred)); + +% grad = 1 / m .* (X' * (pred - y)); + +J = (1 / (2*m)) * sum((pred - y).^2); + +grad = (1 / m) * X' * (pred - y); + +% ============================================================= + +end diff --git a/R_LogR/mlclass-ex2/costFunctionReg.m b/R_LogR/mlclass-ex2/costFunctionReg.m new file mode 100644 index 0000000..cc73386 --- /dev/null +++ b/R_LogR/mlclass-ex2/costFunctionReg.m @@ -0,0 +1,36 @@ +function [J, grad] = costFunctionReg(theta, X, y, lambda) +%COSTFUNCTIONREG Compute cost and gradient for logistic regression with regularization +% J = COSTFUNCTIONREG(theta, X, y, lambda) computes the cost of using +% theta as the parameter for regularized logistic regression and the +% gradient of the cost w.r.t. to the parameters. + +% Initialize some useful values +m = length(y); % number of training examples + +% You need to return the following variables correctly +% J = 0; +% grad = zeros(size(theta)); + +% ====================== YOUR CODE HERE ====================== +% Instructions: Compute the cost of a particular choice of theta. +% You should set J to the cost. +% Compute the partial derivatives and set grad to the partial +% derivatives of the cost w.r.t. each parameter in theta + + +pred = sigmoid(X*theta); + +J = 1./m .* sum(-y .* log(pred) - (1-y) .* log(1-pred)) + lambda ./ 2 ./ m .* sum(theta.^2); + + +reg = lambda .* theta ./ m; +reg(1) = 0; +grad = 1 / m .* (X' * (pred - y)) + reg; + + + + + +% ============================================================= + +end diff --git a/R_LogR/mlclass-ex2/ex2.m b/R_LogR/mlclass-ex2/ex2.m new file mode 100644 index 0000000..c0a7774 --- /dev/null +++ b/R_LogR/mlclass-ex2/ex2.m @@ -0,0 +1,135 @@ +%% Machine Learning Online Class - Exercise 2: Logistic Regression +% +% Instructions +% ------------ +% +% This file contains code that helps you get started on the logistic +% regression exercise. You will need to complete the following functions +% in this exericse: +% +% sigmoid.m +% costFunction.m +% predict.m +% costFunctionReg.m +% +% For this exercise, you will not need to change any code in this file, +% or any other files other than those mentioned above. +% + +%% Initialization +clear ; close all; clc + +%% Load Data +% The first two columns contains the exam scores and the third column +% contains the label. + +data = load('ex2data1.txt'); +X = data(:, [1, 2]); y = data(:, 3); + +%% ==================== Part 1: Plotting ==================== +% We start the exercise by first plotting the data to understand the +% the problem we are working with. + +fprintf(['Plotting data with + indicating (y = 1) examples and o ' ... + 'indicating (y = 0) examples.\n']); + +plotData(X, y); + +% Put some labels +hold on; +% Labels and Legend +xlabel('Exam 1 score') +ylabel('Exam 2 score') + +% Specified in plot order +% legend('Admitted', 'Not admitted') +hold off; + +fprintf('\nProgram paused. Press enter to continue.\n'); +pause; + + +%% ============ Part 2: Compute Cost and Gradient ============ +% In this part of the exercise, you will implement the cost and gradient +% for logistic regression. You neeed to complete the code in +% costFunction.m + +% Setup the data matrix appropriately, and add ones for the intercept term +[m, n] = size(X); + +% Add intercept term to x and X_test +X = [ones(m, 1) X]; + +% Initialize fitting parameters +initial_theta = zeros(n + 1, 1); + +% Compute and display initial cost and gradient +[cost, grad] = costFunction(initial_theta, X, y); + +fprintf('Cost at initial theta (zeros): %f\n', cost); +fprintf('Gradient at initial theta (zeros): \n'); +fprintf(' %f \n', grad); + +fprintf('\nProgram paused. Press enter to continue.\n'); +%pause; + + +%% ============= Part 3: Optimizing using fminunc ============= +% In this exercise, you will use a built-in function (fminunc) to find the +% optimal parameters theta. + +% Set options for fminunc +options = optimset('GradObj', 'on', 'MaxIter', 400); + +% Run fminunc to obtain the optimal theta +% This function will return theta and the cost +[theta, cost] = ... + fminunc(@(t)(costFunction(t, X, y)), initial_theta, options); + +% Print theta to screen +fprintf('Cost at theta found by fminunc: %f\n', cost); +fprintf('theta: \n'); +fprintf(' %f \n', theta); + +% Plot Boundary +plotDecisionBoundary(theta, X, y); + +% Put some labels +hold on; +% Labels and Legend +xlabel('Exam 1 score') +ylabel('Exam 2 score') + +% Specified in plot order +legend('Admitted', 'Not admitted') +hold off; + +fprintf('\nProgram paused. Press enter to continue.\n'); +%pause; + +%% ============== Part 4: Predict and Accuracies ============== +% After learning the parameters, you'll like to use it to predict the outcomes +% on unseen data. In this part, you will use the logistic regression model +% to predict the probability that a student with score 20 on exam 1 and +% score 80 on exam 2 will be admitted. +% +% Furthermore, you will compute the training and test set accuracies of +% our model. +% +% Your task is to complete the code in predict.m + +% Predict probability for a student with score 45 on exam 1 +% and score 85 on exam 2 + +prob = sigmoid([1 45 85] * theta); +fprintf(['For a student with scores 45 and 85, we predict an admission ' ... + 'probability of %f\n\n'], prob); + +% Compute accuracy on our training set +p = predict(theta, X); + +fprintf('Train Accuracy: %f\n', mean(double(p == y)) * 100); + +fprintf('\nProgram paused. Press enter to continue.\n'); +%pause; + diff --git a/R_LogR/mlclass-ex2/ex2_reg.m b/R_LogR/mlclass-ex2/ex2_reg.m new file mode 100644 index 0000000..a7b95c2 --- /dev/null +++ b/R_LogR/mlclass-ex2/ex2_reg.m @@ -0,0 +1,117 @@ +%% Machine Learning Online Class - Exercise 2: Logistic Regression +% +% Instructions +% ------------ +% +% This file contains code that helps you get started on the second part +% of the exercise which covers regularization with logistic regression. +% +% You will need to complete the following functions in this exericse: +% +% sigmoid.m +% costFunction.m +% predict.m +% costFunctionReg.m +% +% For this exercise, you will not need to change any code in this file, +% or any other files other than those mentioned above. +% + +%% Initialization +clear ; close all; clc + +%% Load Data +% The first two columns contains the exam scores and the third column +% contains the label. + +data = load('ex2data2.txt'); +X = data(:, [1, 2]); y = data(:, 3); + +plotData(X, y); + +% Put some labels +hold on; + +% Labels and Legend +xlabel('Microchip Test 1') +ylabel('Microchip Test 2') + +% Specified in plot order +legend('y = 1', 'y = 0') +hold off; + + +%% =========== Part 1: Regularized Logistic Regression ============ +% In this part, you are given a dataset with data points that are not +% linearly separable. However, you would still like to use logistic +% regression to classify the data points. +% +% To do so, you introduce more features to use -- in particular, you add +% polynomial features to our data matrix (similar to polynomial +% regression). +% + +% Add Polynomial Features + +% Note that mapFeature also adds a column of ones for us, so the intercept +% term is handled +X = mapFeature(X(:,1), X(:,2)); + +% Initialize fitting parameters +initial_theta = zeros(size(X, 2), 1); + +% Set regularization parameter lambda to 1 +lambda = 1; + +% Compute and display initial cost and gradient for regularized logistic +% regression +[cost, grad] = costFunctionReg(initial_theta, X, y, lambda); + +fprintf('Cost at initial theta (zeros): %f\n', cost); + +fprintf('\nProgram paused. Press enter to continue.\n'); +% pause; + +%% ============= Part 2: Regularization and Accuracies ============= +% Optional Exercise: +% In this part, you will get to try different values of lambda and +% see how regularization affects the decision coundart +% +% Try the following values of lambda (0, 1, 10, 100). +% +% How does the decision boundary change when you vary lambda? How does +% the training set accuracy vary? +% + +% Initialize fitting parameters +initial_theta = zeros(size(X, 2), 1); + +% Set regularization parameter lambda to 1 (you should vary this) +lambda = 0.1; + +% Set Options +options = optimset('GradObj', 'on', 'MaxIter', 400); + +% Optimize +[theta, J, exit_flag] = ... + fminunc(@(t)(costFunctionReg(t, X, y, lambda)), initial_theta, options); + +% Plot Boundary +plotDecisionBoundary(theta, X, y); +hold on; +title(sprintf('lambda = %g', lambda)) + +% Labels and Legend +xlabel('Microchip Test 1') +ylabel('Microchip Test 2') + +legend('y = 1', 'y = 0', 'Decision boundary') +hold off; + +% Compute accuracy on our training set +p = predict(theta, X); + +fprintf('Train Accuracy: %f\n', mean(double(p == y)) * 100); + + + diff --git a/R_LogR/mlclass-ex2/mapFeature.m b/R_LogR/mlclass-ex2/mapFeature.m new file mode 100644 index 0000000..d02a72a --- /dev/null +++ b/R_LogR/mlclass-ex2/mapFeature.m @@ -0,0 +1,21 @@ +function out = mapFeature(X1, X2) +% MAPFEATURE Feature mapping function to polynomial features +% +% MAPFEATURE(X1, X2) maps the two input features +% to quadratic features used in the regularization exercise. +% +% Returns a new feature array with more features, comprising of +% X1, X2, X1.^2, X2.^2, X1*X2, X1*X2.^2, etc.. +% +% Inputs X1, X2 must be the same size +% + +degree = 6; +out = ones(size(X1(:,1))); +for i = 1:degree + for j = 0:i + out(:, end+1) = (X1.^(i-j)).*(X2.^j); + end +end + +end
\ No newline at end of file diff --git a/R_LogR/mlclass-ex2/plotData.m b/R_LogR/mlclass-ex2/plotData.m new file mode 100644 index 0000000..2eda757 --- /dev/null +++ b/R_LogR/mlclass-ex2/plotData.m @@ -0,0 +1,33 @@ +function plotData(X, y) +%PLOTDATA Plots the data points X and y into a new figure +% PLOTDATA(x,y) plots the data points with + for the positive examples +% and o for the negative examples. X is assumed to be a Mx2 matrix. + +% Create New Figure +figure; hold on; + +% ====================== YOUR CODE HERE ====================== +% Instructions: Plot the positive and negative examples on a +% 2D plot, using the option 'k+' for the positive +% examples and 'ko' for the negative examples. +% + +#positive_vals = find(y == 1); +#negative_vals = find(y == 0); + + +#plot(X(positive_vals, 1), X(positive_vals, 2), 'k+', 'MarkerSize', 7); +#plot(X(negative_vals, 1), X(negative_vals, 2), 'ko', 'MarkerSize', 7); + + +pos = find(y==1); neg = find(y == 0); +plot(X(pos, 1), X(pos, 2), 'k+', 'MarkerSize', 7); +plot(X(neg, 1), X(neg, 2), 'ko', 'MarkerSize', 7); + +% ========================================================================= + + + +hold off; + +end diff --git a/R_LogR/mlclass-ex2/plotDecisionBoundary.m b/R_LogR/mlclass-ex2/plotDecisionBoundary.m new file mode 100644 index 0000000..cfdf3e4 --- /dev/null +++ b/R_LogR/mlclass-ex2/plotDecisionBoundary.m @@ -0,0 +1,49 @@ +function plotDecisionBoundary(theta, X, y) +%PLOTDECISIONBOUNDARY Plots the data points X and y into a new figure with +%the decision boundary defined by theta +% PLOTDECISIONBOUNDARY(theta, X,y) plots the data points with + for the +% positive examples and o for the negative examples. X is assumed to be +% a either +% 1) Mx3 matrix, where the first column is an all-ones column for the +% intercept. +% 2) MxN, N>3 matrix, where the first column is all-ones + +% Plot Data +plotData(X(:,2:3), y); +hold on + +if size(X, 2) <= 3 + % Only need 2 points to define a line, so choose two endpoints + plot_x = [min(X(:,2))-2, max(X(:,2))+2]; + + % Calculate the decision boundary line + plot_y = (-1./theta(3)).*(theta(2).*plot_x + theta(1)); + + % Plot, and adjust axes for better viewing + plot(plot_x, plot_y) + + % Legend, specific for the exercise + legend('Admitted', 'Not admitted', 'Decision Boundary') + axis([30, 100, 30, 100]) +else + % Here is the grid range + u = linspace(-1, 1.5, 50); + v = linspace(-1, 1.5, 50); + + z = zeros(length(u), length(v)); + % Evaluate z = theta*x over the grid + for i = 1:length(u) + for j = 1:length(v) + z(i,j) = mapFeature(u(i), v(j))*theta; + end + end + z = z'; % important to transpose z before calling contour + + % Plot z = 0 + % Notice you need to specify the range [0, 0] + contour(u, v, z, [0, 0], 'LineWidth', 2) +end +hold off + +end + diff --git a/R_LogR/mlclass-ex2/predict.m b/R_LogR/mlclass-ex2/predict.m new file mode 100644 index 0000000..7af3a20 --- /dev/null +++ b/R_LogR/mlclass-ex2/predict.m @@ -0,0 +1,32 @@ +function p = predict(theta, X) +%PREDICT Predict whether the label is 0 or 1 using learned logistic +%regression parameters theta +% p = PREDICT(theta, X) computes the predictions for X using a +% threshold at 0.5 (i.e., if sigmoid(theta'*x) >= 0.5, predict 1) + +m = size(X, 1); % Number of training examples + +% You need to return the following variables correctly +p = zeros(m, 1); + +% ====================== YOUR CODE HERE ====================== +% Instructions: Complete the following code to make predictions using +% your learned logistic regression parameters. +% You should set p to a vector of 0's and 1's +% +thresh = 0.5 + +pred = sigmoid(X * theta); +for i = 1:m + if pred(i) >= thresh + p(i) = 1; + else + p(i) = 0; + endif + + + +% ========================================================================= + + +end diff --git a/R_LogR/mlclass-ex2/sigmoid.m b/R_LogR/mlclass-ex2/sigmoid.m new file mode 100644 index 0000000..a79fccd --- /dev/null +++ b/R_LogR/mlclass-ex2/sigmoid.m @@ -0,0 +1,18 @@ +function g = sigmoid(z) +%SIGMOID Compute sigmoid functoon +% J = SIGMOID(z) computes the sigmoid of z. + +% You need to return the following variables correctly +% g = zeros(size(z)); + +% ====================== YOUR CODE HERE ====================== +% Instructions: Compute the sigmoid of each value of z (z can be a matrix, +% vector or scalar). + + +g = 1 ./ (1 + exp(-z)); + + +% ============================================================= + +end diff --git a/R_LogR/mlclass-ex2/submit.m b/R_LogR/mlclass-ex2/submit.m new file mode 100644 index 0000000..224a541 --- /dev/null +++ b/R_LogR/mlclass-ex2/submit.m @@ -0,0 +1,333 @@ +function submit(partId) +%SUBMIT Submit your code and output to the ml-class servers +% SUBMIT() will connect to the ml-class server and submit your solution + + fprintf('==\n== [ml-class] Submitting Solutions | Programming Exercise %s\n==\n', ... + homework_id()); + if ~exist('partId', 'var') || isempty(partId) + partId = promptPart(); + end + + % Check valid partId + partNames = validParts(); + if ~isValidPartId(partId) + fprintf('!! Invalid homework part selected.\n'); + fprintf('!! Expected an integer from 1 to %d.\n', numel(partNames) + 1); + fprintf('!! Submission Cancelled\n'); + return + end + + [login password] = loginPrompt(); + if isempty(login) + fprintf('!! Submission Cancelled\n'); + return + end + + fprintf('\n== Connecting to ml-class ... '); + if exist('OCTAVE_VERSION') + fflush(stdout); + end + + % Setup submit list + if partId == numel(partNames) + 1 + submitParts = 1:numel(partNames); + else + submitParts = [partId]; + end + + for s = 1:numel(submitParts) + % Submit this part + partId = submitParts(s); + + % Get Challenge + [login, ch, signature] = getChallenge(login); + if isempty(login) || isempty(ch) || isempty(signature) + % Some error occured, error string in first return element. + fprintf('\n!! Error: %s\n\n', login); + return + end + + % Attempt Submission with Challenge + ch_resp = challengeResponse(login, password, ch); + [result, str] = submitSolution(login, ch_resp, partId, output(partId), ... + source(partId), signature); + + fprintf('\n== [ml-class] Submitted Homework %s - Part %d - %s\n', ... + homework_id(), partId, partNames{partId}); + fprintf('== %s\n', strtrim(str)); + if exist('OCTAVE_VERSION') + fflush(stdout); + end + end + +end + +% ================== CONFIGURABLES FOR EACH HOMEWORK ================== + +function id = homework_id() + id = '2'; +end + +function [partNames] = validParts() + partNames = { 'Sigmoid Function ', ... + 'Logistic Regression Cost', ... + 'Logistic Regression Gradient', ... + 'Predict', ... + 'Regularized Logistic Regression Cost' ... + 'Regularized Logistic Regression Gradient' ... + }; +end + +function srcs = sources() + % Separated by part + srcs = { { 'sigmoid.m' }, ... + { 'costFunction.m' }, ... + { 'costFunction.m' }, ... + { 'predict.m' }, ... + { 'costFunctionReg.m' }, ... + { 'costFunctionReg.m' } }; +end + +function out = output(partId) + % Random Test Cases + X = [ones(20,1) (exp(1) * sin(1:1:20))' (exp(0.5) * cos(1:1:20))']; + y = sin(X(:,1) + X(:,2)) > 0; + if partId == 1 + out = sprintf('%0.5f ', sigmoid(X)); + elseif partId == 2 + out = sprintf('%0.5f ', costFunction([0.25 0.5 -0.5]', X, y)); + elseif partId == 3 + [cost, grad] = costFunction([0.25 0.5 -0.5]', X, y); + out = sprintf('%0.5f ', grad); + elseif partId == 4 + out = sprintf('%0.5f ', predict([0.25 0.5 -0.5]', X)); + elseif partId == 5 + out = sprintf('%0.5f ', costFunctionReg([0.25 0.5 -0.5]', X, y, 0.1)); + elseif partId == 6 + [cost, grad] = costFunctionReg([0.25 0.5 -0.5]', X, y, 0.1); + out = sprintf('%0.5f ', grad); + end +end + +function url = challenge_url() + url = 'http://www.ml-class.org/course/homework/challenge'; +end + +function url = submit_url() + url = 'http://www.ml-class.org/course/homework/submit'; +end + +% ========================= CHALLENGE HELPERS ========================= + +function src = source(partId) + src = ''; + src_files = sources(); + if partId <= numel(src_files) + flist = src_files{partId}; + for i = 1:numel(flist) + fid = fopen(flist{i}); + while ~feof(fid) + line = fgets(fid); + src = [src line]; + end + fclose(fid); + src = [src '||||||||']; + end + end +end + +function ret = isValidPartId(partId) + partNames = validParts(); + ret = (~isempty(partId)) && (partId >= 1) && (partId <= numel(partNames) + 1); +end + +function partId = promptPart() + fprintf('== Select which part(s) to submit:\n', ... + homework_id()); + partNames = validParts(); + srcFiles = sources(); + for i = 1:numel(partNames) + fprintf('== %d) %s [', i, partNames{i}); + fprintf(' %s ', srcFiles{i}{:}); + fprintf(']\n'); + end + fprintf('== %d) All of the above \n==\nEnter your choice [1-%d]: ', ... + numel(partNames) + 1, numel(partNames) + 1); + selPart = input('', 's'); + partId = str2num(selPart); + if ~isValidPartId(partId) + partId = -1; + end +end + +function [email,ch,signature] = getChallenge(email) + str = urlread(challenge_url(), 'post', {'email_address', email}); + + str = strtrim(str); + [email, str] = strtok (str, '|'); + [ch, str] = strtok (str, '|'); + [signature, str] = strtok (str, '|'); +end + + +function [result, str] = submitSolution(email, ch_resp, part, output, ... + source, signature) + + params = {'homework', homework_id(), ... + 'part', num2str(part), ... + 'email', email, ... + 'output', output, ... + 'source', source, ... + 'challenge_response', ch_resp, ... + 'signature', signature}; + + str = urlread(submit_url(), 'post', params); + + % Parse str to read for success / failure + result = 0; + +end + +% =========================== LOGIN HELPERS =========================== + +function [login password] = loginPrompt() + % Prompt for password + [login password] = basicPrompt(); + + if isempty(login) || isempty(password) + login = []; password = []; + end +end + + +function [login password] = basicPrompt() + login = input('Login (Email address): ', 's'); + password = input('Password: ', 's'); +end + + +function [str] = challengeResponse(email, passwd, challenge) + salt = ')~/|]QMB3[!W`?OVt7qC"@+}'; + str = sha1([challenge sha1([salt email passwd])]); + sel = randperm(numel(str)); + sel = sort(sel(1:16)); + str = str(sel); +end + + +% =============================== SHA-1 ================================ + +function hash = sha1(str) + + % Initialize variables + h0 = uint32(1732584193); + h1 = uint32(4023233417); + h2 = uint32(2562383102); + h3 = uint32(271733878); + h4 = uint32(3285377520); + + % Convert to word array + strlen = numel(str); + + % Break string into chars and append the bit 1 to the message + mC = [double(str) 128]; + mC = [mC zeros(1, 4-mod(numel(mC), 4), 'uint8')]; + + numB = strlen * 8; + if exist('idivide') + numC = idivide(uint32(numB + 65), 512, 'ceil'); + else + numC = ceil(double(numB + 65)/512); + end + numW = numC * 16; + mW = zeros(numW, 1, 'uint32'); + + idx = 1; + for i = 1:4:strlen + 1 + mW(idx) = bitor(bitor(bitor( ... + bitshift(uint32(mC(i)), 24), ... + bitshift(uint32(mC(i+1)), 16)), ... + bitshift(uint32(mC(i+2)), 8)), ... + uint32(mC(i+3))); + idx = idx + 1; + end + + % Append length of message + mW(numW - 1) = uint32(bitshift(uint64(numB), -32)); + mW(numW) = uint32(bitshift(bitshift(uint64(numB), 32), -32)); + + % Process the message in successive 512-bit chs + for cId = 1 : double(numC) + cSt = (cId - 1) * 16 + 1; + cEnd = cId * 16; + ch = mW(cSt : cEnd); + + % Extend the sixteen 32-bit words into eighty 32-bit words + for j = 17 : 80 + ch(j) = ch(j - 3); + ch(j) = bitxor(ch(j), ch(j - 8)); + ch(j) = bitxor(ch(j), ch(j - 14)); + ch(j) = bitxor(ch(j), ch(j - 16)); + ch(j) = bitrotate(ch(j), 1); + end + + % Initialize hash value for this ch + a = h0; + b = h1; + c = h2; + d = h3; + e = h4; + + % Main loop + for i = 1 : 80 + if(i >= 1 && i <= 20) + f = bitor(bitand(b, c), bitand(bitcmp(b), d)); + k = uint32(1518500249); + elseif(i >= 21 && i <= 40) + f = bitxor(bitxor(b, c), d); + k = uint32(1859775393); + elseif(i >= 41 && i <= 60) + f = bitor(bitor(bitand(b, c), bitand(b, d)), bitand(c, d)); + k = uint32(2400959708); + elseif(i >= 61 && i <= 80) + f = bitxor(bitxor(b, c), d); + k = uint32(3395469782); + end + + t = bitrotate(a, 5); + t = bitadd(t, f); + t = bitadd(t, e); + t = bitadd(t, k); + t = bitadd(t, ch(i)); + e = d; + d = c; + c = bitrotate(b, 30); + b = a; + a = t; + + end + h0 = bitadd(h0, a); + h1 = bitadd(h1, b); + h2 = bitadd(h2, c); + h3 = bitadd(h3, d); + h4 = bitadd(h4, e); + + end + + hash = reshape(dec2hex(double([h0 h1 h2 h3 h4]), 8)', [1 40]); + + hash = lower(hash); + +end + +function ret = bitadd(iA, iB) + ret = double(iA) + double(iB); + ret = bitset(ret, 33, 0); + ret = uint32(ret); +end + +function ret = bitrotate(iA, places) + t = bitshift(iA, places - 32); + ret = bitshift(iA, places); + ret = bitor(ret, t); +end diff --git a/R_LogR/mlclass-ex2/submitWeb.m b/R_LogR/mlclass-ex2/submitWeb.m new file mode 100644 index 0000000..22688ac --- /dev/null +++ b/R_LogR/mlclass-ex2/submitWeb.m @@ -0,0 +1,349 @@ +function submitWeb(partId) +%SUBMITWEB Generates a base64 encoded string for web-based submissions +% SUBMITWEB() will generate a base64 encoded string so that you can submit your +% solutions via a web form + + fprintf('==\n== [ml-class] Submitting Solutions | Programming Exercise %s\n==\n', ... + homework_id()); + if ~exist('partId', 'var') || isempty(partId) + partId = promptPart(); + end + + % Check valid partId + partNames = validParts(); + if ~isValidPartId(partId) + fprintf('!! Invalid homework part selected.\n'); + fprintf('!! Expected an integer from 1 to %d.\n', numel(partNames)); + fprintf('!! Submission Cancelled\n'); + return + end + + [login] = loginPrompt(); + if isempty(login) + fprintf('!! Submission Cancelled\n'); + return + end + + [result] = submitSolution(login, partId, output(partId), ... + source(partId)); + result = base64encode(result); + + fprintf('\nSave as submission file [submit_ex%s_part%d.txt]: ', ... + homework_id(), partId); + saveAsFile = input('', 's'); + if (isempty(saveAsFile)) + saveAsFile = sprintf('submit_ex%s_part%d.txt', homework_id(), partId); + end + + fid = fopen(saveAsFile, 'w'); + if (fid) + fwrite(fid, result); + fclose(fid); + fprintf('\nSaved your solutions to %s.\n\n', saveAsFile); + fprintf(['You can now submit your solutions through the web \n' ... + 'form in the programming exercises. Select the corresponding \n' ... + 'programming exercise to access the form.\n']); + + else + fprintf('Unable to save to %s\n\n', saveAsFile); + fprintf(['You can create a submission file by saving the \n' ... + 'following text in a file: (press enter to continue)\n\n']); + pause; + fprintf(result); + end + +end + +% ================== CONFIGURABLES FOR EACH HOMEWORK ================== + +function id = homework_id() + id = '2'; +end + +function [partNames] = validParts() + partNames = { 'Sigmoid Function ', ... + 'Logistic Regression Cost', ... + 'Logistic Regression Gradient', ... + 'Predict', ... + 'Regularized Logistic Regression Cost' ... + 'Regularized Logistic Regression Gradient' ... + }; +end + +function srcs = sources() + % Separated by part + srcs = { { 'sigmoid.m' }, ... + { 'costFunction.m' }, ... + { 'costFunction.m' }, ... + { 'predict.m' }, ... + { 'costFunctionReg.m' }, ... + { 'costFunctionReg.m' } }; +end + +function out = output(partId) + % Random Test Cases + X = [ones(20,1) (exp(1) * sin(1:1:20))' (exp(0.5) * cos(1:1:20))']; + y = sin(X(:,1) + X(:,2)) > 0; + if partId == 1 + out = sprintf('%0.5f ', sigmoid(X)); + elseif partId == 2 + out = sprintf('%0.5f ', costFunction([0.25 0.5 -0.5]', X, y)); + elseif partId == 3 + [cost, grad] = costFunction([0.25 0.5 -0.5]', X, y); + out = sprintf('%0.5f ', grad); + elseif partId == 4 + out = sprintf('%0.5f ', predict([0.25 0.5 -0.5]', X)); + elseif partId == 5 + out = sprintf('%0.5f ', costFunctionReg([0.25 0.5 -0.5]', X, y, 0.1)); + elseif partId == 6 + [cost, grad] = costFunctionReg([0.25 0.5 -0.5]', X, y, 0.1); + out = sprintf('%0.5f ', grad); + end +end + + +% ========================= SUBMIT HELPERS ========================= + +function src = source(partId) + src = ''; + src_files = sources(); + if partId <= numel(src_files) + flist = src_files{partId}; + for i = 1:numel(flist) + fid = fopen(flist{i}); + while ~feof(fid) + line = fgets(fid); + src = [src line]; + end + fclose(fid); + src = [src '||||||||']; + end + end +end + +function ret = isValidPartId(partId) + partNames = validParts(); + ret = (~isempty(partId)) && (partId >= 1) && (partId <= numel(partNames)); +end + +function partId = promptPart() + fprintf('== Select which part(s) to submit:\n', ... + homework_id()); + partNames = validParts(); + srcFiles = sources(); + for i = 1:numel(partNames) + fprintf('== %d) %s [', i, partNames{i}); + fprintf(' %s ', srcFiles{i}{:}); + fprintf(']\n'); + end + fprintf('\nEnter your choice [1-%d]: ', ... + numel(partNames)); + selPart = input('', 's'); + partId = str2num(selPart); + if ~isValidPartId(partId) + partId = -1; + end +end + + +function [result, str] = submitSolution(email, part, output, source) + + result = ['a:5:{' ... + p_s('homework') p_s64(homework_id()) ... + p_s('part') p_s64(part) ... + p_s('email') p_s64(email) ... + p_s('output') p_s64(output) ... + p_s('source') p_s64(source) ... + '}']; + +end + +function s = p_s(str) + s = ['s:' num2str(numel(str)) ':"' str '";']; +end + +function s = p_s64(str) + str = base64encode(str, ''); + s = ['s:' num2str(numel(str)) ':"' str '";']; +end + +% =========================== LOGIN HELPERS =========================== + +function [login] = loginPrompt() + % Prompt for password + [login] = basicPrompt(); +end + + +function [login] = basicPrompt() + login = input('Login (Email address): ', 's'); +end + + +% =========================== Base64 Encoder ============================ +% Thanks to Peter John Acklam +% + +function y = base64encode(x, eol) +%BASE64ENCODE Perform base64 encoding on a string. +% +% BASE64ENCODE(STR, EOL) encode the given string STR. EOL is the line ending +% sequence to use; it is optional and defaults to '\n' (ASCII decimal 10). +% The returned encoded string is broken into lines of no more than 76 +% characters each, and each line will end with EOL unless it is empty. Let +% EOL be empty if you do not want the encoded string broken into lines. +% +% STR and EOL don't have to be strings (i.e., char arrays). The only +% requirement is that they are vectors containing values in the range 0-255. +% +% This function may be used to encode strings into the Base64 encoding +% specified in RFC 2045 - MIME (Multipurpose Internet Mail Extensions). The +% Base64 encoding is designed to represent arbitrary sequences of octets in a +% form that need not be humanly readable. A 65-character subset +% ([A-Za-z0-9+/=]) of US-ASCII is used, enabling 6 bits to be represented per +% printable character. +% +% Examples +% -------- +% +% If you want to encode a large file, you should encode it in chunks that are +% a multiple of 57 bytes. This ensures that the base64 lines line up and +% that you do not end up with padding in the middle. 57 bytes of data fills +% one complete base64 line (76 == 57*4/3): +% +% If ifid and ofid are two file identifiers opened for reading and writing, +% respectively, then you can base64 encode the data with +% +% while ~feof(ifid) +% fwrite(ofid, base64encode(fread(ifid, 60*57))); +% end +% +% or, if you have enough memory, +% +% fwrite(ofid, base64encode(fread(ifid))); +% +% See also BASE64DECODE. + +% Author: Peter John Acklam +% Time-stamp: 2004-02-03 21:36:56 +0100 +% E-mail: pjacklam@online.no +% URL: http://home.online.no/~pjacklam + + if isnumeric(x) + x = num2str(x); + end + + % make sure we have the EOL value + if nargin < 2 + eol = sprintf('\n'); + else + if sum(size(eol) > 1) > 1 + error('EOL must be a vector.'); + end + if any(eol(:) > 255) + error('EOL can not contain values larger than 255.'); + end + end + + if sum(size(x) > 1) > 1 + error('STR must be a vector.'); + end + + x = uint8(x); + eol = uint8(eol); + + ndbytes = length(x); % number of decoded bytes + nchunks = ceil(ndbytes / 3); % number of chunks/groups + nebytes = 4 * nchunks; % number of encoded bytes + + % add padding if necessary, to make the length of x a multiple of 3 + if rem(ndbytes, 3) + x(end+1 : 3*nchunks) = 0; + end + + x = reshape(x, [3, nchunks]); % reshape the data + y = repmat(uint8(0), 4, nchunks); % for the encoded data + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Split up every 3 bytes into 4 pieces + % + % aaaaaabb bbbbcccc ccdddddd + % + % to form + % + % 00aaaaaa 00bbbbbb 00cccccc 00dddddd + % + y(1,:) = bitshift(x(1,:), -2); % 6 highest bits of x(1,:) + + y(2,:) = bitshift(bitand(x(1,:), 3), 4); % 2 lowest bits of x(1,:) + y(2,:) = bitor(y(2,:), bitshift(x(2,:), -4)); % 4 highest bits of x(2,:) + + y(3,:) = bitshift(bitand(x(2,:), 15), 2); % 4 lowest bits of x(2,:) + y(3,:) = bitor(y(3,:), bitshift(x(3,:), -6)); % 2 highest bits of x(3,:) + + y(4,:) = bitand(x(3,:), 63); % 6 lowest bits of x(3,:) + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Now perform the following mapping + % + % 0 - 25 -> A-Z + % 26 - 51 -> a-z + % 52 - 61 -> 0-9 + % 62 -> + + % 63 -> / + % + % We could use a mapping vector like + % + % ['A':'Z', 'a':'z', '0':'9', '+/'] + % + % but that would require an index vector of class double. + % + z = repmat(uint8(0), size(y)); + i = y <= 25; z(i) = 'A' + double(y(i)); + i = 26 <= y & y <= 51; z(i) = 'a' - 26 + double(y(i)); + i = 52 <= y & y <= 61; z(i) = '0' - 52 + double(y(i)); + i = y == 62; z(i) = '+'; + i = y == 63; z(i) = '/'; + y = z; + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Add padding if necessary. + % + npbytes = 3 * nchunks - ndbytes; % number of padding bytes + if npbytes + y(end-npbytes+1 : end) = '='; % '=' is used for padding + end + + if isempty(eol) + + % reshape to a row vector + y = reshape(y, [1, nebytes]); + + else + + nlines = ceil(nebytes / 76); % number of lines + neolbytes = length(eol); % number of bytes in eol string + + % pad data so it becomes a multiple of 76 elements + y = [y(:) ; zeros(76 * nlines - numel(y), 1)]; + y(nebytes + 1 : 76 * nlines) = 0; + y = reshape(y, 76, nlines); + + % insert eol strings + eol = eol(:); + y(end + 1 : end + neolbytes, :) = eol(:, ones(1, nlines)); + + % remove padding, but keep the last eol string + m = nebytes + neolbytes * (nlines - 1); + n = (76+neolbytes)*nlines - neolbytes; + y(m+1 : n) = ''; + + % extract and reshape to row vector + y = reshape(y, 1, m+neolbytes); + + end + + % output is a character array + y = char(y); + +end diff --git a/R_LogR/survey.csv b/R_LogR/survey.csv new file mode 100644 index 0000000..f39e287 --- /dev/null +++ b/R_LogR/survey.csv @@ -0,0 +1,751 @@ +MYDEPV,Price,Income,Age +1,10,33,37 +0,20,21,55 +1,30,59,55 +1,20,76,44 +0,30,24,37 +0,20,22,32 +1,10,28,32 +1,10,49,38 +0,30,76,43 +1,20,59,55 +0,30,45,32 +0,30,21,46 +0,30,49,44 +0,10,23,30 +1,10,55,55 +0,20,29,32 +1,10,49,44 +0,20,45,32 +0,20,24,37 +0,10,30,32 +0,10,24,55 +1,10,59,55 +0,30,31,32 +0,20,33,32 +0,30,22,32 +0,30,29,32 +0,10,30,32 +0,20,28,32 +1,30,59,55 +0,30,56,43 +1,30,77,43 +1,20,97,18 +0,20,23,32 +0,30,25,37 +0,30,23,32 +0,30,88,43 +0,30,49,44 +1,30,76,44 +1,20,67,25 +1,10,55,55 +0,20,26,37 +1,20,49,44 +1,20,68,25 +0,30,45,32 +1,20,68,43 +0,20,32,35 +1,30,22,55 +1,30,55,55 +1,20,66,43 +0,20,29,32 +1,10,49,44 +1,10,28,32 +1,10,23,37 +0,20,45,32 +0,30,22,37 +1,10,66,25 +0,20,30,32 +0,20,43,27 +0,20,34,55 +0,30,32,32 +1,10,67,25 +0,20,25,27 +1,20,49,38 +0,30,33,55 +0,20,30,32 +1,10,34,37 +0,30,33,32 +0,10,32,27 +0,20,30,32 +1,20,66,25 +0,30,29,32 +1,10,25,37 +1,20,55,55 +0,30,22,32 +1,10,28,38 +0,20,22,44 +0,30,28,32 +0,10,45,32 +1,20,65,22 +1,10,78,21 +1,30,66,25 +1,20,99,25 +0,10,21,44 +0,20,23,37 +0,30,22,37 +1,30,88,43 +0,30,28,32 +1,30,49,55 +1,10,55,55 +0,20,29,32 +0,30,87,43 +1,30,66,25 +1,20,77,22 +1,10,26,37 +0,30,45,32 +0,20,43,22 +1,30,64,33 +0,20,45,32 +0,10,30,32 +0,30,56,43 +0,20,30,32 +0,30,30,32 +1,10,78,25 +1,20,77,43 +1,20,49,38 +0,30,32,35 +0,10,29,32 +1,20,89,22 +0,30,30,32 +1,30,55,55 +0,20,22,32 +0,20,32,32 +0,30,30,32 +0,30,49,44 +1,10,77,43 +1,20,59,55 +0,20,30,32 +0,30,22,27 +1,20,68,25 +1,10,59,55 +1,30,17,23 +0,20,22,32 +1,10,44,43 +1,20,76,21 +0,20,29,32 +1,10,59,55 +0,20,29,32 +0,30,23,30 +1,20,49,44 +0,20,33,32 +0,20,23,32 +1,10,64,33 +1,10,49,44 +1,30,57,25 +1,10,28,32 +0,10,22,32 +0,30,22,44 +0,20,33,23 +0,30,46,43 +0,30,22,32 +1,20,59,55 +0,10,22,32 +1,20,59,55 +1,10,33,24 +0,10,55,44 +0,30,49,38 +1,30,77,25 +0,20,22,37 +1,30,55,55 +1,30,22,25 +1,10,44,37 +0,30,21,37 +1,20,49,44 +1,20,55,55 +0,30,33,32 +0,10,30,32 +0,10,29,32 +0,30,49,38 +1,10,21,37 +1,10,55,25 +0,30,22,32 +0,20,28,32 +0,10,25,27 +1,20,98,43 +1,20,43,37 +0,30,49,38 +1,20,76,43 +0,10,30,32 +0,30,32,27 +1,10,59,55 +0,20,21,27 +0,30,55,44 +1,20,77,24 +0,30,34,37 +1,10,59,55 +1,10,65,25 +1,10,78,65 +0,20,19,46 +1,10,65,22 +1,20,59,55 +1,30,55,27 +0,20,29,32 +1,20,49,38 +0,20,23,38 +1,20,34,37 +0,30,30,32 +1,30,59,55 +1,10,22,25 +1,10,55,23 +0,30,29,32 +0,20,22,32 +0,20,33,27 +1,10,56,43 +1,10,49,44 +1,10,68,25 +0,10,22,32 +0,20,33,32 +0,20,22,27 +0,30,28,32 +0,20,45,32 +0,30,28,38 +0,30,24,27 +0,20,30,32 +0,20,29,32 +0,10,24,32 +1,10,28,32 +1,10,55,55 +0,20,20,47 +0,20,30,32 +0,30,28,32 +0,10,30,32 +0,20,22,37 +0,30,20,47 +0,30,45,32 +0,10,30,32 +0,20,22,27 +1,10,33,25 +0,10,30,32 +0,10,21,55 +0,10,45,32 +1,30,68,25 +0,10,30,32 +1,30,65,22 +0,30,49,44 +1,30,44,25 +0,20,28,32 +1,10,49,32 +1,10,66,43 +0,30,45,32 +1,10,65,25 +1,20,55,23 +1,30,78,21 +1,10,66,22 +0,20,25,37 +0,10,43,22 +1,10,66,43 +0,30,21,55 +0,20,23,27 +0,30,29,32 +1,20,56,43 +0,30,24,27 +1,10,55,44 +1,20,59,55 +0,10,34,25 +0,20,34,23 +1,20,66,25 +0,30,34,25 +0,20,32,32 +0,10,33,27 +1,10,88,23 +0,30,29,32 +0,30,22,27 +1,20,17,23 +1,10,54,25 +1,20,77,25 +1,10,59,55 +0,10,33,32 +0,20,32,37 +0,10,22,37 +1,20,55,37 +1,30,59,55 +0,10,29,32 +1,10,32,32 +1,20,28,38 +1,10,66,25 +0,10,45,32 +1,20,55,55 +0,10,19,46 +0,30,21,44 +1,20,49,44 +0,10,33,32 +0,20,30,32 +1,30,89,22 +0,30,30,32 +0,20,34,25 +1,30,55,55 +0,30,30,32 +0,20,55,44 +0,20,30,32 +1,30,59,55 +0,30,34,55 +0,10,33,23 +0,10,30,32 +0,10,45,32 +0,10,29,32 +0,30,78,43 +0,30,30,32 +0,30,22,37 +1,20,49,44 +1,20,49,38 +1,30,33,24 +1,20,57,25 +1,10,17,23 +1,10,55,55 +1,10,76,21 +0,10,29,32 +0,10,23,32 +0,20,33,55 +0,30,29,32 +0,20,29,32 +0,10,29,32 +0,20,28,32 +1,20,55,25 +0,10,22,32 +0,30,32,32 +1,20,78,43 +1,10,87,43 +1,10,49,44 +0,10,43,27 +0,30,26,37 +0,20,29,32 +0,20,30,32 +0,10,22,66 +1,30,66,25 +0,10,30,32 +1,10,88,43 +0,20,33,34 +1,10,99,25 +1,20,55,55 +1,10,34,33 +0,30,28,32 +0,10,29,32 +0,30,29,32 +0,30,49,38 +0,30,33,44 +0,10,33,32 +1,10,59,55 +1,20,55,44 +1,20,66,43 +1,10,67,25 +0,10,30,32 +0,30,21,37 +0,30,30,32 +0,20,22,37 +0,20,30,32 +0,30,45,32 +0,30,28,38 +1,20,65,25 +0,30,30,32 +1,10,76,44 +1,10,49,44 +1,30,34,33 +0,30,22,27 +0,10,33,44 +0,10,30,32 +1,30,55,44 +1,20,77,25 +0,10,21,27 +1,10,76,43 +0,20,22,45 +0,30,29,32 +0,20,21,37 +0,30,33,37 +0,20,43,24 +1,10,59,55 +1,10,55,37 +1,20,49,44 +1,30,88,23 +0,20,25,37 +0,30,55,37 +0,10,34,55 +0,20,28,32 +0,30,30,32 +0,30,28,32 +0,10,45,32 +1,10,59,55 +0,30,29,32 +0,20,24,32 +0,10,30,32 +1,10,77,25 +1,20,87,43 +0,10,23,38 +1,10,28,38 +1,30,98,43 +0,20,33,32 +1,10,59,55 +0,20,45,32 +1,20,67,25 +0,10,21,46 +0,20,22,32 +1,20,28,38 +1,10,21,37 +1,30,44,22 +0,10,33,27 +0,20,28,32 +0,30,29,32 +1,20,78,65 +0,20,24,27 +0,30,67,43 +1,30,97,18 +0,30,28,32 +0,10,30,32 +0,30,24,55 +0,20,33,37 +0,30,33,32 +1,20,33,24 +1,30,55,25 +0,10,33,34 +1,10,55,55 +0,10,24,37 +0,10,30,32 +0,10,22,37 +0,30,22,45 +0,30,30,32 +1,30,55,55 +1,30,66,25 +0,30,29,32 +1,10,22,55 +0,30,29,32 +0,10,30,32 +0,30,30,32 +0,30,33,23 +0,20,31,32 +1,30,55,55 +0,30,29,32 +0,10,32,35 +0,30,33,32 +0,30,30,32 +1,10,49,44 +0,30,23,38 +1,20,64,33 +1,20,78,43 +1,10,67,43 +1,30,78,65 +0,20,33,23 +0,30,49,44 +1,10,28,32 +0,20,28,32 +0,20,30,32 +0,20,30,32 +0,30,22,37 +1,10,49,44 +1,10,88,43 +1,10,32,32 +1,20,33,43 +1,20,56,26 +0,30,44,37 +0,20,32,27 +0,10,22,37 +0,20,33,27 +1,10,98,43 +0,20,21,37 +0,30,30,32 +0,30,31,32 +0,30,33,23 +0,30,30,32 +0,20,29,32 +0,30,29,32 +1,20,49,38 +1,30,59,55 +1,30,59,55 +0,30,43,27 +0,30,21,54 +0,10,22,44 +1,10,56,26 +0,30,30,32 +0,10,22,27 +1,10,68,25 +1,10,66,25 +1,30,77,25 +0,20,28,32 +0,30,49,44 +0,10,33,32 +1,30,33,25 +1,10,28,32 +0,20,22,27 +0,20,33,32 +0,20,30,32 +1,30,33,43 +1,10,33,43 +1,20,59,55 +0,10,34,23 +0,30,49,44 +1,10,77,22 +1,20,49,44 +1,10,56,43 +1,20,65,25 +0,10,23,27 +1,10,78,43 +1,30,55,55 +0,20,22,66 +1,10,59,55 +0,10,25,37 +1,10,59,55 +0,30,33,32 +0,10,45,32 +0,20,22,32 +0,20,28,32 +0,10,21,54 +1,10,44,22 +0,30,43,37 +0,20,45,32 +0,20,25,27 +1,20,49,44 +0,30,43,22 +0,10,33,55 +1,10,55,23 +0,10,22,32 +0,30,29,32 +0,10,30,32 +1,20,22,55 +0,20,33,44 +1,30,55,55 +0,10,29,32 +1,30,65,25 +1,30,99,25 +1,30,66,43 +0,10,22,32 +0,20,29,32 +1,30,67,25 +1,20,66,25 +0,20,22,27 +0,30,30,32 +0,30,22,32 +0,20,29,32 +1,10,49,38 +0,30,24,32 +0,20,21,54 +0,10,29,32 +0,30,23,27 +1,10,28,32 +0,30,49,44 +1,30,49,32 +0,20,29,32 +1,20,66,25 +0,30,33,34 +0,20,29,32 +1,10,46,43 +0,10,30,32 +1,30,65,25 +1,20,44,25 +1,10,59,55 +0,10,24,27 +0,10,22,27 +0,20,22,37 +1,10,77,25 +0,20,30,32 +0,10,33,32 +1,10,55,25 +1,30,56,26 +0,30,68,43 +1,20,55,55 +1,30,77,24 +0,30,49,44 +1,30,59,55 +0,10,29,32 +0,30,49,38 +1,20,49,44 +1,20,59,55 +0,30,49,44 +1,20,55,27 +0,30,19,46 +0,10,29,32 +0,10,29,32 +1,30,66,43 +1,20,55,55 +1,10,55,55 +1,10,28,32 +0,30,22,32 +1,20,59,55 +0,30,45,32 +1,10,49,38 +1,20,28,38 +0,10,33,32 +1,10,22,37 +0,30,33,27 +0,30,33,32 +1,10,28,38 +1,20,59,55 +0,30,33,37 +1,20,33,25 +1,10,55,55 +0,30,78,43 +1,20,67,43 +1,20,49,32 +0,10,30,32 +1,10,66,25 +1,10,49,38 +1,20,56,43 +1,20,78,25 +1,30,55,55 +0,30,22,37 +1,30,59,55 +1,20,55,55 +0,30,23,37 +1,10,49,44 +1,10,49,38 +0,10,43,24 +0,10,23,32 +1,20,49,44 +0,30,31,32 +0,30,33,27 +0,20,22,37 +1,30,77,22 +1,30,59,55 +0,20,22,32 +1,30,55,23 +0,30,30,32 +1,10,49,44 +0,20,22,32 +1,10,68,43 +1,10,49,55 +1,20,49,55 +0,20,29,32 +0,10,24,27 +1,20,36,37 +0,30,32,37 +1,10,57,25 +0,10,21,37 +1,20,59,55 +0,30,22,32 +0,10,31,32 +0,30,29,32 +1,20,55,25 +1,10,89,22 +0,30,22,66 +0,10,22,27 +0,30,34,23 +0,20,29,32 +1,20,34,33 +0,10,45,32 +0,10,20,47 +1,10,33,37 +0,20,30,32 +0,10,45,32 +0,30,28,38 +0,20,21,37 +1,30,76,21 +0,30,29,32 +0,30,49,38 +0,20,55,36 +1,10,55,27 +0,10,29,32 +0,20,24,27 +1,10,28,32 +0,30,22,27 +0,30,29,32 +1,10,97,18 +1,30,67,25 +1,30,55,55 +0,30,25,37 +1,10,22,37 +0,30,28,32 +0,20,33,32 +0,30,49,44 +1,20,22,25 +1,10,77,24 +0,10,29,32 +0,30,55,36 +0,10,32,37 +1,20,59,55 +0,20,29,32 +1,10,28,38 +1,20,88,43 +0,20,29,32 +0,20,23,30 +1,30,55,25 +1,20,88,43 +1,10,49,44 +1,30,54,25 +1,20,55,55 +0,30,28,32 +1,20,88,23 +0,20,44,37 +0,20,21,46 +1,10,49,38 +1,20,55,23 +0,10,29,32 +1,10,44,25 +0,20,31,32 +0,30,29,32 +0,30,33,24 +0,10,33,23 +0,10,31,32 +1,30,59,55 +0,10,22,27 +0,10,22,32 +1,20,55,55 +1,10,43,37 +0,30,22,32 +0,10,25,27 +0,20,31,32 +0,20,29,32 +1,20,44,43 +0,20,45,32 +0,10,29,32 +1,30,55,23 +0,20,30,32 +0,30,30,32 +1,10,49,44 +0,20,30,32 +0,30,25,27 +0,10,29,32 +0,20,33,24 +1,20,55,55 +0,30,44,43 +0,10,29,32 +1,10,36,37 +0,30,21,27 +1,20,66,43 +0,30,49,44 +0,30,36,37 +0,30,30,32 +1,20,88,23 +1,20,49,38 +0,30,45,32 +1,20,46,43 +0,20,21,44 +1,20,66,22 +0,30,23,32 +1,20,59,55 +0,10,22,45 +0,20,30,32 +0,10,33,24 +0,10,29,32 +0,30,29,32 +0,10,31,32 +1,10,78,43 +0,20,33,37 +1,20,78,21 +1,10,88,23 +1,20,59,55 +1,30,59,55 +0,30,43,24 +1,30,78,25 +1,30,88,23 +1,30,66,22 +1,20,54,25 +0,20,45,32 +1,20,49,44 +0,20,24,55 +1,10,66,43 +1,20,44,22 +1,10,55,55 +1,30,59,55 +0,20,30,32 +0,10,22,32 +1,20,49,44 +0,30,66,43 +1,30,68,25 +1,30,59,55 +0,20,28,38 +1,10,59,55 +0,20,29,32 +1,10,55,55 +0,30,25,27 +0,10,29,32 +0,10,55,36 +0,30,21,37 +0,30,28,38
\ No newline at end of file |
