Блог пользователя Perlik

Автор Perlik, 13 лет назад, По-русски
Всем привет. Столкнулся с проблемой и не знаю как решить. Загрузил генератор тестов во вкладке Files. Захожу в Tests, проверяю, он его успешно компилирует. После сохранения скрипта (пишу GenTest > {15-20}) во всех этих тестах появляется запись GenTest и стоит параметр Script, но как заставить его запустить этот генератор, чтобы он эти тесты сделал?
  • Проголосовать: нравится
  • +20
  • Проголосовать: не нравится

13 лет назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится
Вроде показывает тесты, если на превью нажать.
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    О, точно) У меня только почему-то Crashed. А rand можно использовать? И конструкции типа
    #ifdef WIN32  
    printf("%I64d",v[i]);
    #else
    printf("%lld",v[i]);
    #endif

    • 13 лет назад, # ^ |
        Проголосовать: нравится +1 Проголосовать: не нравится
      Использовать rand() то можно, но testlib'овский rnd.next(), по-моему удобнее. Насчет таких конструкций - там на виндоуз все запускается, так что можно просто "%I64d" писать.
      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Спасибо, и еще вопрос, а количество памяти для генератора как ограничено?
        • 13 лет назад, # ^ |
            Проголосовать: нравится +1 Проголосовать: не нравится
          Никогда не задавался таким вопросом :) Один раз я написал очень медленный генератор и он ТЛил примерно через минуту, так что, думаю, и на память ограничение есть, но чисто символическое.
          • 13 лет назад, # ^ |
            Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

            А с чем еще может быть связан вердикт Crashed? Запустил генератор здесь (насколько понимаю, версия C++ одна и та же) во вкладке "Запуск" и все нормально отработало.

            UPD. Уже разобрался.
      • 13 лет назад, # ^ |
          Проголосовать: нравится +1 Проголосовать: не нравится
        1. Не нужно использовать rand().
        2. Не нужно просто писать "%I64d".
        Это затрудняет повторное использование задач. А сделать генератор более переносимым совсем не сложно.
    • 13 лет назад, # ^ |
        Проголосовать: нравится +1 Проголосовать: не нравится
      Использовать rand() не следует. Это затрудняет переиспользование задачи. Поскольку в стандарте языка Си не указано, как именно должна работать эта функция, в разных компиляторах она по-разному реализована. Когда такой генератор будут запускать на различных компьютерах под различными операционными системами и компилировать различными компиляторами, он в лучшем случае будет выдавать различные тесты. В худшем (если после этого автор тестов подбирает seed или не все генерируемые тесты корректны) окажется, что сгенерированы гораздо менее содержательные тесты или некорректные тесты. А это значит, что какое-то решение, падающее только на некоторых случайных тестах, может упасть в одном случае и не упасть в другом.

      Можно написать свой генератор в несколько строчек, взяв хорошие константы отсюда. Эта же страница помогает проэмулировать rand(), если кто-то таки сделал тесты через него (а это происходит всё время), и надо заставить генераторы работать под другим компилятором.

      Кстати, в версии testlib (0.6.4?), которая была на момент зимних сборов в Петрозаводске, генератор хоть и взят из Java, однако написан так, что последние версии GCC со включёнными оптимизациями компилируют его неправильно. Кажется, ничего не изменилось с тех пор?..

      Насчёт #ifdef WIN32: это действительно широко применяющийся способ. Когда printf-ов несколько, удобнее сделать #define INT64 "%lld" или "%I64d" и дальше писать printf (INT64 "\n", v[i]);
      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Вы, наверное, никогда не писали под polygon. Там есть свой rand, который инициализируется входными параметрами. В testlib.h можно найти инструкцию по применению.
        • 13 лет назад, # ^ |
            Проголосовать: нравится +1 Проголосовать: не нравится
          Да, не писал. Только читал :) .

          Интересно. С конкретным названием rand() в testlib 0.7.1 я вижу только

          int rand()
          {
              quitf(_fail, "Don't use rand(), use rnd.next()");
              return 0;
          }


          Или есть ещё что-то в polygon, но при этом не в testlib?
          • 13 лет назад, # ^ |
            Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

            Оказывается и random_shuffle нельзя, нужно просто shuffle. Порой полезно читать исходники ;) А можно писать rnd.next(1,а тут long long)?

            UPD. Нельзя.
      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Вроде я довольно быстро поправил этот баг. В 0.7.1 его точно нет, а он был выпущен в середине февраля.

        Видимо писать #ifdef WIN32 не очень круто, так как, наверное, это не суперпереносимый вариант. Насколько я знаю под MinGW в g++ использование %I64d или %lld зависит от msvcrt.dll или какой-то похожей. Да и windows бывает не только 32-х битный.
        • 13 лет назад, # ^ |
            Проголосовать: нравится +1 Проголосовать: не нравится
          Можно извратиться и сделать что-то такое:

          char tmp[100];
          sprintf(tmp, "%lld", 10000000000LL);
          bool use_lld = true;
          if (strcmp(tmp, "10000000000")) use_lld = false;

          И затем писать
          if (use_lld) printf("%lld", a); else
          printf("%I64d", a);

          Это, правда, считается не во время компиляции и кода надо больше, зато будет работать.
        • 13 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          Действительно, это место поменялось. Значит, я куда-то не туда посмотрел, когда читал в прошлый раз. Прошу прощения.

          Ну, #ifdef WIN32 гораздо лучше, чем ничего, его в будущем можно скормить автозамене. Вообще, MinGW полупереведённый в 64 бита: вот сейчас проверил с TDM-GCC MinGW 4.5.1 x86_64, там задефайнено и WIN32, и WIN64. Хотя, действительно, #ifdef WIN64 тоже нужен на будущее.
13 лет назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится
Круто. Готовите первый "синий" раунд в истории кодфорс? =)
  • 13 лет назад, # ^ |
      Проголосовать: нравится +1 Проголосовать: не нравится
    До уровня Codeforces мне рановато еще ;) Может поднабравшись опыта и знаний....
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Вы бы выложили код генератора.
  • 13 лет назад, # ^ |
    Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Синтакс типа "gen > {10-12}" нужно использовать, если генератор создает файлы 10,11,12. Это удобно делать с помощью функции startTest(n). Лучше всего прочитайте пример multigen.cpp из дистрибутива testlib.

      Как отмечено выше, используйте cout для вывода 64-битных чисел. Конечно это подтормаживает, но проблем с выводом даже нескольких мегабайт не будет. А делать тесты на десятки мегабайт просто не стоит.

      Чтобы получше со всем разобраться, почитайте все исходники из дистрибутива testlib.
      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        А если использовать startTest(n), то как должен выглядеть скрипт?
        • 13 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          >> Лучше всего прочитайте пример multigen.cpp из дистрибутива testlib.
          • 13 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится
            Ну из того, что я прочитал и попробовал у себя, получается, что он просто создает файл с номером теста и пишет туда. Сейчас я делаю так, генератор получает в качестве параметра номер теста, получаю его как atoi(argv[0]). А затем запускаю от этого startTest. Что я не так делаю? Вообще я могу просто загрузить архив - так будет проще, но уже хочется разобраться с этим.
            • 13 лет назад, # ^ |
                Проголосовать: нравится +12 Проголосовать: не нравится
              В argv[0] лежит номер теста? Я думал, что там лежит название исполняемого файла.
              • 13 лет назад, # ^ |
                  Проголосовать: нравится 0 Проголосовать: не нравится
                Усталость берет свое... Спасибо)
                • 13 лет назад, # ^ |
                    Проголосовать: нравится +1 Проголосовать: не нравится
                  И сразу feature request: положите в один из argv номер теста. Как минимум, это решит проблему генерации n тестов по одному правилу но с разными seed.
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
А как все тесты через валидатор прогнать?
  • 13 лет назад, # ^ |
      Проголосовать: нравится +1 Проголосовать: не нравится
    Сами прогоняются, если есть валидатор.
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Просто что-то очень быстро прогоняются. Там он довольно долго должен работать. И вот такой вопрос, если тест >4 мб, он почему-то показывает начало, может тестить на нем, но не может добавить его в архив?
      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Это странно. Я в этом случае генерю стандартный архив и компилирую на месте, обычно, хватает.
        • 13 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          А точно, я просто full создавал. Всем спасибо.