update week 39

This commit is contained in:
Morten Hjorth-Jensen
2025-09-22 06:31:07 +02:00
parent b230cbd984
commit ef3465a8cd
21 changed files with 42249 additions and 15780 deletions
File diff suppressed because it is too large Load Diff
+100
View File
@@ -0,0 +1,100 @@
1, 21, 1, 0
2, 23, 1, 0
3, 25, 1, 1
4, 29, 1, 0
5, 21, 1, 0
6, 24, 1, 0
7, 27, 1, 0
8, 29, 1, 0
9, 28, 1, 0
10, 26, 1, 0
11, 30, 2, 0
12, 31, 2, 0
13, 31, 2, 0
14, 31, 2, 1
15, 32, 2, 0
16, 34, 2, 0
17, 34, 2, 0
18, 31, 2, 0
19, 32, 2, 0
20, 32, 2, 0
21, 33, 2, 0
22, 34, 2, 0
23, 31, 2, 1
24, 30, 2, 0
25, 33, 2, 0
26, 36, 3, 1
27, 35, 3, 0
28, 35, 3, 0
29, 38, 3, 0
30, 37, 3, 1
31, 36, 3, 0
32, 35, 3, 0
33, 39, 3, 0
34, 39, 3, 0
35, 38, 3, 1
36, 37, 3, 0
37, 37, 3, 0
38, 40, 4, 0
39, 41, 4, 1
40, 44, 4, 0
41, 44, 4, 0
42, 43, 4, 1
43, 42, 4, 0
44, 41, 4, 0
45, 40, 4, 1
46, 42, 4, 0
47, 42, 4, 0
48, 43, 4, 0
49, 44, 4, 1
50, 44, 4, 0
51, 42, 4, 0
52, 41, 4, 1
53, 45, 5, 0
54, 45, 5, 1
55, 49, 5, 0
56, 48, 5, 1
57, 47, 5, 0
58, 49, 5, 1
59, 46, 5, 1
60, 45, 5, 0
61, 49, 5, 1
62, 48, 5, 0
63, 47, 5, 1
64, 46, 5, 0
65, 47, 5, 0
66, 50, 6, 1
67, 51, 6, 1
68, 51, 6, 0
69, 54, 6, 1
70, 53, 6, 1
71, 51, 6, 0
72, 52, 6, 1
73, 54, 6, 0
74, 55, 7, 1
75, 56, 7, 1
76, 58, 7, 0
77, 59, 7, 1
78, 59, 7, 1
79, 58, 7, 0
80, 55, 7, 1
81, 56, 7, 1
82, 57, 7, 1
83, 58, 7, 1
84, 59, 7, 0
85, 55, 7, 1
86, 56, 7, 1
87, 57, 7, 1
88, 58, 7, 0
89, 59, 7, 1
90, 56, 7, 1
91, 60, 8, 1
92, 65, 8, 1
93, 67, 8, 1
94, 66, 8, 0
95, 63, 8, 1
96, 61, 8, 1
97, 69, 8, 1
98, 65, 8, 1
99, 64, 8, 1
100, 63, 8, 0
1 1 21 1 0
2 2 23 1 0
3 3 25 1 1
4 4 29 1 0
5 5 21 1 0
6 6 24 1 0
7 7 27 1 0
8 8 29 1 0
9 9 28 1 0
10 10 26 1 0
11 11 30 2 0
12 12 31 2 0
13 13 31 2 0
14 14 31 2 1
15 15 32 2 0
16 16 34 2 0
17 17 34 2 0
18 18 31 2 0
19 19 32 2 0
20 20 32 2 0
21 21 33 2 0
22 22 34 2 0
23 23 31 2 1
24 24 30 2 0
25 25 33 2 0
26 26 36 3 1
27 27 35 3 0
28 28 35 3 0
29 29 38 3 0
30 30 37 3 1
31 31 36 3 0
32 32 35 3 0
33 33 39 3 0
34 34 39 3 0
35 35 38 3 1
36 36 37 3 0
37 37 37 3 0
38 38 40 4 0
39 39 41 4 1
40 40 44 4 0
41 41 44 4 0
42 42 43 4 1
43 43 42 4 0
44 44 41 4 0
45 45 40 4 1
46 46 42 4 0
47 47 42 4 0
48 48 43 4 0
49 49 44 4 1
50 50 44 4 0
51 51 42 4 0
52 52 41 4 1
53 53 45 5 0
54 54 45 5 1
55 55 49 5 0
56 56 48 5 1
57 57 47 5 0
58 58 49 5 1
59 59 46 5 1
60 60 45 5 0
61 61 49 5 1
62 62 48 5 0
63 63 47 5 1
64 64 46 5 0
65 65 47 5 0
66 66 50 6 1
67 67 51 6 1
68 68 51 6 0
69 69 54 6 1
70 70 53 6 1
71 71 51 6 0
72 72 52 6 1
73 73 54 6 0
74 74 55 7 1
75 75 56 7 1
76 76 58 7 0
77 77 59 7 1
78 78 59 7 1
79 79 58 7 0
80 80 55 7 1
81 81 56 7 1
82 82 57 7 1
83 83 58 7 1
84 84 59 7 0
85 85 55 7 1
86 86 56 7 1
87 87 57 7 1
88 88 58 7 0
89 89 59 7 1
90 90 56 7 1
91 91 60 8 1
92 92 65 8 1
93 93 67 8 1
94 94 66 8 0
95 95 63 8 1
96 96 61 8 1
97 97 69 8 1
98 98 65 8 1
99 99 64 8 1
100 100 63 8 0
+201
View File
@@ -0,0 +1,201 @@
TrueLabel,PredictedLabel
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,0
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1 TrueLabel PredictedLabel
2 0 0
3 0 0
4 0 0
5 0 0
6 0 0
7 0 0
8 0 0
9 0 0
10 0 0
11 0 0
12 0 0
13 0 0
14 0 0
15 0 0
16 0 0
17 0 0
18 0 0
19 0 0
20 0 0
21 0 0
22 0 0
23 0 0
24 0 0
25 0 0
26 0 0
27 0 0
28 0 0
29 0 0
30 0 0
31 0 0
32 0 0
33 0 0
34 0 0
35 0 0
36 0 0
37 0 0
38 0 0
39 0 0
40 0 0
41 0 0
42 0 0
43 0 0
44 0 0
45 0 0
46 0 0
47 0 0
48 0 0
49 0 0
50 0 0
51 0 0
52 0 0
53 0 0
54 0 0
55 0 0
56 0 0
57 0 0
58 0 0
59 0 0
60 0 0
61 0 0
62 0 0
63 0 0
64 0 0
65 0 0
66 0 0
67 0 0
68 0 0
69 0 0
70 0 0
71 0 0
72 0 0
73 0 0
74 0 0
75 0 0
76 0 0
77 0 0
78 0 0
79 0 0
80 0 0
81 0 0
82 0 0
83 0 0
84 0 0
85 0 0
86 0 0
87 0 0
88 0 0
89 0 0
90 0 0
91 0 0
92 0 0
93 0 0
94 0 0
95 0 0
96 0 0
97 0 0
98 0 0
99 0 0
100 0 0
101 0 0
102 1 1
103 1 1
104 1 1
105 1 1
106 1 1
107 1 1
108 1 1
109 1 1
110 1 1
111 1 1
112 1 1
113 1 1
114 1 1
115 1 1
116 1 1
117 1 1
118 1 1
119 1 1
120 1 1
121 1 1
122 1 1
123 1 1
124 1 1
125 1 1
126 1 1
127 1 1
128 1 1
129 1 1
130 1 1
131 1 1
132 1 1
133 1 0
134 1 1
135 1 1
136 1 1
137 1 1
138 1 1
139 1 1
140 1 1
141 1 1
142 1 1
143 1 1
144 1 1
145 1 1
146 1 1
147 1 1
148 1 1
149 1 1
150 1 1
151 1 1
152 1 1
153 1 1
154 1 1
155 1 1
156 1 1
157 1 1
158 1 1
159 1 1
160 1 1
161 1 1
162 1 1
163 1 1
164 1 1
165 1 1
166 1 1
167 1 1
168 1 1
169 1 1
170 1 1
171 1 1
172 1 1
173 1 1
174 1 1
175 1 1
176 1 1
177 1 1
178 1 1
179 1 1
180 1 1
181 1 1
182 1 1
183 1 1
184 1 1
185 1 1
186 1 1
187 1 1
188 1 1
189 1 1
190 1 1
191 1 1
192 1 1
193 1 1
194 1 1
195 1 1
196 1 1
197 1 1
198 1 1
199 1 1
200 1 1
201 1 1
File diff suppressed because it is too large Load Diff
+80
View File
@@ -0,0 +1,80 @@
import numpy as np
import pandas as pd
# Load the dataset (ensure the CSV file is in the working directory)
df = pd.read_csv('creditcard.csv')
# Preprocess the data
df = df.drop('ID', axis=1) # drop ID column
# Rename the target column for convenience (optional)
df = df.rename(columns={'default payment next month': 'default'})
# Separate features and target
X = df.drop('default', axis=1).values # features (shape: [30000, 23])
y = df['default'].values # target (shape: [30000,])
# Standardize features (zero mean, unit std dev)
X_mean = X.mean(axis=0)
X_std = X.std(axis=0)
X = (X - X_mean) / X_std
# Split into training and test sets (80/20 split)
m = X.shape[0]
train_size = int(0.8 * m)
indices = np.random.permutation(m) # shuffle indices for randomness
train_idx, test_idx = indices[:train_size], indices[train_size:]
X_train, X_test = X[train_idx], X[test_idx]
y_train, y_test = y[train_idx], y[test_idx]
# Add intercept term (bias) to features by adding a column of 1s
X_train = np.hstack([np.ones((X_train.shape[0], 1)), X_train])
X_test = np.hstack([np.ones((X_test.shape[0], 1)), X_test])
# Initialize logistic regression parameters
n_features = X_train.shape[1] # number of features including bias
theta = np.zeros(n_features) # model weights (initialized to 0)
# Set training hyperparameters
learning_rate = 0.1
epochs = 500
# Training loop (gradient descent)
m_train = X_train.shape[0]
for epoch in range(epochs):
# Compute predictions (sigmoid of linear combination)
z = X_train.dot(theta) # linear combination
predictions = 1 / (1 + np.exp(-z)) # sigmoid function
# Compute the gradient of loss w.r.t. theta
error = predictions - y_train # vector of (pred - true) for each example
grad = (X_train.T.dot(error)) / m_train # gradient vector
# Update weights
theta -= learning_rate * grad
# (Optional) compute and print loss every 50 epochs for monitoring
if epoch % 50 == 0:
# Binary cross-entropy loss
loss = -np.mean(y_train * np.log(predictions + 1e-15) +
(1 - y_train) * np.log(1 - predictions + 1e-15))
print(f"Epoch {epoch}: Training loss = {loss:.4f}")
# 5. Evaluate the model on training and test data
# Predict probabilities for test set and classify as 1 if sigmoid >= 0.5
# (We can equivalently check linear term >= 0, since sigma(x)>=0.5 iff x>=0)
train_prob = 1 / (1 + np.exp(-X_train.dot(theta)))
test_prob = 1 / (1 + np.exp(-X_test.dot(theta)))
train_pred = (train_prob >= 0.5).astype(int)
test_pred = (test_prob >= 0.5).astype(int)
# Calculate accuracy
train_accuracy = (train_pred == y_train).mean()
test_accuracy = (test_pred == y_test).mean()
# Calculate final loss on training set for reference
final_loss = -np.mean(y_train * np.log(train_prob + 1e-15) +
(1 - y_train) * np.log(1 - train_prob + 1e-15))
# Print performance metrics
print(f"Final Training Loss: {final_loss:.4f}")
print(f"Training Accuracy: {train_accuracy * 100:.2f}%")
print(f"Test Accuracy: {test_accuracy * 100:.2f}%")
+163
View File
@@ -0,0 +1,163 @@
TITLE: Week 40: Credit card example
AUTHOR: Morten Hjorth-Jensen {copyright, 1999-present|CC BY-NC} at Department of Physics, University of Oslo
DATE: Week 40
!split
===== Example case: Logistic Regression on Taiwan Credit Card Default Dataset =====
=== Dataset Overview and Preparation ===
The Default of Credit Card Clients dataset (Taiwan credit card default
data) contains 30,000 instances and 23 features (plus an ID and a
binary default indicator). The target variable is _default payment
next month_ (1 = default, 0 = no default) . Key characteristics of the
data include:
o Instances: 30,000 card clients (each a unique ID)
o Features: 23 predictive features (mostly numeric, including demographics, credit limit, payment history, bill amounts, etc.)
o Target: Binary default indicator for the next month (Yes=1, No=0)
o Missing Values: None the dataset has no missing values recorded
o Class Distribution: 22.1% of clients (6,636) defaulted vs 77.9% non-default (i.e. the data is imbalanced about 1:3).
o Basic Stats: Average credit limit is around NT$167,500, and mean age is ~35.5 years . Bill statement amounts are on the order of tens of thousands NT (mean ≈ 40k), while monthly payment amounts average a few thousand NT (mean ≈ 5k) .
=== Feature details ===
All features are numeric. Some are categorical in nature (encoded as
integers): e.g. SEX (1=male, 2=female), EDUCATION (1=graduate,
2=university, 3=high school, 4=others, with 5-6 as unknown) and
MARRIAGE (1=married, 2=single, 3=others) . Others are continuous
(credit amount, bill amounts, payments) or ordinal (e.g. $PAY_0 PAY_6$
repayment status, where -1 = pay duly, 1 = 1 month delay, 2 = 2 months
delay, etc.) .
=== Preprocessing steps ===
For binary classification, we prepare the data as follows:
o Remove the ID column (identifier not useful for prediction).
o Use the 23 remaining features as $X$ and the _default payment next month_ as the binary target $y$.
o The categorical features (SEX, EDUCATION, MARRIAGE) are already integer-encoded; for simplicity, we will use them as-is (one could one-hot encode these, but its not strictly necessary for logistic regression).
o Standardize the feature values i.e. scale each feature to zero mean and unit variance. This helps the gradient descent in logistic regression converge faster.
o Split the dataset into a training set and testing set (well use an 80/20 split). The model will be trained on the training set and evaluated on the test set to gauge performance on unseen data.
!split
===== Implementing Logistic Regression =====
We will implement a logistic regression classifier using only NumPy,
without any machine learning libraries. Logistic regression computes a
weighted linear combination of features (plus a bias term) and applies
a sigmoid function $\sigma(z) = 1/(1+e^{-z})$ to produce a probability
between 0 and 1. We train the model by minimizing the logistic loss
(binary cross-entropy) using gradient descent.
Below is a single Python script that loads and preprocesses the data,
then defines and trains the logistic regression model using gradient
descent. It also outputs the models performance metrics (accuracy and
loss). The file can be downloaded from the UCI database at URL:"https://archive.ics.uci.edu/dataset/350/default+of+credit+card+clients"
!bc pycod
import numpy as np
import pandas as pd
# Load the dataset (ensure the CSV file is in the working directory)
df = pd.read_csv('credit_card_clients.csv')
# Preprocess the data
df = df.drop('ID', axis=1) # drop ID column
# Rename the target column for convenience (optional)
df = df.rename(columns={'default payment next month': 'default'})
# Separate features and target
X = df.drop('default', axis=1).values # features (shape: [30000, 23])
y = df['default'].values # target (shape: [30000,])
# Standardize features (zero mean, unit std dev)
X_mean = X.mean(axis=0)
X_std = X.std(axis=0)
X = (X - X_mean) / X_std
# Split into training and test sets (80/20 split)
m = X.shape[0]
train_size = int(0.8 * m)
indices = np.random.permutation(m) # shuffle indices for randomness
train_idx, test_idx = indices[:train_size], indices[train_size:]
X_train, X_test = X[train_idx], X[test_idx]
y_train, y_test = y[train_idx], y[test_idx]
# Add intercept term (bias) to features by adding a column of 1s
X_train = np.hstack([np.ones((X_train.shape[0], 1)), X_train])
X_test = np.hstack([np.ones((X_test.shape[0], 1)), X_test])
# Initialize logistic regression parameters
n_features = X_train.shape[1] # number of features including bias
theta = np.zeros(n_features) # model weights (initialized to 0)
# Set training hyperparameters
learning_rate = 0.1
epochs = 500
# Training loop (gradient descent)
m_train = X_train.shape[0]
for epoch in range(epochs):
# Compute predictions (sigmoid of linear combination)
z = X_train.dot(theta) # linear combination
predictions = 1 / (1 + np.exp(-z)) # sigmoid function
# Compute the gradient of loss w.r.t. theta
error = predictions - y_train # vector of (pred - true) for each example
grad = (X_train.T.dot(error)) / m_train # gradient vector
# Update weights
theta -= learning_rate * grad
# (Optional) compute and print loss every 50 epochs for monitoring
if epoch % 50 == 0:
# Binary cross-entropy loss
loss = -np.mean(y_train * np.log(predictions + 1e-15) +
(1 - y_train) * np.log(1 - predictions + 1e-15))
print(f"Epoch {epoch}: Training loss = {loss:.4f}")
# 5. Evaluate the model on training and test data
# Predict probabilities for test set and classify as 1 if sigmoid >= 0.5
# (We can equivalently check linear term >= 0, since sigma(x)>=0.5 iff x>=0)
train_prob = 1 / (1 + np.exp(-X_train.dot(theta)))
test_prob = 1 / (1 + np.exp(-X_test.dot(theta)))
train_pred = (train_prob >= 0.5).astype(int)
test_pred = (test_prob >= 0.5).astype(int)
# Calculate accuracy
train_accuracy = (train_pred == y_train).mean()
test_accuracy = (test_pred == y_test).mean()
# Calculate final loss on training set for reference
final_loss = -np.mean(y_train * np.log(train_prob + 1e-15) +
(1 - y_train) * np.log(1 - train_prob + 1e-15))
# Print performance metrics
print(f"Final Training Loss: {final_loss:.4f}")
print(f"Training Accuracy: {train_accuracy * 100:.2f}%")
print(f"Test Accuracy: {test_accuracy * 100:.2f}%")
!ec
Explanation: We initialize the weight vector theta (including a bias term) to zeros. In each training epoch, we compute the logistic predictions for all training examples and then update the weights using the gradient of the cross-entropy loss. The learning rate and number of epochs are set to fixed values (which can be tuned). We periodically print the training loss to ensure the model is learning (decreasing loss). After training, we obtain predicted probabilities on the train and test sets, convert them to class labels (threshold 0.5), and compute the accuracy.
!split
===== Model performance and results =====
After training, the code prints out the final loss and accuracies. You should observe that the training and test accuracy are around 7880% for this logistic model.
This performance is in line with expectations. The datasets class imbalance means that always predicting “no default” would already achieve ~77.9% accuracy . Our logistic regression does slightly better, around 7981% accuracy, by identifying some of the default cases correctly. (In one reference implementation, logistic regression achieved ~81.3% accuracy on a test set .)
The models loss converges to a reasonable value, indicating the gradient descent optimization was successful.
Note: The relatively modest improvement over the baseline is due to the imbalance and the limited complexity of a linear model. In practice, one could improve default prediction by using more complex models or addressing the imbalance (e.g. with oversampling or adjusting the classification threshold). Nonetheless, the above example demonstrates the complete process: data loading, preprocessing, model training, and evaluation, fulfilling the binary classification task on the Taiwan credit card default dataset.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

+301
View File
@@ -0,0 +1,301 @@
TrueLabel,PredictedLabel
0,0
0,1
0,0
0,0
0,1
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,1
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,1
0,0
0,2
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
0,0
1,1
1,1
1,0
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,0
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,0
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,0
1,1
1,1
1,0
1,1
1,1
1,1
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
2,2
1 TrueLabel PredictedLabel
2 0 0
3 0 1
4 0 0
5 0 0
6 0 1
7 0 0
8 0 0
9 0 0
10 0 0
11 0 0
12 0 0
13 0 0
14 0 0
15 0 0
16 0 0
17 0 0
18 0 0
19 0 0
20 0 0
21 0 0
22 0 0
23 0 0
24 0 0
25 0 0
26 0 0
27 0 0
28 0 0
29 0 0
30 0 0
31 0 0
32 0 0
33 0 0
34 0 0
35 0 1
36 0 0
37 0 0
38 0 0
39 0 0
40 0 0
41 0 0
42 0 0
43 0 0
44 0 0
45 0 0
46 0 0
47 0 0
48 0 0
49 0 0
50 0 0
51 0 0
52 0 0
53 0 0
54 0 0
55 0 0
56 0 0
57 0 0
58 0 0
59 0 0
60 0 0
61 0 0
62 0 0
63 0 0
64 0 0
65 0 0
66 0 0
67 0 0
68 0 0
69 0 0
70 0 0
71 0 0
72 0 0
73 0 0
74 0 0
75 0 0
76 0 0
77 0 0
78 0 0
79 0 0
80 0 0
81 0 0
82 0 0
83 0 0
84 0 0
85 0 1
86 0 0
87 0 2
88 0 0
89 0 0
90 0 0
91 0 0
92 0 0
93 0 0
94 0 0
95 0 0
96 0 0
97 0 0
98 0 0
99 0 0
100 0 0
101 0 0
102 1 1
103 1 1
104 1 0
105 1 1
106 1 1
107 1 1
108 1 1
109 1 1
110 1 1
111 1 1
112 1 0
113 1 1
114 1 1
115 1 1
116 1 1
117 1 1
118 1 1
119 1 1
120 1 1
121 1 1
122 1 1
123 1 1
124 1 1
125 1 1
126 1 0
127 1 1
128 1 1
129 1 1
130 1 1
131 1 1
132 1 1
133 1 1
134 1 1
135 1 1
136 1 1
137 1 1
138 1 1
139 1 1
140 1 1
141 1 1
142 1 1
143 1 1
144 1 1
145 1 1
146 1 1
147 1 1
148 1 1
149 1 1
150 1 1
151 1 1
152 1 1
153 1 1
154 1 1
155 1 1
156 1 1
157 1 1
158 1 1
159 1 1
160 1 1
161 1 1
162 1 1
163 1 1
164 1 1
165 1 1
166 1 1
167 1 1
168 1 1
169 1 1
170 1 1
171 1 1
172 1 1
173 1 1
174 1 1
175 1 1
176 1 1
177 1 1
178 1 1
179 1 1
180 1 1
181 1 1
182 1 1
183 1 1
184 1 1
185 1 1
186 1 1
187 1 1
188 1 1
189 1 1
190 1 1
191 1 1
192 1 1
193 1 1
194 1 1
195 1 0
196 1 1
197 1 1
198 1 0
199 1 1
200 1 1
201 1 1
202 2 2
203 2 2
204 2 2
205 2 2
206 2 2
207 2 2
208 2 2
209 2 2
210 2 2
211 2 2
212 2 2
213 2 2
214 2 2
215 2 2
216 2 2
217 2 2
218 2 2
219 2 2
220 2 2
221 2 2
222 2 2
223 2 2
224 2 2
225 2 2
226 2 2
227 2 2
228 2 2
229 2 2
230 2 2
231 2 2
232 2 2
233 2 2
234 2 2
235 2 2
236 2 2
237 2 2
238 2 2
239 2 2
240 2 2
241 2 2
242 2 2
243 2 2
244 2 2
245 2 2
246 2 2
247 2 2
248 2 2
249 2 2
250 2 2
251 2 2
252 2 2
253 2 2
254 2 2
255 2 2
256 2 2
257 2 2
258 2 2
259 2 2
260 2 2
261 2 2
262 2 2
263 2 2
264 2 2
265 2 2
266 2 2
267 2 2
268 2 2
269 2 2
270 2 2
271 2 2
272 2 2
273 2 2
274 2 2
275 2 2
276 2 2
277 2 2
278 2 2
279 2 2
280 2 2
281 2 2
282 2 2
283 2 2
284 2 2
285 2 2
286 2 2
287 2 2
288 2 2
289 2 2
290 2 2
291 2 2
292 2 2
293 2 2
294 2 2
295 2 2
296 2 2
297 2 2
298 2 2
299 2 2
300 2 2
301 2 2
File diff suppressed because it is too large Load Diff