Разработка сайта для Вашего бизнеса. Веб дизайн. Дизайн логотипа, фирменного стиля, рекламная фотография . Комплексный рекламный креатив.

Ralex. We do the work.
На рынке с 1999го года. Средняя ценовая категория. Ориентация на эффективность решений.
Ознакомтесь с нашим портфолио
Узнайте больше о услугах
Свяжитесь с нами:
E-mail: [email protected]
Tel: (044) 587 - 84 - 78
Custom web design & дизайн и разработка сайта "под ключ"
Креативный, эффективный дизайн. Система управления сайтом (СУС).
Custom flexible разработка систем электронной коммерции
Система e-commerce разрабатывается под индивидуальные потребности. Гибкая функциональность.
Search Engine Optimzation & оптимизация под поисковые системы (SEO)
Постоянная оптимизация и мониторинг сайта в поисковых системах. Достигаем результата быстро и эффективно
Custom logo design & дизайн логотипа и фирменного стиля
Многолетний опыт. Огромное портфолио. Уникальное предложение и цена.
профессиональная рекламная фотография
креативно, смело, качественно
Custom logo design & рекламный креатив. дизайн рекламы
Многолетний опыт. Огромное портфолио. Уникальное предложение и цена.

Як ми робили олімпіаду з SQL

  1. Вступна
  2. Перший тур, відбірковий. Грудень 2016
  3. Другий тур, основною. Березень 2017

Наша взаимовыгодная связь https://banwar.org/

На самому початку осені 2016 року керівництво поставило мені завдання підготувати технічну частину олімпіади з SQL На самому початку осені 2016 року керівництво поставило мені завдання підготувати технічну частину олімпіади з SQL. Обговоривши ситуацію з колегами, в тому числі з колишніми, я був ткнуть (ткнён?) До статті, де в декларативному стилі на SQL вирішувалося завдання з побудови найкоротшого виходу з лабіринту. Зібравши в одну купку частини запиту і запустивши його на справжній базі, я прошепотів "магія! .." і зрозумів, що олімпіаді бути.

Думаю, що типовий читач Хабра на олімпіадах хоч раз так бував, але скоріше в ролі учасника, а не організатора. Я теж бував на різних, і мені завжди було дивно, чому на одних олімпіадах цікаво, а на інших туга смертна. Можу показати, як виглядає цей театр з іншого боку завіси, і як я намагався, щоб ця олімпіада виявилася з тих, які цікаві. Інтриги, скандали, розслідування - нічого цього не буде. Зате розповім як готувалися завдання, що від них очікували і що виходило в результаті.


Вступна


Олімпіада 2016/17 рр. проводилась вже в десятий раз, як би ювілей. Хоч олімпіада і заявлена ​​міжнародної, основний її мова російська, так що особисто я б назвав її швидше Всесоюзної. Я готував технічну частину конкурсу з мови програмування SQL (були ще й інші номінації). За ідеєю другим організатором цієї номінації був Oracle, але їх представників я так і не зустрів. Так що єдиним слідом від Oracle залишилося те, що використовувалася оракловая база даних з усією відповідною специфікою SQL.


Ось звіт про фінал нашої олімпіади 2016/17 на офіційному сайті: http://world-it-planet.org/press/news/detail.php?ID=323774


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


Оскільки ніяких додаткових вказівок мені керівництвом озвучено не було (повний карт-бланш), основною метою проведення олімпіади я визначив популяризацію мови SQL. До речі кажучи, це дійсно один з небагатьох реально використовуваних в життя декларативних мов програмування. А якщо на горизонті з'являються бази даних, особливо промислові, які з серверами, то альтернатив взагалі реально немає - індустріальний стандарт де-факто. Плюс дуже багато нішеві рішення використовують SQL-подібний синтаксис запитів, коли треба чогось вибрати і згрупувати або впорядкувати. Наприклад, JQL в JIRA або мова запитів в Sphinx Search Engine.


Так, так ось, основна мета була поставлена ​​- популяризація SQL. Щоб більше народу про SQL знало і на SQL писати вміло. Тоді і у нас з кадровим резервом буде все в порядку. Попутно ми звичайно будемо рекламувати себе і шукати таланти. Це само собою. Але головне - привернути увагу до SQL. А раз популяризувати, значить має бути цікаво.


Організатори анонсували наступний розклад проведення конкурсу: два заочних туру і очний фінал. Загальну концепцію визначимо так. Перший тур відбірковий, потрібно відсіяти якомога більше тих, хто не в темі. Другий тур - найцікавіше. Даємо завдання типу "а слабо в один запит SQL зробити щось-там-таке?" Часу даємо побільше, щоб була можливість подумати, але обмежено, щоб розсиджуватися було колись. Очний фінал в тому ж дусі провести не можна, за три (так нехай хоч навіть і за всі вісім) години фіналу придумати щось таке на SQL проблематично. Тобто буде бліц, куди ж подітися. Це звичайно не найкращий спосіб визначати найсильнішого програміста, але все ж трохи краще, ніж просто запитати генератор випадкових чисел.


І підготовча робота закипіла.


Перший тур, відбірковий. Грудень 2016


Тут я звичайно скористався напрацюваннями своїх колег від того ж самого конкурсу, але в попередньому році, за що їм окрема подяка. У IT-Планети є спеціальний движок, який проводить тестування. Була зібрана база із сотні з гаком питань з варіантами відповідей, які потрібно вибрати. Учаснику видається 30 питань. Навіть якщо учасник брав участь в минулому році, більше одного-двох питань навряд чи повториться. І особливої ​​погоди це нікому не зробить.


Так що міняти питання кардинально я не став, перетрусив наявні, виправив кілька помічених помилок, дещо напевно залишив на розлучення наступним поколінням. Питання такі вийшли бадьорі, рівня типового прометріковского онлайн-тесту. Плюс спеціально було зроблено утруднення в тому, що в кожному питанні потрібно вибрати всі правильні варіанти, але скільки їх там правильних не вказувалося. При цьому враховувалися тільки питання, на які вказані всі вірні відповіді. Тобто просто потикати мишкою і отримати, як в деяких тестах, середньостатистичні 25% не вийде ні разу. В результаті я сам, поки регулював правильність завантаження питань / відповідей, при повному проходженні всіх питань регулярно відповідав неправильно на пару з них.


Очікувалося, що таке сито добре розподілить учасників за рівнем знань SQL взагалі і Oracle SQL зокрема, більш обізнані займуть більш високу позицію. Тридцять питань на кожного учасника статистично нівелюють "особливості" окремих питань. Плюс терапевтичний ефект для учасників, що все серйозно і пощади не буде.


Практика підтвердила правильність очікувань, дійсно учасники досить непогано розподілилися по Пуассону (?) З сімома правильно отвеченних питаннями в середньому. Один учасник навіть зумів все 30 питань правильно відповісти (повезло, чого вже там!), 29 правильних відповідей вже були у чотирьох учасників. Шестеро людей пройшли чисто, чи не вгадавши жодного разу. Коротше, то що треба. Такий підхід дозволив вибрати відповідний прохідний бал, щоб сформувати потрібну кількість учасників другого туру, відібравши кращих. За планами організаторів до другого туру повинно було пройти близько двох сотень учасників з деякими цілком розумними обмеженнями, максимізує різноманітність учасників по країнах і вузам.


Другий тур, основною. Березень 2017


Другий тур був безсумнівно найцікавішою подією всієї цієї олімпіади. Саме в ньому можна було спробувати свої сили в хардкорних магії SQL.


Так як використовувати повторно ці завдання все одно не вийде, вони вже засвітилися, наведу їх тут. Почасти ця публікація і замислювалася як привід поділитися підготовленими завданнями для подальшої популяризації мови SQL. Кожне завдання, образно кажучи, починається словами "У один SQL-запит ..." і далі йде Something Completely Different © Monty Python. На жаль в одну фразу укласти завдання було не можна, доводилося додавати багатослівні пояснення для коректного формулювання умови, а також приводити для пояснення тестові дані і приклад вирішення на цих тестових даних.


Я дуже старався, щоб завдання мали виражений вау-ефект типу "так невже таке взагалі можливо на SQL", і щоб бути подалі від традиційної олімпіадної тематики, що вимагає досить специфічних навичок. Складність кожного завдання полягала в першу чергу в тому, щоб представити (ну і в подальшому реалізувати) сам декларативний спосіб вирішення цілком собі самостійною і нетривіальною навіть для класичного програмування завдання. Також ми почали вимагати в учасників скласти текстове пояснення до кожного завдання. З одного боку нам були цікаві люди, які можуть чітко викладати свої думки, і таких хотілося заохотити. З іншого боку, якби відповіді на завдання другого туру надіслали всі запрошені учасники, то такі пояснення сильно б нам допомогли в перевірці. Забігаючи вперед скажу, що з 200+ учасників другого туру надіслали відповіді тільки 34 людини. Що не так багато, але (як не дивно) приблизно дорівнює кількості активних учасників другого туру в попередньому році. Це дозволило нам ретельно в ручному режимі і на два рази перевірити всі роботи, і покликати на фінал дійсно найдостойніших.


Другий тур за розкладом організаторів починався першого березня. На рішення п'яти завдань ми дали півтора тижні, навіть трохи більше, до 23:59 12 березня. Так щоб кінець періоду припадав на вихідні після 8 березня. Щоб учасники могли ударно потрудитися в останні два дні і при цьому не надто псувати їм їх особисте життя. Тестові випробування на собі і колег показували, що на кожну задачу потрібно півдня-день. Плюс якийсь час на оформлення, плюс налаштуватися і розгойдатися. Тобто часу має бути достатньо, але без надлишку.


Ну-с, погнали про завдання. Сховаю під спойлер, щоб місця вони займали менше.


Завдання №1.Календар

Напишіть один SQL-запит, який згенерує кишеньковий календар. В параметрах до задачі вказується рік календаря і кількість рядків і стовпців для формування матриці з місяців. Параметри задаються наступним запитом:


with param (year, c, r) (...)

де, відповідно,


  • year - рік календаря
  • c - кількість стовпців матриці календаря
  • r - кількість рядків матриці.

Місяці розташовані в клітинах матриці календаря по порядку зліва направо і потім зверху вниз. Числа в кожному місяці розташовані по днях тижня, перший день тижня в першому стовпці і так далі. Початок тижня має відповідати налаштувань локалізації бази на момент запуску запиту. Назва місяця береться теж з налаштувань локалізації і виводиться по центру над числами. Між місяцями потрібно залишити проміжок, щоб числа сусідніх місяців «не злипалися». Найпершою рядком повинен йти вирівняний по центру рік. Порожніх рядків бути не повинно.


Наприклад, при наступних заданих параметрах:


with param (year, c, r) as (select 2016, 3, 4 from dual)

повинен вийти наступний висновок запиту:


2016 Січень Лютий Березень 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5 6 4 5 6 7 8 9 10 8 9 10 11 12 13 14 7 8 9 10 11 12 13 11 12 13 14 15 16 17 15 16 17 18 19 20 21 14 15 16 17 18 19 20 18 19 20 21 22 23 24 22 23 24 25 26 27 28 21 22 23 24 25 26 27 25 26 27 28 29 30 31 29 28 29 30 31 Квітень травень Червень 1 2 3 1 1 2 3 4 5 4 5 6 7 8 9 10 2 3 4 5 6 7 8 6 7 8 9 10 11 12 11 12 13 14 15 16 17 9 10 11 12 13 14 15 13 14 15 16 17 18 19 18 19 20 21 22 23 24 16 17 18 19 20 21 22 20 21 22 23 24 25 26 25 26 27 28 29 30 23 24 25 26 27 28 29 27 28 29 30 30 31 Липень серпень Вересень 1 2 3 1 2 3 4 5 6 7 1 2 3 4 4 5 6 7 8 9 10 8 9 10 11 12 13 14 5 6 7 8 9 10 11 11 12 13 14 15 16 17 15 16 17 18 19 20 21 12 13 14 15 16 17 18 18 19 20 21 22 23 24 22 23 24 25 26 27 28 19 20 21 22 23 24 25 25 26 27 28 29 30 31 29 30 31 26 27 28 29 30 Жовтень листопад Грудень 1 2 1 2 3 4 5 6 1 2 3 4 3 4 5 6 7 8 9 7 8 9 10 11 12 13 5 6 7 8 9 10 11 10 11 12 13 14 15 16 14 15 16 17 1 8 19 20 12 13 14 15 16 17 18 17 18 19 20 21 22 23 21 22 23 24 25 26 27 19 20 21 22 23 24 25 24 25 26 27 28 29 30 28 29 30 26 27 28 29 30 31 31
Завдання №2. переливання

Є дві посудини місткістю 3 і 5 літрів і кран з водою. Можна переливати воду з однієї посудини в іншу (до тих пір, поки один з них не наповниться або не стане порожнім), виливати воду (тільки повністю) і наповнювати будь-яку посудину з крана доверху. Потрібно знайти всі можливі варіанти переливань, які дозволяють відміряти рівно 4 літри. Щоб виключити зациклення, відкидаються варіанти, де стан наповненості судин повторюється.


Запит SQL повинен вивести всі можливі варіанти переливань в наступному вигляді: для кожного з варіантів вивести ланцюжок переливань у вигляді пар чисел, що показують кількість води в кожній посудині на відповідному кроці. Числа відокремлюються одна від одної мінусом, а пари - комою і пробілом.


Потрібно вирішити задачу в загальному вигляді, параметрами задаються ємність першого v1 і другого v2 судин і результат res, який потрібно отримати в результаті переливань. Приклад умов:


with param (v1, v2, res) as (select 3, 5, 4 from dual)

Приклад виведення:


PATH ------------------------------------------------- -------------------------------- 0-0, 3-0, 3-5, 0-5, 3 2, 0-2, 2-0, 2-5, 3-4 0-0, 3-0, 0-3, 3-3, 3-5, 0-5, 3-2, 0-2, 2 -0, 2-5, 3-4 0-0, 3-0, 0-3, 3-3, 1-5, 0-5, 3-2, 0-2, 2-0, 2-5, 3-4 ...
Завдання №3. Про шляхи

Є неорієнтований граф, заданий вершинами і ребрами. Дано довжини ребер і назва початкової та кінцевої вершини. Потрібно одним SQL-запитом знайти шлях з найкоротшим відстанню з початкової до кінцевої вершину. Результат повинен бути представлений у вигляді двох значень:


  1. рядок шляху, перераховані назви вершин через мінус,
  2. довжина шляху (сума довжин ребер).

Потрібно вивести три найліпших варіанту, відсортованих по довжині шляху по зростанню. В умові задачі задаються пари вершин і відстань між ними (граф неорієнтований, відстань вірно і для руху з першої вершини в другу, так і назад з другої в першу), і початкова і кінцева вершини для побудови найкоротшого шляху.


Кількість ребер в графі розумно обмежена, не більше 50 ребер.


На наступних тестових даних:


with edges (from_node, to_node, range) as (select 'Москва', 'Санкт-Петербург', 706 from dual union all select 'Москва', 'Воронеж', 516 from dual union all select 'Москва', 'Єкатеринбург', 1793 from dual union all select 'Москва', 'Алмати', 3956 from dual union all select 'Москва', 'Краснодар', 1345 from dual union all select 'Москва', 'Новосибірськ', 3356 from dual union all select 'Москва ',' Нижній Новгород ', 421 from dual union all select' Москва ',' Чита ', 6274 from dual union all select' Москва ',' Київ ', 856 from dual union all select' Москва ',' Ярославль ', 272 from dual union all select 'Москва', 'Новокузнецьк', 3723 from dual union all select 'Москва', 'Красноярськ', 4141 from dual union all select 'Москва', 'Білгород', 666 from dual union all select 'Москва' , 'Курськ', 524 from dual union all select 'Москва', 'Владивосток', 9141 from dual union all select 'Воронеж', 'Курськ', 237 from dual union all select 'Воронеж', 'Білгород', 265 from dual union all select 'Курськ', 'Білгород', 146 from dual union all select 'Ярославль', 'Нижній Новгород', 856 from dual union all select 'Єкатеринбург', 'Новосибірськ', тисячі п'ятсот дев'яносто вісім from dual union all select 'Новосибірськ', 'Чита', 2923 from dual union all select 'Новосибірськ', 'Красноярськ', 790 from dual union all select 'Новокузнецьк', 'Красноярськ', 751 from dual union all select 'Красноярськ', 'Чита', 2139 from dual union all select 'Чита', ' Владивосток ', 2861 from dual), param (begin_node, end_node) as (select' Краснодар ',' Владивосток 'from dual)

Повинен бути отриманий наступний результат:


PATH LEN ------------------------------------------------ - ---------- Краснодар-Москва-Чита-Владивосток 10480 Краснодар-Москва-Новосибірськ-Чита-Владивосток 10485 Краснодар-Москва-Владивосток 10486
Завдання №4. калькулятор

Задано арифметичний вираз у вигляді рядка. Потрібно одним SQL-запитом порахувати значення виразу. Вираз містить знаки наступних операцій: додавання, віднімання, множення, ділення, піднесення до степеня, унарний мінус і дужки. Унарний мінус може потрапляти тільки на початку виразу або після відкриває дужки. Числа можуть містити десяткову частину і по формату повністю відповідають типу NUMBER в поточних мовних налаштуваннях БД. Для більшої наочності вираження можуть містити символи пробілу. Довжина вирази розумно обмежена: не більше 50 операндів, глибина вкладеності дужок не більше 20. Вираз завжди коректне.


Запит повинен видати одне значення в форматі NUMBER.


Приклад тестових даних:


with param (expr) as (select '(-1 + 5 ^ (1/2)) / 2' from dual)

Приклад результату роботи запиту на цих даних:


VAL ------------------------------------------------- , 61803398874989484820458683436563811772
Завдання №5. лабіринт

Заданий лабіринт у вигляді пронумерованих рядків. Стіни позначені символами "#", точка входу "s» і виходу «e». За межі виходити не можна, номери рядків йдуть по порядку, довжина всіх рядків однакова. Потрібно одним SQL-запитом намалювати поверх лабіринту символами «*» найкоротший шлях від входу до виходу (один з них, якщо шляхів кілька).


Розмір лабіринту обмежений так, що можлива кількість варіантів проходу по лабіринту (без внутрішніх петель) не перевищує 10000.


Приклад тестових даних:


with maze (linenum, line) as (select 01, '## ### ######' from dual union all select 02, 's # #' from dual union all select 03, '#### # ## # ##### 'from dual union all select 04,' # # # 'from dual union all select 05,' # ### ######### 'from dual union all select 06, '# e' from dual)

Приклад результату роботи запиту на цих даних:


## *** ### ###### s ** # * # #### * ### # ##### # *** # # # ### * ##### #### # ********** e

Звичайно, якби ми мали більше часу, ми б зробили завдання ще краще. Але і так вийшло непогано. По кожній із завдань були свої несподіванки і підводні камені.


Наприклад, раптово дуже нетривіальною виявилася перша задача, про календар. Складнощі в учасників викликала вже динамічно формується матриця, а також раптово далеко не всі зуміли правильно згенерувати всі дні року. З урахуванням високосного їх зазвичай 365 або 366. Але в 1582 році в нашому григоріанському календарі відсутні дні з 5 по 14 жовтня. Коректно обробити 1582 рік вдалося небагатьом. Плюс тиждень в різних локалях з різного дня починається. При такій кількості несподіваних засідок, ніхто навіть не настав на граблі з вирівнюванням назв місяців. Всі, хто до цього добрався, чи не зламавшись по ходу справи, користувалися функціями, які видають неправильну довжину слова в кодуванні UTF8.


Завдання №3 "про шляхи" є варіацією на тему завдань про комівояжера. Міста взяті ті, в яких є наші представництва, а відстані реально відповідають довжині автомобільних доріг з атласів. Уже розіславши умови ми виявили, що не обумовили явно наявність / відсутність циклів в шляхах. Якось навіть в голову відразу не спало розглядати, що завдання комівояжера можна вирішувати з циклами. При перевірці довелося вважати обидва підходи вірними. Але тільки якщо вже учасник допускає цикли, то щоб все правильні рішення в такому підході були знайдені. Перевірочні тести довелося допрацьовувати. З несподіваного з'ясувалося, що не всі учасники знайомі з таким фундаментальним поняттям в програмуванні, як рекурсія. У рішенні одного наполегливої ​​людини рекурсія була зроблена вручну на вкладеність в глибину до 11 рівня. Для тестового прикладу з умови задачі цього вистачило, на інші наші тести звичайно ж немає, там ми в тому числі і всякої екзотики набрали. Дивно було це побачити, я припускав, що студенти і молоді фахівці, які пишуть на SQL (а це явно не може бути першою мовою програмування), про рекурсію повинні б знати і вміти застосовувати її на практиці. Без цього в програмуванні ну зовсім ніяк.


Завдання №5 "лабіринт" є особисто для мене самої чарівної, саме нею був навіяний весь другий тур олімпіади. Хоча після перших чотирьох завдань вона вже, напевно, не викликає того ефекту. В умовах спеціально обумовили, що рішення в лоб з перебором всіх варіантів спрацює. До речі, довго думали, як це обмеження взагалі можна сформулювати. Порожній лабіринт 7х7 без стін вже обраховується довго, так як кількість варіантів проходу по ньому велику. З іншого боку, лабіринт з великою кількістю стін (і, відповідно, малою кількістю варіантів проходу) вирішується швидко навіть в розмірах 60х60. Алгоритмічно правильніше було звичайно скористатися при вирішенні цього завдання хвильовим алгоритмом. Такий метод працює швидко і оптимально знаходить найкоротший шлях, відкидаючи свідомо гірші варіанти, але складніше в реалізації. Дуже приємно було побачити ці міркування в супровідному описі до цього завдання від одного з учасників. Але ніхто хвильової алгоритм так і не реалізував. Втім, і ми теж не стали.


Завдання №4 "калькулятор" була найбільш технічно складною. Передбачалася двоходівка: спершу перевести вираз в щось більш легкотравне (полізім або стекову нотацію), а потім вже порахувати результат. Дійсно, вирішили її учасників виявилося найменше. Дехто пробував вирішувати за допомогою регулярних виразів, по черзі вихоплюючи чергове підвираз, яке можна порахувати, і замінюючи його на пораховані значення, але все такі реалізації виявилися з помилками, особливо легко ламаючись на нелюдських виразах типу "(((- ((( ((((- ((- (- (- ((- ((-, 0-, 0)))))))))))))))))) ". Наша реалізація була теж неідеальна, реалізувати стек на SQL довелося рядками, а це обмежує глибину вкладеності стека технічними обмеженнями на довжину строкових полів в базі.


Завдання №2 про переливанні була взята з корпоративної вікі, де вона колись пропонувалася нашим програмістам від наших же програмістів для розминки розуму. Наші вирішили її спершу на різних класичних мовах програмування, потім на деяких екзотичних і навіть езотеричних (наприклад, brainfuck) і, врешті-решт, декларативно на SQL, на чому тема і була благополучно закрита. Гріх було не використати настільки добре розібрану завдання на олімпіаді.


До речі про brainfuck. У процесі підготовки завдань був реалізований інтерпретатор brainfuck в один SQL-запит. До завдань ми його висувати не стали, уникаючи двозначностей, пов'язаних з назвою. Але тим не менше маємо підтверджений факт, що це піддається реалізації. Бажаючі можуть повторити.


Думаю, що придумувати завдання було навіть цікавіше, ніж вирішувати. Тому що вирішувати їх в процесі придумування теж треба було, а часто і не по одному разу. По-перше, потрібно було гарантувати, що рішення задачі взагалі існує. По-друге, в процесі вирішення уточнювалося умова, щоб захоплюючу складову максимально залишити, а непотрібну рутину по можливості прибрати. Рутиною учасники нехай потім в промисловому програмуванні займаються до самої пенсії. Плюс по ходу справи всякі неочевидності спливали. Ну і по-третє, нам потрібно було референсне рішення, з яким ми б порівнювали рішення учасників при перевірці.


Оцінювалися завдання по десять балів максимально за код і по десять за супровідний опис. Код запускався на підготовлених наборах даних, першим з яких завжди йшов той, який був у умови завдання. Тобто правильні результати на даних з умови задачі давали вже мінімум один бал. З документацією було важче, оцінити об'єктивно (хоча б формально об'єктивно) було проблематично. Старалися, щоб при порівнянні двох різних рішень більш хороша документація оцінювалася в більшу кількість балів.


У надісланих роботах виявилося два кластери однакових рішень. Тобто вони звичайно відрізнялися окремими символами і десь навіть окремими словами. І трошки форматуванням. Але абсолютно очевидно було, що це одне і те ж. Я насправді думаю, що учасників не списували один у одного, а просто разом завдання вирішували. Але так як ми зі свічкою поруч не стояли і не бачили, хто там був справжнім автором рішення, а хто просто переписав, то довелося дискваліфікувати всі роботи зі слідами плагіату. Навіщо вони взагалі посилали в кілька відповідей одне і те ж рішення? Невже думали, що ніхто не помітить? Не в перший раз вже стикаюся з таким дивним поведінкою у людей, коли вони абсолютно втрачають здатність до критичного мислення. Ну невже організатор олімпіади, який відповідає своєю репутацією за перевірку, не зможе зрозуміти, що перед ним один і той же запит? Ну не можуть дві різні людини все проміжні таблиці і поля в них придумати з однаковими назвами. І навіть зі схожими не можуть.


Пара слів про технічний оформленні. Учасники повинні були приготувати файл для запуску в SQL * PLUS з під нашого скрипта для автоматичного тестування. Подробиці під катом, напевно не всім це буде цікаво.


Технічне оформлення завдань

Рішення повинно було оформлятися в окремому файлі, який запускався з зовнішнього скрипта-обгортки. Так було зроблено, щоб розділити параметри завдань і рішення. Параметри у вигляді "with params as (select 1,2,3 from dial)" були в зовнішньому скрипті. Ось приклад скрипта-обгортки:


set pagesize 999 linesize 999 numwidth 50 trimspool on trimout on set heading off verify off feedback off set serveroutput on size 999999 whenever sqlerror exit spool taskX.log - test dataset here with param (num) as (select 10 from dual) @taskX. sql / exit

Тоді скрипт taskX.sql виконається і висновок буде в файлі taskX.log.


Ось вміст скрипта-рішення taskX.sql, яке вважає факторіал від числа, заданого параметром param.num:


- = IT Planet, SQL 2016/17 = - = Task X (Sample) = - - with param (num) as (select 10 from dual), seq (n, fact) as (select 1, 1 from dual union all select n + 1, fact * (n + 1) from seq, param where n <param.num) select fact as factorial from seq, param where n = num

Сформувавши таким чином запуск скрипта на всіх наших спеціально підготовлених тестових даних, можна потім дивитися результати і порівнювати їх з нашими "еталонними" рішеннями.


Щоб зменшити кількість помилок при оформленні, для учасників були заготовлені і розіслані файли-шаблони для всіх задачок (файли task [1,2,3,4,5] .sql) і відповідні їм "запускалкі" разом з тестовими даними з умов завдань. Також був підготовлений і відправлений тестовий приклади розв'язання задач, щоб показати, як це все має виглядати. Ось цей самий факторіал, який вище.


Перевіряли ми, як я вже згадував вище, на два рази. Після першого прогону тестів і розбору результатів з'ясувалося, що частина тестів за завданнями потрібно уточнити. А частина зробити нових, щоб покрити деякі несподіванки, виявлені під час розбору рішень, на які ми не закладалися. Потім двоє людей незалежно провели повну перевірку рішень, і далі повна ж звірка з розбором всіх розбіжностей.


Підсумковий протокол регулювали ми довго, але, на мій погляд, він повністю відображав правильне ранжування учасників. У фінал пройшли дійсно мега-люди.


To be continued! Обсяг статті вийшов великим, продовження у другій частині .


PS Користуючись нагодою, хочу сказати велике людське спасибі колегам, які разом зі мною брали участь у вигадуванні, оформленні та проведенні цієї олімпіади! Єгор, Слава, Миша, Артем - вам в першу чергу.

Кнён?
Php?
Даємо завдання типу "а слабо в один запит SQL зробити щось-там-таке?
Навіщо вони взагалі посилали в кілька відповідей одне і те ж рішення?
Невже думали, що ніхто не помітить?
Ну невже організатор олімпіади, який відповідає своєю репутацією за перевірку, не зможе зрозуміти, що перед ним один і той же запит?
Категории
  • Биология
  • Математика
  • Краеведению
  • Лечебная
  • Наука
  • Физике
  • Природоведение
  • Информатика
  • Новости

  • Новости
    https://banwar.org/
    Наша взаимовыгодная связь https://banwar.org/. Запустив новый сайт, "Пари Матч" обещает своим клиентам незабываемый опыт и возможность выиграть крупные суммы.


    Наши клиенты
    Клиенты

    Быстрая связь

    Тел.: (044) 587-84-78
    E-mail: [email protected]

    Имя:
    E-mail:
    Телефон:
    Вопрос\Комментарий: