1. Куча / Говнокод #26489

    +5

    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
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    .
                                    Т Е С Т
    
    
                 К А К О Й     В Ы    П Р О Г Р А М М И С Т ?
    
    
                       Источник: Datamation, march, 1977
              Norman Grabowsky "What kind of programmer are you?"
    
    
         Этот тест расскажет о вашем программировании больше,  чем  вы  сами
    хотели бы знать.
    
         Переменная  I  представляет  собой  полное  слово  с  фиксированной
    точкой. I принимает значения 1  либо  2.  Если  I  оказалось  равным  1,
    замените его на 2 и наоборот.
         Сравните ваше решение с десятью  предложенными.  Найдите  одно  или
    несколько  наиболее  похожих  на ваше и прочитайте в разделе "категории"
    краткую характеристику. Вы можете кодировать  на  любом  языке,  но  для
    сравнения предпочтительнее всего использовать PL/1.
    
    
                        Р е ш е н и я.
    
    1.           IF I='2' THEN I=1;
                 ELSE I=2;
    
    2.           IF I=2 THEN I=1;
                 IF I=1 THEN I=2;
    
    3.           IF I=1 THEN GOTO SKIP;
                 I=1;
                 GOTO DONE;
        SKIP:    I=2;
        DONE:
    
    4.           J=2;
                 IF I=2 THEN J=1;
                 I=J;
    
    5.           DECLARE SWITCH LABEL;
                 .  .  .
                 IF I=1 THEN SWITCH=ONE;
                 IF I=2 THEN SWITCH=TWO;
                 GOTO SWITCH;
        ONE:     I=2;
                 GOTO DONE;
        TWO:     I=1;
        DONE:
    
    6.           DECLARE ONETWO(2) FIXED BIN(31) INIT (2,1);
                 .  .  .
                 I=ONETWO(I);
    
    7.           I=3-I;
    
    8.           I=I-(I/2*2)+1;
    
    9.           IF I=2
                       THEN DO;
                            I=1;
                       END;
                       ELSE DO;
                            I=2;
                       END;
    
    10.          IF I=1 THEN I=2;
                 IF I^=2 THEN DO;
                   PUT LIST('ПЛOXOE  I - ЗAMEHEHO HA 1');
                        I=1;
                   END;

    https://www.cs.bgu.ac.il/~barnshte/CompHumor/texts/TEST.koi

    Запостил: j123123, 11 Марта 2020

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

    • .
                               Т Е С Т
      
                          К А Т Е Г О Р И И
      
           1. Недавний выпускник школы IBM.
           Не  более одного из десяти окончивших эту школу знают разницу между
      2 и "2". Удивительно, как можно вообще программировать без знания  столь
      фундаментальной концепции.
      
           2. Преподаватель программирования.
           Это  решение  хуже  предыдущего.  Много   ли,   однако,   обучающих
      программированию сами написали и отладили хотя бы одну программу?
      
           3. Программист на FORTRAN'е, только что окончивший курс PL/1.
           Да, старую собаку не научишь новым штукам! Это решение дает  верный
      результат, но это все, что можно про него сказать.
      
           4. Программист на ассемблере, прошедший тот же курс.
           Это решение не является ни прямым  ни  эффективным.  Возможно,  это
      результат  обучения  языку  PL/1.  В  нем  есть  та прелесть, что оно не
      содержит самомодифицирующих кодов, но это  лишь  результат  возврата  на
      землю после изучения языка высокого уровня.
      
           5. Системный аналитик.
           Прекрасная  иллюстрация  для  тех,  кто  думает,  что   обязанность
      системного  аналитика  -  такая разработка алгоритма, в которой окажется
      некомпетентен даже хороший и опытный программист.
      Ответить
      • .
             6. Сomputer Scientist.
             Наверное,  это  самое  умное решение. Однако такие "сальто-мортали"
        без  комментариев  оказываются  весьма  непонятными.  Искусство  требует
        жертв,  а  жертвой  будет  тот, кто разбирается в этой программе - может
        быть, сам автор через три месяца.
        
             7. Математик.
             Очень  похоже  на  предыдущее,  столь  же  элегантно, но опять-таки
        встает проблема: как же в нем разобраться?
        
             8. Программист, заботящийся о секретности своей программы.
             Вот работа настоящего композитора, и конечно, никаких комментариев.
        "Я могла бы придумать и более запутанный способ, как это  сделать,  -  с
        гордостью сказала белая королева".
        
             9. Структурный программист.
             Каждому ясно, что сие произведение - структурная программа.  Иногда
        заботятся  только  о  том, сколько колонок надо отступить от края листа.
        Настоящее структурное программирование - это  прежде  всего  техника,  и
        применять ее надо с умом.
        
             10. Хороший программист.
             Заметьте, что ни одно из решений 1-9 не проверяло диапазон значений
        I,  а это весьма опасно. К несчастью, вас не спасут ни структурность, ни
        фантастические алгоритмы, ни элегантность решения, если вдруг  окажется,
        что I первоначально не было равно ни единице ни двойке.
        Ответить
        • > не проверяло диапазон

          11. Крестоблядь

          Зачем? В условии не сказано, что делать для других чисел. Поэтому будем считать, что поведение программы не определено.
          Ответить
          • Подтверждаю.
            Явно писать в условии, что «I принимает значения 1 либо 2», а потом ругать решения за то, что они не проверяют другие числа — долбоебизм.
            Ответить
        • Кстати, "хорошее" решение не меняет 2 на 1.

          Какой тест )))
          Ответить
          • Вероятно, автор
            > Преподаватель программирования.
            > Это решение хуже предыдущего. Много ли, однако, обучающих программированию сами написали и отладили хотя бы одну программу?
            Ответить
          • > Кстати, "хорошее" решение не меняет 2 на 1.

            Там просто ТЗ нечеткое. Написано:

            > Переменная I представляет собой полное слово с фиксированной точкой. I принимает значения 1 либо 2. Если I оказалось равным 1, замените его на 2 и наоборот.

            Что значит "наоборот"? Может "наоборот" значит что можно вообще ничего не заменять и оставить всё как есть, если I оказалось не равным 1?
            Ответить
    • Именно поэтому я за «Python».
      I = (42, 2, 1)[i]
      Ответить
      • Очень интересная хуйня. В квадратных скобочках у меня стоит большая «I», а ГК упорно переделывает её в маленькую.

        Какого хера?
        Ответить
        • Ньюфаги не могут в [I].
          Ответить
          • Ну-ка…
            [‎I]
            Ответить
            • Читер! У Борманда больше код скомпилится после копипаста.
              Ответить
              • Ответить
                • Ньюфаги не могут в пустые комментарии.
                  Ответить
                  • Ньюфаги не умеют в комментарии из пробелов >2K символов и в жирный ноль. Вот с точки зрения жирного нуля я полный ньюфаг. Я не могу ‍0 честно написать.
                    Ответить
                    • Жирный ноль "" это самый сложный тест. Его вроде нереально без невидимых пробелов сделать.
                      Ответить
                    • +0 математически эквивалентно.

                      -0
                      Ответить
                      • ߀
                        Ответить
                        • Кстати, «Python» этот ноль понимает. Именно поэтому я за «Python».
                          >>> int('߀')
                          0
                          Ответить
                          • Похоже, это какая-то питушня с копипастеньем из браузера (как у ньюфагов, которые не могли в трифорс).
                            Я копирую в консольку хрома даже из исходного кода страницы, а там сначала
                            '<b>0</b>'.length // 8

                            а потом
                            '>0<'.length // 3
                            Ответить
                            • Ничего не понял. Это какой ноль?
                              Ответить
                              • Это Ваш жирный ноль с этой страницы в её исходнике, открытом через view-source: в браузере.

                                P.S. "потом" происходит после того, как я вручную удаляю символы, т.к. умею считать только до трёх, и длина 8 мне не говорит о том, есть ли дополнительный символ, или нет.
                                Ответить
                                • Очень странно. Вообще-то это юникодный ноль, и у меня он копируется как надо:
                                  >>> '߀'.encode('utf-8')
                                  b'\xdf\x80'
                                  Ответить
                                  • А, действительно юникодный. Но он жирный, поэтому вокруг него <b></b>. Я копировал с ними, чтобы захватить возможные символы по краям.

                                    Теперь всё ясно. 8 и 3 вместо 9 и 4 - из-за того, что ноль сам специальный, и нет подвохов с утерей спецушни.

                                    А вот мой ноль обычный, поэтому психоза вокруг него присутствует и копируется.
                                    Ответить
                      • 00
                        Ответить
            • Коварная юникодушня. Когда я вставляю её в ко-ко-консоль хрома, у меня визуально выходит так:
              > '[•I]'
              < '[I]'
              Ответить
              • А мне пишет «Uncaught SyntaxError: Invalid or unexpected token». Странно.
                Ответить
                • Я написал в кавычках, чтобы JS подумал, что это в переносном смысле и не ругался.
                  Ответить
          • Лайфхак для ньюфагов: вместо [I] можно использовать [l].
            Ответить
          • test [I] [i]
            Ответить
      • I = (42, 2, 1)[i]
        Ответить
      • >I = (42, 2, 1)[i]
        кАКОЙ ПИТУХ )))
        І = (2, 1)[І-1]


        Реально табличное решение — это вореции п.6.
        Ответить
        • > I-1
          Ну а как понять, что этот код решает задачу "если I оказалось равным 1, замените его на 2 и наоборот." ?
          Это тупо "вычли I1 из 3I и присвоили в I использовали его для индексирования" - хуй знает что это и зачем это надо
          Ответить
    • А где же i ^= 3?
      Ответить
    • >>> I=3-I;
      >>> но опять-таки встает проблема: как же в нем разобраться?
      Чот какая-то питушня.
      Ответить
      • Ну а как понять, что этот код решает задачу "если I оказалось равным 1, замените его на 2 и наоборот." ?
        Это тупо "вычли I из 3 и присвоили в I" - хуй знает что это и зачем это надо
        Ответить
        • Ну да, это переворот отрезка от 0 до 3.
          Ответить
        • >Это тупо "вычли I из 3 и присвоили в I" - хуй знает что это и зачем это надо

          Я о вас был лучшего мнения. Это же классическая битушня.
          К тому же вычитание — слишком дорогая операция.
          А сумматоры нынче в цене.

          I^=3;
          Ответить
          • > слишком дорогая операция

            Ну да, распространение переноса совсем не бесплатное. А у xor'а все биты параллелятся.
            Ответить
    • uint32_t test(const uint32_t i)
      {
        if ( i != 1 && i != 2)
        {
          fprintf(stderr, "Fatal error, variable \"i\" in file \"%s\" in function \"%s\" is out of range\n", __FILE__, __FUNCTION__);
          fprintf(stderr, "\"i\" must be 1 or 2 but we got %" PRIu32 "\n", i);
          exit(EXIT_FAILURE);
        }
        static const uint32_t arr[2] = {2,1};
        return arr[i-1];
      }
      Ответить
      • Какой синьор си девелопер )))
        Ответить
        • А мне кажется, сова питушок.
          Стоило бы было бы проверить домен там, где данные приходят от питользователя или апитушка, а в отдельную функцию вынести только бизнес-логику и assert.
          Ответить
          • Ну ничего, это поправимо:


            uint32_t test(const uint32_t i)
            {
            
            #ifdef RUNTIME_ASSERTS
              if ( i != 1 && i != 2)
              {
                fprintf(stderr, "Fatal error, variable \"i\" in file \"%s\" in function \"%s\" is out of range\n", __FILE__, __FUNCTION__);
                fprintf(stderr, "\"i\" must be 1 or 2 but we got %" PRIu32 "\n", i);
                exit(EXIT_FAILURE);
              }
            #endif
            
              static const uint32_t arr[2] = {2,1};
              return arr[i-1];
            }
            Ответить
        • template <typename T>
          T test(std::enable_if<std::is_arithmetic<T>::value, T>::type i)
          {
              if ((i != 1) || (i != 2))
                  throw std::runtime_error("... лень писать ...");
              return i == 1 ? 2 : 1;
          }
          Ответить
          • > if ((i != 1) || (i != 2))

            У вас баг
            Ответить
            • Бля :(
              Ответить
            • З.Ы. Это не баг, это фича. Этот код работает для таких T, у которых 1 == 2.
              Ответить
              • А, ну да, там «==» перегружено может быть.
                Что ж это за такая особая арифметика, где она применяется?
                Ответить
                • Арифметика многопоточности.
                  Для отладки редко проявляющихся багов создаются переменные такого типа.
                  Ответить
      • >зтатiс сопзт иiпт32_т агг[2] = {Z,1};
        >гётигп агг[i-l]

        Чем обычное З^I не зашло?
        Ответить
        • > Чем обычное З^I не зашло?

          Это слишком частное решение. Завтра заказчик может поменять ТЗ и захотеть чтоб если i равно 3 то тогда менялось на 7, если i равно 2 то тогда менялось на 5, если i равно 1 то тогда менялось на 100500 - тогда весь код с xor-ом надо будет полностью выкинуть, а в моем решении придется лишь слегка поменять правило в ассерте и изменить таблицу поиска.
          Ответить
          • Но мы же за пирфоманс и простоту.

            >Завтра заказчик может поменять ТЗ и захотеть чтоб если i равно 3 то тогда менялось на "3" , если i равно 2 то тогда менялось на белочку, если i равно 1 то тогда менялось на 7 красных линий, некоторые нужно нарисовать зеленым цветом, а еще некоторые — прозрачным.

            >Тогда весь код с таблицей надо будет полностью выкинуть
            Ответить
            • Но на самом деле никто не гарантирует, что xor будет быстрее. Настоящий царь будет делать бенчмарки вариантов с ксором, вычитанием, таблицей, условным переходом (и возможно еще каких-то вариантов, например некоторые процессоры умеют делать условный мув CMOVcc https://www.felixcloutier.com/x86/cmovcc ) и выберет самый оптимальный вариант. Возможно даже напишет на ассемблере, если анскилушный компилятор неосилит сделать наиболее оптимально
              Ответить
            • >Завтра заказчик может поменять ТЗ и захотеть чтоб если i равно 3 то тогда менялось на "3" , если i равно 2 то тогда менялось на белочку, если i равно 1 то тогда менялось на 7 красных линий, некоторые нужно нарисовать зеленым цветом, а еще некоторые — прозрачным.

              Ну тут же очевидно. Надо тогда таблицу заменить на массив из указателей на функции, вторая функция меняет на "3", первая меняет на белочку, нулевая меняет на 7 красных линий, некоторые нужно нарисовать зеленым цветом, а еще некоторые — прозрачным. Так что код с таблицей надо будет только слегка поменять
              Ответить
              • >Надо тогда таблицу заменить на массив из указателей на функции

                Оверхедная питушня.
                Пример: расширить программу чтобы нечетные значения удваивались, а чётные декрементились.

                Решение с таблицей лажает.

                Подгадывать, под то что «завтра захочет заказчик» — безблагодатно. Нужно выбирать простейшее решение.
                Ответить
                • Для максимального пирфоманса предлагаю написать SSE версию
                  Ответить
    • Номер три напоминает листинг "программ" из EXAPUNKS.
      Ответить
    • -- для остальных чисел будет runtime error
      -- именно поэтому я за хаски
      test 1 = 2
      test 2 = 1
      Ответить
    • #!/usr/bin/env python3
      import logging
      from typing import TypeVar, Sequence, Generic
      
      
      T = TypeVar('T')
      
      
      class ValidationError(BaseException):
          def __init__(self, *args, **kwargs):
              super().__init__(*args, **kwargs)
      
      
      class AbstractValidator(Generic[T]):
          def validate(self, value: T) -> bool:
              raise NotImplementedError
      
      
      class ExactValueValidator(AbstractValidator[T]):
          def __init__(self, valid_value: T):
              self._valid_value: T = valid_value
             
          def validate(self, value: T) -> bool:
              if value != self._valid_value:
                  raise ValidationError
              else:
                  return True
      
      
      class SequenceValidator(AbstractValidator[T]):
          def __init__(self, valid_values: Sequence[T]):
              self._valid_values = set(valid_values)
              
          def validate(self, value: T) -> bool:
              if value not in self._valid_values:
                  raise ValidationError
              else:
                  return True
      
      
      def test(i: int) -> int:
          validator = SequenceValidator((1, 2))
          try:
              validator.validate(i)
          except ValidationError:
              logging.error('test() validation error')
              raise ValueError
          
          return {1: 2, 2: 1}[i]
      
      
      def main():
          print(test(1))
          print(test(2))
          print(test(3))
      
      
      if __name__ == '__main__':
          main()
      Ответить
      • Какая валидация)))
        Ответить
      • Нерасширяемо. Где фабрики, где dependency injection...
        Ответить
      • Бля, я забыл. В SequenceValidator должны были создаваться ExactValueValidator на каждое значение в valid_values.
        Ответить
        • Во:
          class SequenceValidator(AbstractValidator[T]):
              def __init__(self, valid_values: Sequence[T]):
                  self._exact_value_validators = [
                      ExactValueValidator(value)
                      for value
                      in valid_values
                  ]
                  
              def validate(self, value: T) -> bool:
                  validation_results: List[bool] = []
                  for validator in self._exact_value_validators:
                      try:
                          validator.validate(value)
                          validation_results.append(True)
                      except ValidationError:
                          validation_results.append(False)
                  if not any(validation_results):
                      raise ValidationError
                  else:
                      return True
          Ответить
          • Кстати, а эти аннотации типов реально работают? Или их для красоты пишут?
            Ответить
            • Их только внешние тайп-чекеры вроде «mypy», «pyright» и встроенных в IDE проверяют. В рантайме доступ к этим аннотациям есть (причём его кардинально меняют с каждой новой версией, лол), но пока что при выполнении они полностью игнорируются.
              Ответить
            • Интересно, с такими возможностями же можно добавить аннотациушню, которая добавит перегрузку питушни и проверку типов. Можно будет добиться аналога специализации шаблонов как в C++ и вывода типов как в хаскеле.
              Ответить
              • Да можно, наверное. Даже в лиспе умели по аннотациям проверять типы и оптимизировать код...
                Ответить
    • Тест хороший. И тред хороший.
      Но все решения, признаться — скучное говно, без фантазии.

      Потому я представляю вам:
      #include <stdio.h>
      
      typedef struct{
          unsigned v : 1;
      } ONETWO;
      
      int get(ONETWO x){
      	return x.v+1;
      }
      int main(void) {
      	ONETWO x={0};
      	
      	printf("%d\n",get(x));
      	x.v++;
      	printf("%d\n",get(x));
      	x.v++;	
      	printf("%d\n",get(x));	
      	x.v++;	
      	printf("%d\n",get(x));		
      	return 0;
      }
      https://ideone.com/gl49UO
      Ответить
      • 12. Царь. 
        
                Вы устало берёте Сишку, и привычно сливаете анскильное отребье в хламину. 
        Поскольку только биомусор использует больше одного бита для хранения двух значений.
        
        Сишка валяет в говне эти потуги. Никаких проверок диапазона значений тут нет, 
        но они и не нужны. Недоязычки могут только так. Тут мы замечаем то, что дизайн
        большинства языков — бездарное говно и скриптуха.
        Ответить
    • Блять. Какое же Пассаль говнище редкостное.
      Не зря он меня ещё в универе от него страшно тошнило.
      В отличие от Сишки и асма, которые ещё тогда мне нравились.

      Type
        ONETWO = 1 .. 2;
      var I: ONETWO;
      	I:=1;
      	I:=I+1; //2
      	I:=1+I; //3
      	inc(I);  //4
      	inc(I); //5

      https://ideone.com/mtmPPq
      Если ещё увижу пассаль-сектанта, блеющего об охуенно развитой типизации этой дырявой вербозной недосишки, мгновенно солью мразотное животное.
      Ответить
      • USE $R+, Luke!

        https://ideone.com/hJUQXe

        На строчке, где должно вывести 3, падает с ошибкой 201.

        Режим $R+ не стали включать по умолчанию из-за сишников, которые ноют, что проверки снижают пирфоманс.
        Ответить
    • I+=(1&I)-(I>>1)
      Просто и понятно.
      Ответить
      • Побочным полезным эффектом кода является то, что он либо не меняет входные значения (0 и 3).
        Либо через несколько итераций сводит большинство входных значений I к искомым 1 и 2.

        PS. Хотя блин, похоже на случай №8.
        Ответить
        • Да, №8 идеален:
          I+=1-(I&~1)
          Разве что это работает во всякой скриптухе.
          Ответить
          • Сложно. Без ста граммов не разобраться, как это работает.
            Ответить
            • I & ~1 зануляет младший бит. Т.е. для чётных чисел формула раскрывается в I = I + 1 - I = 1. А для нечётных в I = I + 1 - (I - 1) = 2.
              Ответить
          • Зачем? Зачем? I - I/2*2 это же просто взятие младшего бита, если деление округляет вниз.
            Ответить
      • I = (I & 1) + 1
        Ответить
      • #define SHIFT 1
        #define BITNUM 2
        
        I = (I << SHIFT) | (I >> (BITNUM - SHIFT));

        Циклический сдвиг влево (на самом деле похрен куда, учитывая что два бита всего)
        Ответить
        • I = 2
          I = (2 << 1) | (2 >> (2 - 1)) = 4 | 1 = 5

          Хуйня какая-то. Надо &3 добавить, наверное.
          Ответить
          • Битфилды лучше
            #define SHIFT 1
            #define BITNUM 2
            
            typedef struct{
                unsigned v : BITNUM;
            } ONETWO;
            
            ONETWO I;
            I.v = (I.v << SHIFT) | (I.v >> (BITNUM - SHIFT));
            Ответить
            • Битфилды одна из самых любимых мною фич сишки.
              Не проще ли тогда сделать
              union{
                struct{
                    unsigned a : 1;
                    unsigned b : 1;
                } s
                int val;
              } I;
              
              std::swap(I.s.a,I.s.b);
              Ответить
              • Ссылки на битушню же не пашут, как и указатели...
                Ответить
                • Так точно!
                  error: cannot bind bitfield 'I.main()::<unnamed union>::s.main()::<unnamed union>::<unnamed struct>::a' to 'unsigned int&'

                  Крестоговно опять обосралось
                  Ответить
                  • Ещё один аргумент в пользу божественной Сишки.

                    Боже Царя храни!
                    Ответить
                • https://wandbox.org/permlink/EzRvPaljXOwlVelh

                  #include <stdio.h>
                  #include <stdlib.h>
                  
                  #define XORSWAP_UNSAFE(a, b)                                                   \
                    ((a) ^= (b), (b) ^= (a),                                                     \
                     (a) ^= (b))
                  
                  #define XORSWAP(a, b)                                                         \
                    ((&(a) == &(b)) ? (a) /* Check for distinct addresses */                    \
                                    : XORSWAP_UNSAFE(a, b))
                  
                  int main()
                  {
                  
                      union{
                      struct{
                          unsigned a : 1;
                          unsigned b : 1;
                      } s;
                      int val;
                    } I;
                    I.val = 2;
                    XORSWAP_UNSAFE(I.s.a,I.s.b);
                    printf("%d ", I.val);
                    XORSWAP_UNSAFE(I.s.a,I.s.b);
                    printf("%d ", I.val);
                    XORSWAP_UNSAFE(I.s.a,I.s.b);
                    printf("%d ", I.val);
                    printf("\n");
                    return EXIT_SUCCESS;
                  }


                  Поэтому я за Си
                  Ответить

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