aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2022-12-06 12:35:38 +0000
committerGitHub <noreply@github.com>2022-12-06 12:35:38 +0000
commit3c4e6204c9ec1d680983855f00ea3c7e0fd11f0e (patch)
tree7709b91b293ba828cb03b8484db292614bc8278e
parent34156f88b5207ad2f8ed170a32badf4d06afe762 (diff)
parent6d3a2db228f138453c4e94d2332426cd2db28ff7 (diff)
downloadperlweeklychallenge-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/.cbuild2
-rw-r--r--challenge-193/duncan-c-white/C/Makefile4
-rw-r--r--challenge-193/duncan-c-white/C/README8
-rw-r--r--challenge-193/duncan-c-white/C/ch-2.c200
-rwxr-xr-xchallenge-193/duncan-c-white/perl/ch-2.pl6
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);
}