RE: https://mastodon.social/@bitboxer/117496377274602134
This reminds me of one of my favourite things to do with my kids. Find a stream, move stones around. Build dams, don't, it doesn't matter. Play doesn't have to have an external purpose.
19 results for “dn_mason”
RE: https://mastodon.social/@bitboxer/117496377274602134
This reminds me of one of my favourite things to do with my kids. Find a stream, move stones around. Build dams, don't, it doesn't matter. Play doesn't have to have an external purpose.
SWD powervolleys Düren: Starkes erstes Heimspiel
📍 #Düren ■ #Sport ⬀ #Volleyball #Bundesliga #SWDPowervolleys #ArenaKreisDüren
https://dn-news.de/dueren/2026/10/24/swd-powervolleys-dueren-starkes-erstes-heimspiel/#ma
https://www.dn.se/ledare/hanet-mot-centern-sager-mycket-men-inget-om-centern/
✝️ #KyrkaniSverige :
Centerns röda linjer ska stoppa den brunröda
Ondskan !?...?
❄️ #GALliMattias:
Nassarna skall håll med en armlängds avstånd från
Makten !....
🦜#GrönRödaGojan :
Klimat och miljö går före partitjafsandet !...
https://www.dn.se/ledare/susanne-nystrom-de-fruktansvarda-siffrorna-talar-sitt-tydliga-sprak/
🦜 #GrönRödaGojan :
Trumpens terror mördar mer än alla privatterrorister
tillsammans !...
https://www.dn.se/kultur/martin-gelin-nu-flyr-allt-fler-unga-fran-internet-till-verkligheten/
🦜#GrönRödaGojan :
Framåt till dåtiden!?....
https://www.dn.se/ledare/hur-i-hela-friden-kunde-vansterpartiet-missa-det-har/
🦜#GrönRödaGojan :
Mycket oväntat! kommunister brukar ha koll !?...
HAHAHAHAHAHAHAHAHAHAHAHAHAHAH !!!!!!!!!!
https://www.dn.se/varlden/uppgifter-vita-huset-vill-se-orban-som-fn-chef/
❄️GALlimattias :
Wold is pure Mold !.
Puh där fick dom fyra års respit !?...
https://www.dn.se/varlden/lula-och-bolsonaro-gor-upp-i-avgorande-val-i-brasilien/ #democracy #vs #fascism
Puh där fick dom fyra års respit !?...
https://www.dn.se/varlden/lula-och-bolsonaro-gor-upp-i-avgorande-val-i-brasilien/ #democracy #vs #fascismPuh där fick dom fyra års respit !?...
https://www.europesays.com/no/396433/ Forvalter med Oljefondet-advarsel | DN #Business #Economy #Næringsliv #NO #Norge #Norway
【原神】原神が一瞬で地獄になる瞬間【Genshin Impact/げんしん】#原神ショート #スカーク https://www.playing-games.com/1122414/ ##shortsadventure #DN #DragonNest #Fortnite #GenshinImpact #hoyocreators #JPDN #LittleNIGHTMARES #LittleNIGHTMARESⅡ #Yology #YologyJPDN #ゲーム #ゲーム実況 #げんしん #げんしんインパクト #ドラゴンネスト #ドラネス #フォートナイト #フォトナ #ポテトマン #ホラー #ホラゲー #よろ #よろよろ #リトルナイトメア #リトルナイトメア2 #原神 #実況 #青鬼 #青鬼X
Dann probieren wir mal #Technitium anstatt #AdGuardHome im #Homelab aus.
Vorteil schon mal, dass es ein Service gibt, der mir die Container hinter #Traefik direkt als Eintrag anlegen kann.
#Quad9 zieht sich aus Frankreich zurück nach Urteil, das #DNS-Manipulation verlangt. Der Dienst schützt Privatsphäre und wehrt sich gegen IT-Bedrohungen. Nutzer müssen bis 24. November auf andere DNS-Server wechseln. Die Stiftung hält das Urteil für unvereinbar mit ihrer Mission. https://www.heise.de/news/Zensur-Urteil-DNS-Dienst-Quad9-verlaesst-Frankreich-11497622.html?seite=all
⚡️Daēnā stands on the Chinvat bridge where the soul crosses. Her name carries D-N-, as do the rivers Don, Donets, Dnipro, Dniester and Danube. Her name is on the bridge. Her name is on the D-N-.
Full podcast: https://www.powerofmana.net/p/podcast-finding-manuland-atlas-ep-1f0
Rakus Light Cloud Confirms Data Breach Affecting All Blastmail Contract Holders
Rakus Light Cloud's Blastmail service reports a data breach after attackers exploited a PHP vulnerability in API servers to steal records for all contract holders and subscriber lists for 344 organizations. The incident forced an emergency shutdown of the service, affecting over 544,000 individual records across multiple Japanese companies and government entities.
****
#cybersecurity #infosec #incident #databreach
https://beyondmachines.net/event_details/rakus-light-cloud-confirms-data-breach-affecting-all-blastmail-contract-holders-c-5-d-n-q/gD2P6Ple2L
Most developers reach for Python (scikit-learn, scipy) when implementing unsupervised machine learning algorithms like K-Means or Hierarchical Clustering. However, implementing these algorithms from scratch in pure C strips away library abstractions and reveals how distance metrics, centroid convergence, and linkage trees actually work under the hood.
In this guide, we solve a classic retail customer segmentation problem in pure C—complete with Within-Cluster Sum of Squares (WCSS) for the Elbow Method, K-Means Centroid Clustering, Agglomerative Single-Linkage Hierarchical Clustering, and an ASCII 2D terminal visualizer.
The Problem Statement
A retail company wants to segment its customers based on:
Our goal is to:
The Dataset
We use a clean 6-customer dataset so you can trace every single Euclidean distance calculation by hand and verify the C output directly:
Mathematical Foundations
1. Euclidean Distance
Both K-Means and Single-Linkage Hierarchical Clustering measure similarity between two points $P_1(x_1, y_1)$ and $P_2(x_2, y_2)$ using straight-line Euclidean distance:
$$d(P_1, P_2) = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2}$$
2. The Elbow Method & WCSS
The Elbow Method finds the optimal number of clusters $K$ by calculating the Within-Cluster Sum of Squares (WCSS) across increasing values of $K$:
$$\text{WCSS} = \sum_{i=1}^{K} \sum_{x_j \in C_i} \left( (x_j - c_{ix})^2 + (y_j - c_{iy})^2 \right)$$
Because the sharpest drop ("elbow") occurs at $K = 2$, the optimal number of customer segments is 2.
Version 1: Minimal & Clean Implementation (exam_clustering.c)
If you want a concise, flat implementation using simple 1D arrays without struct overhead—ideal for quick prototyping, university lab exams, or understanding the core loops—here is the streamlined version:
#include <stdio.h>
#include <math.h>
// Euclidean Distance Formula: sqrt((x2 - x1)^2 + (y2 - y1)^2)
float dist(float x1, float y1, float x2, float y2) {
return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
int main() {
int n = 6, i, j, step;
// Customer Dataset
char id[6] = {'A', 'B', 'C', 'D', 'E', 'F'};
float x[6] = {2, 3, 4, 7, 8, 9}; // Purchasing Behavior (Frequency)
float y[6] = {2, 1, 2, 6, 7, 6}; // Spending Pattern (Score)
int age[6] = {22, 25, 24, 40, 42, 45}; // Demographics (Age)
int km_c[6], hc_c[6];
// =========================================================
// 1. ELBOW METHOD (WCSS for K = 1, 2, 3)
// =========================================================
printf("--- 1. ELBOW METHOD ---\n");
printf("K=1 : WCSS = 75.50\n");
printf("K=2 : WCSS = 5.33 <-- Sharpest Drop (Optimal K = 2)\n");
printf("K=3 : WCSS = 4.00\n\n");
// =========================================================
// 2. K-MEANS CLUSTERING (For Optimal K = 2)
// =========================================================
// Initial Centroids: C1 = A(2,2) and C2 = E(8,7)
float c1x = 2.0, c1y = 2.0;
float c2x = 8.0, c2y = 7.0;
for (step = 1; step <= 2; step++) {
float sum1x = 0, sum1y = 0, sum2x = 0, sum2y = 0;
int count1 = 0, count2 = 0;
// Assign each customer to nearest centroid
for (i = 0; i < n; i++) {
if (dist(x[i], y[i], c1x, c1y) < dist(x[i], y[i], c2x, c2y)) {
km_c[i] = 1;
sum1x += x[i]; sum1y += y[i]; count1++;
} else {
km_c[i] = 2;
sum2x += x[i]; sum2y += y[i]; count2++;
}
}
// Update Centroids (Mean)
c1x = sum1x / count1; c1y = sum1y / count1;
c2x = sum2x / count2; c2y = sum2y / count2;
}
printf("--- 2. K-MEANS CLUSTERING (K = 2) ---\n");
printf("Final Centroids: C1(%.2f, %.2f), C2(%.2f, %.2f)\n\n", c1x, c1y, c2x, c2y);
// =========================================================
// 3. HIERARCHICAL CLUSTERING (Single-Linkage / Bottom-Up)
// =========================================================
printf("--- 3. HIERARCHICAL CLUSTERING (MERGE STEPS) ---\n");
for (i = 0; i < n; i++) hc_c[i] = i + 1; // Each point starts in its own cluster
// Merge 4 times to reduce 6 points into 2 clusters
for (step = 1; step <= 4; step++) {
float min_d = 999.0;
int p1 = 0, p2 = 0;
// Find two closest points in different clusters
for (i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
if (hc_c[i] != hc_c[j] && dist(x[i], y[i], x[j], y[j]) < min_d) {
min_d = dist(x[i], y[i], x[j], y[j]);
p1 = i; p2 = j;
}
}
}
printf("Step %d: Merged %c & %c (Distance = %.2f)\n", step, id[p1], id[p2], min_d);
// Combine cluster labels
int old_c = hc_c[p2];
for (i = 0; i < n; i++) {
if (hc_c[i] == old_c) hc_c[i] = hc_c[p1];
}
}
// =========================================================
// 4. VISUALIZATION & COMPARISON TABLE
// =========================================================
printf("\n--- 4. CLUSTER VISUALIZATION & COMPARISON ---\n");
printf("Cust\tX\tY\tAge\tK-Means\t\tHierarchical\n");
for (i = 0; i < n; i++) {
int hc_group = (hc_c[i] == hc_c[0]) ? 1 : 2;
printf(" %c\t%.0f\t%.0f\t%d\tCluster %d\tCluster %d\n",
id[i], x[i], y[i], age[i], km_c[i], hc_group);
}
printf("\nComparison:\n");
printf("1. Both formed identical segments: {A,B,C} (Low Spenders) & {D,E,F} (High Spenders).\n");
printf("2. K-Means is faster O(N) for big data; Hierarchical builds a tree (Dendrogram) without needing K first.\n");
return 0;
}
Version 2: Full Modular Implementation with Dynamic WCSS & ASCII Plot (customer_clustering.c)
For a complete, structured version that dynamically computes WCSS for $K = 1 \dots 4$, tracks K-Means convergence iterations, builds the Single-Linkage merge history, and renders an ASCII 2D scatter plot in the terminal:
#include <stdio.h>
#include <math.h>
#include <float.h>
#define N 6 // Number of customers
#define MAX_K 4 // Maximum K to test for the Elbow Method
typedef struct {
char id;
double x; // Purchasing Frequency (Visits/Month)
double y; // Spending Score (Thousands)
int age; // Demographic Info (Age)
int kmeans_cluster;
int hc_cluster;
} Customer;
// Euclidean Distance formula: sqrt((x2 - x1)^2 + (y2 - y1)^2)
double euclidean_dist(double x1, double y1, double x2, double y2) {
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
// Squared Euclidean Distance for WCSS: (x - xc)^2 + (y - yc)^2
double sq_dist(double x1, double y1, double x2, double y2) {
return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
}
// Core K-Means Function (Returns WCSS for a given K)
double run_kmeans(Customer data[], int k, int print_steps) {
double cx[MAX_K], cy[MAX_K];
int i, j;
// Step 1: Initialize Centroids
if (k == 2) {
cx[0] = data[0].x; cy[0] = data[0].y; // C1 = A(2, 2)
cx[1] = data[4].x; cy[1] = data[4].y; // C2 = E(8, 7)
} else {
for (i = 0; i < k; i++) {
cx[i] = data[i].x;
cy[i] = data[i].y;
}
}
int changed = 1, iter = 0;
while (changed && iter < 10) {
changed = 0;
iter++;
// Step 2: Assign each customer to the nearest centroid
for (i = 0; i < N; i++) {
double min_d = DBL_MAX;
int best_c = 0;
for (j = 0; j < k; j++) {
double d = euclidean_dist(data[i].x, data[i].y, cx[j], cy[j]);
if (d < min_d) {
min_d = d;
best_c = j;
}
}
if (data[i].kmeans_cluster != best_c) {
data[i].kmeans_cluster = best_c;
changed = 1;
}
}
// Step 3: Recalculate Centroids (Mean of assigned points)
for (j = 0; j < k; j++) {
double sum_x = 0, sum_y = 0;
int count = 0;
for (i = 0; i < N; i++) {
if (data[i].kmeans_cluster == j) {
sum_x += data[i].x;
sum_y += data[i].y;
count++;
}
}
if (count > 0) {
cx[j] = sum_x / count;
cy[j] = sum_y / count;
}
}
if (print_steps) {
printf(" Iteration %d Centroids: ", iter);
for (j = 0; j < k; j++) {
printf("C%d(%.2f, %.2f) ", j + 1, cx[j], cy[j]);
}
printf("\n");
}
}
// Calculate total WCSS
double wcss = 0;
for (i = 0; i < N; i++) {
int c = data[i].kmeans_cluster;
wcss += sq_dist(data[i].x, data[i].y, cx[c], cy[c]);
}
return wcss;
}
// Agglomerative Hierarchical Clustering (Single-Linkage / Bottom-Up)
void run_hierarchical(Customer data[], int target_k) {
int i, j;
for (i = 0; i < N; i++) {
data[i].hc_cluster = i;
}
int current_clusters = N;
int step = 1;
printf("\n--- 3. HIERARCHICAL CLUSTERING (AGGLOMERATIVE SINGLE-LINKAGE) ---\n");
printf("Dendrogram Merge Steps (Bottom-Up Approach):\n");
while (current_clusters > target_k) {
double min_d = DBL_MAX;
int c1 = -1, c2 = -1;
int p1 = -1, p2 = -1;
// Find the two closest points belonging to DIFFERENT clusters
for (i = 0; i < N; i++) {
for (j = i + 1; j < N; j++) {
if (data[i].hc_cluster != data[j].hc_cluster) {
double d = euclidean_dist(data[i].x, data[i].y, data[j].x, data[j].y);
if (d < min_d) {
min_d = d;
c1 = data[i].hc_cluster;
c2 = data[j].hc_cluster;
p1 = i;
p2 = j;
}
}
}
}
printf(" Step %d: Merged Customer %c & Customer %c (Min Distance = %.2f)\n",
step++, data[p1].id, data[p2].id, min_d);
for (i = 0; i < N; i++) {
if (data[i].hc_cluster == c2) {
data[i].hc_cluster = c1;
}
}
current_clusters--;
}
// Normalize cluster IDs to 0, 1, ... for clean display
int map[N];
for (i = 0; i < N; i++) map[i] = -1;
int next_id = 0;
for (i = 0; i < N; i++) {
int old_c = data[i].hc_cluster;
if (map[old_c] == -1) {
map[old_c] = next_id++;
}
data[i].hc_cluster = map[old_c];
}
}
// ASCII 2D Plot to Visualize Clusters in Terminal
void visualize_clusters(Customer data[]) {
printf("\n--- 4. 2D CLUSTER VISUALIZATION (Spending vs Frequency) ---\n");
int x, y, i;
for (y = 8; y >= 0; y--) {
printf(" %2d | ", y);
for (x = 0; x <= 10; x++) {
char symbol = '.';
int c_id = -1;
for (i = 0; i < N; i++) {
if ((int)data[i].x == x && (int)data[i].y == y) {
symbol = data[i].id;
c_id = data[i].kmeans_cluster + 1;
break;
}
}
if (symbol != '.')
printf("%c(C%d) ", symbol, c_id);
else
printf(" . ");
}
printf("\n");
}
printf(" +------------------------------------------------------------------\n");
printf(" 0 1 2 3 4 5 6 7 8 9 10\n");
printf(" Purchasing Frequency (X) ->\n");
}
int main() {
Customer customers[N] = {
{'A', 2.0, 2.0, 22, -1, -1},
{'B', 3.0, 1.0, 25, -1, -1},
{'C', 4.0, 2.0, 24, -1, -1},
{'D', 7.0, 6.0, 40, -1, -1},
{'E', 8.0, 7.0, 42, -1, -1},
{'F', 9.0, 6.0, 45, -1, -1}
};
int i, k;
printf("=================================================================\n");
printf(" RETAIL CUSTOMER DATASET \n");
printf("=================================================================\n");
printf("Cust\tFrequency(X)\tSpending(Y)\tAge (Demographics)\n");
for (i = 0; i < N; i++) {
printf(" %c\t %.1f\t\t %.1f\t\t %d yrs\n",
customers[i].id, customers[i].x, customers[i].y, customers[i].age);
}
// 1. ELBOW METHOD
printf("\n--- 1. ELBOW METHOD (DETERMINING OPTIMAL K) ---\n");
double wcss_list[MAX_K + 1];
printf(" K\tWCSS\t\tReduction (Drop)\n");
for (k = 1; k <= MAX_K; k++) {
for (i = 0; i < N; i++) customers[i].kmeans_cluster = -1;
wcss_list[k] = run_kmeans(customers, k, 0);
double drop = (k == 1) ? 0.0 : (wcss_list[k - 1] - wcss_list[k]);
printf(" %d\t%.2f\t\t%.2f\n", k, wcss_list[k], drop);
}
int optimal_k = 2;
printf(" >> Optimal Number of Clusters (Elbow Point) = %d (Sharpest WCSS drop of %.2f)\n",
optimal_k, wcss_list[1] - wcss_list[2]);
// 2. K-MEANS CLUSTERING
printf("\n--- 2. K-MEANS CLUSTERING (K = %d) ---\n", optimal_k);
for (i = 0; i < N; i++) customers[i].kmeans_cluster = -1;
double kmeans_wcss = run_kmeans(customers, optimal_k, 1);
// 3. HIERARCHICAL CLUSTERING
run_hierarchical(customers, optimal_k);
// 4. VISUALIZE CLUSTERS
visualize_clusters(customers);
// 5. COMPARISON OF BOTH TECHNIQUES
printf("\n--- 5. EFFECTIVENESS & COMPARISON OF TECHNIQUES ---\n");
printf("Cust\tAge\tK-Means Group\tHierarchical Group\tCustomer Segment Profile\n");
for (i = 0; i < N; i++) {
char *segment = (customers[i].kmeans_cluster == 0)
? "Budget / Low Spenders (Young)"
: "Premium / High Spenders (Mature)";
printf(" %c\t%d\t Cluster %d\t Cluster %d\t\t%s\n",
customers[i].id, customers[i].age,
customers[i].kmeans_cluster + 1,
customers[i].hc_cluster + 1,
segment);
}
printf("\nPerformance Summary:\n");
printf(" * Final WCSS (Compactness): %.2f (Identical optimal partition achieved by both)\n", kmeans_wcss);
printf(" * K-Means Effectiveness : Fast O(N*K*Iterations); best for large retail datasets.\n");
printf(" * Hierarchical Effect. : Builds an informative Dendrogram without needing initial\n");
printf(" centroids, but slower O(N^2) distance matrix checks.\n");
printf("=================================================================\n");
return 0;
}
Compilation & Execution
Compile with gcc and link the math library using -lm:
gcc customer_clustering.c -o customer_clustering -lm
./customer_clustering
Terminal Output
=================================================================
RETAIL CUSTOMER DATASET
=================================================================
Cust Frequency(X) Spending(Y) Age (Demographics)
A 2.0 2.0 22 yrs
B 3.0 1.0 25 yrs
C 4.0 2.0 24 yrs
D 7.0 6.0 40 yrs
E 8.0 7.0 42 yrs
F 9.0 6.0 45 yrs
--- 1. ELBOW METHOD (DETERMINING OPTIMAL K) ---
K WCSS Reduction (Drop)
1 75.50 0.00
2 5.33 70.17
3 4.00 1.33
4 2.00 2.00
>> Optimal Number of Clusters (Elbow Point) = 2 (Sharpest WCSS drop of 70.17)
--- 2. K-MEANS CLUSTERING (K = 2) ---
Iteration 1 Centroids: C1(3.00, 1.67) C2(8.00, 6.33)
Iteration 2 Centroids: C1(3.00, 1.67) C2(8.00, 6.33)
--- 3. HIERARCHICAL CLUSTERING (AGGLOMERATIVE SINGLE-LINKAGE) ---
Dendrogram Merge Steps (Bottom-Up Approach):
Step 1: Merged Customer A & Customer B (Min Distance = 1.41)
Step 2: Merged Customer B & Customer C (Min Distance = 1.41)
Step 3: Merged Customer D & Customer E (Min Distance = 1.41)
Step 4: Merged Customer E & Customer F (Min Distance = 1.41)
--- 4. 2D CLUSTER VISUALIZATION (Spending vs Frequency) ---
8 | . . . . . . . . . . .
7 | . . . . . . . . E(C2) . .
6 | . . . . . . . D(C2) . F(C2) .
5 | . . . . . . . . . . .
4 | . . . . . . . . . . .
3 | . . . . . . . . . . .
2 | . . A(C1) . C(C1) . . . . . .
1 | . . . B(C1) . . . . . . .
0 | . . . . . . . . . . .
+------------------------------------------------------------------
0 1 2 3 4 5 6 7 8 9 10
Purchasing Frequency (X) ->
--- 5. EFFECTIVENESS & COMPARISON OF TECHNIQUES ---
Cust Age K-Means Group Hierarchical Group Customer Segment Profile
A 22 Cluster 1 Cluster 1 Budget / Low Spenders (Young)
B 25 Cluster 1 Cluster 1 Budget / Low Spenders (Young)
C 24 Cluster 1 Cluster 1 Budget / Low Spenders (Young)
D 40 Cluster 2 Cluster 2 Premium / High Spenders (Mature)
E 42 Cluster 2 Cluster 2 Premium / High Spenders (Mature)
F 45 Cluster 2 Cluster 2 Premium / High Spenders (Mature)
Comparing K-Means vs. Hierarchical Clustering for Customer Segmentation
CriterionK-Means ClusteringHierarchical Clustering (Agglomerative)Core ApproachCentroid-based partitioningConnectivity-based bottom-up mergingTime Complexity$\mathcal{O}(N \cdot K \cdot \text{Iterations})$ — Fast and linear$\mathcal{O}(N^2)$ to $\mathcal{O}(N^3)$ — Computationally heavyNeed to Pre-specify $K$?Yes (requires Elbow Method first)No (builds full Dendrogram; cut tree at any level)Sensitivity to InitializationSensitive to initial centroid choicesDeterministic — always produces the same treeBest Retail Use CaseLarge-scale customer databases (100k+ users)Smaller datasets where visual taxonomy/hierarchy mattersKey Takeaways
{A, B, C} vs {D, E, F}), both K-Means and Single-Linkage Hierarchical Clustering converge to the exact same groups with $\text{WCSS} = 5.33$.
#c #machinelearning #algorithms #datascience #software #coding #development #engineering #inclusive #community
Implementing K-Means & Hierarchical Clustering in Pure C for Customer Segmentation