Мануал
В этом наборе заданий мы просим вас решать контесты с CodeForces на C-подобном языке CrowdScript (сравнительно подробный мануал есть здесь), описывая свой мыслительный процесс. Когда вы получите задание, вы увидите следующий интерфейс:
Обратите внимание на ссылку Problem Statement в левом верхнем углу. Первым делом надо нажать на нее и прочитать условие задачи. Затем следует переключится в интерфейс NEARCrowd, и в поле Thought Process описать ваше понимание задачи без сказки. Что вам дано, что просят найти. Опционально можно написать высокоуровневую идею решения, если в этот момент уже понятно как решать.
В интерфейсе в каждый момент времени вы можете либо думать (тогда активно текстовое поле справа, но не редактор кода слева), либо решать (тогда наоборот активен редактор кода слева). Чтобы переключаться между этими двумя режимами, нажимайте кнопку Switch to Coding / Thinking сверху. На скриншоте ниже участник уже переключился один раз на редактор кода, и написал код для считывания данных. Обратите внимание, что код неправильный. Мы вернемся к этому моменту ниже. Когда люди пишут код, они допускают ошибки. Не допускайте ошибок специально, но если вы допустили ошибку случайно, как в этом примере, это не страшно. Решение должно быть в функции solve (вы при этом можете дописать любое количество других вспомогательных функций и структур), которая принимает весь входной файл как строку, и должна вернуть весь выходной файл как строку. Смотрите примеры чтобы увидеть как средствами CrowdScript можно (сравнительно) удобно парсить входные данные и собирать выходные.
Если сейчас опять переключиться на Thinking, появится новое текствое поле над уже заполненным. Ваша задача переключаясь между Thinking и Coding решить задачу, подробно описывая все ваши мысли. Где-то в начале следует описать общую идею решения. Ниже будет пример где это происходит. Эта задача на реализацию, и в ней нет общей идеи, поэтому на скриншоте ниже участник сразу стал описывать свои следующие шаги:
Следуйте следующим правилам когда решаете задачу: 1. Переключайтесь на Thinking часто, желательно каждые несколько строк кода (не считая считывания данных). 2. Старайтесь сначала описать логику в Thinking, и только потом ее реализовать. 3. Если вы забыли описать логику, и код обогнал мысли, обязательно переключитесь на Thinking и опишите что вы только что написали. Затем не забудьте описать следующие шаги до того, как переключитесь обратно на Coding. 4. Если вы допустили фактическую ошибку в коде, или мыслях, на одном из прошлых шагов, не редактируйте ее (код предыдущих шагов нельзя редактировать в принципе). Вместо этого упомяните ошибку на новом шагу (ниже будет много примеров этой концепции). В примере ниже участник переключился на Coding, но сразу понял, что забыл упомянуть важную деталь в условии, которая влияет на то, что он сейчас будет писать. Он переключился обратно на Thinking не меняя код, и дописал пропущенную идею, и что будет писать дальше.
Тут также видна другая важная деталь: в ваших мыслях можно ссылаться на концпеции из сказки (в данном случае говорить про "детей", хотя ваше короткое описание условие детей не упоминало, говорило только о тройках чисел). Затем участник переключился на код, и дописал только что описанный код. Однако, участник также написал логику, которую еще не описал, при этом логика явно не тривиальная (обратите внимание на условие выхода из цикла). Согласно пункта 3 выше, участник переключился на Thinking, и описал код пост-фактум:
Описав код пост-фактум важно не забыть также написать следующую мысль! Участник ниже не забыл и дописал ее, и только затем реализовал:
Обратите внимание, что логика опять неправилная, в этот раз и в коде и в размышлениях (например, номер следующего за i-ым ребенка не j=i, а j=i+1). Опять же, допускать ошибки не страшно. Дописав эту часть кода участник переключился обратно на Thinking, и описал следующие шаги, и только потом их реализовал:
По ходу разработки решения у вас есть ряд инструментов для его запуска. При нажатии на кнопку Compile решение компилируется, и дает возможность запускать любую функцию с любыми параметрами. Мы здесь не будем описывать эту возможность. Помимо этого, можно ввести input и нажать на Run `solve` on this input. Это основной способ запуска решения. На скриншоте ниже участник дописал решение до конца, и запустил его на семпле:
Ответ неправильный (правильный ответ 2). Мы просим вас в ваших мыслях не упоменать результаты запусков. В примере ниже участник начал искать ошибки, нашел одну, но никак не ссылается на запуск, который подтолкнул его к поиску ошибок:
Ниже скриншот показывает другой способ обойти требование не упоминать запуски: участник исправил чтение, запустил, и снова получил неправильный ответ. Вместо того, чтобы сказать "я запустил и увидел...", что будет противоречить требованию не упоминать запуски, участник говорит о гипотетическом запуске ("если запустить ..."). Так делать можно.
Это также хороший пример правила о том, что не надо исправлять старые мысли. В начале процесса участник неправильно рассудил о том, что надо вычитать в строке 20 (ошибка была как в коде, так и в мыслях). У вас есть функционал исправления предыдущих мыслей (для этого надо на мысль нажать), но исправлять надо только опечатки, или стилистические ошибки. Фактические ошибки так исправлять не надо. Вместо этого их надо упоменуть и проанализировать в текущем окне для мыслей, как в примере выше. Тут также видно, что ссылаться на номера строк можно. Если вам нужно использовать отладочный вывод, это можно делать, но тоже надо описывать:
К сожалению, никакого IO в CrowdScript нет, и единственный способ делать отладочный вывод -- это возвращать его.
Когда решение проходит семплы, его можно отправить на CodeForces на провеку, для этого надо нажать Submit to Codeforces:
Страница сама не обновляется, надо нажимать Refresh (справа от статуса). Это решение упало на 12-ом тесте (скриншот сделан неудачно и не показывает это). Как и запуски локально, не ссылайтесь на отправки в ваших мыслях. Вместо этого говорите "если отправить", или просто "такое решение не проходит".
Участник опять нашел ошибку. В этот раз она в понимании условия. Как всегда, не надо редактировать старые мысли, ошибку следует упомянуть и проанализировать в текущем окне для мыслей.
В примере ниже участник сразу переключился в код и начал его писать, не описав заранее следующие шаги. Согласно пункта 3 выше, он переключился обратно в мысле. Сейчас необходимо описать только что написанный код:
Что участник немедленно делает:
Затем участник опять оптарвляет на CodeForces, получает снова WA, и продолжает описывать ход мыслей. Обратите внимание, что он опять не ссылается на посылку, как если бы ее никогда не было:
В этот раз участник не забывает сразу написать в это же окно следующие шаги, прежде чем их реализовать:
Но часть реализации все-таки обогнала мысли. Участник дописал ее. В этот момент он снова отправил на CodeForces и получил Accepted. В этот момент редактировать решение и мысли дальше нельзя. Теперь, когда задача решена, мы просим вас придумать идеи еще двух задач, которые проще той, которую вы только что решили, но используют теже идеи. Хочется, чтобы если задачи по вашим идеям были сделаны (и, в действительности, план в итоге их сделать), то участник соревнований по программированию, решивший такие две задачи был бы лучше подготовлен решить задачу c CodeForces, которую вы только что решили.
На скриншоте ниже участник написал две таких задачи. Требование к этому полю следующее: другой участник NEARCrowd, прочитав текст, должен смочь приготовить задачу. Обычно достаточно написать только идею условия, но для более сложных задач следует писать также идею решения.
Написав идеи следует нажать Save Onramp Problems, после чего появится кнопка Submit for Review:
Обратите внимание, что участник, которому в будущем попадется задание приготовить ваши задания, будет видеть только то, что вы написали в поле. У него не будет контекста (он не будет знать, какую задачу вы решали, и как). Поэтому то что написано в этом поле должно быть самодостаточно (в частности, эти две задачи будут даны двум разным участникам, то есть поля не могут ссылаться друг на друга тоже). Следует нажать Submit for Review, это отправит ваше решение на проверку другим участникам. Такие проверки будут приходить и вам. На проверке следует проверить, что участник подошел к требованиям ответственно, и подробно описывал все шаги. В конце этого документа есть больше деталей. Рассмотрим еще один пример. Участник получил новую задачу, и в начале видит такой же интерфейс (но название задачи другое):
Участник прочитал условие. Затем он переключился в интерфейс NEARCrowd, и в поле Thought Process описал свое понимание задачи без сказки. Что дано, что просят найти. В этот момент опционально можно написать высокоуровневую идею решения, если в этот момент уже понятно как решать.
В интерфейсе в каждый момент времени вы можете либо думать (тогда активно текстовое поле справа, но не редактор кода слева), либо решать (тогда наоборот активен редактор кода слева). Чтобы переключаться между этими двумя режимами, нажимайте кнопку Switch to Coding / Thinking сверху. На скриншоте ниже участник уже переключился один раз на редактор кода, написал код для считывания данных, и перключился обратно.
Обратите внимание, что при переключении обратно появилось новое текстовое поле. Вы можете редактировать старые, нажав на них, но это следует делать только если вы нашли опечатки, или незаконченные мысли. Если вы ошиблись фактически (например, неправильно оценили сложность, неправильно описали переход в динамике, итд), такие ошибки исправлять не надо. Мы хотим видеть настоящий процесс решения задачи, с ошибками. Если вы поняли, что ваши размышления ниже были неправильными, просто напишите об этом в текущем поле для мыслей. В примере ниже участник не написал идею решения сразу, и пишет ее сейчас.
Помимо требования к тому, что в первом блоке должно быть описано в кратце что просят в задаче, нет никаких других требований в плане организации мыслей. Пишите так, как думаете. В частности, если вы обычно начинаете писать решение до того, как оно у вас полностью сложилось в голове (например, вы чувствуете, что понадобится паросочетание, и начинаете его писать), то так и делайте, не откладывайте до тех пор, пока не придумаете все решение. В то время как нет требований к организации мыслей, есть определенные пожелания по их частоте, и тому, как они пересекаются с кодом. Во-первых, лучше, чтобы вы сначала написали в Thought Process что хотите написать, а уже потом написали это в коде, чем сначала написать код, а потом описать что вы только что реализовали (то есть желательно, чтобы мысли обгоняли код, а не наоборот.) В примере ниже, описав в кратце решение, участник сразу написал какой код собирается писать:
Если код все-таки обогнал мысли, следует пост-фактум объяснить что уже написано (в данном случае, участник уже написал код проверки вхождения в интервал, и описывает его пост-фактум).
Акцентируем внимание, что в примере выше более желательно было, чтобы участник сначала описал логику проверки вхождения в интервал, а уже потом ее реализовал. Это пример показывает что делать, если все-таки реализация обогнала мысли. За исключением кода для считывания данных, следует переключаться на Thinking после каждых нескольких строк кода, которые вы написали, описывая ваш процесс мышления, и комментируя только что написанный код. Обратите также внимание, что в коде проверки вхожедения в интервал есть ошибка, используется value вместо pos. Это нормально, мы хотим видеть ошибки, которые возникают естественным образом, и их исправление, а не безупречную реализацию с первой попытки. Но когда вы находите такие ошибки, обязательно следует об этом написать. В данном примере участник дописал весь метод set прежде чем заметил ошибку.
В этом примере также хотелось бы, чтобы участник более подробно объяснил работу функции set (как она вызывается рекурсивно, какие инварианты выполняются). Еще раз напоминаем, что ваш мыслительный процесс не должен ссылаться на запуски кода, только на сам код который вы написали. Например, "и здесь в строках 20-21 у нас бинарный поиск" -- это хорошо, а "как видно из результатов запуска пока что семплы не проходят" -- плохо. При использовании ваших работ мы не будем видеть что и когда вы запускали. Если результат запуска влияет на ваш мыслительный процесс, используйте обороты, похожие на "если сейчас запустить код на (таком-то входе), то мы увидим (такой-то выход)". Когда вы готовы послать решение, нажмите на кнопку Submit to CodeForces. В этот момент ваше решение транспилируется в C++, и полученный файл отправляется на проверку на CF. Если результат Accepted, то работу можно отправлять на проверку другим участникам (кнопка Submit to CodeForces поменяется на Submit for Review). Иначе надо продолжать решать. Опять же, факт вашей посылки не будет виден при использовании вашей работы, поэтому если результат важен для дальнейшего мыслительного процесса, о нем стоит писать в виде "такое решение пока что не пройдет тесты, упав по времени". Обратите внимание, что при запуске в браузере код транспилируется в JavaScript, а при отправке в С++. Транспайлеры не идентичны. В частности, транспайлер в JavaScript значительно медленнее, и тип int в С++ представлен типом int64_t, а в JavaScript -- BigInt (реализующий длинную арифметику). Задания выдаются раз в определенный промежуток времени (промежуток будет виден когда предыдущее задание выполенно). При выдаче выдаются сразу все задачи с какого-то одного контеста. Вы должны их решать по порядку. Вы можете пропустить любую задачу (кнопка Give up on this task вверху), но вернуться к такому заданию в будущем будет нельзя. С++, который получается из CrowdScript, сильно не оптимальный. Не гарантируется, что любая задача может быть решена на CrowdScript: иногда добавленная сложность от транспайлера может не дать задаче уложиться в ограничение по времени или памяти. Будьте готовы, что некоторые задачи может не получиться сдать. Для простых задач описывайте все максимально подробно. Для более сложных можно не расписывать каждый цикл. В целом хороший ориентир -- это описывать так, чтобы человек, для которого эта задача является сложной, мог по вашим мыслям понять что вы делаете. Например, для задачи A ориентируйтесь на человека, который только начал программировать, а для задачи F на человека, который может решать стабильно задачи уровня C.
Проверки
Вы можете брать задачи на проверку решений других участников (и иногда такие проверки будут приходить вам). Когда вы делаете проверку, убеждайтесь в следующем: 1. Участник действительно решает задачу, которую ему дали, и в конечном итоге его мысли приходят к правильному решению. 2. Что участник описывает все шаги решения, не пропуская важные детали, и мысли плотно покрывают решение. 3. Что мысли участника дейсвительно описывают идеи решения, а не просто описывают код (например, что он говорит "а тут мы делаем бинарный поиск", а не "заведем переменные l и r, затем заведем переменную mid"). Подробное описание кода после описания идеи допустимо (то есть обе цитаты подряд допустимы: "а тут мы делаем бинарный поиск, для этого заведем переменные l и r, затем заведем переменную mid"). 4. Что участник не упоминает свои запуски и отправки. 5. Что onramp задачи самостоятельны и имеют смысл. Убеждайтесь также, что автор не ссылается на задачу, которую он решал, и свое решение в onramp задачах. Эти задачи будут даваться другим участникам без контекста. Того, что указано в поле, должно быть достаточно, чтобы приготовить задуманную задачу. Интерфейс проверок выглядит следующим образом (скриншоты ниже сделаны до добавления опции Has Mistakes, у вас будет на одну опцию больше):
Обратите внимание, что вы видите и решение, и две простых задачи. Reject следует нажать, если решение совершенно неправильное (например, участник решает не ту задачу, не описывает мысли, в мыслях написано что-то совсем не релевантное, итд). Если работа выполнена, но в ней есть нарушения требований, такие как отсутствие краткого описания задачи или упоминание запусков или отправок, следует поставить Has Mistakes. Если решение в целом правильное, не нарушает требования, но некачественное (мало шагов в описании, много опечаток, грязный код), то следует выбрать Low Quality. Это незначительно понизит награду участнику. Если задание выполнено хорошо, следует выбрать Good Quality. Если участник подошел к выполнению задания невероятно ответственно, следует выбрать Outstanding Quality. Это незначительно повысит награду участнику. Обратите внимание, что ответственный подход к выставлению оценок проверяющими сильно влияет на то, как сильно другие участники относятся к качеству выполняемой работы, что в свою очередь влияет на то, как долго существует набор заданий. Независимо от того, какую оценку вы выставляете, оставьте комментарий. Что хочется улучшить, что сделано хорошо. Это помогает другим участникам расти:
Во время проверки вы можете смотреть как выглядит код участника в разные моменты времени нажимая на соответствующие шаги. Часто задание будет проверяться несколькими участниками. Если вы не первый проверяющий, вы будете видеть все прыдущие вердикты и комментарии. ВАЖНО: участник, выполнивший задание, будет видеть только вердикт, вынесенный последним проверяющим. Если среди вердиктов, которые вы видите от предыдущих проверяющих, есть хорошие идеи, копируйте их в свой вердикт. Прежде чем приступать к работе, посмотрите на примеры (кнопка Examples на главной странице). Обратите внимание, что не все примеры имеют onramp-задачи. В ваших работах onramp задачи должны присутствовать обязательно.