From 2b9a4ec6dd2cab68be478993516d05df0624ba67 Mon Sep 17 00:00:00 2001 From: Cody Boone Ferguson <53008573+xexyl@users.noreply.github.com> Date: Tue, 17 Oct 2023 15:50:22 -0700 Subject: [PATCH] Drop char count of 1991/fine to 85 (was 80 -> 106) With clever use of the Makefile and removing a cast that is not strictly necessary (it does trigger a warning but it still produces correct output) I was able to get what was once 80 characters but when fixed increased to 106 characters all the way back down to 85. As for how this was done it might be helpful to look at what it was prior to this update as well as the original. The previous version was: int main(int a, char **b){while((a=getchar())+1)putchar((b=64^a&223)&&(int)b<27?a&96|((int)b+12)%26+1:a); and the original was: main(a,b){while((a=getchar())+1)putchar((b=64^a&223)&&b<27?a&96|(b+12)%26+1:a);} The problem with the original besides needing one of the casts is that clang is stricter with the types of args of main(). Now it looks like: main(a,b){while((a=getchar())+1)putchar((b=64^a&223)&&b<27?a&96|((int)b+12)%26+1:a);} which is almost the same as the original. But how was this done? The Makefile does: -D'main(a,b)'='int main(a,b)char**b;' which lets the main() part be the same as the original but still compile with clang. I also added the script demo.sh which simplifies running the command I had added (or more likely extended) but it also shows it line by line so you can see how the text is rotated. One of my favourites of the lot is from Brian Westley and that is one I added. --- 1991/fine/Makefile | 4 ++-- 1991/fine/README.md | 18 +++++++----------- 1991/fine/demo.sh | 23 +++++++++++++++++++++++ 1991/fine/fine.c | 2 +- thanks-for-fixes.md | 12 ++++++++++++ 5 files changed, 45 insertions(+), 14 deletions(-) create mode 100755 1991/fine/demo.sh diff --git a/1991/fine/Makefile b/1991/fine/Makefile index 1aa9ac350..6d59c67fa 100644 --- a/1991/fine/Makefile +++ b/1991/fine/Makefile @@ -39,7 +39,7 @@ include ../../var.mk # Common C compiler warnings to silence # CSILENCE= -Wno-bitwise-op-parentheses -Wno-error -Wno-implicit-function-declaration \ - -Wno-int-conversion -Wno-pointer-to-int-cast + -Wno-int-conversion -Wno-pointer-to-int-cast -Wno-implicit-int # Common C compiler warning flags # @@ -58,7 +58,7 @@ ARCH= # Defines that are needed to compile # -CDEFINE= +CDEFINE= -D'main(a,b)'='int main(a,b)char**b;' # Include files that are needed to compile # diff --git a/1991/fine/README.md b/1991/fine/README.md index 50ad37bbb..174be0493 100644 --- a/1991/fine/README.md +++ b/1991/fine/README.md @@ -19,18 +19,10 @@ echo text | ./fine ## Try: ```sh -echo "green terra -vex -tang -vend onyx -cheryl be flashy -rail -clerk -the rug gary lenT -" | ./fine +./demo.sh ``` -Read the last line backwards! Credit goes to [Merlyn LeRoy (Brian +Make sure that you read the last line backwards! Credit goes to [Merlyn LeRoy (Brian Westley)](/winners.html#Brian_Westley) for that. See his 22 August 1992 [rec.puzzles post](https://groups.google.com/g/rec.puzzles/c/z_xVPMRVBtg/m/lyEYSAeBD4gJ). To @@ -43,13 +35,17 @@ rotated from `the rug gary lent`! This filter, 80 chars plus a newline, fits into a single line on most terminals (unless your terminal has a line wrap mis-feature :-)). +Note in 2023: fixing this entry to work with modern systems increased the size, +originally to 106 characters but dropped down to 85 with clever use of the +Makefile and removal of a cast that was not strictly necessary. + This entry is likely one of the smallest C implementations of this filter, excluding programs that resort to command line or include file tricks. How does this program work? Which 3 bytes of C code can be changed into 2 bytes, allowing the program to still work, but also stripping -the high bit off of some input? +the high bit off some input? ## Author's remarks: diff --git a/1991/fine/demo.sh b/1991/fine/demo.sh new file mode 100755 index 000000000..fce54fd84 --- /dev/null +++ b/1991/fine/demo.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +make all || exit 1 + +echo -n "Green terra: " +echo "Green terra" |./fine + +echo -n "Vex: " +echo "Vex" | ./fine + +echo -n "Tang: " +echo "Tang" | ./fine + +echo -n "Vend onyx: " +echo "Vend onyx" | ./fine +echo -n "Cheryl be flashy: " +echo "Cheryl be flashy" | ./fine +echo -n "Rail: " +echo "Rail" | ./fine +echo -n "Clerk: " +echo "Clerk" | ./fine +echo -n "The rug gary lenT: " +echo "The rug gary lenT" | ./fine diff --git a/1991/fine/fine.c b/1991/fine/fine.c index b465e06f3..5209bdb35 100644 --- a/1991/fine/fine.c +++ b/1991/fine/fine.c @@ -1 +1 @@ -int main(int a, char **b){while((a=getchar())+1)putchar((b=64^a&223)&&(int)b<27?a&96|((int)b+12)%26+1:a);} +main(a,b){while((a=getchar())+1)putchar((b=64^a&223)&&b<27?a&96|((int)b+12)%26+1:a);} diff --git a/thanks-for-fixes.md b/thanks-for-fixes.md index fcc2438a2..2b90d3c5a 100644 --- a/thanks-for-fixes.md +++ b/thanks-for-fixes.md @@ -650,6 +650,18 @@ and he also made an [alternate version](1991/dds/dds.alt.c) that works with `clang`. The alternate code, described in the README.md file, is what is needed for clang. Reading it might be instructive even if you have gcc. +## [1991/fine](1991/fine/fine.c) ([README.md](1991/fine/README.md)) + +Cody made it look much more like the original entry even after the fix that +increased the count in characters from 80 to 106, getting it back down to just 85. +This was done by redefining `main` at the compiler line so that it looks like +the original where one didn't have to worry about the type of args of main() and +there were other fewer restrictions and also by removing a cast that was +not strictly necessary (this does create a new warning: `ordered comparison +between pointer and integer ('char **' and 'int')` but it works just fine). + +Cody also added the [demo.sh](1991/fine/demo.sh) script which feeds the program +some fun input for fun but mostly different output. ## [1991/westley](1991/westley/westley.c) ([README.md](1991/westley/README.md]))