Хабр не дает опубликовать текст программы не запихивая его под кат, или не разбивая его катом, это очень печально — читайте под катом:

Update: Программа распечатывает известное стихотворение, я пытался сделать ее как можно короче, и пока не вижу как ее можно еще умять — хорошо бы дойти до 1000 символов — тогда кат был бы не обязателен.

#include <stdio.h>
int main(int s) {
  switch (s) {
  case 1:
    printf("Вот дом,\n"); break;
  case 2:
    printf("\nА это пшеница,\n"); break;
  case 3:
    printf("\nА это весёлая птица-синица,\n"); break;
  case 4:
    printf("\nВот кот,\n"); break;
  case 5:
    printf("\nВот пёс без хвоста,\n"); break;
  case 6:
    printf("\nА это корова безрогая,\nЛягнувшая"); break;
  case 7:
    printf("\nА это старушка, седая и строгая,\n"); break;
  case 8:
    printf("\nА это ленивый и толстый пастух,\n");
  }
  switch (s) {
  case 9:
    printf("\nВот два петуха,\nКоторые будят того пастуха,\n");
  case 8:
    printf("Который бранится с коровницей строгою,\n");
  case 7:
    printf("Которая доит корову безрогую,\nЛягнувшую");
  case 6:
    printf(" старого пса без хвоста,\n");
  case 5:
    printf("Который за шиворот треплет кота,\n");
  case 4:
    printf("Который пугает и ловит синицу,\n");
  case 3:
    printf("Которая часто ворует пшеницу,\n");
  case 2:
    printf("Которая в темном чулане хранится\nВ доме,\n");
  case 1:
    printf("Который построил Джек.\n");
  }
  if (s++<9) main(s);
}

Комментарии (56)


  1. Zalechi
    05.04.2019 19:07
    +2

    ТТ 34


    1. rekub Автор
      05.04.2019 19:11

      Непонятно, что вы хотите сказать?


      1. zagayevskiy
        05.04.2019 20:35
        +4

        Такой же вопрос и к вам.


        1. rekub Автор
          05.04.2019 21:18

          Текст программы вполне самодокументируемый и интересный. Добавил небольшой комментарий.


        1. thatsme
          06.04.2019 09:47
          -1

          Это отличная пятничная шутка для программистов. Да она простая. Но вполне себе прикольная. Само стихотворение рекурсивное, и просто просится в код. Я думаю шутка удалась. Однако автору сочуствую.


  1. Zalechi
    05.04.2019 19:18
    +1

    Название музыкальной группы исполняющей песню «Джек» текст которой содержит слова применённые вами.

    Извините, но я не программист и не понял, что Вы хотите сказать. Много лет на хабре, но такого не видал. Обычно авторы поясняют и разжёвывают.


    1. delphinpro
      05.04.2019 19:21
      +2

      Программный вывод всем известного текста.

      Прикольный код, зачем минуса-то летят? На статью не тянет?


      1. rekub Автор
        05.04.2019 19:24
        -6

        наверно потому, что подзаголовок «сообщество разработчиков» уже не имеет никакого отношения к habr'у.


        1. Zalechi
          05.04.2019 20:18

          Ну вы не будьте столь категоричны. Взять меня к примеру — не разработчи, но связист и местный житель.

          Как Вы воспримите статью с таким скромным содержанием:
          Инспектируем трафик локалки и внешки
          ip inspect name INSPECT_OUT dns
          ip inspect name INSPECT_OUT icmp
          ip inspect name INSPECT_OUT ntp
          ip inspect name INSPECT_OUT tcp router-traffic
          ip inspect name INSPECT_OUT udp router-traffic
          ip inspect name INSPECT_OUT icmp router-traffic


          1. rekub Автор
            05.04.2019 21:27

            Я последние 13 лет слишком далек от настроек цисок, так что оценить не смог бы.


          1. vectorplus
            05.04.2019 23:48

            Как Вы воспримите статью
            Я бы промотал ленту и забыл, что такая статья существует.


            1. Zalechi
              06.04.2019 00:44

              Меня зацепило, то что код для программиста лёгкий, да и я сам его вроде читаю, но нетпонимаю полноценно, как работает. А описания никакого нет. Ну и полез задавать вопросы.


      1. Zalechi
        05.04.2019 20:03

        Ну раз такое дело, помогите понять…
        1. Инициализация программы функцией main()
        2. Switch() — не знаю что делает.
        3. Case () — какое-то пред-удсловие, если так можно выразиться?
        4. Printf () — выводит на экран.
        5. Break — похоже на то что не даёт printf сделать свою работу сразу.
        6. If () — в итоге я не понял условие и, что оно выполняет.

        Вижу, что до 7го case-а включительно используется break, потом case-ы идут с 9го по убывающей и в конце программа ждёт исполнения условия с аргументом (s++<9) возвращает в main(s)?

        Только как это в итоге выведет н экран я не понимаю. Знаю, что могу покопать интернет по каждой функции, но раз такая пляска было интересно почитать вашу интерпретацию кода.

        Пишу с мобилы, извините за ошибки.


        1. rekub Автор
          05.04.2019 21:46
          -1

          Ну, это еще целая статья будет, а меня так заминусовали, что вряд ли я смогу ее выложить ((


          1. vectorplus
            05.04.2019 23:50

            А вдруг, если вы толково начнёте комментировать, наплюсуют?
            :)


        1. DocJester
          06.04.2019 06:24

          Switch/case — это оператор множественного ветвления; сама программа представляет собой несложную рекурсию.


  1. Neikist
    05.04.2019 19:31
    +1

    Эм… Это несет какой то глубокий смысл? Или объясняет тонкости работы какого то механизма? Какую это практическую пользу несет?


    1. rekub Автор
      05.04.2019 19:35
      -6

      Just for fun.
      жуть какая — прямо в Совок вернули — «Чему учит данное произведение?»
      Но если очень хочется, то как учебный пример, для начинающего учить программирование, очень даже.


      1. Neikist
        05.04.2019 20:15
        +1

        Имхо, это все же не уровень хабра. Я тут выбирал из тем «разобрать работу под капотом какого нибудь хитрого класса из android SDK», или «варианты архитектуры обменов приложения под андроид на kotlin с беком на 1с с описанием плюсов и минусов» и решил что они обе слишком простенькие, подожду еще писать пока что поинтереснее не придет в голову, а тут такое…


        1. rekub Автор
          05.04.2019 20:56

          А какое такое? Простое? А вы разобрали пример? Вы поняли почему эта программа распечатает весь текст стихотворения? Вы видели много сишных программ с рекурсией функции main? — все-таки раздел «ненормальное пронраммирование». И если хотите вызов, напишите программу, которая распечатает весь текст стихотворения, и при этом будет короче (можно на другом языке).


          1. Neikist
            05.04.2019 21:21
            +1

            В том и проблема что ничего хитрого не увидел и понял сразу, хотя на C не писал почти. P.S. Оно конечно прикольно да, второй switch оригинально сделан, в связке с рекурсией, но слишком как то все просто в итоге. Не говоря уж что в продакшен код я бы такой точно не выпустил. Он вроде простой, но с первого взгляда может не распознаться, соответственно возможно ошибку допустить.


            1. rekub Автор
              05.04.2019 21:32
              +1

              В продакшен был бы тупо выложен сам текст стихотворения, чего уж там.


              1. Neikist
                05.04.2019 21:37
                +2

                Мне кажется если бы вы именно в формате статьи для новичков в программировании пост написали с описанием как это работает — он бы зашел, но в таком виде непонятна его ЦА. Программистам с опытом квайны и такого рода головоломки, имхо, скучны уже, а новички без описания скорее всего не разберутся.


                1. Zalechi
                  05.04.2019 23:11

                  Я например — конечно догадался что она весь текст красиво выводит на экран, но как не понял. Думаю окей. Давай в комментах вместе с ребятами пофантазирую. Бестолку — заминусовали)


                  1. Neikist
                    05.04.2019 23:29

                    В том и проблема. Человек знающий операторы применяемые быстро поймет что к чему, решение пусть местами элегантное, но простое. А без знаний операторов — вряд ли.


          1. DocJester
            06.04.2019 06:27

            Решение элегантное.
            Но проблема в том, что выложить код не значит написать статью.
            К тому же, если уж говорить о «Не нормальном программировании», то уровень статей Хабра — это не рекурсивный вызов main, а представление данной функции как массива.
            Да, так можно.
            Да, такое делали.
            Нет, так делал не я, и нет, я написать такую статью не смогу.


  1. CoolCmd
    05.04.2019 19:41
    +2

    мультфильм в свое время доставлял, а шедевр из «статьи» почему-то нет.


  1. SbWereWolf
    05.04.2019 20:56
    +1

    Если голову включить над кодом, то забавно, програмка прокручивает себя 8 раз и прекращает работу.
    За это время она успевает сгенерить стихотворение.
    Но Хабр это посты в которых тебе разжёвывают от и до, а в конце ты такой «вау!» и просветлился, а эта заметка, это просто анекдот.
    Надо было прикрутить подводку (интро) про авто-генерацию стихов что ли.
    Даже не понятно зачем читатель на него время потратил.


  1. vlad9486
    05.04.2019 21:34
    -1

    Еще прикольнее рекурсию сделать через system("./путь_к_бинарнику") или как это в си? Автору плюс, жаль что заминусовали.


    1. rekub Автор
      05.04.2019 22:11
      -1

      да, прикольно.


  1. Quiensabe
    05.04.2019 22:17

    Уже забыл Си, но если задача сделать короче, то почему не нельзя как-то так (псевокод)
    main (int s){
    if (s=1) print("Вот дом,\n");
    if (s=2) print("\nА это пшеница,\n");
    if (s=3) print("\nА это весёлая птица-синица,\n");
    if (s=4) print("\nВот кот,\n");
    if (s=5) print("\nВот пёс без хвоста,\n");
    if (s=6) print("\nА это корова безрогая,\nЛягнувшая");
    if (s=7) print("\nА это старушка, седая и строгая,\n");
    if (s=8) print("\nА это ленивый и толстый пастух,\n");
    goto s;
    9: print("\nВот два петуха,\nКоторые будят того пастуха,\n");
    8: print("Который бранится с коровницей строгою,\n");
    7: print("Которая доит корову безрогую,\nЛягнувшую");
    6: print(" старого пса без хвоста,\n");
    5: print("Который за шиворот треплет кота,\n");
    4: print("Который пугает и ловит синицу,\n");
    3: print("Которая часто ворует пшеницу,\n");
    2: print("Которая в темном чулане хранится\nВ доме,\n");
    1: print("Который построил Джек.\n");
    if (s++<9) main(s);
    }


    1. staticlab
      05.04.2019 22:36

      Нельзя, потому что в C метки являются идентификаторами, т.е. нельзя сделать числовую метку и перейти на неё по значению переменной.


      1. rekub Автор
        05.04.2019 22:43

        так можно на бейсике, например, но там не пройдет номер с рекурсией и понадобится цикл, в итоге надо написать работающий пример, чтобы понять короче он или нет.


        1. Quiensabe
          05.04.2019 23:11
          +4

          Можно и без меток обойтись
          for(s=1;s<10;s++){
            if (s=1) print("Вот дом,\n");
            if (s=2) print("\nА это пшеница,\n");
            if (s=3) print("\nА это весёлая птица-синица,\n");
            if (s=4) print("\nВот кот,\n");
            if (s=5) print("\nВот пёс без хвоста,\n");
            if (s=6) print("\nА это корова безрогая,\nЛягнувшая");
            if (s=7) print("\nА это старушка, седая и строгая,\n");
            if (s=8) print("\nА это ленивый и толстый пастух,\n");
            if (s>8) print("\nВот два петуха,\nКоторые будят того пастуха,\n");
            if (s>7) print("Который бранится с коровницей строгою,\n");
            if (s>6) print("Которая доит корову безрогую,\nЛягнувшую");
            if (s>5) print(" старого пса без хвоста,\n");
            if (s>4) print("Который за шиворот треплет кота,\n");
            if (s>3) print("Который пугает и ловит синицу,\n");
            if (s>2) print("Которая часто ворует пшеницу,\n");
            if (s>1) print("Которая в темном чулане хранится\nВ доме,\n");
            print("Который построил Джек.\n");
          }


          1. Quiensabe
            06.04.2019 01:19
            +2

            #include <stdio.h>
            const char* a[] = {"Вот дом,\n","\nА это пшеница,\n","\nА это весёлая птица-синица,\n","\nВот кот,\n","\nВот пёс без хвоста,\n","\nА это корова безрогая,\nЛягнувшая","\nА это старушка, седая и строгая,\n","\nА это ленивый и толстый пастух,\n","","","\nВот два петуха,\nКоторые будят того пастуха,\n","Который бранится с коровницей строгою,\n","Которая доит корову безрогую,\nЛягнувшую"," старого пса без хвоста,\n","Который за шиворот треплет кота,\n","Который пугает и ловит синицу,\n","Которая часто ворует пшеницу,\n","Которая в темном чулане хранится\nВ доме,\n","Который построил Джек.\n"};
            int main() {
            for(int s=1;s<9;s++) {
             printf(a[s-1]);
             for(int b=8;b>=0;b--) {
              if (s>b) printf(a[18-b]);
            }}}

            Онлайн компилятор Си


            1. rekub Автор
              06.04.2019 01:27
              +1

              в первом for надо s<10, и в итоге суперский результат в 725 символов — уже близко к примеру с gzip!


              1. Quiensabe
                06.04.2019 13:23

                в первом for надо s<10,
                По ссылке правильный вариант, а сюда скопировал с ошибкой :)

                Сам код в этом случае
                190 сиволов
                #include <stdio.h>const char* a[]={"","","","","","","","","","","","","","","","","",""};
                int main(){for(int s=1;s<10;s++){printf(a[s-1]);for(int b=8;b>=0;b--){if(s>b)printf(a[18-b]);}}}


      1. oam2oam
        06.04.2019 01:38
        +1

        ну что вы, конечно можно!

        void * m[]={&&a,&&b};
         goto *m[0];
        a:;
        b:;


        1. rekub Автор
          06.04.2019 01:46

          это какие-то неправильные пчелы %)


          1. oam2oam
            06.04.2019 01:50

            в С можно вообще практически все…
            Вот очевидное сокращение программ:
            вместо int main() { int s можно писать main(s) { — переменная s будет по умолчанию целой… и да, два цикла можно, наверно, развернуть в что-то типа

            const char* a[] = {...
            main(s,i){
            return (s>9?0:i>0?printf("%s%s",a[i],a[10-i]),main(s,0):main(s,i+1));
            }
            

            ну или как-то так (что-то не думается :) — в этом случае рекурсия сильно сократит текст (жалко, что имя main не сократишь)


  1. kirillsulim
    05.04.2019 22:38

    Можно пожать полный текст в gzip и при вызове распаковывать. В питоне 3 уложился в 579 символов:


    import zlib
    import base64
    print(zlib.decompress(base64.a85decode('Gb"/%92<Ai%,LXl4ofQA-;c3)JtRu9>TuluFIKSY($ln0m)b$k@08h]Psptlp#l-6c_S55>%6KCCYiFGN*k)SB.iqk,B!!.P$$lAh/c$_b\\ujX]Kt`pab.SW9((V"Ya8S>NiI%F.</+e*:FJk2C(pe\\Ddpo,?\\]E--\'\\a,(%l"@J=>$3BN)UXoa+X?3>B\\YQ#TA/FeP-\'&#--U%i:f8UbZr<j#=BA#X.R5qg.B#nUjqJ\\Etb4bj!Obh]5!`+ullW,GcQFuE69b8C>o%g,tK\'mHTSL$=Q9dH$33E]>7STER$UQ;KFsMFWT=8daSY*\'(7XE(4shA]I""F!iiZV+*tW,X>B[$$L_3!KO(l68-Xk@dWVG(/7h$NatT?a"plK3Q_,MLTCi-^pPJ6"]08OR;Ef\\"[Xb0R]K:=l/ajog[H,&#lLnJFc^lPO2&:JrI6H3HM*h@qO`u0F9<..,W4S-"brQc-#VG*Mqa]R45PISL&')).decode())

    Думаю, что в си можно сделать аналогично, хотя и будет чуть длиннее.


    1. rekub Автор
      05.04.2019 22:41

      Здорово, работает! жаль пропуски между многостишиями пропустили, но это не суть уже.


  1. aknew
    05.04.2019 23:15
    +1

    А макросы подойдут? Если да, то можно сделать вот так:

    #define p printf
    #define c case
    #define b break;

    и заменить все вхождения case, printf и break;. Это сэкономит 155 символов и в сумме вроде получается меньше 1000


    1. rekub Автор
      06.04.2019 01:41

      да если это додумать то этот вариант занимает 844 символа и почетное третье место после gzip'а и строк в массиве:

      #include <stdio.h>
      #define c(L,S) case L:printf(S);
      #define b break;
      int main(int s) {
        switch (s) {
        c(1,"Вот дом,\n")b
        c(2,"\nА это пшеница,\n")b
        c(3,"\nА это весёлая птица-синица,\n")b
        c(4,"\nВот кот,\n")b
        c(5,"\nВот пёс без хвоста,\n")b
        c(6,"\nА это корова безрогая,\nЛягнувшая")b
        c(7,"\nА это старушка, седая и строгая,\n")b
        c(8,"\nА это ленивый и толстый пастух,\n")
        }
        switch (s) {
        c(9,"\nВот два петуха,\nКоторые будят того пастуха,\n")
        c(8,"Который бранится с коровницей строгою,\n")
        c(7,"Которая доит корову безрогую,\nЛягнувшую")
        c(6," старого пса без хвоста,\n")
        c(5,"Который за шиворот треплет кота,\n")
        c(4,"Который пугает и ловит синицу,\n")
        c(3,"Которая часто ворует пшеницу,\n")
        c(2,"Которая в темном чулане хранится\nВ доме,\n")
        c(1,"Который построил Джек.\n")
        }
        if (s++<9) main(s);
      }
      


  1. Griboks
    05.04.2019 23:21
    +1

    Что это за ерунда? Можно как-нибудь добавить подобные статьи в черный список?


  1. third112
    05.04.2019 23:43
    +1

    А меня, как говорят в соцсетях: «улыбнуло» :) Пусть на пару минут — ну так и в серьезных журналах бывает веселая картинка без особых претензий. Спасибо.

    Автор правильно указал хаб: «Ненормальное программирование», а вот хаб «Программирование» лучше убрать, чтобы не было завышенных ожиданий у читателей, м.б. добавить «Кодобред». ИМХО тогда никаких претензий быть не должно, тем более, что заметка породила содержательные комменты с вариантами решений: нпр.


  1. staticlab
    05.04.2019 23:49
    +3

    #include <stdio.h>
    
    const char *SUBJECT[] = {
      "house that Jack built.",
      "malt",
      "rat,",
      "cat,",
      "dog,",
      "cow with the crumpled horn,",
      "maiden all forlorn,",
      "man all tatter'd and torn,",
      "priest all shaven and shorn,",
      "cock that crow'd in the morn,",
      "farmer sowing his corn,"
    };
    
    const char *STATE[] = {
      "lay in",
      "ate",
      "kill'd",
      "worried",
      "toss'd",
      "milk'd",
      "kiss'd",
      "married",
      "waked",
      "kept"
    };
    
    int main() {
      for (int i = 0; i < 11; i++) {
        printf("\nThis is ");
        for (int j = i; j >= 0; j--) {
          printf("the %s\n", SUBJECT[j]);
          if (j) printf("That %s ", STATE[j-1]);
        }
      }
    }

    $ wc -c jack.c
    650


  1. Sirion
    06.04.2019 01:00
    +2

    Проблема не в том, что плохой код, а в том, что плохая статья. Не тот формат. Для публикации кусков кода без пояснений существуют другие ресурсы. Посмотрите аналогичные статьи в хабе «Ненормальное программирование», сравните, что есть в них и чего нет у вас.


  1. kvaps
    06.04.2019 02:29
    +2

    #!/bin/bash
    A=(
      "Вот дом,\n"
      "\nА это пшеница,\n"
      "\nА это весёлая птица-синица,\n"
      "\nВот кот,\n"
      "\nВот пёс без хвоста,\n"
      "\nА это корова безрогая,\nЛягнувшая"
      "\nА это старушка, седая и строгая,\n"
      "\nА это ленивый и толстый пастух,\n"
    )
    B=(
      "\nВот два петуха,\nКоторые будят того пастуха,\n"
      "Который бранится с коровницей строгою,\n"
      "Которая доит корову безрогую,\nЛягнувшую"
      " старого пса без хвоста,\n"
      "Который за шиворот треплет кота,\n"
      "Который пугает и ловит синицу,\n"
      "Которая часто ворует пшеницу,\n"
      "Которая в темном чулане хранится\nВ доме,\n"
      "Который построил Джек.\n"
    )
    for ((i=0; i<=9; i++)); do
      printf "$(printf "%s" "${A[$i]}" "${B[@]: -$(($i+1))}")"
    done


  1. GrigorGri
    06.04.2019 03:52

    В почти всех решениях можно заменить "\nА это " на s+"...", что даст выгоду в 6*5=30 символов (-декларация s). Тоже самое с "Котор"


  1. pakager
    06.04.2019 05:02

    #include <stdio.h>
    #define A ,"\nА это "
    #define K ,"\nКотор"
    char* a[]={"\nВот два петуха,"A"ленивый и толстый пастух,"A"старушка, седая и строгая,"A"корова безрогая,\nЛягнувшая","\nВот пёс без хвоста,","\nВот кот,"A"весёлая птица-синица,"A"пшеница,","Вот дом,"K"ые будят того пастуха,"K"ый бранится с коровницей строгою,"K"ая доит корову безрогую,\nЛягнувшую"," старого пса без хвоста,"K"ый за шиворот треплет кота,"K"ый пугает и ловит синицу,"K"ая часто ворует пшеницу,"K"ая в темном чулане хранится\nВ доме,"K"ый построил Джек.\n"};
    main(){int x,y;for(x=8;x>=0;x--){printf(a[x]);for(y=x;y<9;y++){printf(a[y+9]);};};}

    $ wc -m jack.c
    621 jack.c


  1. netricks
    06.04.2019 05:14

    Поставил минус. Думаю, поставил правильно.


    Свитч-кейс автомат — это может быть интересно. Рекурсивный main — это может быть интересно. Кстати, по стандарту языка нельзя рекурсивный main.


    Но статья требует какого-то рассмотрения чтоли… А иначе общий уровень хабра будет неуклонно падать и получим со временем ithappens...


    1. third112
      06.04.2019 07:26

      Но статья требует какого-то рассмотрения чтоли…

      Интересный вопрос. А конкретнее можно: какое тут нужно рассмотрение? — Пересказ вики-статьи о рекурсии явно не нужен. Объяснение для чайника как это работает? — Пусть запустит в отладке и посмотрит по шагам, если в уме сообразить не может.

      По первому впечатлению и мне показалось, что заметка неприлично краткая. Но подумал: как бы я это написал? — И понял, что однозначного ответа пока не имею. М.б. Вы поможете? (Вопрос не праздный: надеюсь понятно, что это мне нужно для публикаций на другие темы).
      Заранее спасибо.


      1. rekub Автор
        06.04.2019 09:05
        -1

        Лично для меня habr куда-то скатился, и стал чудовищно скучен — «Хабр уже не торт», именно из-за того, что наличие в статье чего-то раздражающего немедленно тянет ее в бан. К сожалению, некий вызов на подумать, тоже крайне раздражает, вот что грустно… Неразмусолил код, который выложил, — читатель должен сам думать — в бан. Высказался резко — в бан, например одну прошлую мою статью мою забанили за фразу «это не программист, а дурак какой-то». Это совет как сделать, чтобы не забанили. Для меня, как для автора, это слишком серьёзные ограничения, так что моих статей здесь, видимо, больше не будет ((


        1. third112
          06.04.2019 09:25

          На текущий момент из 1700 читателей только ок. 3% оставили комменты и оценки. Комменты есть интересные, а 3% оценок не могут отразить общего мнения. Как и во многих других статьях. ИМХО если бы не возникали ограничения, то на рейтинг никто бы не смотрел, а писали бы ради обратной связи.


    1. rekub Автор
      06.04.2019 09:00
      +1

      не видел на ithappens кусков кода. Может бывает, конечно, я их мало смотрел.