diff options
| author | Yves Orton <demerphq@gmail.com> | 2023-10-15 18:15:40 +0200 |
|---|---|---|
| committer | Yves Orton <demerphq@gmail.com> | 2023-10-15 18:16:57 +0200 |
| commit | f74b2e4890eb1fff7aa03c2685fdab6668b89226 (patch) | |
| tree | 617d366e471342e1412b28a34aba672c4db95987 | |
| parent | d9345ca8d5bd2ffac181bec0e44d891769273c9d (diff) | |
| download | perlweeklychallenge-club-f74b2e4890eb1fff7aa03c2685fdab6668b89226.tar.gz perlweeklychallenge-club-f74b2e4890eb1fff7aa03c2685fdab6668b89226.tar.bz2 perlweeklychallenge-club-f74b2e4890eb1fff7aa03c2685fdab6668b89226.zip | |
Challenge 238, Perl, Rust, JS, and C
| -rwxr-xr-x | challenge-238/demerphq/C/build_and_test.sh | 7 | ||||
| -rw-r--r-- | challenge-238/demerphq/C/ch-1.c | 66 | ||||
| -rw-r--r-- | challenge-238/demerphq/C/ch-2.c | 133 | ||||
| -rw-r--r-- | challenge-238/demerphq/README.md | 139 | ||||
| -rw-r--r-- | challenge-238/demerphq/js/ch-1.js | 26 | ||||
| -rw-r--r-- | challenge-238/demerphq/js/ch-2.js | 57 | ||||
| -rw-r--r-- | challenge-238/demerphq/perl/ch-1.pl | 26 | ||||
| -rw-r--r-- | challenge-238/demerphq/perl/ch-2.pl | 41 | ||||
| -rw-r--r-- | challenge-238/demerphq/rust/Cargo.lock | 16 | ||||
| -rw-r--r-- | challenge-238/demerphq/rust/Cargo.toml | 17 | ||||
| -rw-r--r-- | challenge-238/demerphq/rust/src/ch-1.rs | 48 | ||||
| -rw-r--r-- | challenge-238/demerphq/rust/src/ch-2.rs | 92 | ||||
| -rw-r--r-- | challenge-238/demerphq/rust/src/main.rs | 3 |
13 files changed, 532 insertions, 139 deletions
diff --git a/challenge-238/demerphq/C/build_and_test.sh b/challenge-238/demerphq/C/build_and_test.sh new file mode 100755 index 0000000000..35a1fc97eb --- /dev/null +++ b/challenge-238/demerphq/C/build_and_test.sh @@ -0,0 +1,7 @@ +#!/usr/bin/bash +gcc -o ch-1 ch-1.c +gcc -o ch-2 ch-2.c +echo === ch-1 ========================================== +./ch-1 +echo === ch-2 ========================================== +./ch-2 diff --git a/challenge-238/demerphq/C/ch-1.c b/challenge-238/demerphq/C/ch-1.c new file mode 100644 index 0000000000..87bc8c0857 --- /dev/null +++ b/challenge-238/demerphq/C/ch-1.c @@ -0,0 +1,66 @@ +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <string.h> + +#define ARRAY_LENGTH(arr) (sizeof(arr) / sizeof((arr)[0])) +#define ARRAY(...) __VA_ARGS__ +#define STMT_START do +#define STMT_END while (0) + +void +print_int_array(char *prefix, int *array, size_t length) { + printf("%s ", prefix); + for (size_t i = 0; i < length; i++) { + if (i > 0) { + printf(", "); + } + printf("%d", array[i]); + } + printf("\n"); +} + +int * +running_sum(int *array, size_t length) { + int* sum = (int *)malloc(length * sizeof(int)); + if (!sum) { + perror("Memory allocation failed"); + exit(1); + } + sum[0] = array[0]; + for (size_t i = 1; i < length; i++) { + sum[i] = array[i] + sum[i - 1]; + } + return sum; +} + + +#define TEST_RUNNING_SUM(a1,a2) STMT_START { \ + int input[] = a1; \ + int want[] = a2; \ + int len = ARRAY_LENGTH(input); \ + int *got = running_sum(input, len); \ + assert(ARRAY_LENGTH(input) == ARRAY_LENGTH(want)); \ + \ + test_count++; \ + print_int_array("# Input:", input, len); \ + print_int_array("# R Sum:", got, len); \ + print_int_array("# Want :", want, len); \ + printf("%sok %d\n", memcmp(got, want, sizeof(want[0]) * len) \ + ? "not " : "", test_count); \ + free(got); \ +} STMT_END + + +int +run_tests() { + int test_count = 0; + TEST_RUNNING_SUM(ARRAY({1, 2, 3, 4, 5}), ARRAY({1, 3, 6, 10, 15})); + TEST_RUNNING_SUM(ARRAY({1, 1, 1, 1, 1}), ARRAY({1, 2, 3, 4, 5})); + TEST_RUNNING_SUM(ARRAY({0, -1, 1, 2}), ARRAY({0, -1, 0, 2})); +} + +int +main(int argc, char *argv[]) { + return run_tests(); +} diff --git a/challenge-238/demerphq/C/ch-2.c b/challenge-238/demerphq/C/ch-2.c new file mode 100644 index 0000000000..807f5b3890 --- /dev/null +++ b/challenge-238/demerphq/C/ch-2.c @@ -0,0 +1,133 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <assert.h> + +#define ARRAY_LENGTH(arr) (sizeof(arr) / sizeof((arr)[0])) +#define ARRAY(...) __VA_ARGS__ +#define STMT_START do +#define STMT_END while (0) + +void +print_uint32_array(char *prefix, uint32_t *array, size_t length) { + printf("%s ", prefix); + for (size_t i = 0; i < length; i++) { + if (i > 0) { + printf(", "); + } + printf("%u", array[i]); + } + printf("\n"); +} + + +// Function to calculate the digit weight of a number +uint32_t digit_weight(uint32_t n) { + uint32_t count = 0; + + while (n > 9) { + count++; + uint32_t tmp = 1; + uint32_t temp_n = n; + + while (temp_n > 0) { + tmp *= temp_n % 10; + temp_n /= 10; + } + + n = tmp; + } + + return count; +} + +struct sort_data { + uint32_t *weight; + uint32_t *data; +}; +struct sort_data compare_state; + +int compare(const void *a, const void *b) { + const uint32_t l = *(uint32_t *)a; + const uint32_t r = *(uint32_t *)b; + + if (compare_state.weight[l] == compare_state.weight[r]) { + if (compare_state.data[l] == compare_state.data[r]) { + return 0; + } else if (compare_state.data[l] < compare_state.data[r]) { + return -1; + } else { + return 1; + } + } else if (compare_state.weight[l] < compare_state.weight[r]) { + return -1; + } else { + return 1; + } +} + +// Function to sort the input array based on digit weight and value +uint32_t * +persistence_sort(uint32_t *array, uint32_t length) { + uint32_t bytes = length * sizeof(uint32_t); + uint32_t *weight = (uint32_t *)malloc(bytes); + uint32_t *sorted_idx = (uint32_t *)malloc(bytes); + + for (uint32_t i = 0; i < length; i++) { + weight[i] = digit_weight(array[i]); + sorted_idx[i] = i; + } + + compare_state.weight = weight; + compare_state.data = array; + + // Sort the indices based on weight and value + qsort(sorted_idx, length, sizeof(uint32_t), compare); + + for (uint32_t i = 0; i < length; i++) { + weight[i] = array[sorted_idx[i]]; + } + free(sorted_idx); + + return weight; +} + +#define TEST_PERSISTENCE_SORT(a,b) STMT_START { \ + uint32_t input[] = a; \ + uint32_t want[] = b; \ + int len = ARRAY_LENGTH(input); \ + int *got = persistence_sort(input, len); \ + assert(ARRAY_LENGTH(input) == ARRAY_LENGTH(want)); \ + \ + test_count++; \ + print_uint32_array("# Input:", input, len); \ + print_uint32_array("# Psort:", got, len); \ + print_uint32_array("# Want :", want, len); \ + printf("%sok %d\n", memcmp(got, want, sizeof(want[0]) * len) \ + ? "not " : "", test_count); \ + free(got); \ +} STMT_END + + +int +run_tests() { + uint32_t test_count = 0; + + TEST_PERSISTENCE_SORT(ARRAY({15, 99, 1, 34}), + ARRAY({1, 15, 34, 99})); + + TEST_PERSISTENCE_SORT(ARRAY({50, 25, 33, 22}), + ARRAY({22, 33, 50, 25})); + + TEST_PERSISTENCE_SORT(ARRAY({12347, 2347, 347, 47, 7}), + ARRAY({ 7, 47, 347, 2347, 12347})); + + return 0; +} + + +int +main(int argc, char *argv[]) { + return run_tests(); +} diff --git a/challenge-238/demerphq/README.md b/challenge-238/demerphq/README.md deleted file mode 100644 index 66d2bdc1ca..0000000000 --- a/challenge-238/demerphq/README.md +++ /dev/null @@ -1,139 +0,0 @@ -# Challenge 237 - Seize The Day and Maximise Greatness - -## Seize The Day - Simple Rules The Day - -My solution was based on using Time::Local to compute the epoch for noon -on the first day of the month, and then stepping forward by day until -the required day of week has been found, and then stepping forward by -week until the required repetition of that day has been found, or we ran -off the end of the calender month. Using noon instead of midnight is IMO -a prudent guard against issues related leap seconds, but probably isn't -really necessary but doesn't hurt either. - -## Maximise Greatness - Permutation Misdirection - -Task #2 is more difficult and IMO more interesting. The problem is -stated as the following: "Maximise Greatness: You are given an array of -integers. Write a script to permute the give[n] array such that you get -the maximum possible greatness. To determine greatness, [count pairs -that satisfy] nums[i] < perm[i] where 0 <= i < nums.length", and then -gives the example of - - Input: @nums = (1, 3, 5, 2, 1, 3, 1) - Output: 4 - - One possible permutation: (2, 5, 1, 3, 3, 1, 1) - which returns 4 greatness as below: - nums[0] < perm[0] - nums[1] < perm[1] - nums[3] < perm[3] - nums[4] < perm[4] - -I think this is a fun little problem and a good example of the kind of -problem that gets posed in the perl-weekly challenge. Simple input, -simple output, simple description, but a deeper problem than it might -seem at first blush. - -The reason I say deeper is that way the problem is stated it makes it -seem like we need to compute a permutation, and that the solution to the -problem might be `O(N!)` or `O(N**2)`. But on closer inspection we can -see that we need not compute a permutation at all, and we only need to -do so if we want to visually debug that our answer is correct. It -actually turns out that all we need to do is find the count of the most -frequently occuring number in the array. The maximum greatness will be -the number of elements in the array minus the count of the most -frequently occuring element in the array. - -A complete proof of this is a bit beyond this document. But we can get -the general idea by considering a sorted array. Lets say we have an -array with duplicates, such that `A[0] < A[1] < A[2] ... < A[n-1]`. It -is obvious that the maximum element in the array is the only one that -cannot be paired with something larger than it. We can view this as a -rotation of the array: - -``` - | 1, 2, 3 | - | 2, 3, 1 | <- rotate left by 1. - | X X | <- Which columns satisfy the constraint -``` - -In this case it is obvious that the maximum greatness is 1 less than -number of elements in the array, and 1 is the count of the most -frequently occuring element. If we then duplicate one of the elements -and we rotate the array by different numbers of elements we can see -maximum is the same regardless of which element is duplicated, and that -the rotating any more than the number of duplicates causes the number of -pairs that satisify the constraint to reduce. - -``` - | 1, 1, 2, 3 | 1, 2, 2, 3 | 1, 2, 3, 3 | - | 1, 2, 3, 1 | 2, 2, 3, 1 | 2, 3, 3, 1 | <- rotate 1 - | X X | X X | X X | - - | 1, 1, 2, 3 | 1, 2, 2, 3 | 1, 2, 3, 3 | - | 2, 3, 1, 1 | 2, 3, 1, 2 | 3, 3, 1, 2 | <- rotate 2 - | X X | X X | X X | - - | 1, 1, 2, 3 | 1, 2, 2, 3 | 1, 2, 3, 3 | - | 3, 1, 1, 2 | 3, 1, 2, 2 | 3, 1, 2, 3 | <- rotate 3 - | X | X | X | -``` - -The same pattern holds if the array contains two sets of duplicated -numbers, the maximum number of pairs is found when the rotation matches -the count of the most frequently repeated element: - -``` - | 1, 1, 2, 2, 3 | 1, 2, 2, 3, 3 | 1, 1, 2, 3, 3 | - | 1, 2, 2, 3, 1 | 2, 2, 3, 3, 1 | 1, 2, 3, 3, 1 | <- rotate left by 1 - X X | X X | X X | - - | 1, 1, 2, 2, 3 | 1, 2, 2, 3, 3 | 1, 1, 2, 3, 3 | - | 2, 2, 3, 1, 1 | 2, 3, 3, 1, 2 | 2, 3, 3, 1, 1 | <- rotate left by 2 - | X X X | X X X | X X X | - - | 1, 1, 2, 2, 3 | 1, 2, 2, 3, 3 | 1, 1, 2, 3, 3 | - | 2, 3, 1, 1, 2 | 3, 3, 1, 2, 2 | 3, 3, 1, 1, 2 | <- rotate left by 3 - | X X | X X | X X | -``` - -And lastly consider what happens when we have 1 unique element, 1 pair, -and 1 triplicate: - -``` - | 1, 2, 2, 3, 3, 3 | 1, 1, 2, 2, 2, 3 | 1, 1, 1, 2, 3, 3 | - | 2, 2, 3, 3, 3, 1 | 1, 2, 2, 2, 3, 1 | 1, 1, 2, 3, 3, 1 | <- rotate 1 - | X X | X X | X X | - - | 1, 2, 2, 3, 3, 3 | 1, 1, 2, 2, 2, 3 | 1, 1, 1, 2, 3, 3 | - | 2, 3, 3, 3, 1, 2 | 2, 2, 2, 3, 1, 1 | 1, 2, 3, 3, 1, 1 | <- rotate 2 - | X X X | X X X | X X X | - - | 1, 2, 2, 3, 3, 3 | 1, 1, 2, 2, 2, 3 | 1, 1, 1, 2, 3, 3 | - | 3, 3, 3, 1, 2, 2 | 2, 2, 3, 1, 1, 2 | 2, 3, 3, 1, 1, 1 | <- rotate 3 - | X X X | X X X | X X X | - - | 1, 2, 2, 3, 3, 3 | 1, 1, 2, 2, 2, 3 | 1, 1, 1, 2, 3, 3 | - | 3, 3, 1, 2, 2, 3 | 2, 3, 1, 1, 2, 2 | 3, 3, 1, 1, 1, 2 | <- rotate 4 - | X X | X X | X X | -``` - -In each case we can see that the maximum greatness is determined only -by the number of elements in the array and the count of the most -frequent element. Note, that there may actually be two rotations of a -sorted array that produce the maximum greatness, that of the count of -the most frequent element, and that of the count of the second most -frequent element. If the counts differ then there will be two possible -rotations that give the maximum greatness. - -The last point to observe is that if we **must** produce a permutation -that would produce the maximum greatness then we can produce an array -`S` of the indexes of the input array such that `A[S[i]] <= A[S[i+1]]`. -We can then solve for the sorted array by rotating it left by the count -of the most frequent element, and then use `S` to map the solution into -the appropriate order for the actual input array. - -Thus if we are to compute the maximum greatness alone we can do so -in `O(N)` steps. If we are to produce a permutation of the input -array would produce that maximum greatness we can do so in -`O(N log2 N)` steps. diff --git a/challenge-238/demerphq/js/ch-1.js b/challenge-238/demerphq/js/ch-1.js new file mode 100644 index 0000000000..6e7a6f78c6 --- /dev/null +++ b/challenge-238/demerphq/js/ch-1.js @@ -0,0 +1,26 @@ +"use strict"; + +function runningSum(array) { + const sum = []; + sum[0] = array[0]; + for (let i = 1; i < array.length; i++) { + sum[i] = array[i] + sum[i - 1]; + } + return sum; +} + +const assert = require('assert'); + +const testCases = [ + { input: [1, 2, 3, 4, 5], want: [1, 3, 6, 10, 15] }, + { input: [1, 1, 1, 1, 1], want: [1, 2, 3, 4, 5] }, + { input: [0, -1, 1, 2], want: [0, -1, 0, 2] }, +]; + +testCases.forEach((testCase, index) => { + const { input, want } = testCase; + const got = runningSum(input); + assert.deepStrictEqual(got, want, `Test [${input}]`); +}); + +console.log('All tests passed.'); diff --git a/challenge-238/demerphq/js/ch-2.js b/challenge-238/demerphq/js/ch-2.js new file mode 100644 index 0000000000..6c69e3587e --- /dev/null +++ b/challenge-238/demerphq/js/ch-2.js @@ -0,0 +1,57 @@ +"use strict"; // make the browsers happy. + +const digitWeight = {}; + +function calculateDigitWeight(num) { + if (digitWeight[num] !== undefined) { + return digitWeight[num]; + } + + if (num < 0) { + throw new Error(`Not expecting a negative number (${num})`); + } + + let n = num; + let count = 0; + + while (n > 9) { + count++; + const digits = n.toString().split('').map(Number); + n = digits.pop(); + while (digits.length > 0) { + n *= digits.pop(); + } + } + + digitWeight[num] = count; + return count; +} + +function persistenceSort(array) { + return array.sort((a, b) => { + const weightA = calculateDigitWeight(a); + const weightB = calculateDigitWeight(b); + + if (weightA !== weightB) { + return weightA - weightB; + } else { + return a - b; + } + }); +} + +const assert = require('assert'); + +const testCases = [ + { input: [15, 99, 1, 34], want: [1, 15, 34, 99] }, + { input: [50, 25, 33, 22], want: [22, 33, 50, 25] }, + { input: [12347, 2347, 347, 47, 7], want: [7, 47, 347, 2347, 12347] }, +]; + +testCases.forEach((testCase) => { + const { input, want } = testCase; + const output = persistenceSort([...input]); + assert.deepStrictEqual(output, want, `persistenceSort(${input})`); +}); + +console.log('All tests passed.'); diff --git a/challenge-238/demerphq/perl/ch-1.pl b/challenge-238/demerphq/perl/ch-1.pl new file mode 100644 index 0000000000..e5313febeb --- /dev/null +++ b/challenge-238/demerphq/perl/ch-1.pl @@ -0,0 +1,26 @@ +use strict; +use warnings; + +sub running_sum { + my ($array) = @_; + my @sum; + $sum[0] = $array->[0]; + for(my $i = 1; $i < @$array; $i++) { + $sum[$i] = $array->[$i] + $sum[$i-1]; + } + return \@sum; +} + +use Test::More; + +foreach my $tuple ( + [[1, 2, 3, 4, 5], [1, 3, 6, 10, 15]], + [[1, 1, 1, 1, 1], [1, 2, 3, 4, 5]], + [[0, -1, 1, 2], [0, -1, 0, 2]], +) { + my ($input, $want) = @$tuple; + my $got = running_sum($input); + is( "@$got", "@$want", "Test [@$input]"); +} +done_testing(); +__END__ diff --git a/challenge-238/demerphq/perl/ch-2.pl b/challenge-238/demerphq/perl/ch-2.pl new file mode 100644 index 0000000000..f875bebd87 --- /dev/null +++ b/challenge-238/demerphq/perl/ch-2.pl @@ -0,0 +1,41 @@ +use strict; +use warnings; + +my %digit_weight; +sub digit_weight { + my ($num)= @_; + + return $digit_weight{$num} //= do { + die "Not expecting a negative number ($num)" if $num < 0; + my $n = $num; + my $count = 0; + + while ($n > 9) { + $count++; + my $tmp = 1; + for my $digit (split //, $n) { + $tmp *= $digit; + } + $n = $tmp; + } + $count; + }; +} + +sub persistence_sort { + my ($array) = @_; + my @sorted= sort { digit_weight($a) <=> digit_weight($b) || $a <=> $b } @$array; + return \@sorted; +} + +use Test::More; +foreach my $tuple ( + [ [ 15, 99, 1, 34], [ 1, 15, 34, 99 ] ], + [ [ 50, 25, 33, 22], [ 22, 33, 50, 25 ] ], + [ [ 12347, 2347, 347, 47, 7], [ 7, 47, 347, 2347, 12347 ] ], +) { + my ($input, $want) = @$tuple; + my $output = persistence_sort($input); + is("@$output","@$want","persistence_sort(@$input)"); +} +done_testing(); diff --git a/challenge-238/demerphq/rust/Cargo.lock b/challenge-238/demerphq/rust/Cargo.lock new file mode 100644 index 0000000000..2a398e9b28 --- /dev/null +++ b/challenge-238/demerphq/rust/Cargo.lock @@ -0,0 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "challenge-238" +version = "0.1.0" +dependencies = [ + "once_cell", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" diff --git a/challenge-238/demerphq/rust/Cargo.toml b/challenge-238/demerphq/rust/Cargo.toml new file mode 100644 index 0000000000..a8451f6d2e --- /dev/null +++ b/challenge-238/demerphq/rust/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "challenge-238" +version = "0.1.0" +edition = "2021" + +[[bin]] +name = "ch-1" +path = "src/ch-1.rs" + +[[bin]] +name = "ch-2" +path = "src/ch-2.rs" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +once_cell = "1.7" diff --git a/challenge-238/demerphq/rust/src/ch-1.rs b/challenge-238/demerphq/rust/src/ch-1.rs new file mode 100644 index 0000000000..56aaabc5d2 --- /dev/null +++ b/challenge-238/demerphq/rust/src/ch-1.rs @@ -0,0 +1,48 @@ +use std::env; + +fn running_sum(array: &Vec<i32>) -> Vec<i32> { + let mut sum = Vec::new(); + sum.push(array[0]); + + for i in 1..array.len() { + sum.push(array[i] + sum[i - 1]); + } + + sum +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_running_sum() { + let test_cases = vec![ + (vec![1, 2, 3, 4, 5], vec![1, 3, 6, 10, 15]), + (vec![1, 1, 1, 1, 1], vec![1, 2, 3, 4, 5]), + (vec![0, -1, 1, 2], vec![0, -1, 0, 2]), + ]; + + for (input, want) in test_cases { + let got = running_sum(&input); + assert_eq!(got, want); + } + } +} + +fn main() { + // Get command-line arguments, excluding the program name + let args: Vec<String> = env::args().collect(); + + // Create a Vec<i32> by parsing the command-line arguments + let in_vec: Vec<i32> = args + .iter() + .skip(1) // Skip the first argument, which is the program name + .filter_map(|arg| arg.parse().ok()) + .collect(); + + // Print the resulting Vec<i32> + let out_vec: Vec<i32> = running_sum(&in_vec); + println!(" Input: {:?}", in_vec); + println!("Running Sum: {:?}", out_vec); +} diff --git a/challenge-238/demerphq/rust/src/ch-2.rs b/challenge-238/demerphq/rust/src/ch-2.rs new file mode 100644 index 0000000000..7d270460d0 --- /dev/null +++ b/challenge-238/demerphq/rust/src/ch-2.rs @@ -0,0 +1,92 @@ +use std::collections::HashMap; +use once_cell::sync::Lazy; +use std::sync::Mutex; +use std::env; + +static DIGIT_WEIGHT: Lazy<Mutex<HashMap<i32, i32>>> = Lazy::new(|| { + Mutex::new(HashMap::new()) +}); + +fn calculate_digit_weight(num: i32) -> i32 { + let mut cache = DIGIT_WEIGHT.lock().unwrap(); + + if let Some(&cached) = cache.get(&num) { + return cached; + } + + let mut n = num; + let mut count = 0; + + while n > 9 { + count += 1; + let mut tmp = 1; + for digit in n.to_string().chars() { + tmp *= digit.to_digit(10).unwrap() as i32; + } + n = tmp; + } + + cache.insert(num, count); + count +} + +fn persistence_sort(array: &Vec<i32>) -> Vec<i32> { + let mut sorted_array = array.clone(); + + sorted_array.sort_by(|a, b| { + let weight_a = calculate_digit_weight(*a); + let weight_b = calculate_digit_weight(*b); + + if weight_a != weight_b { + weight_a.cmp(&weight_b) + } else { + a.cmp(b) + } + }); + + sorted_array +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_calculate_digit_weight() { + assert_eq!(calculate_digit_weight(9), 0); + assert_eq!(calculate_digit_weight(15), 1); + assert_eq!(calculate_digit_weight(99), 2); + assert_eq!(calculate_digit_weight(12347), 4); + } + + #[test] + fn test_persistence_sort() { + let test_cases = vec![ + (vec![15, 99, 1, 34], vec![1, 15, 34, 99]), + (vec![50, 25, 33, 22], vec![22, 33, 50, 25]), + (vec![12347, 2347, 347, 47, 7], vec![7, 47, 347, 2347, 12347]), + ]; + + for (input, want) in test_cases { + let output = persistence_sort(&input); + assert_eq!(output, want); + } + } +} + +fn main() { + // Get command-line arguments, excluding the program name + let args: Vec<String> = env::args().collect(); + + // Create a Vec<i32> by parsing the command-line arguments + let in_vec: Vec<i32> = args + .iter() + .skip(1) // Skip the first argument, which is the program name + .filter_map(|arg| arg.parse().ok()) + .collect(); + + // Print the resulting Vec<i32> + let out_vec: Vec<i32> = persistence_sort(&in_vec); + println!(" Input: {:?}", in_vec); + println!("Running Sum: {:?}", out_vec); +} diff --git a/challenge-238/demerphq/rust/src/main.rs b/challenge-238/demerphq/rust/src/main.rs new file mode 100644 index 0000000000..54b1a5b863 --- /dev/null +++ b/challenge-238/demerphq/rust/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("use `cargo test` to run tests"); +} |
