1. Pascal / Говнокод #27889

    −8

    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
    Program print_numbers_twice;
    
    Procedure give(p: pptrint);
    begin
    	if pptrint(p^) <> nil then begin
    		give(pptrint(p^));
    		writeln((p-1)^)
    	end
    end;
    
    Procedure take;
    var n: ptrint;
    begin
    	if not SeekEof then begin
    		read(n);
    		take
    	end else begin
    		n := (pptrint(@n)+1)^;
    		give(pptrint(n));
    		give(pptrint(n))
    	end
    end;
    
    Begin
    	take
    End.

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

    Очень простая и короткая программа. Я думаю, вам не составит труда понять, как она работает. Пишите в комментариях!

    Запостил: Threadwalker, 22 Декабря 2021

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

    • Тип pptrint не описан.
      Ответить
      • P.S. В библиотеке Фрипескаря описан, оказывается:
        type
         PtrInt = LongInt;
         PPtrInt = ^PtrInt


        Целое размером с указатель, как ptrdiff_t в сишном <stddef.h>
        Ответить
      • Это встроенный в язык тип, вот: https://www.freepascal.org/docs-html/current/rtl/system/pptrint.html

        В общем, это знаковое целое того же размера, что и указатель на текущей системе. Можешь сам прописать.
        Ответить
        • А как используется тот факт, что ptrint хранит число, в которое может поместиться указатель? Или он используется без семантики, просто как первый подвернувшийся под руку целочисленный?
          Ответить
    • Тарас бы за такое форматирование в щи с вертушки прописал.
      Ответить
    • Так что, никто так и не понял, как это работает?
      Ответить
      • Переведи на «PHP».
        Ответить
      • Ну что, никто не знает?
        Ответить
        • мужики, не обижайтесь, но я забыл в чем косяк.
          Ответить
      • Переведи на <<"Erlang">>.
        Ответить
      • Переведи на «Си»
        Ответить
      • Боюсь, что придётся смотреть ассемблерный листинг, чтобы понять.

        Вот тут пахнет:
        n := (pptrint(@n)+1)^;


        Набиваем стек, а потом его затираем введённым с консоли значением.
        Ответить
        • Ну хоть один комментарий по делу. Но тут происходит присваивние локальной переменной n, так что ничего страшного нет и ничего не ломается. Вся запись происходит только в локальную переменную процедуры, а это допустимо.
          Ответить
        • Ну или хотя бы как устроена конвенция вызовов функций. Кажется, он там проходит по цепочке сохраненных BP... а так - да, ничего страшного. Всегда так делаю.
          Ответить
          • > цепочке BP

            Именно поэтому я за FPO, чтобы у царей не было желания шариться по стеку.
            Ответить
            • Отменили уже твой FPO. Регистров уже никому не жаль (чай не под 486 пишем) а раскручивать стеки без символов иногда нужно, чтобы хотябы понять в каком районе обосралось примерно.

              Теперь все собрано с указателем рамки
              Ответить
              • > Отменили уже твой FPO
                Какая cancel culture.
                Ответить
              • > отменили

                Пруф?
                Ответить
                • Я читал в the old new thing, что начиная с Vista MS собирает свои продукты с фрейм поинтером, потому что экономить BP уже не актуально.

                  Ты ведь можешь сам это проверить как-то взяв MSную dllку?
                  Ответить
                  • А теперь сходи и отключи его сам для своих виндовых дллок под х64, собранных в msvc...
                    Ответить
                    • ой, за x64 не скажу, там может всё иначе быть
                      А нахуй он там? Там же регистров как у дурака фантиков
                      Ответить
                      • х64 соглашения заточены на пирфоманс, всё через регистры.

                        А тут писать на стек сраный rbp, который кроме отладчика (без символов) да аллоки никто не юзает. Вот и выбросили.
                        Ответить
                        • 1. BP нужно сохранять, без него хуй адресуешь локальные переменные.
                          2. Мы научилось адресовать их от SP, BP заюзаем под что-то другое
                          3. У нас стало больше регистров, давайте опять юзать BP
                          4. Зачем нам BP? Давайте от него откажаемся
                          [вы находитесь здесь]

                          Алсо, если я пишу асм руками, то наверное я хочу frame pointer, иначе отступы будут неочивидны? Или современные асмы все за меня посчитают?
                          Ответить
                          • Я руками с фреймпоинтером пишу, так проще.

                            Возможно какой-нибудь fasm и умеет об rsp считать... Но маловероятно т.к. ему придётся понимать инструкции, а не тупо их конпелять.
                            Ответить
                            • Зато если руками писать без BP, то это заставит тебя сначала все спланировать, потому что спонтанное "ой, а добавлю-ка я переменную еще одну" может превратиться в адскую боль
                              Ответить
                              • > переменную

                                Да хуй с ними, с переменными, они на х64 обычно все в регистрах...

                                Проблема в том, что любой пуш и у тебя rsp поехал.

                                > BP

                                А может я хочу об rdi базироваться? Или об r11.
                                Ответить
                                • Я никогда не писал под x64 руками. Ты прям все-все пельменные в регистрах хранишь? все тридцать штук?

                                  А зачем тогда тебе что-то пушать тогда? Чтобы кольнуть 32х битное говно?

                                  >об rdi
                                  чтобы запутать того, кто будет без символов пытаться стек вызовов понять?
                                  Ответить
                                  • > пушить

                                    Ну например чтобы callee-saved регистр начать юзать.

                                    > зачем

                                    Для самовыражения и уникальности.
                                    Ответить
                                    • >Ну например чтобы callee-saved регистр начать юзать.

                                      а, типа ты папин регистр припрятал, поюзал, и вернул обратно, да?

                                      чото я сразу не сообразил, так же обычно всегда и делали. были даже ПУША и ПОПА для этого.

                                      >Для самовыражения и уникальности.
                                      чувак, ты пишешь на асме в 2021, ты и так уникален
                                      Ответить
                                  • > 32х

                                    16, лол.

                                    З.Ы. И это не шутка.
                                    Ответить
                                    • как ты из 64 вызываешь 16? разве не надо там v86 настраивать (который вроде в лонгмоде не работает)?

                                      или у тебя 16bit protected, как в 286/win3.11?

                                      И зачем? Биосы железок дергать?
                                      Ответить
                                      • Отключаю всё обратно и ухожу в труъ реалмод...

                                        > бивисы

                                        Угу. Легаси-хуегаси.
                                        Ответить
                                        • "перезагрузить компьютер в режиме эмуляции MS-DOS" (c)

                                          Useless fact: в двойках нельзя было вернуться из протектд режима в реальный никак кроме колд ресета. Я у Гука читал.

                                          Но в тройке уже починили
                                          Ответить
                                          • Вроде не колд, а достаточно без очисток памяти, кокойто меджик надо записать по волшебному адресу. Надо было писать label far
                                            Ответить
          • Интересно, а есть гарантия, что в начале будет именно 0?
            Ответить
            • Я не помню соглашение, но наверное да. Иначе дебаггеру будет неудобно. А эти фреймы в основном ему и нужны.
              Ответить
    • Кому надо переводить — сами и переводите.
      Ответить
    • Как же я не люблю структуро-указателеёблю в олимпиадочных прогах!..
      Поубивал бы.
      Ответить
    • - Я люблю программировать.
      - Покажи.
      - ...
      - Ты больной ублюдок.
      Ответить
      • https://3.bp.blogspot.com/-HYckh-ls4eA/Sh3SV6ipJCI/AAAAAAAAALc/WO0kfDfEVq0/w1200-h630-p-k-no-nu/linuxdevelopers.jpg
        Ответить
        • помоему питон уже окончательно заменил перла в амплуа "пламбер ленгвидж" в линуксе
          Ответить
          • К счастью, нет. А те, кто заменил, поплатились:
            https://blogs.gentoo.org/mgorny/2021/11/07/the-future-of-python-build-systems-and-gentoo/
            Ответить
            • P.S. В одной конторе был классный момент с питонопарашниками, которые отлаженные, протестированные в CI и документированные (там network diagram аска-артом была в комментах) m4 кружева для генерации некой конфы решили заменить на пухтон. Мой аргумент был: для простого скрипта вы понатащили пять зависимостей, которые требуют ебли с какими-то ``virtualenv'', ``pip'' и прочей хернёй, если она сломается, вы будете ебаться с ней сами.
              Она конечно же сломалась, и утащила за собой load-balancer'ы в проде. Помогать чинить это говно я конечно им не стала.
              Сисадмин питонист — горе в семье.
              Ответить
              • Потом они спрашивают, почему я за «PHP». Да вот хотя бы поэтому.
                Ответить
                • да-да, только ПХП на CI не хватало
                  Ответить
                  • > ПХП на CI

                    CI на ПХП
                    Ответить
                    • не думаю, что пыхеры могут в CI.

                      Разные культуры развиваются с разной скоростью. У кого-то компьютеры, а у бушменов мезолит.

                      Пыхеры только-только юнит-тесты освоили, лет через двадцать и до CI доберутся
                      Ответить
            • ну как нет, когда уебунта уже от него зависит, а когда я говорю коллегам про перл, то у них такие лица бывают, словно я предложил им пописать на Visual Basic под WinME
              Ответить
    • Как видишь, местное отребье применило свой старый, испытанный прием: пустилось завивать лесенку из оффтопных комментов, чтобы отклонить обсуждение и скрыть за плоскими шуточками ебаный стыд от своей некомпетентности. В мою бытность они тоже так поступали, а потом удивлялись, почему я столь нещадно громлю их оффтопы.
      Ответить
      • Думаешь, никто не понял, как работает?
        Ответить
        • Не отвечай уёбку.
          Ответить
        • ...Либо им просто лень вникать, что ещё хуже.

          Честно говоря, не совсем понятно, почему идет инкремент указателя на единицу; чтобы выполнить условие, когда список уже EOF?
          Ответить
          • Не, спойлерить в комментах не буду. Кто первый догадается, тот и напишет сразу решение.
            Ответить
    • Сломал твою программу, проверь:
      procedure lom(s: string);
      begin
      	writeln(s);
      	take
      end;
      
      Begin
      	lom('lomayu')
      End.
      Ответить
    • В таком виде она должна вывести одно лишнее число, которого не было на входе.
      Ответить
      • А что это за число?
        Ответить
        • 33066031629954054 наверное. Но сам посмотри, я-то что.
          Ответить
          • А что оно значит? Откуда оно взялось?
            Ответить
            • Так я правильно угадал или нет? Я просто не запускал твою версию.

              Если правильно — сам думай, программа на то и написана. Если нет — ну значит я ошибся где-то.
              Ответить
            • Не, на самом деле выводится другое число — это адрес строчки lomayu. Видимо строка передалась в процедуру по ссылке.
              Ответить
    • Блядь, как всё сложно... Неудивительно, что в современности на этом языке больше никто не пишет.
      То ли дело «Python»:
      numbers = []
      try:
          while True:
              numbers.append(int(input()))
      except EOFError:
          pass
      
      
      for i in range(2):
          for num in numbers:
              print(num)
      Ответить
      • Ещё в турбопаскалевском «Turbo Vision» были коллекции (да, там был модуль Objects с невизуальными объектами), а в «Delphi» ещё добавили динамические массивы. Во «Фрипаскале» всё это есть.
        Ответить
      • В паскале тоже так можно, если взять динамический массив — но это будет слишком просто и скучно.
        Ответить
      • Блядь, как всё сложно... Неудивительно, что в современности на этом языке больше никто не пишет.
        То ли дело «Python»:
        import sys
        
        numbers = [int(line) for line in sys.stdin]
        
        for num in numbers * 2:
            print(num)

        Прости, Царь, за дублирование дублирование массива.
        Ответить
        • Да начнётся специальная олимпиада!
          import sys;print(*[*map(int,sys.stdin)]*2,sep='\n')

          Условиям оригинальной задачи первый коммент не соответствует — в нём числа надо вводить по одному на строку, а не через любые пробельные символы — но да ладно, раз уж начали так, то похуй.
          Ответить
          • Да и вообще, нахера нам кастить в инт?
            import sys;print(*[*sys.stdin]*2)
            Ответить
            • Ну не. Пили честный эквивалент через анализ бектрейса.
              Ответить
              • Ну ладно.
                import sys
                import threading
                
                
                def give(frame):
                    if frame is None or frame.f_code.co_name != 'take':
                        return
                
                    give(frame.f_back)
                    print(frame.f_locals['n'])
                
                
                def take():
                    try:
                        n = int(input())
                        take()
                    except EOFError:
                        frame = sys._current_frames()[threading.get_ident()].f_back
                        give(frame)
                        give(frame)
                
                
                def main():
                    take()
                
                
                if __name__ == '__main__':
                    main()
                Ответить
                • Оно же берёт строками, не отдельными символами.
                  Надо ещё split сделать.

                  И зачем в инт переводить?
                  Ответить
                  • > Оно же берёт строками, не отдельными символами.
                    Об этом я в примечании выше написал. Лень ебаться с этими вашими сплитами (надо не просто сплит, а сплит по \s: «Питон» соснул).

                    > И зачем в инт переводить?
                    Для коньсистентности.
                    Ответить
                    • split без параметров как раз по \s и сплитит же?
                      https://ideone.com/b3WFU4
                      Ответить
                      • А и правда.

                        > None (the default value) means split according to any whitespace,
                        > and discard empty strings from the result.
                        Ответить
    • Перевёл на "Си":
      #include <stdio.h>
      #include <stdint.h>
      
      void give(intptr_t *p, int count)
      {
      	if (p != NULL && (intptr_t*)*p != NULL && count != 0) {\
      		give((intptr_t*)*p, count -1);
      		printf("%d\n", (p[-1]));
      	}
      }
      
      void take_(int count)
      {
      	intptr_t n;
      	if (!feof(stdin)) {
      		scanf("%d", &n);
      		take_(count + 1);
      	} else {
      		n = (&n)[1];
      		give((intptr_t*)n, count);
      		give((intptr_t*)n, count);
      	}
      }
      
      void take(void) {
      	take_(0);
      }
      
      int main(void)
      {
      	take();
      	return 0;
      }
      Ответить
      • Молодец, а теперь собери под 64 бита с оптимизацией с помощью gcc.
        Ответить
        • Ну и что же должно произойти? ;)
          Ответить
        • Собирать с -O0
          Ответить
          • А почему?
            Ответить
          • Это из той же группы требований что и
            * Отключить интернет во время установки.
            * Установочный путь не должен содержать пробелов.
            * Собирать только GCC 3.4.6 с этими флагами и никакими другими.
            * Устанавливать можно только на диск C.
            * В региональных настройках необходимо поставить десятичным разделителем точку.
            * В настройках рабочего стола включите Aeroю
            * Программу нужно запускать от администратора.
            * Шиндовс должен стоять исключительно в С:\Windows.
            ¿
            Ответить
            • А также не забудьте откдючить антивирус
              Ответить
              • При установке сторонней программы, системный антивирус автоматически отключается. Единственные две причины деактивировать его, на наш взгляд, это повышение производительности ПК или предотвращение случайных блокировок нужных файлов, которые антивирусу показались опасными.
                Ответить
                • Антивирусы вообще не нужны.
                  Ответить
                  • Вот ты попался, троллякка
                    Ответить
                    • Но ведь сейчас антивирусы и вправду не нужны. Они были нужны в эпоху DOS и Windows 95-98.

                      Сейчас и вирусов-то почти нет. Кругом только трояны.
                      Ответить
                      • Ну дык и антивирус сейчас -- это не просто сканер файлов по сигнатурам, а фаервол и IDS.

                        Да и по сигнатурам они известных троянов вполне так выпиливают.
                        Ответить
                        • Фаерволла обычно достаточно штатного.
                          Ответить
                          • Который тебя голой жопой в инет выставит, если ты случайно не ту кнопку при подключении к сети нажмёшь?
                            Ответить
                            • ну так ты не забывай делать ``Get-NetConnectionProfile`` же
                              Ответить
                              • > не забывай

                                Что ещё нужно не забыть?
                                Ответить
                                • Ну вот дебиан вообще по умочланию пустой и с политикой ACCEPT.

                                  Но просто прыщи можно выстаавить в Инет без файра, им ничего не будет, а у винды анонимные петухи уже через пару минут начнут щупать твои пайпы через SMB
                                  Ответить
                            • Кстати, вот пример поедания говна.


                              Прыши:
                              iptables -I INPUT --src=1.2.3.4 -j ACCEPT

                              винда
                              $rule = New-NetFirewallRule -Name "foo -DisplayName  "bar"
                              $rule | Get-NetFirwallAddressFilter | Set-NetFirewallAddressFilter -RemoteAddress 1.2.3.4


                              Пирдолинг заказываои?
                              Ответить
                            • Купил сдуру "Агнитум" коробошный, когда он только-только засветился в Интернет. Он тогда стоил около семисот рублей. Установил на "Висту", поигрался - понял, что говно, - снёс.
                              700 кровных - на ветер. Коробка до сих пор где-то валяется.
                              Ответить
                          • Файерволл не нужен.
                            В одной очень серьезной проге на которой сидит вся отчетность России используется indy, COM и прочие устаревшие технологии. Прога эта стоит охулион рублей.

                            В доке черным по белому писано:
                            Для работы приложения требуется отключить антивирус, файерволл и брандмауэр.
                            На делфи, кстати.
                            Ответить
          • -fno-omit-frame-pointer не поможет кста вместо отключения оптимизации?
            Ответить
        • Taaaaaake ooooon meeeeeeee
          Taaaaaake meeeee oooooooon
          I'll beeeee goooone
          In a d

          Segmentation fault
          Ответить
      • Как-то коряво по-моему. Зачем лишняя процедура? Зачем вообще счётчик?
        Ответить
        • Чтобы посчитать, сколько чисел ввели
          Ответить
          • А откуда моя изначальная программа знает, сколько чисел ввели, по-твоему?
            Отдельный счётчик не нужен.
            Ответить
            • А почему если твою процедуру вызвать из другой, она выводит лишние числа?
              Ответить
              • В документации к процедуре не сказано, что её можно вызывать не из main. Так что всё ок.
                Ответить
                • Проапдейтил инструкцию.

                  * Отключить интернет во время установки.
                  * Установочный путь не должен содержать пробелов.
                  * Собирать только GCC 3.4.6 с этими флагами и никакими другими.
                  * Устанавливать можно только на диск C.
                  * В региональных настройках необходимо поставить десятичным разделителем точку.
                  * В настройках рабочего стола включите Aeroю
                  * Программу нужно запускать от администратора.
                  * Шиндовс должен стоять исключительно в С:\Windows.
                  * Вызывать только из main.
                  * Не засирать стек посторонними данными.
                  Ответить
                  • > 3.4.6

                    Мутабельных литералов захотелось? Или что там закопали в том районе?
                    Ответить
                  • Имя пользователя не должно начинаться на 'u' или 'x'.
                    Ответить
                    • Чёрт! Я обычно в Винде ставлю имя пользователя «user», чтобы не ломать голову.
                      Ответить
                  • После вызова моей функции лучше сделать sleep на пол секунды, чтобы у планировщика было время все подчистить
                    Ответить
                    • Перед вызовом функции нужно сделать форк, а после -- завершить процесс.
                      Ответить
                      • напоминает ``vfork()``, где ребенок должен вести себя правильно, чтобы случайно папку не завалить
                        Ответить
                        • Потому что он ещё не отпочковался.
                          Ответить
                          • на пуповине висит, скажем так

                            Вообще хуевый, негативный вызов. Лучше им не пользоваться
                            Ответить
                            • > не пользоваться

                              Почему? Джве функции подряд не так сложно написать...
                              Ответить
                              • Наскока я помню, vfork запилили до страничной адресации еще, потому что без коровы было ОЧЕ дорого каждый раз копировать (как делал обчный fork), потому сделали такую лоу левел парашу

                                Поскоку теперь у всех (кроме j123123) есть MMU и COW (ха-ха, я родил каламбур) то смысла в вфорке мало
                                Ответить
              • Вот потому и выводит, что использует глубину стека вызовов вместо счётчика.
                Ответить
        • Дополнительную функцию можно опустить. Я просто убрал странную необходимость всегда передавать ноль, и заодно показал, что функция работает корректно в не зависимости откуда её вызвали.
          Ответить
          • У меня у первой процедуры вообще нет параметров, а у второй только один. На C это можно при желании переписать один-в-один и будет работать.
            Ответить
            • Перепищи
              Ответить
              • — хочу переписать скрипт на Линукс
                — перепрыщи
                Ответить
              • Уже давно переписал и проверил. Получилось примерно то же самое, что выше, но более кратко и без лишних параметров.
                Ответить
            • > будет работать

              Ну такое... Царские Лямбды тоже работали в конкретных условиях на конкретном конпеляторе. Очень тонкий лёд.
              Ответить
      • >intptr_t
        мы вам перезвоним
        Ответить
        • Ещё и через %d его читает... Низачот.
          Ответить
          • Оно ещё и некооректно роботает если в конец пробелов добавить.

            Да, надо было в инт кастить
            Ответить
      • Я так и думал, что ты сишник. Они все ебнутые.
        Ответить
        • Особенно, после того, как понажимают клавиши, на которых обтер пальцы инкубатор мной заселенный
          Ответить
    • https://i.postimg.cc/6pz2zJnm/wow.png
      Ответить
    • https://fstec.ru/normotvorcheskaya/informatsionnye-i-analiticheskie-materialy/2314-informatsionnoe-soobshchenie-fstek-rossii-ot-21-dekabrya-2021-g-n-240-22-6319
      Ответить

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