Комментарии 107
Как то весьма ожидаемо от Озона. Они и не такое совершали и «сидели с покер-фейсом».
Чего только стоит ситуация с хранением паролей в открытом виде
2012 год — РРраз habr.com/ru/sandbox/45548
2016 год — Двввааа interface31.ru/forum/index.php?topic=79.0
2019 год — Трррри! habr.com/ru/news/t/459600
Как минимум 7 лет их поливали критикой, указывая на очевидный косяк и даже этого не хватило, чтобы они признали и исправили свою ошибку.
А ведь неизвестно сколько пользователей пострадало. Представьте себе среднестатистического пользователя, который весьма бережно хранит свои данные, но по незнанию использует одинаковые пароли на различных сервисах и почте. И вот 7 лет не хватило, чтобы озон заделали дырищу, из-за которой такой пользователь оказался под серьезной угрозой.
В памяти всплыл собственный горький опыт прохождения контестов лет 15 назад. Хочеться сказать, тогда это не было мейнстримом и воспринималось организмом как новая зубная пломба и когда от нее что-то отпадало то доктор ставивший пломбу переживал за качество ;)
Не жалею что потратил несколько дней пытаясь решить задание E, приобрел хороший опыт. Хотя такое отношение организаторов немного расстраивает, не ужели чтобы собрать резюме не достаточно открыть вакансии на хх.
Жаль потраченного времени. Весь опыт прохождения этого отбора сводится к тому, что не стоит учавствовать в подобных мероприятиях.
Сама по себе задача Е была достаточно интересна, поэтому желание проверить варианты решений вдохновило одного из участников группы сделать сайт для проверки, где можно проверить свое решение и посмотреть код других правильных решений. Варианты правильных решений достаточно разнообразны. Более того, эта задача перекочевала и в бесплатный курс по Go на Stepike.
Ну она была одна из самых простых заданий и затрат по времени меньше чем в остальных. Не считая невозможности прохождения.
Ну не знаю, все кроме Е мне показались не сложными — уровня первых двух на районных олимпиадах или кодфорсе, а над Е пришлось немного задуматься, почитать про каналы чтоб написать свое правильное решение, а потом пойти искать тех самых недобросовестных людей про которых писали организаторы.
Согласен. Тех, кто не остановился перед трудностями, эта ситуация заставила проработать самые сложные и не очевидные варианты, и в конечном итоге докопаться до сути. И заодно они поделились опытом с другими.
Некоторые ВУЗы используют в своей программе задачи у которых нет решения. Это позволяет искать новые знания и придумывать новые подходы. Правда у Озона это вышло не намеренно.
Будем надеяться, что первые блины дадут Озону хорошую почву развития и успеха.
В нормально настроенном тестовом отборе, не должно быть возможности его взломать, чтобы посмотреть как работает проверка решения, и подставить ложное решение, которое вдобавок организаторами будет засчитано, потому что они на самом деле не проверяют код.
И ведь могли бы взять себе действительно классных специалистов, кто докопался до сути и стоял до конца.
я думаю что так и получилось, они набрали лучших. Только лучших в их понимании: возраст, пол, навыки, зарплатные ожидания(а их легко можно выявить косвенно по резюме). И тут все честно, лично мне просто для себя хотелось бы получить фидбек о своем техническом уровне по отношению к другим участникам контеста, а получил типовую отписку. Но опять же никто фидбеков не обещал, как говорится ваши ожидания — ваши проблемы )

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

Да я как бы сам из тех кто несколько дней убил на это задание, думая что делаю что — то не так и все такие есть решение, еще 1 попытка, еще 1 рефакторинг, еще 1 подход к решению, еще 1 раз перепишу все заново и так по кругу )))) Хорошо что хоть из дома не выгнали.
Видимо задача взять лучших именно в школу не стояла. Лучшим наверное сразу работу предложили.
Самое обидное, что Ozon четко не сказали, что в задании/тестовой системе/конфигурации баг и в результате нельзя получить 'OK'. Все их ответы еще больше вводили в заблуждение. Эти мифические 32 человека, которые сумели выполнить задание Е, размытые формулировки, о том, что тест был составлен слишком широко — всё это только наталкивало на мысль, что ты заблудился в 3х соснах. Печалька.

С самого начала было понятно, что это такой плохо замаскированный рекрутинг. Плохо только, что в этой истории к потенциальным сотрудникам отнеслись как к дурачкам, ибо первое правило найма гласит: всегда нанимай людей умнее себя, иначе через пару лет твоя компания превратится в сборище дилетантов.

Почему "плохо замаскированный"? Наоборот — громко объявленный на главной странице проекта :)


Мне, кажется, наоборот очень круто, что компания решает ту самую проблему "курицы и яйца" для многих разработчиков — "хочу начать писать на го, но без опыта не берут".


image

На лэндинге было написано "по итогам обучения", но скорее всего несколько офферов были сделаны по итогам отборочного конкурса. Так-то устроить качественную школу и похантить оттуда топовых выпускников — идея достойная, Яндекс это делает давно.

Товарищи ex-Lazada не позорьте, а!


Надо было сразу заявлять об отборе на full time работу и, видимо, onsite. Нехорошо сделали.

Привет!

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

Принять участие в школе может любой специалист, но поскольку для нас важно пригласить разработчиков на работу по окончании курса, было ограничение по возрасту 18+ — возможно, стоило написать об этом более явно. А вот жить в Москве и области не обязательно — в школу пригласили участников и из Санкт-Петербурга, Перми, Краснодара, Пензы, Челябинска, Екатеринбурга, Уфы, Брянска. При этом, учитывая конкурс в 55 человек на место, делать решение задач единственным фактором отбора не получится, просто потому что 4 из 5 задач решили многие — по той же причине скрыли лидерборд.

И о задаче Е — в ее условиях и алгоритме проверки мы допустили сразу несколько ошибок, и чтобы наши недоработки не повлияли на результат, не учитывали решение при прохождении отбора. Возможно, стоило убрать ее раньше – но тогда оставался риск потерять полученные решения, а значит, кто-то из участников мог лишиться своих 4 из 5.

Первый отбор прошел совсем не идеально, и мы это понимаем. Мы разобрали все ошибки, том числе из этой статьи, чтобы в будущем их не повторять и сделать набор таким как нужно.

Если вы действительно представитель Озона — как насчёт прокомментировать предметно то, что освещено в статье, в т.ч. "Я не я и хата не моя"? Пока что ваш ответ выглядит как жалкая попытка оправдаться и сгладить явные косяки.

А зачем им что-то комментировать?
Задание было где?
пройти тестовые задания по программированию на платформе Яндекс.Контест

Виноват яндекс.

Вы о чём? Ему PR отдел не разрешит дать прямой ответ. Вот я работаю на галере <большая_company_name> — любые публичные заявление при которых я говорю что-то от имени <большая_company_name> или даже просто заявляю, что я там работаю и моё мнение такое-то — я обязан согласовать с PR отделом (не суть важно, как именно отдел наазывается). Ну а публичное признание ошибок — это то, что ни одна сколько-нибудь большая компания не допустит. Исключения из этого правила — в основном небольшие компании, либо уж ну просто очень серьёзный факап, который зарегистрирован чуть ли не гос. органами.

Одно дело совершить ошибку в задаче, это случается. Другое дело нагло врать о том, что «все нормально, 32 участника уже решили»
Мы на самом деле получили 32 ответа с вердиктом «ок», и не вычитывали их до момента, пока не начали получать сообщения об ошибках. Но когда количество ответов с итогом Wrong Answer стало массовым, в попытке помочь участникам изменили настройку чекера — и в итоге задача, вместо того чтобы стать проще, перестала решаться вовсе. Действительно мы заметили это не сразу, но как только стало понятно, что ошибка на нашей стороне, сообщили всем участникам, что не будем засчитывать задание Е.
что собственно Вам мешало не юлить, а просто обратить внимание на массовые репорты, а позже и на детальный разбор Вашей ошибки, или хотя бы попробовать самим отправить верное решение на тесты в контест и убедиться самим. Как и было написано в статье — решение задачи E которое было предложено Ozon, так же не проходило тесты.

Нельзя ничего чинить, потому-что-
Доработать это в режиме реального времени у нас нет возможности: есть риск потерять уже существующие решения.
Серьезно? 32 участника которых никто не видел, но их решение каким-то не совсем ясным образом прошло сломанные тесты. Отсюда вопрос — почему эти результаты вообще важны и должны считаться легитимными если тесты сломаны, какой вообще тогда смысл прикрываться 32-мя решениями?
Собственно что мешало исправить тесты тоже не понятно, написать что-то вроде — «да, мы тут нашли баг, наш косяк, уже исправили», аннулировать все результаты по задаче E, и попросить всех участников заново отправить свои решения на тест?
Времени было достаточно.
Если Вам будет легче, я один из тех 32-х, у кого система приняла решение.
Роман, а можно посмотреть на Ваш код, который приняла система?
Да, конечно
package main

import (
	"fmt"
	"time"
)

func main() {

	n := 10

	in1 := make(chan int)
	in2 := make(chan int)
	out := make(chan int)

	go func(in1 chan<- int, n int) {
		for i := 0; i < n; i++ {
			fmt.Println("Write to in1: ", i)
			in1 <- i
		}
	}(in1, n)

	go func(in2 chan<- int, n int) {
		for i := 0; i < n; i++ {
			fmt.Println("Write to in2: ", i)
			in2 <- i * 10
		}
	}(in2, n)

	go func(out <-chan int) {
		for i := range out {
			fmt.Println("Read from Out: ", i)
		}
	}(out)

	Merge2Channels(func(x int) int {
		time.Sleep(time.Duration(x%3) * time.Second)
		return x * x
	}, in1, in2, out, n)

	fmt.Println("Done")
	fmt.Scanln()
}

type orderedNumer struct {
	pos int
	num int
}

//Merge2Channels merges 2 channels
func Merge2Channels(f func(int) int, in1 <-chan int, in2 <-chan int, out chan<- int, n int) {

	fin1 := make(chan orderedNumer)
	fin2 := make(chan orderedNumer)

	go funcNum(f, in1, fin1, n)
	go funcNum(f, in2, fin2, n)

	go mergeFNums(fin1, fin2, out, n)
}

func funcNum(f func(int) int, in <-chan int, fin chan<- orderedNumer, n int) {
	pos := 0
	for i := 0; i < n; i++ {
		num := <-in
		// fmt.Println("Read from in: ", num)
		onum := orderedNumer{pos, num}
		pos++
		go func(f func(int) int, onum orderedNumer, fin chan<- orderedNumer) {
			onum.num = f(onum.num)
			// fmt.Println("Write to fin: ", onum)
			fin <- onum
		}(f, onum, fin)
	}
}

func mergeFNums(fin1 <-chan orderedNumer, fin2 <-chan orderedNumer, out chan<- int, n int) {
	nums1 := make(map[int]int, n)
	nums2 := make(map[int]int, n)

	sendPos := 0
	for i := 0; i < n*2; i++ {
		select {
		case onum1 := <-fin1:
			nums1[onum1.pos] = onum1.num
		case onum2 := <-fin2:
			nums2[onum2.pos] = onum2.num
		}

		// fmt.Println("Check ", sendPos)
		sendNum1, ok1 := nums1[sendPos]
		sendNum2, ok2 := nums2[sendPos]

		if ok1 && ok2 {
			out <- sendNum1 + sendNum2
			sendPos++
		}
	}

	for i := sendPos; i < n; i++ {
		sendNum1 := nums1[i]
		sendNum2 := nums2[i]
		out <- sendNum1 + sendNum2
	}
}



решение было принято 13-го мая
Система не была поломана на старте, это случилось позже, когда перенастроили «для улучшения вывода ошибок». По крайней мере так оно выглядит. Ниже есть тред с техническим описание того, что случилось. До фикса даже референсные решения из соседней статьи от озона не работали.
Видимо было еще и возрастное ограничение сверху, но об этом нам не скажут. А можете озвучить максимальный возраст ученика взятого в школу по результатам отбора?
да, что-то упустил этот момент — сейчас вроде даже в институты ограничений по возрасту нет, а в союзе до 35 лет только брали.

Это да… пытался тут мидл программистом андроида удаленно устроится — не берут )


Возраст 40+. Опыт программирования на многих языках. В мега-супер проектах не участвовал, но есть приложения на маркете, которые живут со времен андроида 2. Есть опыт программирования на жаве со времен 1.4.

Уверены что дело в этом? Просто учитывая дефицит специалистов как то тяжело поверить в такое, хотя не исключаю что может быть правдой.
Может стоит хайповые темы и знание модных библиотек еще подтянуть? Всякие там корутины, архитектуры и архитектурные принципы, и прочее что обычно в вакансиях болтается? На гитхаб чего нибудь выложить и попросить кого нибудь проверенного отревьюить. Я конечно молодой, что мне скидку делает в глазах работодателей, но в андроид и вовсе из 1с перепрыгнуть умудрился.

Я использую rxjava и room в последних приложениях, делаю верстку экранов не на horizontal/vertical/border layout с клеем, а на ConstraintLayout, и вместо SimpleCursorAdapter использую RecyclerView.


Мне в лучшем случае присылают ответ: "вы нам не подходите". Вполне возможно hr специалисты отсекают мое резюме по ключевым словам, хотя скорей всего по возрасту. Сеньору 25 лет страшно работать с дяденькой, который программировал на ассемблере z80, когда он еще не родился.


И, да, 1с я тоже программирую. Нормальный программист выбирает язык под задачу — так меня учили в школе )

А с архитектурой у вас как? MVP, MVVM, MVI, редакс какой нибудь или что нибудь более экзотическое? С тестами? На гитхабе есть что нибудь?
Эйджизм конечно существует, но насколько мне известно чтобы его преодолеть достаточно приложить усилий не немногим больше чем молодежи. По крайней мере если человек уже программист, а не из маркетинга, например, приходит.

Еще раз: меня просто не зовут на собеседования программиста андроид.


Программистом 1с позвали с первой рассылки (резюме другое).

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

Я совершенно не понял ваше описание проблем с задачей E в посте, хотя сам готовил много "классических" задач под разные системы (в том числе Я.Контест). Впрочем, пост в Telegram кое-то прояснил, процитирую:


и дальше наша теория того, что произошло:
1) они настроили задачу по умолчанию, stdout был включен, они прогнали свой тест — все ок, соответственно в run.sh они не добавляли перенаправление
2) они пошли смотреть как выглядит страничка для участников, увидели что там "стандартный вывод" в поле "Вывод" под названием задачи и сделали "рефакторинг" — отключили его, установили имя файла как "см формат вывода", не проверили авторское решение (там есть кнопка "пересудить" для него)
(есть еще вариант что они по какой-то другой причине отключили stdout не сразу, а через пару дней, но это на суть не влияет)

Вот это уже звучит реалистично. Вполне разумная схема для впихивания нетривиальных задач в олимпиадную систему: компилируем участника вместе со своими юнит-тестами, запускаем, упало — Runtime Error, не упало — всё прошло. Чекер тривиален и ничего не проверяет.


Правда, совершенно непонятно, как тут можно разумно получить Wrong Answer, если уж чекер тривиален.


Для контекста: практически все системы для олимпиад работают по одной и той же схеме, сомневаюсь, что Я.Контест сильно отличается:


  1. Предполагается, что решение задачи — отдельная программа, читает некоторые данные, выводит некоторые данные, всё за ограниченное время. Решение помещается в один файл. Это позволяет поддерживать сразу кучу языков, только бы компилятор был.
  2. При создании задачи выставляется "имя входного файла", "имя выходного файла", а также список пар (входные данные, "ответ жюри" на тест) плюс специальный "чекер".
  3. Каждое решение система "компилирует" в один файл. В очень творческом смысле — например, действительно, скопировав исходники в архив.
  4. Далее на каждом тесте система независимо "запускает" решение, подсунув входной файл. Выходной файл решение должно создать самостоятельно. Файл с "ответом жюри" в этот момент в песочнице отсутствует, чтобы участник не скатать.
  5. Если решение упало (ненулевой код возврата) или заняло много времени, то оно убивается. Получаем либо Runtime Error, либо Time Limit Exceeded (много процессорного времени в каком-то из смыслов), либо Idleness Limit Exceeded (процессорного мало, но много wall clock, например, решение заблокировалось на чтении). Иногда дополнительно после этого проверяется наличие созданного выходного файла (увы, не помню, как в Я.Контесте).
  6. Если решение не упало и прошло по времени, то в песочницу копируется файл с ответом жюри и запускается чекер. На обычных контестах обычно пишется на testlib и принимает три аргумента командной строки: входной файл, выходной файл (который должен был создать запуск участника), только что скопированный файл с ответом жюри. В целом "файл с ответом" может быть творческий и содержать не ответ, а какую-то подсказку для чекера, но это не очень хорошо.
  7. Если чекер вернул 0 — ответ засчитан. Иначе — Wrong Answer, Presentation Error, Jury Error ("всё сломалось, зовите жюри разбираться"), в зависимости от настроек.
Правда, совершенно непонятно, как тут можно разумно получить Wrong Answer, если уж чекер тривиален.


А все просто — чекеру не приходили данные.

Процитирую первую часть сообщения:
чтобы чекер работал надо чтобы был включен stdout или run.sh писал в файл (у них как мы видели не пишет)
дальше чекер может хитро проверять вывод, в их случае мог бы проверять время тестов или как-то по другому парсить вывод go test — но как мы видели, даже если записать пробел в файл то чекер говорит ок, соответственно никакой пользовательской логики в нем нету. если чекер возвращает 0 — платформа пишет ok (https://admin.contest.yandex.ru/docs/advanced-usage-examples/default-tests-for-language.html)

Если чекер тривиален, он не проверяет данные никак и пустой вход его тоже устроит. Если чекер нетривиален, то он не будет съедать абсолютно любой ввод. Чекер, которые проверяет, что вход непуст — это что-то очень странное.


Подозреваю, что Я.Контест проверяет, что решение участника создало выходной файл ещё перед запуском чекера. Тогда это было бы разумно сделать Presentation Error, но, возможно, пошли по пути Codeforces и убрали этот вердикт.

Выходной файл, как ни странно, создается системой автоматически (как мы видели).
Presentation error мы ни разу не видели.

Что конкретно проверяет их чекер мы не видели, это недоступная информация.
Мы создали свой контест и использовали простейший пример чекера из статьи.

Я могу лишь предположить, что их чекер искал в файле слово FAIL (вывод go test) и проверял что файл не пуст (так как файл создается автоматически всегда).

Кстати, любой желающий может создать свой контест и посмотреть как он работает. Какие-то нюансы мы могли и пропустить.
Кстати пару часов назад они кликнули нужную галку (включили stdout) и теперь задача работает. А всего-то надо было это сделать месяц назад :-D
Отличная статья!!! Тот разбор задачи и ситуации, который ждали от Озона. Первые подозрения о качестве организации закрались, когда Озон опубликовал статью о преподавателях, которые будут обучать. Основная масса лекторов с опытом разработки на go меньше года. При этом в вебинаре Озоновцы сказали, что у них 200 go программистов. Получается, что на организацию школы и обучение смогли выделить только джунов.

После того, как я из задания E достал Makefile, shell-скрипты и их код на go, и указал им на их ошибку по почте, мне вообще больше не ответили ни да, ни нет, просто молчание.

а нас таких в группе было 170 человек, и каждый думал, что проблема у нас

А я благодарен озону, сделал два вывода из этой истории: 1) Go не быстрее Python, но сложнее в написании.(меньше ест памяти) 2) Крупные it компании России далеки от того места где хотелось бы работать. (лицемерие и обман не прибавляют доверия).
ну и да, было приятно коллегам в понедельник рассказывать решение задачи о поиске двух слогающих числа target и смотреть на их удивление от простоты решения
Да и не понятно, зачем было С++ переименовывать в первые две буквы гугла ))) и выдавать за новый ЯП.

Я программировал на обоих. Мое сугубое имхо: Go быстрее, дает более компактные докер образы, и не сложнее. Есть своя специфика — он более явный, ты больше пишешь, явно обрабатываешь ошибки, явно запускаешь горутины, вместо всей машинерии с async/await/task. Питон более лаконичный: те же comprehensions, with, и прочее, что позволяет в несколько строк написать много действий.
Не хочу скатываться в холивар — у каждого инструмента свое применение, в котором он хорош.

Согласен, не может компилируемый язык быть медленнее интерпретируемого, но именно это случилось на мероприятии, о котором идет речь(что удивительно и о чем я написал выше). И да ЯП это только инструмент, главное кто и как им пользуется.
Если алгоритм сильно упирается в I/O или какие другие блокирующие вызовы, то языки по производительности мало будут отличаться друг от друга. Ничего удивительного нет.
Так они в итоге сильно отличаются. В задаче 3, написал на 3 языках. Go с TL на 7 уровне застрял, Python дошел до 9 уровня с 201мс (но сьел 86мб), C++ прошел 9 уровень с 189 мс и съел 42мб.
Тут ещё смотря как код написан. В C++ легко выстрелить себе в ногу и получить много лишних копирований при передаче значений из функции в функцию, а в Питоне, например, получим просто передачу указателя.
из функции в функцию? А мы точно об одном и том же говорим? Там несколько ветвлений и итераций
У меня в этой задаче на Питоне получалось либо большое потребление памяти (86.25Mb при 299ms на 9 тесте), либо по времени не укладывался (1.586s при 3.98Mb на 8 тесте). Золотую середину найти так и не удалось. Интересно, реально ли вообще её решить на Питоне с поставленными ограничениями?
Пробовал сборщик мусора и типизацию всего, становилось хуже. Думаю реально, но надо больше времени
Думаю реально, но надо больше времени
Реально (но уже с новым ограничением в 1.5 секунды.) :)
(Если прочитать всю входную строку с сделать split() — не хватает памяти
(«9: memory-limit-exceeded 189ms / 74.14Mb»).
Срабатывает, если, например, вручную по прочитанной строке пройти, находя числа по одному. (Читать сразу из входа по 1 символу было слишком долго).
Регулярные выражения не пробовал.)
Python 2.7
№ Вердикт Ресурсы Баллы
1 ok 32ms / 2.38Mb -
2 ok 32ms / 2.38Mb -
3 ok 33ms / 2.38Mb -
4 ok 32ms / 2.38Mb -
5 ok 34ms / 2.38Mb -
6 ok 367ms / 3.29Mb -
7 ok 246ms / 4.86Mb -
8 ok 1.438s / 4.86Mb -
9 ok 333ms / 26.05Mb -


# -*- coding: utf-8 -*-
IN_FILE = 'input.txt'
OUT_FILE = 'output.txt'

seen = set()  # Было
result = 0  # ничего не нашли

def get_number(st, start):
    result = ''
    i = start
    l = len(st)
    while st[i].isdigit() and i < l - 1:
        result += st[i]
        i += 1
    # forward to next number if any
    while not st[i].isdigit() and i < l - 1:
        i += 1

    if len(result):
        return int(result), i
    else:
        return None, None


with open(IN_FILE) as f:
    target = int(f.readline())
    # for number in [int(x) for x in f.readline().split()]: # Out-of-memory
    next = 0
    numbers = f.readline()
    while(True):
        number, next = get_number(numbers, next)
        if number is None:
            break
        complement = target - number
        if complement > 0 and complement in seen:
            result = 1
            break
        seen.add(number)

# print(target, result)

with open(OUT_FILE, "w") as f:
    f.write(str(result))


Во время конкурса решилось на С++ (после попыток на других языках).
Теперь покажу как O(n) -> O(n)⁄4.
На последнюю задачу много времени потратил, после стало не интересно пробовать и некогда.
import sys
data = open('input.txt', 'r')
target, sequence = data.read().splitlines()
target = int(target)
digits: List[int] = [map(int, sequence.split()))
file_out = open('output.txt', 'w')
x = target//2
y = target -x
if(x==y):
    y+=1
z = tuple(filter(lambda u: u<=x, digits))
w = tuple(filter(lambda u: u>=y, digits))
for i in z:
    for j in w:
        if i+j==target:
            file_out.write('1')
            sys.exit()
file_out.write('0')
Видимо вы что-то не то делаете, 3 задача (F) решается с помощью порционного чтения, где надо бросто выбрать размер буфера. У меня вышло на питоне 357ms 3.97Mb
А можно увидеть ваш код, как вами было это реализовано?
Конечно
from itertools import chain
result = "0"
trash = set()
with open("input.txt", "r") as in_file:
    target = int(in_file.readline())
    prev = ""
    while True:
        chars = in_file.read(1000)
        if chars:
            numbers_str = chars.split(" ")
            first = numbers_str[0]
            last = numbers_str[-1]
            numbers = map(lambda x: int(x), numbers_str[1:-1])
            if prev == "":
                first = int(first)
            elif first == "":
                first = int(prev)
            else:
                first = int(prev + first)
            prev = last
            for number in chain([first], numbers):
                if number < target:
                    if number in trash:
                        result = "1"
                        break
                    trash.add(target - number)
            if result == "1":
                break
        else:
            break

with open("output.txt", "w") as out_file:
    out_file.write(result)


Не идеальное решение, но имеет место быть
Я решил. Все задачи кроме последней на питоне (и SQL).
Но пришлось очень аккуратно подгонять размер кусков считывания входного файла. =)
16 май 2020, 00:24:50 33060438 F Python 3.7.3 OK — 0.931s. 3.95Mb
def f_sum_of_two():
    has_sum = 0
    diffs = set()
    digits = ""
    with open("input.txt") as f:
        target = int(f.readline().rstrip())
        while True:
            char = f.read(1)
            if not char:
                break
            if not char.isdigit():
                number = int(digits)
                digits = ""
                if number > target:
                    continue
                if number in diffs:
                    has_sum = 1
                    break
                diff = target - number
                diffs.add(diff)
            else:
                digits += char

    with open("output.txt", "w") as f:
        f.write(str(has_sum))
В Go очень медленный стандартный ввод (через fmt.Scan() ) — нужно читать ввод через bufio. С++ в этом плане гораздо быстрее считывает данные стандартными средствами cin, отчасти поэтому всех начинающих олимпиадников на него с питона пересаживают (можно посмотреть код решения подобных задач на разных языках на кодфорсе)
Может в этом проблема, я с Go знаком поверхностно. Мне ввод и вывод коллега писал.
 file, err := os.Open("input.txt")
 if err != nil {
  panic(err)
 }
 defer file.Close()
 data := make([]byte, 64)
 for {
  n, err := file.Read(data)
  if err == io.EOF {
   break
  }
  str += string(data[:n])
 }
Чтение маленькими блоками, я бы блоками меньше 4к не читал никогда, ибо размер страницы памяти. А еще с маленькими блоками больше перевыделений памяти при сложении.

Строки в Go иммутабельны, при выполнении конкатенации каждый раз создаётся новая строка.


Go не быстрее Python, но сложнее в написании.

Странно делать такой вывод, если знакомство хотя бы с одним из языков — поверхностное

У Вас более странный вывод относительно моего вывода. Видимо, это следствие поверхностнных знаний относительно понятия Вывод. Вывод (лат. conclusio) в логике — процесс рассуждения, в ходе которого осуществляется переход от некоторых исходных суждений (предпосылок) к новым суждениям — заключениям. Вывод может проводиться в несколько этапов—умозаключений.
тоже переписал решение задачи е раз 5 )
побаловался с go
нашел душевный чатик и поучаствовал в ковыряниях палочкой в этом всем ))
в целом неплохо провел время.
главное, имхо, как и в любом деле, вовремя соскочить )
Идея школы была интересна многим в её изначальном представлении — чисто онлайн (особенно учитывая текущие обстоятельства) школа про go. Уже потом мы заметили, что FAQ на сайте стал меняться и появились новые условия :-)

Да и сам контест был интересным, задания казались не сложными (хотя вот например задание А, если внимательно прочитать условия, можно было решить чисто алгоритмически, я вот не прочитал и когда увидел их вариант решения — порадовался) и можно было быстро попрактиковаться в алгоритмических задачах на go (не как в обычной жизни).

Весь сыр бор из-за Е начался именно из-за того, что задача выглядела простой, но не работала. Многие потратили бОльшее время на решение, чем ожидали. Я потратил 2 ночи на задание: 1ую — пытаясь переписать задание по-разному, потом написал свои тесты с нереальными угловыми случаями и в итоге так перестарался с решением, что потратил вторую ночь ловя дедлоки. И даже это задание не прошло.
Надо, конечно, было бы раньше полезть в систему и посмотреть почему так, тут сам виноват :-)
И вот когда мы нашли косяки в системе, тогда то нас и пробило на «добиться правды».

Тем, кто не участвовал, наверно все это кажется дичью, и оно, от части, так и есть :-)
В общем то, эта статья — это просто наша попытка привнести правду в случившееся и показать, что признавать ошибки — это правильно, а юлить — не очень :-)

Получил моральное удовлетворение от вашей публикации. Вы описали весь мой путь от и до. За исключением того:


  • через панику и ошибки последний тест я продебажил самостоятельно за 63 подхода.
  • на мои два письма о проблемах контеста мне никто не ответил

Полученный опыт заключается в большем скептицизме относительно подобных мероприятий. И да, времени жаль.
Собеседование было, на уровне пары общих вопросов. Отписка что вы не подходите тоже была.

Мой коммент тоже на модерации (писал в ответ на то что отписки получили те кто решил 3 и менее задач). Решил 4 задачи (и по задаче Е прислал решение), но получил такую же отписку: «Побольше практики: участвуйте в проектах, чемпионатах, олимпиадах.». Причем мое решение такое же как описано в той статье. Возможно, все из-за того, что не завершал тестирование до последнего, ожидая какого-либо прояснения информации по задаче Е.
Мой коммент тоже на модерации (писал в ответ на то что отписки получили те кто решил 3 и менее задач). Решил 4 задачи (и по задаче Е прислал решение), но получил такую же отписку: «Побольше практики: участвуйте в проектах, чемпионатах, олимпиадах.».
Мне прислали такое же письмо (тоже решил 4 и Е (сейчас то же самое (плюс коммент, чтобы формально отличалось) решение, что давало «WA», даёт «OK» (говорят, недавно (уже после подведения результатов) тестирование починили)).

Причем мое решение такое же как описано в той статье. Возможно, все из-за того, что не завершал тестирование до последнего, ожидая какого-либо прояснения информации по задаче Е.
Вероятно, лучше не искать закономерностей там, где их нет (и держаться подальше от болот).
Участвовал в данном тестировании.
Я один из требований и описания тестирования/школы понял, что для прохождения тестов необходимо знание какого то ЯП и не обязательно GO?

Прошёл все тесты на Питоне и был сильно удивлён заданию на Go. В школу Go. Которое не работает. =)

Да, прикольно получилось )
Задание на Go шло как дополнительное, если уже имеешь где-то посмотрел go, прошел go tour, то можешь показать знания.
Но в итоге так и вышло — задание необязательное :)

А у вас случайно не осталось решения задачи «F. Сумма двух» на Питоне, которое прошло тесты Яндекс Контеста? Очень хотелось бы на него взглянуть.
конечно осталось. =)
За 80 истраченых попыток я успел:
— Вычитать все сходные параметры.
— Составить карту верных ответов (если за 95 попыток не получится).
— Попробовать несколько вариантов оптимизации в плане обработки и хранения данных.
— Побиться головой о стену )

Прошу не судить строго, я его только начал пробовать)
input_file = open("input.txt")

target = input_file.readline()
target = int(target)

numbers_trg = []
chunk_len_def = 2200000
chunk_len = chunk_len_def
tail = ""
is_exit = 0
is_double = 0

while chunk_len > 0:
    chunk = input_file.read(chunk_len_def)
    chunk_len = len(chunk)

    if chunk_len == 0:
        break

    split_chunk = [int(i) for i in chunk.split()]

    if chunk[0].isdigit() and tail != "":
        split_chunk[0] = int(str(tail) + str(split_chunk[0]))

    if chunk[-1].isdigit() and chunk_len == chunk_len_def:
        tail = split_chunk[-1]
        split_chunk.pop(-1)
    else:
        tail = ""
    if len(split_chunk) == 0:
        break

    if target % 2 == 0:
        is_double += split_chunk.count(target / 2)
        if is_double > 1:
            is_exit = 1
            break
    if len(list(filter(lambda x: target - x in numbers_trg, set(split_chunk)))) > 0:
        is_exit = 1
        break

    numbers_trg.extend(list(filter(lambda x: x < target and not x in numbers_trg, set(split_chunk))))
    split_chunk.clear()
    chunk = ""
    #print(numbers_trg)
    #print(split_chunk)
    #print(is_exit)

imin = 1
imax = target - 1

while imin < imax and is_exit != 1:
    if imin in numbers_trg and imax in numbers_trg:
        is_exit = 1

    if is_exit == 1:
        break


    imin += 1
    imax -= 1


input_file.close()

output_file = open("output.txt", "w")

#print(f"{imin},{imax},{is_exit},{is_double},{numbers_trg}")

if is_exit == 1:
    output_file.write("1")
else:
    output_file.write("0")




В ВК была компания рекламная, мелькала в ленте. «По словам организаторов, заявки подали более 4000 человек, что стало неожиданностью для них.» — слабо верю в эту неожиданность.
возможно, морально готовят к реальной работе. когда постановка задачи корявая, обратная связь не работает, а в отделе тестирования сплошь норкоманы. в общем, всё правильно сделали.

Именно реакция на такие ситуации и формирует репутацию технологической компании.


OZON: WA

Ozon объявляет о наборе нубов в школу Go, "нубы" прут с такой силой, что хакают платформу проведения тестов Яндекса, запускают playground правильной проверки задания, объясняют Озону как надо делать сборку, попутно х##сося его на Хабре.


Шел 5 месяц самоизоляции :)

вот- вот, может, все- таки хакнувшие платформу попали в какой- то особый лист и их сразу утащат на работу в отдел кибербезопасности, например?
В очередной раз PR отдел крупной российской компании показал свою недееспособность. Как-то уже в порядке вещей.
До начальства ваш пост скорее всего не дойдёт, а менеджер за это отвечающий очень не хочет выглядеть идиотом и прилюдно обделаться. К сожалению, в менеджеры часто набирают кого попало.
Предположу, что это было так:

Приходит hr к одному из лидов со словами: «Нам для pr нужно то-то.» Лид отрывает пару человек от задач и говорит: «С вас задачи на конкурс». За небольшое время появляется контест и рабочие руки возвращаются к таскам в спринте. Далее происходит то, что происходит.

Хотел принять участие, но решил, что опыта маловато. Как оказалось — не зря, убил бы время и нервы. Кстати, школа-то вообще работает? Или это просто был замаскированный набор сотрудников?

Сложности связаны также с тем, что Go — новый язык для платформы

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

Да достаточно знать, что они состоят в АКИТ, чтобы игнорировать все их проявления жизнедеятельности.
Что-бы вы понимали, у OZONа не только тут косяки. Весь OZON в той, или иной мере косячен с ног до головы, начиная с работы с партнерами, которые поставляют товары и месяцами ждут ответ саппорта на внезапные блокировки и т.д., заканчивая переносами некоторых доставок неделями и последующей отменой некоторых позиций.

Там в целом набрали команду не пойми кого, которые работают не пойми как. )
Сколько я не взаимодействовал с озоном как клиент, у меня всегда остается ощущение, что это компания застрявшая в начале нулевых. Какими они были тогда, такими они и остались.

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

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.