1. C++ / Говнокод #12355

    +24

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    #include <iostream>
    #define n 1
    int main()
    {
    using namespace std;
    cout << (n < 0 ? 1 : 0)+
    ((n << 1) < 0 ? 1 : 0)+
    ((n << 2) < 0 ? 1 : 0)+
    ((n << 3) < 0 ? 1 : 0)+
    ((n << 4) < 0 ? 1 : 0)+
    ((n << 5) < 0 ? 1 : 0)+
    ((n << 6) < 0 ? 1 : 0)+
    ((n << 7) < 0 ? 1 : 0)+
    ((n << 8) < 0 ? 1 : 0)+
    ((n << 9) < 0 ? 1 : 0)+
    ((n << 10) < 0 ? 1 : 0)+
    ((n << 11) < 0 ? 1 : 0)+
    ((n << 12) < 0 ? 1 : 0)+
    ((n << 13) < 0 ? 1 : 0)+
    ((n << 14) < 0 ? 1 : 0)+
    ((n << 15) < 0 ? 1 : 0)+
    ((n << 16) < 0 ? 1 : 0)+
    ((n << 17) < 0 ? 1 : 0)+
    ((n << 18) < 0 ? 1 : 0)+
    ((n << 19) < 0 ? 1 : 0)+
    ((n << 20) < 0 ? 1 : 0)+
    ((n << 21) < 0 ? 1 : 0)+
    ((n << 22) < 0 ? 1 : 0)+
    ((n << 23) < 0 ? 1 : 0)+
    ((n << 24) < 0 ? 1 : 0)+
    ((n << 25) < 0 ? 1 : 0)+
    ((n << 26) < 0 ? 1 : 0)+
    ((n << 27) < 0 ? 1 : 0)+
    ((n << 28) < 0 ? 1 : 0)+
    ((n << 29) < 0 ? 1 : 0)+
    ((n << 30) < 0 ? 1 : 0)+
    ((n << 31) < 0 ? 1 : 0)
    << endl;
    return 0;
    }

    Для заданного пятизначного целого числа подсчитать количество его нулей.
    Прямо с экзамена. Преподаватель катается по полу. Не шучу.

    Запостил: LispGovno, 25 Декабря 2012

    Комментарии (65) RSS

    • Мой вариант:
      #include <algorithm>
      ....
      std::string s;
      std::cin >> s;
      assert(5 == s.size());
      std::cout << std::count(s.begin(), s.end(), '0') << std::endl;
      .....
      Ответить
    • > cout << (n < 0 ? 1 : 0)+
      > ((n << 1) < 0 ? 1 : 0)+
      Тонко ;)

      P.S. А нули надо было в двоичном или в десятичном представлении? Тут чел походу понял, что в двоичном...
      Ответить
      • Мой вариант:
        http://liveworkspace.org/code/MTM2MT$12
        #include <iostream>
        #include <bitset>
        #include <assert.h>
        using namespace std;
        int main() {
           long long v;
           std::cin >> v;
           const std::bitset<5> s(~v);
           cout<<s.count()<<endl;   
           return 0;
        }
        Ответить
        • зачем <assert.h>?
          Ответить
        • Читерство! Реализуй свой битсэт.
          Ответить
          • > Читерство!
            Все по стандарту.

            > Реализуй свой битсэт.
            Я не велосипедист.
            Ответить
        • http://ideone.com/2miM4W

          Неоптимальный, но простой алгоритм на сишке. Строк столько же.
          Ответить
          • Мне тоже нужно было вместо ~v написать что-то типа ~(v and 0xf+0xf+1)
            Ответить
            • Кстати, есть идеи, как не вводя цикл или рекурсию (то есть за О(1)), посчитать то самое 0xf+0xf+1 из поста выше, как зависимость от N==5?
              Для тех кто не понял 0xf+0xf+1 == N == 5 первых битов установлены в единицу, а остальные 0 == 0b11111.
              Ответить
              • Тривиально ~(~(0U) << N)
                Ответить
                • А это пашет для нуля, но не пашет для 32 (вместо всех единичек выдает ноль).
                  Ответить
                  • roman-kashitsyn
                    bormand
                    Тривиально. Фейспалм мне. :/
                    Ответить
                    • Не так уж тривиально, судя по дискуссии ниже. Фейспалм всем нам, такое простое битоебство так долго приводили в соответствие стандарту.
                      Ответить
              • Навскидку: 0xFFFFFFFF >> 32-N (для нуля не пашет).
                Ответить
                • А для нуля почему не пашет?
                  Имхо норм:
                  http://liveworkspace.org/code/MjEzMz$8
                  Ответить
                  • У них походу 64 битная ось, у меня на 32хбитке 0xFFFFFFFFu << 32 выдает 0xFFFFFFFF.

                    При этом gcc пишет:
                    1.cpp:8:38: предупреждение: величина сдвига вправо больше или равна ширине данного типа [по умолчанию включена]

                    Ой не зря я всегда боялся двигать больше чем на N-1 бит...

                    P.P.S. Вижуалка на 32хбитной платформе у друга выдает тож самое. Вот сишкоблядство то, даже сдвиги забагованы. (Жаль, что тут нет Тараса).
                    Ответить
                    • The behavior is undefined if the right operand is negative, or
                      greater than or equal to the length in bits of the promoted left operand.
                      Ответить
              • Есть. И даже реализация.
                Но тебе я не скажу. На хацкиле лиспе битоёбство не в почёте.
                Так что юзай табличку 255 значений.
                Ответить
                • > Так что юзай табличку 255 значений.
                  256битные числа? омг
                  Ответить
                  • Чего?
                    Или я не понял постановку задачи или вам непонятен вариант с таблицей.
                    Количество нулей или единиц для байта - не больше 8, это 3-х битные числа.
                    Ответить
                    • А, вы про основную задачу... для нее согласен, можно бить на байты, да смотреть по табличке. А я то писал про то как по N=5 получить 0x1F, где вполне хватит таблички на 32 элемента для 32х битных чисел.

                      UPD: Ну и кстати - на 256 значений, чтобы не делать ноль отдельным случаем.
                      Ответить
                      • > std::cout << std::count(s.begin(), s.end(), '0') << std::endl;
                        Typical Goomno way.
                        >std::bitset<5> s(~v).count()
                        linq-style

                        Пиздец. Вот собственно обыдление во всей красе.
                        >Ну и кстати - на 256 значений
                        Само собой. Очепятка.
                        Ответить
                        • > std::bitset<5> s(~v).count()
                          > linq-style
                          Это не скомпилируется.
                          Может если так только:
                          std::bitset<5>(~v).count()
                          Ответить
              • чем не катит классический вариант с (1 << N) - 1?

                edit: даже с учетом коммента @bormand про 32-битный гцц:
                http://ideone.com/EnkgNe
                Ответить
                • При N=32 не пашет ;)

                  Беру свои слова обратно. Все ок. Но хотя при N=32 на 32хбитной платформе это все равно UB.
                  Ответить
                  • а, ну ты сам отписался :)
                    Ответить
                    • Да ёбаное крестоблядство! Пишу пример тупо при 32 - все работает, возвращает 0xFFFFFFFFu, пишу пример с циклом от 0 до 32 - при 32 выдает 0. UB такой UB.
                      Ответить
                      • оптимизатороблядство
                        Ответить
                      • >0xFFFFFFFFu
                        Вот именно. Суть С++.
                        Ответить
                        • Лови жабу: https://ideone.com/RtvF6m
                          Ответить
                          • есть подозрение, что это такая фича проца
                            потому что гцц при 1 << 32 не затрудняется сразу подставить результат, а при 1 << N делает sall, который при 32 выдает тупо то, что мы видим
                            Ответить
                            • Да, именно так. Открыл главу про SAL в трехтомнике Intel Architecture, и прочитал там вот такую фразу: The count is masked to 5 bits, which limits the count range to 0 to 31.

                              P.S. Но из-за того, что на тех же ARM'ах все может быть совсем не так, это самый настоящий UB.

                              P.P.S. ARM: You can specify a shift with an immediate value (from zero to thirty one), or by a register which contains a value between zero and thirty one.
                              Ответить
                          • Так а в чем UB? Что жаба не так делает?
                            Оно походу сдвигает на число по модулю 32.
                            (1 << 32) ==1
                            (1 << 33) ==2
                            https://ideone.com/1wT12n
                            Ждем Тараса...
                            Ответить
                            • Да, в спеке жабы все нормально, не то что в крестах:
                              If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are used as the shift distance.

                              If the promoted type of the left-hand operand is long, then only the six lowest-
                              order bits of the right-hand operand are used as the shift distance.
                              Ответить
                              • Ну и там можно в грабли вступить. Правда надо постараться.
                                Может вылезти при расширении типа портировании кода с intов на long.
                                https://ideone.com/PhS98F
                                Различие с С++: там ты дополнительно стреляешь себе в ногу, которая уже застряла в граблях.
                                Ответить
                                • > ногу, которая уже застряла в граблях
                                  Наверное, я совершенно не понимаю сути грабель...
                                  Ответить
                • > http://ideone.com/EnkgNe
                  Ну-ну. UB вносит раздор в наши ряды:
                  http://ideone.com/MQncr8
                  Ответить
                • Убрал UB: i ? (2 << i-1) - 1 : 0)

                  http://ideone.com/RBDiV8

                  И в жабе помогло:
                  https://ideone.com/XMbbGk
                  Ответить
                  • Типы констант может ещё указать литералами (например ul) для надежности?
                    Ответить
                    • i ? (2ul << i-1) - 1ul : 0ul)
                      Ну вот так разве что.

                      А вообще ООП'а стайл:
                      class IShifter {
                          virtual uint32_t shift(uint32_t value, int amount) = 0;
                          virtual ~IShifter() {}
                      };
                      class LeftShifter : public IShifter {
                          uint32_t shift(uint32_t value, int amount) {
                              if (value >= 32)
                                  return 0;
                              if (value <= -32)
                                  return 0;
                              if (value < 0)
                                  return value >> (-amount);
                              return value << amount;
                          }
                      };
                      Ответить
    • YOBA?
      Ответить
    • но ведь быстро работает!
      Ответить
    • вы тут вообще о чем б"я :D
      Ответить
    • http://ideone.com/xJQjkA
      Новый вариант. Оттуда же.
      Похоже пока не удалось.
      int main(void)
      {
              int n;
              scanf("%d ", &n);
              printf("%d\n", !(n%10) + !(n/10%10) + !(n/100%10) + !(n/1000%10));
              return 1488;
      }
      Ответить
      • Теперь цифры десятичные... Кстати, а ведущие нули считать то нужно? А то может быть надо подсчитать только значащие?
        while (a) {
            if (!(a % 10))
                zeros++;
            a /= 10;
        }
        Ответить
        • Не знаю. Уже вышел с экзамена. Там каждому своё задание, но похожее. В разных системах счисления и с прочими разными мелкими особенностями. Кстати, мой вариант с stl не приняли. А в конце, когда я переделал, сказали, что: "Ты пытался обмануть преподавателя, поэтому ставлю на 2 балла меньше".
          Ответить
          • А так это я просто сейчас от нечего делать некоторые задания после экзамена собираю с компов, пока никто не видит и "особо одаренные" постю на гк.
            Ответить
        • Щас мой развратный разум даст тут всем жозу!!!
          char buff[7];
          int nulls = 0;
          sprintf(buff,"%i",somenumber)
          while(buff)
          {
               nulls+=(int)(buff=='0');
                *buff++;
          }
          Ответить
          • Код не скомпилится:
            1) массив не указатель, его нельзя плюсплюсить
            2) нахуя звезда в предпоследней строке, ее результат не используется
            3) где звезда в while(buff) и buff == '0'

            Код имеет следующие проблемы:
            1) Что если число десятизначное (int на 32 битной платфоме)
            2) Без звезды while(buff) является вечным циклом
            Ответить
            • Действительно со звездочками джигурда - лажанул.
              Ответить
    • http://2ch.hk/pr/res/224591.html
      Ответить
    • Ребят. Я тут обдумал своё поведение. Я не прав. Я пессимист. Вижу только черное, а ведь в каждом языке есть много прекрасного. Почему я из него вижу только говно и пощу суда? Свинья везде говно найдёт, даже в самом прекрасном языке. Я не должен закрывать глаза на позитив и постить и хорошее тоже. Ребят, напоминайте мне об этом почаще.
      Ответить
      • >Свинья везде говно найдёт
        Гумно везде говно найдёт.
        >Почему я из него вижу только говно и пощу суда?
        Почему я всё говно что вижу сразу копипащу суда?
        [fixed]
        Ответить
        • Оказывается есть подходящая к ситуации паста: http://lurkmore.to/%D0%9A%D0%BE%D0%BF%D0%B8%D0%BF%D0%B0%D1%81%D1%82%D0%B0:%D0%92%D0%BE%D0%B2%D0%B0%D0%BD #.D0.93.D0.BE.D0.B2.D0.BD.D0.BE.D0.BA.D0.BE.D0.B4
          Ответить
          • Ух ты, лурк?! №4117
            Ответить
          • >lurkmore.to
            Я вас реально уважаю, ребят. Пожалуйста не давайте ссылки на такие сомнительные источники информации.
            Ответить

    Добавить комментарий