diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2022-12-06 12:35:38 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-06 12:35:38 +0000 |
| commit | 3c4e6204c9ec1d680983855f00ea3c7e0fd11f0e (patch) | |
| tree | 7709b91b293ba828cb03b8484db292614bc8278e | |
| parent | 34156f88b5207ad2f8ed170a32badf4d06afe762 (diff) | |
| parent | 6d3a2db228f138453c4e94d2332426cd2db28ff7 (diff) | |
| download | perlweeklychallenge-club-3c4e6204c9ec1d680983855f00ea3c7e0fd11f0e.tar.gz perlweeklychallenge-club-3c4e6204c9ec1d680983855f00ea3c7e0fd11f0e.tar.bz2 perlweeklychallenge-club-3c4e6204c9ec1d680983855f00ea3c7e0fd11f0e.zip | |
Merge pull request #7212 from dcw803/master
slight tweak to ch-2.pl and then translated it into C…
| -rw-r--r-- | challenge-193/duncan-c-white/C/.cbuild | 2 | ||||
| -rw-r--r-- | challenge-193/duncan-c-white/C/Makefile | 4 | ||||
| -rw-r--r-- | challenge-193/duncan-c-white/C/README | 8 | ||||
| -rw-r--r-- | challenge-193/duncan-c-white/C/ch-2.c | 200 | ||||
| -rwxr-xr-x | challenge-193/duncan-c-white/perl/ch-2.pl | 6 |
5 files changed, 209 insertions, 11 deletions
diff --git a/challenge-193/duncan-c-white/C/.cbuild b/challenge-193/duncan-c-white/C/.cbuild index 624a95ebfb..a14ec76520 100644 --- a/challenge-193/duncan-c-white/C/.cbuild +++ b/challenge-193/duncan-c-white/C/.cbuild @@ -1,4 +1,4 @@ -BUILD = ch-1 +BUILD = ch-1 ch-2 CFLAGS = -Wall -g #LDFLAGS = -lm #CFLAGS = -g diff --git a/challenge-193/duncan-c-white/C/Makefile b/challenge-193/duncan-c-white/C/Makefile index e9ebaeaa96..8d85c7d16d 100644 --- a/challenge-193/duncan-c-white/C/Makefile +++ b/challenge-193/duncan-c-white/C/Makefile @@ -1,7 +1,7 @@ # Makefile rules generated by CB CC = gcc CFLAGS = -Wall -g -BUILD = ch-1 +BUILD = ch-1 ch-2 all: $(BUILD) @@ -11,4 +11,6 @@ clean: args.o: args.c ch-1: ch-1.o args.o ch-1.o: ch-1.c args.h +ch-2: ch-2.o args.o +ch-2.o: ch-2.c args.h diff --git a/challenge-193/duncan-c-white/C/README b/challenge-193/duncan-c-white/C/README index 6664968152..a5adc6cda7 100644 --- a/challenge-193/duncan-c-white/C/README +++ b/challenge-193/duncan-c-white/C/README @@ -1,7 +1,7 @@ -Thought I'd also have a go at translating ch-1.pl into C.. +Thought I'd also have a go at translating ch-1.pl and ch-2.pl into C.. -It produces near-identical (non-debugging and even debugging) output to the -Perl original. +Both C versions produce near-identical (non-debugging and even debugging) +output to the Perl originals. -It uses one of my regular support modules: +They use one of my regular support modules: - a command-line argument processing module args.[ch] diff --git a/challenge-193/duncan-c-white/C/ch-2.c b/challenge-193/duncan-c-white/C/ch-2.c new file mode 100644 index 0000000000..2a525f28ec --- /dev/null +++ b/challenge-193/duncan-c-white/C/ch-2.c @@ -0,0 +1,200 @@ +// +// Task 2: Odd Strings +// +// C version. +// + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <ctype.h> +#include <assert.h> + +#include "args.h" + + +// +// char *diffsig = diffsig(str); +// +// Given an alphabetic string $str, form and return the difference signature. +// (a malloc()d string, the caller is responsible for freeing it later). +// +char * diffsig( char *str ) +{ + int len = strlen(str); + assert( len > 1 ); + char *result = malloc( 4 * len + 2 ); // 4 * len: optional -, 1 or 2 + // digits and a comma: + // then add a bit:-) + assert( result != NULL ); + + char *rp = result; // rp will walk the result, appending chars + *rp = '\0'; // let's keep it nul-terminated always + + // foreach char *p that is not the last + for( char *p=str; *(p+1) != '\0'; p++ ) + { + if( p>str ) *rp++ = ','; + sprintf( rp, "%d", *(p+1)-*p ); + while( *rp != '\0' ) rp++; + } + + //printf( "debug: diffstr(%s) = %s\n", str, result ); + return result; +} + + +// +// lowercase(str); +// lowercase str in place. +// +void lowercase( char *str ) +{ + for( char *p=str; *p; p++ ) + { + *p = tolower(*p); + } +} + + +// a (string, diffsig) pair +typedef struct +{ + char *str; + char *sig; +} pair; + + +// qsort comparator for a pair.. couldn't resist the name.. +static int compair( const void *a, const void *b ) +{ + pair *p = (pair *)a; + pair *q = (pair *)b; + return strcmp( p->sig, q->sig ); +} + + +// a ptr to a function taking a signature and list[from]..list[to] +// comprising all the strings with that signature. +typedef void (*sigcallback)( char *sig, pair *list, int from, int to ); + + +// +// find_freq_sigs( list, nel, cb ); +// given a sorted list of nel pairs, locate each set of strings +// with distinct signatures, and call the cb function for each +// set found. +// +void find_freq_sigs( pair *list, int nel, sigcallback cb ) +{ + char *sig = ""; + int from = -1; + int to = -1; + for( int i=0; i<nel; i++ ) + { + if( strcmp( sig, list[i].sig ) != 0 ) + { + // found different signature list[i].sig + // deal with previous set + if( *sig != '\0' ) + { + (*cb)( sig, list, from, to ); + } + + from = i; + to = i; + sig = list[i].sig; + } else + { + to++; + } + } + // deal with final set + if( *sig != '\0' ) + { + (*cb)( sig, list, from, to ); + } +} + + +static void printsigset( char *sig, pair *list, int from, int to ) +{ + int freq = to-from+1; + //printf( "sig %s: list[%d]=%s..list[%d]=%s, freq %d\n", + // sig, from, list[from].str, to, list[to].str, freq ); + if( freq == 1 ) + { + if( debug ) + { + printf( "unique sig %s: %s\n", sig, list[from].str ); + } else + { + printf( "%s\n", list[from].str ); + } + } +} + + +int main( int argc, char **argv ) +{ + int argno = process_flag_n_m_args( "odd-strings", argc, argv, + 1, 100, "strlist" ); + + if( debug ) + { + printf( "debug: argno=%d, argc=%d\n", argno, argc ); + } + + pair list[argc-argno]; // list[i-argno].str : argv[i], + // list[i-argno].sig : diffsig(lc(argv[i])) + + // build list.. indexes 0..argc-argno-1 + int nel=0; + for( int i=argno; i<argc; i++ ) + { + list[nel].str = strdup(argv[i]); + lowercase(list[nel].str); + list[nel].sig = diffsig(list[nel].str); + if( debug ) + { + printf( "debug: unsorted list[%d].str=%s, " + "list[%d].sig=%s\n", + nel, list[nel].str, + nel, list[nel].sig ); + } + nel++; + } + + if( debug ) + { + printf( "debug: nel=%d\n", nel ); + } + + // sort list by signature + qsort( list, nel, sizeof(pair), &compair ); + + // show sorted list + if( debug ) + { + for( int i=0; i<nel; i++ ) + { + printf( "debug: sorted list[%d].str=%s, " + "list[%d].sig=%s\n", + i, list[i].str, i, list[i].sig ); + + } + } + + if( debug ) putchar( '\n' ); + find_freq_sigs( list, nel, &printsigset ); + + // tidy up.. free everything we malloc()d + for( int i=0; i<nel; i++ ) + { + free( list[i].sig ); + free( list[i].str ); + } + + return 0; +} diff --git a/challenge-193/duncan-c-white/perl/ch-2.pl b/challenge-193/duncan-c-white/perl/ch-2.pl index 988f4819cf..4fb47aa330 100755 --- a/challenge-193/duncan-c-white/perl/ch-2.pl +++ b/challenge-193/duncan-c-white/perl/ch-2.pl @@ -106,11 +106,7 @@ map { $freq{$_}++ } @diffsig; foreach my $k (keys %freq) { - delete $freq{$k} if $freq{$k}>1; -} - -foreach my $k (keys %freq) -{ + next if $freq{$k}>1; my $ref = $d2l{$k}; say join(',', @$ref); } |
