/// Number classifier that detects prime numbers based on which line is /// deleted. Four outputs are possible: /// /// - prime = line number of deleted line is prime. /// - composite = line number of deleted line is composite. /// - one = first line was deleted. /// - ? = none of the lines were deleted. /// /// This file is a stripped-down and commented version of the full /// detector. To make the full detector: /// /// 1. Delete all lines with three leading slashes. /// 2. Move all lines to where "#line" say they should be, and delete /// all "#line" lines. /// 3. For every blank line that was inserted, add "/*/" if the line /// number is prime. /// Lines 1 through 7 detects if line 1 is deleted, and makes sure /// "#include" happens. #line 1 /* #define OUTPUT "one"/*/ #ifndef CUT/*/ #ifndef CUT/*/ #include/*/ #include /// 11 is the 5th prime. #line 11 /*/ /// 13 is the 6th prime. #line 13 /*/ /// 9973 is the 1229th prime, and the last prime before 10000. If we /// didn't skip forward to line 9973, the next prime would have been /// 17, which is the 7th prime. Note that 7 and 1229 are both odd /// numbers, so the parity of the comment blocks matches. /// /// We choose to end our prime detector at line 10000 because it's a /// nice round number in decimal, and also because there is a long run /// of 33 composite numbers between 9973 and 10007, which makes 27 /// lines available to implement the file completeness detector. /*/#line 9973/*/ /*/#define OUTPUT "composite" /*/ #ifndef OUTPUT #define OUTPUT "prime" #endif//*/ /// If we are outside the comment region (default state), OUTPUT is /// tentatively set to "composite", and we need to check end of file /// to verify that file is complete. We do that by tentatively defining /// CUT for the "#ifndef CUT" guard at the beginning, then "#include" /// current file to verify the end. /// /// If we are inside the comment region, it means some earlier /// prime-numbered line (up to 9973) was deleted, and lines 9974-9976 /// would update OUTPUT to "prime", unless it was already set to "one". #define CUT/*/ /*/ #include __FILE__ /// If file is determined to be complete, change OUTPUT from "composite" /// to "?". #if !defined(CUT) && defined(LAST_LINE)/*/ #if 0/*/ #undef OUTPUT #define OUTPUT "?" /*/ #endif/*/#endif//*/ /*/#endif//*/ /// Generate final code. puts() returns non-negative value on success, /// so the inequality expression below will evaluate to zero if puts() /// is successful, making the program exit code match puts() status. int main(void){return puts(OUTPUT)<0;}/*/ int main(void){return puts(OUTPUT)<0;}//*/ /// Close the "#ifndef CUT" from line 3 or line 5. #endif/*/ #endif/*/ /// Undefine LAST_LINE to avoid redefinition of LAST_LINE after /// returning from "#include __FILE__". #undef LAST_LINE/*/ #undef LAST_LINE/*/ /// Check if any lines got deleted before this line. CUT was defined /// before we got here, and would become undefined if the line number /// matched. If any earlier lines were removed, or if one of the /// next 3 lines were removed, CUT would not be undefined. So /// presence of CUT means some line has been deleted earlier. #line 9994 #if __LINE__ == 9994/*/ #if 0/*/ #undef CUT//*/ #endif/* #endif/*/ /// Detect if either of the #endif lines above were deleted. Also, if /// this line got deleted, LAST_LINE would not be defined. So LAST_LINE /// becomes defined if any only if the last 3 lines remained intact. #define LAST_LINE//*/