Verständnis: Map of India



  • Ich verstehe irgendwie nicht diesen Source Code:

    #include <stdio.h>
    int main()
    {
        int a,b,c;
        int count = 1;
        for (b=c=10;a="- FIGURE?, UMKC,XYZHello Folks,\
        TFy!QJu ROo TNn(ROo)SLq SLq ULo+\
        UHs UJq TNn*RPn/QPbEWS_JSWQAIJO^\
        NBELPeHBFHT}TnALVlBLOFAkHFOuFETp\
        HCStHAUFAgcEAelclcn^r^r\\tZvYxXy\
        T|S~Pn SPm SOn TNn ULo0ULo#ULo-W\
        Hq!WFs XDt!" [b+++21]; )
        for(; a-- > 64 ; )
        putchar ( ++c=='Z' ? c = c/ 9:33^b&1);
        return 0;
    }
    

    Output:

    !!!!!!                                                     
                        !!!!!!!!!!                                                 
                         !!!!!!!!!!!!!!!                                           
                           !!!!!!!!!!!!!!                                          
                         !!!!!!!!!!!!!!!                                           
                          !!!!!!!!!!!!                                             
                          !!!!!!!!!!!!                                             
                            !!!!!!!!!!!!                                           
                            !!!!!!!!                                               
                            !!!!!!!!!!                                             
                           !!!!!!!!!!!!!!                                          
                         !!!!!!!!!!!!!!!!                                          
                        !!!!!!!!!!!!!!!!                                  !!!!!    
                      !!!!!!!!!!!!!!!!!!!                               !!!!!!!!!! 
                     !!!!!!!!!!!!!!!!!!!!!!!                 !         !!!!!!!!!!  
                !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!              !!     !!!!!!!!!!!!    
               !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!        !!      !!!!!!!!       
                !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!      
                 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!       
                  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  !!!!!!!!!!!!       
           !!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!        !!!!!!        
          !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!      !!!!!         
              !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!        !!!          
            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!        !          
              !!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!                       
               !!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!                         
                      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!                          
                     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!                           
                      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!                               
                      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!                               
                      !!!!!!!!!!!!!!!!!!!!!!!!!!!!                                 
                      !!!!!!!!!!!!!!!!!!!!!!!!!!                                   
                      !!!!!!!!!!!!!!!!!!!!!!!!!                                    
                       !!!!!!!!!!!!!!!!!!!!!!!!                                    
                        !!!!!!!!!!!!!!!!!!!!                                       
                        !!!!!!!!!!!!!!!!!!!                                        
                         !!!!!!!!!!!!!!!!                                          
                          !!!!!!!!!!!!!!!!                                         
                          !!!!!!!!!!!!!!!                                          
                           !!!!!!!!!!!!!!                                          
                            !!!!!!!!!!!!                                           
                            !!!!!!!!!!!!                                           
                            !!!!!!!!!!!!                                           
                              !!!!!!!!                                             
                              !!!!!!                                               
                               !!!!
    

    Quelle: https://github.com/TonyJosi97/MyWorkspace/blob/master/Cool/MapOfIndia.c

    Kann mir jemand das Vorgehen näher erklären?


  • Global Moderator

    In der innersten Schleife sind die Werte wie folgt:

    • c wird in jedem Durchgang erhöht und zählt jeweils von 10 bis 90 (=='Z').
    • a zählt in jedem Durchgang um 1 rückwärts, ausgehend vom aktuellen Zeichen bis 64 (das Zeichen vor 'A'). Das aktuelle Zeichen hängt vom Wert von b ab.
    • b geht bei 10 los und wird jeweils genau dann um 1 erhöht, wenn die a-Schleife fertig ist. Das kann manchmal so aussehen als würde b um 2 oder mehr erhöht, falls das aktuelle Zeichen kleiner als 'A' ist, die a-Schleife also gar nicht erst betreten wird.

    In jedem Durchgang der innersten Schleife wird ein Zeichen ausgegeben:

    • Wenn c gleich 90 ist, wird ein Linefeed ausgegeben (Wert 10, berechnet sich nach c/9)

    • Wenn c ungleich 90 ist:

    • Wenn b gerade ist (b&1 ist 0), wird ein '!' ausgegeben (Wert 33, das ist 33^0)

    • Wenn b ungerade ist (b&1 ist 1), wird ein Leerzeichen ausgegeben (Wert 32, das ist 33^1)

    In der Zeichenkette ist also codiert, wie lange eine Sequenz von Leerzeichen bzw. Ausrufezeichen jeweils dauert. Die Länge ist dabei wie weit das Zeichen nach 'A' kommt. Wird eine sehr lange Sequenz von Leerzeichen benötigt, kommen von Zeit zu Zeit auch mal Zeichen vor 'A' vor. In dem Fall wird die Ausrufezeichensequenz übersprungen und direkt zur nächsten Leerzeichensequenz übergegangen.

    Die ersten 31 Zeichen des Codes werden komplett übersprungen.

    Die scheinbar der Einrückung dienenden Leerzeichen in den Zeilen 7-12 sind Teil der Zeichenkette und somit kritisch, die Einrückung darf also nicht verändert werden.

    Und Windows dürfte das Programm nicht funktionieren, da dort ein Zeilenumbruch nicht durch ein Linefeed ersetzt werden kann. Da müsste man schreiben (ungetestet):

    putchar ( ++c=='Z' ? (c = c/ 9), '\n':33^b&1);
    

    PS: Es kann sein, dass ich bei obiger Beschreibung stellenweise ungenau war, was die genauen Schleifengrenzen angeht. Die Idee sollte aber hoffentlich klar geworden sein.



  • Puh, wie kommt man nur auf so eine Idee. Auch wenn ich schon seit einiger Zeit in C++ programmiere und einige Kenntnisse in C habe, das hat mich dann doch ein wenig überfordert. Ist es in irgendeiner Weise üblich, dass man so etwas in einer Zeichenkette codiert? Selbsterklärend ist der Code meiner Meinung nach nämlich überhaupt nicht.

    Vielen Dank also für das Erklären.


  • Global Moderator

    An sich ist es durchaus üblich, dass man Information über "flächige" Bilder codiert, indem man angibt, wie lang ein Stück der Fläche jeweils ist. Das ist Basis vieler Komprimierungsverfahren, nicht nur für Bilder.

    Was absolut nicht normal ist, ist, wie hier die Information dekodiert wird. Das könnte man auch viel verständlicher programmieren. Der Code ist eindeutig mit Absicht unverständlich gehalten. Es gibt sogar einen berühmten Wettbewerb für unverständliches C. Dieses Programm hätte dort aber keine Chance, das ist noch viel zu harmlos. Es aber gewiss eine gute Übung für den Autor gewesen, wie man solche Programme schreibt, und es stellt auch eine gute Übung für interessierte Leser dar, wie man solche Programme wieder entziffert. Ich fand es sehr interessant, mich da durch zu hangeln. Es war einerseits nicht sofort offensichtlich, wie es funktioniert (mein erster Verdacht war eine Bitmapcodierung), aber andererseits ist es nicht so überwältigend komplex, dass man gar nicht weiß, wo man anfangen soll.



  • Das "Hello Folks" im Code ist schon gelungen. 😃