From 6d3a2db228f138453c4e94d2332426cd2db28ff7 Mon Sep 17 00:00:00 2001 From: dcw Date: Mon, 5 Dec 2022 15:42:03 +0000 Subject: slight tweak to ch-2.pl and then translated it into C (see C/ch-2.c for that), sorting an array of pairs (strings + difference signatures) by signature using qsort.. --- challenge-193/duncan-c-white/C/.cbuild | 2 +- challenge-193/duncan-c-white/C/Makefile | 4 +- challenge-193/duncan-c-white/C/README | 8 +- challenge-193/duncan-c-white/C/ch-2.c | 200 ++++++++++++++++++++++++++++++ challenge-193/duncan-c-white/perl/ch-2.pl | 6 +- 5 files changed, 209 insertions(+), 11 deletions(-) create mode 100644 challenge-193/duncan-c-white/C/ch-2.c 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 +#include +#include +#include +#include +#include + +#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; i1; -} - -foreach my $k (keys %freq) -{ + next if $freq{$k}>1; my $ref = $d2l{$k}; say join(',', @$ref); } -- cgit