Guest User

Quine Solution

a guest
Jul 21st, 2015
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //
  2. //  main.m
  3. //  Quine
  4. //
  5.  
  6. #import <Foundation/Foundation.h>
  7.  
  8. BOOL allowUndefinedRepeatBehavior = NO;
  9. BOOL allowRepeatToCycleAndPrintItself = NO;
  10.  
  11. typedef enum : NSUInteger {
  12.     PRINT,
  13.     REPEAT,
  14. } PrintOrRepeat;
  15.  
  16. @interface Line : NSObject
  17. @property (readwrite,assign) PrintOrRepeat printOrRepeat;
  18. @property (readwrite,assign) int arg1;
  19. @property (readwrite,assign) int arg2;
  20. @end
  21.  
  22. @interface ExecutionState : NSObject
  23. @property (readwrite,assign) int totalNumberOfLines;
  24. @property (readwrite,retain) NSMutableArray* lines;
  25. @property (readwrite,retain) NSMutableArray* outputAlreadyWritten;
  26. @property (readwrite, assign) int currentIndexOfExecution;
  27. @property (readwrite, assign) BOOL isPrinting;
  28. @property (readwrite, assign) int ifIsPrintingPrintUntilWhatLine;
  29. @end
  30.  
  31.  
  32.  
  33. @implementation Line
  34.  
  35. -(NSString*) description {
  36.     if (self.printOrRepeat == PRINT) {
  37.         return [NSString stringWithFormat:@"PRINT %d", self.arg1];
  38.     } else {
  39.         return [NSString stringWithFormat:@"REPEAT %d %d", self.arg1, self.arg2];
  40.     }
  41. }
  42. +(Line*) lineZero {
  43.     Line* r = [[Line alloc] init];
  44.     r.printOrRepeat = PRINT;
  45.     r.arg1 = 0;
  46.     r.arg2 = 0;
  47.     return r;
  48. }
  49. -(Line*) nextLineLineIndex:(int)x ofTotal:(NSUInteger) y carry:(BOOL*) carry {
  50.     *carry = NO;
  51.     Line* r = [[Line alloc] init];
  52.     r.printOrRepeat = self.printOrRepeat;
  53.     r.arg1 = self.arg1;
  54.     r.arg2 = self.arg2;
  55.     if (r.printOrRepeat == PRINT) {
  56.         r.arg1 = r.arg1+1;
  57.         if (r.arg1 > y /*- x - 1*/) {
  58.             r.printOrRepeat = REPEAT;
  59.             r.arg1 = 0;
  60.             r.arg2 = 0;
  61.         }
  62.     } else {
  63.         r.arg1 = r.arg1 + 1;
  64.         if (r.arg1 > y) {
  65.             r.arg1 = 0;
  66.             r.arg2 = r.arg2 + 1;
  67.             if (r.arg2 > y) {
  68.                 *carry = YES;
  69.                 return [Line lineZero];
  70.             }
  71.         }
  72.     }
  73.     return r;
  74. }
  75. -(BOOL) equals:(Line*) rhs {
  76.     if (self.printOrRepeat != rhs.printOrRepeat) {
  77.         return NO;
  78.     }
  79.     if (self.printOrRepeat == PRINT) {
  80.         return self.arg1 == rhs.arg1;
  81.     } else {
  82.         return self.arg1 == rhs.arg1 && self.arg2 == rhs.arg2;
  83.     }
  84.    
  85. }
  86.  
  87. @end
  88.  
  89. @implementation ExecutionState
  90.  
  91. +(ExecutionState*) freshExecutionStateOfScriptLength:(int) length {
  92.     ExecutionState* es = [[ExecutionState alloc] init];
  93.     es.totalNumberOfLines = length;
  94.     es.lines = [NSMutableArray array];
  95.     es.outputAlreadyWritten = [NSMutableArray array];
  96.     es.currentIndexOfExecution = 0;
  97.     es.isPrinting = NO;
  98.     es.ifIsPrintingPrintUntilWhatLine = 0;
  99.     return es;
  100. }
  101. -(ExecutionState*) copy {
  102.     ExecutionState* es = [[ExecutionState alloc] init];
  103.     es.totalNumberOfLines = self.totalNumberOfLines;
  104.     es.lines = [NSMutableArray arrayWithArray:self.lines];
  105.     es.outputAlreadyWritten = [NSMutableArray arrayWithArray:self.outputAlreadyWritten];
  106.     es.currentIndexOfExecution = self.currentIndexOfExecution;
  107.     es.isPrinting = self.isPrinting;
  108.     es.ifIsPrintingPrintUntilWhatLine = self.ifIsPrintingPrintUntilWhatLine;
  109.     return es;
  110. }
  111. -(BOOL) cannotBecomeQuine {
  112.     if (self.outputAlreadyWritten.count > self.totalNumberOfLines) {
  113.         return YES;
  114.     }
  115.     for (int i = 0; i < self.lines.count && i<self.outputAlreadyWritten.count; i++) {
  116.         if (![[self.lines objectAtIndex:i] equals:[self.outputAlreadyWritten objectAtIndex:i]]) {
  117.             return YES;
  118.         }
  119.     }
  120.     return NO;
  121. }
  122. -(BOOL) applyLine:(Line*) line {
  123.    
  124.     [self.lines addObject:line];
  125.     int currentLineNumber = (int)self.lines.count-1;
  126.     if (self.isPrinting) {
  127.         [self.outputAlreadyWritten addObject:line];
  128.         self.isPrinting = self.ifIsPrintingPrintUntilWhatLine > currentLineNumber;
  129.        
  130.     } else {
  131.         if (line.printOrRepeat == PRINT) {
  132.             if (line.arg1 == 0) {
  133.                
  134.             } else {
  135.                 self.isPrinting = YES;
  136.                 self.ifIsPrintingPrintUntilWhatLine = currentLineNumber + line.arg1;
  137.             }
  138.            
  139.         } else {
  140.             int firstOutputLineToPrint = (int)self.outputAlreadyWritten.count - line.arg2;
  141.             int lastOutputLineToPrint = firstOutputLineToPrint + line.arg1 - 1;
  142.             if (!allowRepeatToCycleAndPrintItself && lastOutputLineToPrint >= self.outputAlreadyWritten.count) {
  143.                 return YES;
  144.             }
  145.             if (firstOutputLineToPrint < 0) {
  146.                 if (allowUndefinedRepeatBehavior) {
  147.                     return NO;
  148.                 } else {
  149.                     return YES;
  150.                 }
  151.                
  152.             }
  153.             for (int i =firstOutputLineToPrint; i<=lastOutputLineToPrint; i++) {
  154.                 [self.outputAlreadyWritten addObject:[self.outputAlreadyWritten objectAtIndex:i]];
  155.             }
  156.            
  157.         }
  158.     }
  159.     return NO;
  160. }
  161. -(ExecutionState*) quineFromInitialSegmentWithCommand:(Line*) line {
  162.     ExecutionState* es = [self copy];
  163.     BOOL error = [es applyLine:line];
  164.     if (error) {
  165.         return nil;
  166.     }
  167.     if ([es cannotBecomeQuine]) {
  168.         return nil;
  169.     }
  170.     return [es quineFromInitialSegment];
  171. }
  172. -(BOOL) isOutputEqualToInput {
  173.     if (self.outputAlreadyWritten.count != self.lines.count) {
  174.         return NO;
  175.     }
  176.     for (int i = 0; i<self.lines.count; i++) {
  177.         if (![(Line*)([self.outputAlreadyWritten objectAtIndex:i]) equals: (Line*)([self.lines objectAtIndex:i])]) {
  178.             return NO;
  179.         }
  180.     }
  181.     return YES;
  182. }
  183. -(ExecutionState*) quineFromInitialSegment {
  184.    
  185.     if (self.lines.count == self.totalNumberOfLines) {
  186.         if (!self.isPrinting && [self isOutputEqualToInput]) {
  187.             NSLog(@"%@\n\n",self);
  188.             return nil;
  189.         } else {
  190.             return nil;
  191.         }
  192.     }
  193.    
  194.     if (self.isPrinting && self.outputAlreadyWritten.count > self.lines.count) {
  195.         Line* nextCommand = [self.outputAlreadyWritten objectAtIndex:self.lines.count];
  196.         return [self quineFromInitialSegmentWithCommand:nextCommand];
  197.     }
  198.     if (self.isPrinting && self.outputAlreadyWritten.count < self.lines.count) {
  199.         Line* nextCommand = [self.lines objectAtIndexedSubscript:self.outputAlreadyWritten.count];
  200.         return [self quineFromInitialSegmentWithCommand:nextCommand];
  201.     }
  202.    
  203.     int indexOfNextCommand = (int)self.lines.count;
  204.     int minimumPrintArg1 = 0;
  205.     int maximumPrintArg1 = MIN(self.totalNumberOfLines - indexOfNextCommand - 1, self.totalNumberOfLines -  (int)self.outputAlreadyWritten.count);
  206.     if (self.isPrinting) {
  207.         maximumPrintArg1 = self.totalNumberOfLines;
  208.     }
  209.     for (int arg1 = minimumPrintArg1; arg1 <= maximumPrintArg1; arg1++) {
  210.         Line* nextCommand = [[Line alloc] init];
  211.         nextCommand.printOrRepeat = PRINT;
  212.         nextCommand.arg1 = arg1;
  213.         ExecutionState* es = [self quineFromInitialSegmentWithCommand:nextCommand];
  214.         if (es) {
  215.             return es;
  216.         }
  217.     }
  218.     int minimumRepeatArg1 = 0;
  219.     int maxumumRepeatArg1 = self.totalNumberOfLines -  (int)self.outputAlreadyWritten.count ;
  220.     if (self.isPrinting) {
  221.         maxumumRepeatArg1 = self.totalNumberOfLines;
  222.     }
  223.     for (int arg1 = minimumRepeatArg1; arg1 <= maxumumRepeatArg1; arg1++) {
  224.         int minimumRepeatArg2;
  225.         int maximumRepeatArg2;
  226.         if (self.isPrinting) {
  227.             maximumRepeatArg2 = self.totalNumberOfLines;
  228.             minimumRepeatArg2 = 1;
  229.         } else {
  230.             minimumRepeatArg2 = 1;
  231.             if (allowUndefinedRepeatBehavior) {
  232.                 maximumRepeatArg2 = self.totalNumberOfLines -  (int)self.outputAlreadyWritten.count;
  233.             } else {
  234.                 maximumRepeatArg2 = self.totalNumberOfLines;
  235.             }
  236.         }
  237.        
  238.        
  239.         for(int arg2 = minimumRepeatArg2; arg2 <= maximumRepeatArg2; arg2++) {
  240.             Line* nextCommand = [[Line alloc] init];
  241.             nextCommand.printOrRepeat = REPEAT;
  242.             nextCommand.arg1 = arg1;
  243.             nextCommand.arg2 = arg2;
  244.             ExecutionState* es = [self quineFromInitialSegmentWithCommand:nextCommand];
  245.             if (es) {
  246.                 return es;
  247.             }
  248.         }
  249.     }
  250.     return nil;
  251. }
  252.  
  253.  
  254.  
  255.  
  256. +(ExecutionState*) quineOfLength:(int) length {
  257.     NSLog(@"Checking quines of length %d",length);
  258.     ExecutionState* s = [ExecutionState freshExecutionStateOfScriptLength:length];
  259.     return [s quineFromInitialSegment];
  260. }
  261. +(ExecutionState*) iterateQuineLength {
  262.     int length = 1;
  263.     while (YES) {
  264.         ExecutionState* s = [ExecutionState quineOfLength:length];
  265.         if (s) {
  266.             return s;
  267.         }
  268.         length++;
  269.        
  270.     }
  271. }
  272. -(NSString*) description {
  273.    
  274.     NSMutableString* o = [NSMutableString stringWithFormat:@"Script of length %d:\n",(int)self.totalNumberOfLines];
  275.     for (int i = 0; i< self.lines.count; i++) {
  276.         [o appendString:[[self.lines objectAtIndex:i] description]];
  277.         [o appendString:@"\n"];
  278.     }
  279.    
  280.    
  281.     return o;
  282. }
  283. @end
  284.  
  285.  
  286. int main(int argc, const char * argv[]) {
  287.     @autoreleasepool {
  288.        
  289.         [ExecutionState iterateQuineLength];
  290.     }
  291.     return 0;
  292. }
Advertisement
Add Comment
Please, Sign In to add comment