From 27017eff5849bfc8733b46b7e7fc398ce1f07f63 Mon Sep 17 00:00:00 2001 From: KRZYSZTOF RUDNICKI Date: Wed, 11 Sep 2024 14:59:57 +0200 Subject: [PATCH 1/4] feat: added script for splitting a number symmetrically across another number --- PYTHON/split/split_x_into_n_symmetrically.py | 77 ++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 PYTHON/split/split_x_into_n_symmetrically.py diff --git a/PYTHON/split/split_x_into_n_symmetrically.py b/PYTHON/split/split_x_into_n_symmetrically.py new file mode 100644 index 0000000..9b7d481 --- /dev/null +++ b/PYTHON/split/split_x_into_n_symmetrically.py @@ -0,0 +1,77 @@ +def split_x_into_n_symmetrically(X, N, factors): + """ + X: Total value to distribute + N: Number into which we split + factors: List controlling the difference in weights between consecutive days + Must have length of N // 2 (if N is odd) or (N // 2 - 1) (if N is even) + """ + + # Calculate the mid-point index (for both even and odd N) + half_N = N // 2 + + # Generate the base weights symmetrically around the middle + if N % 2 == 0: # Even number of days + middle_weight = 1 + weights_left = [middle_weight] + for factor in factors: + next_weight = weights_left[-1] + factor + weights_left.append(next_weight) + weights = weights_left[::-1] + weights_left + else: # Odd number of days + middle_weight = 1 + weights_left = [middle_weight] + for factor in factors: + next_weight = weights_left[-1] + factor + weights_left.append(next_weight) + weights = weights_left[::-1] + [middle_weight] + weights_left + + total_weight = sum(weights) + + # Calculate the base unit + base_unit = X / total_weight + + # Calculate the distance for each day + distances = [base_unit * weight for weight in weights] + + return distances + +def split_x_into_n_middle(X, N, middle_value): + """ + X: Total value to distribute + N: Number in which we split + middle_value: Value of the middle number (the biggest weight) + """ + + # Calculate the mid-point index + half_N = N // 2 + + # Initialize the weights list + weights = [0] * N + + # Set the middle value + if N % 2 == 0: # Even number of days + weights[half_N - 1] = middle_value + weights[half_N] = middle_value + else: # Odd number of days + weights[half_N] = middle_value + + # Fill in the decreasing values symmetrically + for i in range(half_N): + # Decrease the weight by 1 for each step toward the edges + if N % 2 == 0: + weights[half_N - 1 - i - 1] = middle_value - (i + 1) + weights[half_N + i + 1] = middle_value - (i + 1) + else: + weights[half_N - i - 1] = middle_value - (i + 1) + weights[half_N + i + 1] = middle_value - (i + 1) + + # Sum the weights and calculate the base unit + total_weight = sum(weights) + + # Calculate the base unit + base_unit = X / total_weight + + # Calculate the distance for each day + distances = [base_unit * weight for weight in weights] + + return distances From b9735d441dddbbc3373fed867e227bb2215d3b9d Mon Sep 17 00:00:00 2001 From: KRZYSZTOF RUDNICKI Date: Wed, 11 Sep 2024 15:01:33 +0200 Subject: [PATCH 2/4] feat: extracted repated functionality from split function --- PYTHON/split/split_x_into_n_symmetrically.py | 121 ++++++++----------- 1 file changed, 51 insertions(+), 70 deletions(-) diff --git a/PYTHON/split/split_x_into_n_symmetrically.py b/PYTHON/split/split_x_into_n_symmetrically.py index 9b7d481..de34e5c 100644 --- a/PYTHON/split/split_x_into_n_symmetrically.py +++ b/PYTHON/split/split_x_into_n_symmetrically.py @@ -1,77 +1,58 @@ +def calculate_symmetric_weights(N, middle_weight, factors=None): + """ + Calculate symmetric weights for both even and odd N. + + N: Number in which to split. + middle_weight: The middle value for symmetry. + factors: If provided, controls the difference in weights (used for the `split_x_into_n_symmetrically` function). + Must have length N // 2 or N // 2 - 1 depending on N. + """ + half_N = N // 2 + weights_left = [middle_weight] + + if factors: + for factor in factors: + next_weight = weights_left[-1] + factor + weights_left.append(next_weight) + else: + for i in range(half_N - 1): + weights_left.append(middle_weight - (i + 1)) + + if N % 2 == 0: + weights = weights_left[::-1] + weights_left + else: + weights = weights_left[::-1] + [middle_weight] + weights_left + + return weights + +def scale_to_total(X, weights): + """ + Scale the weights so that their sum is proportional to X. + + X: Total value to distribute. + weights: The list of weights to be scaled. + """ + total_weight = sum(weights) + base_unit = X / total_weight + distances = [base_unit * weight for weight in weights] + + return distances + def split_x_into_n_symmetrically(X, N, factors): """ - X: Total value to distribute - N: Number into which we split - factors: List controlling the difference in weights between consecutive days - Must have length of N // 2 (if N is odd) or (N // 2 - 1) (if N is even) + X: Total value to distribute. + N: Number in which we split. + factors: List controlling the difference in weights between consecutive days. + Must have length of N // 2 (if N is odd) or (N // 2 - 1) (if N is even). """ - - # Calculate the mid-point index (for both even and odd N) - half_N = N // 2 - - # Generate the base weights symmetrically around the middle - if N % 2 == 0: # Even number of days - middle_weight = 1 - weights_left = [middle_weight] - for factor in factors: - next_weight = weights_left[-1] + factor - weights_left.append(next_weight) - weights = weights_left[::-1] + weights_left - else: # Odd number of days - middle_weight = 1 - weights_left = [middle_weight] - for factor in factors: - next_weight = weights_left[-1] + factor - weights_left.append(next_weight) - weights = weights_left[::-1] + [middle_weight] + weights_left - - total_weight = sum(weights) - - # Calculate the base unit - base_unit = X / total_weight - - # Calculate the distance for each day - distances = [base_unit * weight for weight in weights] - - return distances + weights = calculate_symmetric_weights(N, middle_weight=1, factors=factors) + return scale_to_total(X, weights) def split_x_into_n_middle(X, N, middle_value): """ - X: Total value to distribute - N: Number in which we split - middle_value: Value of the middle number (the biggest weight) + X: Total value to distribute. + N: Number in which we split. + middle_value: Value of the middle number (the biggest weight). """ - - # Calculate the mid-point index - half_N = N // 2 - - # Initialize the weights list - weights = [0] * N - - # Set the middle value - if N % 2 == 0: # Even number of days - weights[half_N - 1] = middle_value - weights[half_N] = middle_value - else: # Odd number of days - weights[half_N] = middle_value - - # Fill in the decreasing values symmetrically - for i in range(half_N): - # Decrease the weight by 1 for each step toward the edges - if N % 2 == 0: - weights[half_N - 1 - i - 1] = middle_value - (i + 1) - weights[half_N + i + 1] = middle_value - (i + 1) - else: - weights[half_N - i - 1] = middle_value - (i + 1) - weights[half_N + i + 1] = middle_value - (i + 1) - - # Sum the weights and calculate the base unit - total_weight = sum(weights) - - # Calculate the base unit - base_unit = X / total_weight - - # Calculate the distance for each day - distances = [base_unit * weight for weight in weights] - - return distances + weights = calculate_symmetric_weights(N, middle_weight=middle_value) + return scale_to_total(X, weights) From aecbb44618f25655de777266742ddb0b54dadbb6 Mon Sep 17 00:00:00 2001 From: KRZYSZTOF RUDNICKI Date: Wed, 11 Sep 2024 15:02:50 +0200 Subject: [PATCH 3/4] chore: updated Licenses --- C/1dvelocitysimulator/LICENSE | 2 +- CPP/SFMLEngine/LICENSE | 2 +- LICENSE | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/C/1dvelocitysimulator/LICENSE b/C/1dvelocitysimulator/LICENSE index 37b2665..21f32e1 100644 --- a/C/1dvelocitysimulator/LICENSE +++ b/C/1dvelocitysimulator/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Krzysztof Rudnicki +Copyright (c) 2024 Krzysztof Rudnicki Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/CPP/SFMLEngine/LICENSE b/CPP/SFMLEngine/LICENSE index 37b2665..21f32e1 100644 --- a/CPP/SFMLEngine/LICENSE +++ b/CPP/SFMLEngine/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Krzysztof Rudnicki +Copyright (c) 2024 Krzysztof Rudnicki Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/LICENSE b/LICENSE index 37b2665..21f32e1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Krzysztof Rudnicki +Copyright (c) 2024 Krzysztof Rudnicki Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 2e2f2979ad42888a07db94aed7644400e02763d1 Mon Sep 17 00:00:00 2001 From: KRZYSZTOF RUDNICKI Date: Wed, 11 Sep 2024 15:04:46 +0200 Subject: [PATCH 4/4] feat: translated split into "C" --- C/misc/split/.gitignore | 1 + C/misc/split/Makefile | 31 +++++++++++++ C/misc/split/main.c | 96 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 C/misc/split/.gitignore create mode 100644 C/misc/split/Makefile create mode 100644 C/misc/split/main.c diff --git a/C/misc/split/.gitignore b/C/misc/split/.gitignore new file mode 100644 index 0000000..01fe8ce --- /dev/null +++ b/C/misc/split/.gitignore @@ -0,0 +1 @@ +split \ No newline at end of file diff --git a/C/misc/split/Makefile b/C/misc/split/Makefile new file mode 100644 index 0000000..f6909d0 --- /dev/null +++ b/C/misc/split/Makefile @@ -0,0 +1,31 @@ +# Compiler +CC = gcc + +# Compiler flags +CFLAGS = -Wall -O3 -march=native -flto -fomit-frame-pointer + +# Libraries +LIBS = -ljpeg + +# Source files +SRCS = main.c + +# Output executable +TARGET = split + +# Default target +all: $(TARGET) + +# Link and compile the program +$(TARGET): $(SRCS) + $(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS) + +# Clean up build artifacts +clean: + rm -f $(TARGET) + +# Install the program (optional) +install: $(TARGET) + install -m 755 $(TARGET) /usr/local/bin/ + +.PHONY: all clean install diff --git a/C/misc/split/main.c b/C/misc/split/main.c new file mode 100644 index 0000000..eb702df --- /dev/null +++ b/C/misc/split/main.c @@ -0,0 +1,96 @@ +#include +#include + +// Function to calculate symmetric weights for both even and odd N +void calculate_symmetric_weights(int N, double middle_weight, double* factors, double* weights) { + int half_N = N / 2; + int i; + weights[half_N] = middle_weight; // Middle value for symmetry + + // Calculate left side weights + if (factors) { + for (i = 0; i < half_N; i++) { + if (i == 0) { + weights[half_N - i - 1] = middle_weight + factors[i]; + } else { + weights[half_N - i - 1] = weights[half_N - i] + factors[i]; + } + } + } else { + for (i = 0; i < half_N; i++) { + weights[half_N - i - 1] = middle_weight - (i + 1); + } + } + + // Mirror left side weights to right side + for (i = 0; i < half_N; i++) { + weights[half_N + i + 1] = weights[half_N - i - 1]; + } +} + +// Function to scale the weights so that their sum is proportional to X +void scale_to_total(double X, double* weights, int N, double* distances) { + double total_weight = 0; + int i; + + // Calculate the total weight + for (i = 0; i < N; i++) { + total_weight += weights[i]; + } + + double base_unit = X / total_weight; + + // Scale weights + for (i = 0; i < N; i++) { + distances[i] = base_unit * weights[i]; + } +} + +// Function to split X into N parts symmetrically +void split_x_into_n_symmetrically(double X, int N, double* factors, double* distances) { + double* weights = (double*)malloc(N * sizeof(double)); + + calculate_symmetric_weights(N, 1.0, factors, weights); + scale_to_total(X, weights, N, distances); + + free(weights); +} + +// Function to split X into N parts, with a specific middle value +void split_x_into_n_middle(double X, int N, double middle_value, double* distances) { + double* weights = (double*)malloc(N * sizeof(double)); + + calculate_symmetric_weights(N, middle_value, NULL, weights); + scale_to_total(X, weights, N, distances); + + free(weights); +} + +// Example usage +int main() { + int N = 5; + double X = 100; + double middle_value = 5.0; + double distances[5]; + + // Example usage for split_x_into_n_middle + split_x_into_n_middle(X, N, middle_value, distances); + + printf("Split values (with middle value = %.2f):\n", middle_value); + for (int i = 0; i < N; i++) { + printf("%.2f ", distances[i]); + } + printf("\n"); + + // Example usage for split_x_into_n_symmetrically + double factors[2] = {1.0, 2.0}; + split_x_into_n_symmetrically(X, N, factors, distances); + + printf("Split values (symmetric with factors):\n"); + for (int i = 0; i < N; i++) { + printf("%.2f ", distances[i]); + } + printf("\n"); + + return 0; +}