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

Автор Igorjan94, история, 5 месяцев назад, По-английски

This summer I decided to visit Kalinindrad from Saint-Petersburg on 4-6 November, bought fly tickets on 10:55AM-13:00PM and everything went well. But Yandex decided to set half-final exactly at 12:00AM on 4th November :( Fortunately I participate at backend track (I'm just magenta in algorithm and I believe at least yellow in backend) and contest lasts for 5 hours. I decided to take my laptop and take part from Kaliningrad
When I came to home airport, I saw "delayed until 12:55". Badumtss! On one hand, it's better that I can read all problems before flight and solve them during flight. On the other hand, it's worse that I'd have less time after landing
Anyway, 12:00, I opened contest, opened all problems, screenshoted them (to be sure that occasional reload won't kill problems) and saved all needed resourced locally
I rushed solving B (yes, this contest has problems B-F and description/instructions in A) while sitting in airport next to gate. Unfortunately this problem needed careful implementation so I failed to implement until boarding was announced at 12:15. Teletrap? No, just wait for bus :( In bus I opened problems from my phone and started reading and thinking about another ones
Boarding. I have almost last raw: fortunatelly it's A319 and it's relatevaly small so boarding was pretty fast. I'm still reading problems from phone as it's bad idea to use laptop during takeoff. Solved C in mind, skipped D as "goolge required" started thinking about E
Hack yeah, takeoff! Where is my laptop? OK, sheet of paper, just binary search and one formula: done. Let's check if it's correct, it's super easy in this task with python one-liner generator. OK. But I'm flying, I can't submit. OK, going to C. It's classical problem, I've implemented and debugged it I think in about half an hour. Still flying
OK, let's implement E. I'm not sure if this solution pass all tests, but contest uses points per test, so even partial solution matters. Implemented it in another half an hour. Still flying
OK, let's start F. What the ..... problem? It has some strange statement, it's hard to understand what you need to impelement. Though, unlike qualification round I don't have any objective dislikes for problems, only subjective and it's matter of taste. Started implementing F. "Dear passengers, our plane is ready to land". F... I'm impelemnting F. Closed laptop. Landed. Opened laptop. Hotspot. Submit B. Submit C. Submit E. 100. 100. 100. I was sure on 100 for B and C, but pretty surprised on 100 for E. Nice. It's 2:38/5:00. Bad, really bad timing. Good enogth score for such conditions. Closed laptop
Yeah, teletrap! Couple of minutes and I'm at airport! Oh no, we landed more than 30 minutes before schedule and bus from airport to the city is in 40 minutes. Where is some chair to sit? Ah, here. Where is my problem F? Let's continue implementing and testing. Almost done before bus. Let's submit. 0. 0!!! 0 :( Yes, I got 0. Bus. Bus in 5 minutes. Let's go. Queue. Yet another 10 minutes spent without participation
Where is my F? Or maybe goolge some points for D? Googled for some possible bugs in F, fixed. Submit. 20. It's a bit better, than 0
My stop, I came to city. I need to call about renting flat I booked this summer. OK, it's fast, but I still need to go from bus stop, take keys, 9th floor, open doors... Done, I'm in rented flat. It's 16:15, so 45 minutes left. Where is power socket? I have only 20% battery left. Found. Finally nobody disturbs me. Made some fixes for F, got 10
Googled good enough partial solution for D. 0. Yes, One more 0. Ah, I'm dumb. I need to unwrap NULL. Let's google how to unwrap. It's really hard to merge. Finally done. Testing locally. WA on second test. Ah, I make select in wrong order. Oh no, I don't know sql at all. Google. Please help. 16:54. 6 minutes left. Partial solution is also solution, submit. 75(!!!). Let's go back to F. Maybe changing this helps. Tested locally. 16:59. Submit. 0
I finished 23th with 395/500. I don't know what's wrong with my F: please, can anybody share your solution for F? And I know what's wrong with my D, but also want to know correct solution
Yes, I finished 23th. Only 20 goes to finals...
2 hours till football match I'm going. And I haven't eaten anything from about 8:30AM. Cafe. Eat. Footbal. Only 50-60 fans from SPb. Zenit won 2:0. Eat. Flat. And now it's 1:00AM and I'm writing these lines. Good night!
Good luck everybody in finals but not for me!

Полный текст и комментарии »

  • Проголосовать: нравится
  • +97
  • Проголосовать: не нравится

Автор Igorjan94, 15 месяцев назад, По-английски

Hello codeforces!

You know you are a programming competitions addict when this blog was 9 years ago, but you thought it was no more than 3...

More than month ago or, to be more precise from 15 to 19 December 2022, codeforces has five contests in five days. I participated in all of these contests and I thought how many contestants took part in all 5 contests?

TLDR: If you don't want to read why I decided to implement SDK on typescript and how I struggled with python, just scroll down to Typescript paragraph.

TLDR2: Links are below.

Python

Historically I have some python scripts to work with codeforces API, so I've created allContests.py file, imported my old library code with method cf and paused for a while. Which arguments does this method have? Let's look into source code. Ah, clear, def cf(method, **kwargs).

F**k. OK, let's go to API page. OK, then we should call:

standings = cf('contest.standings', contestId = contestId, showUnofficial = True)

But what does it return? Ah, no problem, let's run and see. {"status":"FAILED","comment":"Internal Server Error"}. Whaaat? Codeforces returned 500?

Ok, seams that from is required. No problem:

standings = cf('contest.standings', contestId = contestId, showUnofficial = True, from = 1)

Fail, from is the reserved keyword.

standings = cf('contest.standings', contestId = contestId, showUnofficial = True, **{'from' = 1})

Ok but what does this method returns?

Return value: Returns object with three fields: "contest", "problems" and "rows". Field "contest" contains a Contest object. Field "problems" contains a list of Problem objects. Field "rows" contains a list of RanklistRow objects.

Ok, seams that we need rows:

>>> print(standings.rows)
KeyError: 'rows'

Ah wait, I don't unwrap result in my lib:

>>> print(standings.result.rows)
[{...correct result...}]

Ok, seams legit, almost solved:

name = participant.party.members[0].handle
t = participant.party.participantType
rank = participant.rank
points = participant.points

Ok, which values can have t? Once more time to go to documentation

Enum: CONTESTANT, PRACTICE, VIRTUAL, MANAGER, OUT_OF_COMPETITION

Ok, filtered participants that everybody solved at least one bugaboo, sorted by cumulative rank, run!

503 Service Temporarily Unavailable

API may be requested at most 1 time per two seconds

Yes, I forgot to sleep between API calls:

time.sleep(2)

I don't remember how much time did it take, but it was really bad experience during at least one hour. Fortunately I have dotdict wrapper so I don't need to write obejct['field'] access, I can use object.field. Seams that my solution is really bad.

We need SDK. Let's google existing, there should be many of them!

First one doesn't have any types, so can't help me in my struggle. Second one is really good. But

assert isinstance(from_, int), 'from_ should be of type int, not {}'.format(type(from_))

Of course it's not bad, it's python's feature and library solves this issue really well. But stop, why on earth do I use python?

Typescript!

Unlike javascript and python typescript has static typing. And types really help! We use c++ on codeforces for almost every problem, we know everything about types, yes.

So I decided to implement API wrapper on typescript.

With my sdk I've implemented typescript analog of bugaboo above within 10 minutes without looking at my python code and in documentation: autocomplete did this work for me.

So, why typescript? I use typescript during couple of years and know that it has some pros:

Type system

First of all, its type system really helps. It catches many-many-many errors in compile time whilst python throws it in runtime.

Let's look into example: SDK constructor can accept three arguments: lang, key and secret.

Python (let's take CodeforcesAPI as model solution):

def __init__(self, lang=CodeforcesLanguage.en, key=None, secret=None):

Ok, seams that we can use it as CodeforcesAPI(key=key). Or CodeforcesAPI(secret=secret). It's definetely not what we want. And library will fail in runtime or just say nothing at all.

Typescript:

type DefaultApiOptions = {
    lang?: AvailableLanguages
} & ({} | {
    secret: string
    key: string
})

It explicitly says, that it accepts optional lang and one of (nothing more) and (both key and secret). So if we try to call method with argument of this type with {key: key} it just won't compile.

It's just small example and type system allows you many convenient things.

Aliases

Secondly, typescript allows creating implicitlty unconvertible type aliases.

type First = number & { __unique__: 'first' }
type Second = number & { __unique__: 'second' }
const x: number = 5
const f = (arg: Second) => {}

//f(5)          // <-- CE
//f(x)          // <-- CE
//f(x as First) // <-- CE
f(x as Second)  // <-- AC

Note that types exist ONLY in compile time and don't exists in runtime!

Why is it really cool feature? You can't imaging how many times I messed up function arguments in different order or different object field of same type.

As far as I know nor python neither c++ has this feature (without runtime overhead). Seams that some modern c++-killer language doesn't have this feature too.

Constructing new types

For example you want to query standings of multiple contests:

const multipleStandings = async (
    options: Omit<StandingsOptions, 'contestId'>,
    ...contestIds: Array<ContestId>
) => {
    for (const contestId of contestIds) {
        // const contest = await standings(options) // <-- CE, no contestId field
        const contest = await standings({...options, contestId})
        // ...
    }
}

We just proxyed our options to other method and deleted contestId field from it to ensure that caller won't fill this field. And typescript ensures that we filled removed field ourselves.

Strict null check

Imaging you are calculating some function f(rating: number). You got users with user.info method and call f(user.rating). CE.

Argument of type 'number | undefined' is not assignable to parameter of type 'number'

Why? Because unrated users don't have rating, they have undefined instead. If you are sure, that user has rating, e.g. you filtered unrated users you can add !: f(user.rating!). Otherwise you can add default value if rating is undefined: f(user.rating ?? 0). Anyway you explicitly say typescript that you know what you do.

Modules

Almost everyting you can import in python you can easily import (or at least require) in typescript. For all other things there is mastercard ffi.

Performance

According to Mike's heap benchmark js is only three times slower than c++. But we implement our scripts on python, nobody cares!

Lazyness

If your type is too complicated or you want something forbidden (from typescript's point of view) you can just use any or unknown types. Or even add @ts-ignore annotation to silent compilation error.

Does somebody still needs python?

As for me, I will use python for:

  • testgens;
  • one-liners;
  • calculator;
  • import yyy $$$\implies$$$ solved;
  • legacy.

Can I use typescript in contests?

Yes, but no.

  • It doesn't have long long.
  • It doesn't have stl. You should implement it yourself.
  • Stack size is not set for javascript, I tried to solve this task and failed.

Links

If you want use it or want to see some examples, just follow links below.

NPM

Github


PS: I know that typescript transpiles, not compiles but in this context it doesn't matter.

PPS: ironycally, almost at the same time this library was published (6th January), but mine was created on 20 December though in private repo. It has really similar implementation, but doesn't use type aliases and enums for enums.

PPPS: I know that according to pep8 there is no space here: f(param = param).

PPPPS: There were 1290 participants who took part in all 5 contests.

Полный текст и комментарии »

  • Проголосовать: нравится
  • +10
  • Проголосовать: не нравится

Автор Igorjan94, история, 16 месяцев назад, По-английски

Have you ever seen such a big number?

I can't even estimate how happy this guy was when finally got AC. Contest link, profile

PS: Do not forget to not discuss this problem, because contest is still running!

Полный текст и комментарии »

  • Проголосовать: нравится
  • +15
  • Проголосовать: не нравится

Автор Igorjan94, 4 года назад, По-русски

Сегодня, 19 марта 2020 года количество регистраций на контест впервые перевалило через фантастические 18000. Если быть точным, то 18180 (еще один участник и количество было бы палиндромом). Но всего лишь один год (!) назад это количество перевалило 10000, таким образом мы имеем прирост почти в два раза. Да, мы все больны спортивным программированием и это заразно.

Меньше слов, больше картинок:

По графику видно три занимательных вещи:

  • Март, 2014: Черный день. Я уже успел забыть, что такое когда-то случилось. Тем временем сейчас в начале контеста даже при 10к участников практически нет очереди посылок;
  • Сентябрь, 2015: Вторая революция цветов и званий;
  • Верхняя огибающая включает в себя смешанные раунды, такие как Hello/Goodbye/Global раунды.

Полный текст и комментарии »

  • Проголосовать: нравится
  • +155
  • Проголосовать: не нравится

Автор Igorjan94, 5 лет назад, По-английски

Hello, Codeforces!
About 3 years ago, I made the tool, which was parsing codeforces html and was collecting info about comments and blogs: only author and rating. Later I added dynamic info about users, such as number of posts or comments. It was interesting, funny, but not useful at all: it hardly changes during the time, it changes only when some outstanding blog or comment appears.

So, codeforces added API for blogs, I learned more modern technologies and rewrote code third time. Now I added timestamp, title and first 200 symbols of text to blogs and comments! For example, you can filter comments (and blogs) by time and see most upvoted of them during choosen period! Also you can see comment or blog text preview: just hover its link
Also you can search multiple handles: just insert comma between them: tourist, Petr. For strict search use double quotes: "tourist", "Petr"
As a bonus perfomance was improved significantly: request takes more than 200ms only if you search somebody's handle in comments and this is page with big number (or comments are in the end of choosen sort), while average time is about 10ms

[Try now!](http://codeforces.igorjan94.ru)

Полный текст и комментарии »

  • Проголосовать: нравится
  • +16
  • Проголосовать: не нравится

Автор Igorjan94, история, 6 лет назад, перевод, По-русски

C++17 уже доступен на codeforces, сообщество хочет новую версию C++ tricks, которую написал HosseinYousefi, так что, начнем!
Disclaimer: Я сделал всего лишь немного примеров новых фич, которые по моему мнению относятся к спортивному программированию. Если у Вас есть примеры лучше или Вам что-то непонятно, или нужно больше объяснений каких-то фич  —  пишите в комментах)

Fold expressions (Свертки)

  • Я думаю все знают, что такое reduce и свертка, но все-таки приведу пример из c++11:
vector<int> v = {1, 3, 5, 7};
int res = accumulate(v.begin(), v.end(), 0, [](int a, int b) { return a + b; });
cout << res; // 16
  • Начиная с C++17 есть поддержка свертки для шаблонного списка со следующим синтаксисом:
(pack op ...)
(... op pack)
(pack op ... op init)
(init op ... op pack)
  • Для примера напишем функцию, которая принимает переменное число аргументов и считает их сумму.

Полный текст и комментарии »

  • Проголосовать: нравится
  • +415
  • Проголосовать: не нравится

Автор Igorjan94, история, 8 лет назад, По-русски

Просматривая прямой эфир, я наткнулся на посты с топ 100 и топ 228 заплюсованными и заминусованными комментариями. В результате я решил сделать таблицу, в которой будет вся эта же информация, но которая будет со временем обновляться. Вот что результате получилось : click
На странице с комментариями видны отсортированные комментарии, абсолютное значение рейтинга которых превышает MAGICCOMMENTS(пока что 50). Планируется, что эта страница будет время от времени обновляться (сервер мониторит изменения прямого эфира каждые полчаса, а каждые 4 часов "просматривает" эти блоги на появление новых комментариев/изменение рейтинга старых)
На странице с пользователями виден суммарный "рейтинг" всех комментариев по пользователю, если абсолютное значение суммы превышает MAGICUSERS(пока что 0). Эта страница будет обновляться очень редко и только ручками с полным сканированием всех постов и комментариев заново)
(Голоса за блоги пока что никак не учитываются)

Буду рад услышать какую-нибудь критику/комментарии/предложения!

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

UPD1: Я переписал код немного больше, чем полностью(вплоть до смены языка с питона на джаву :) ), и теперь статистика обновляется по всем блогам, комментариям и пользователям (по приведенному выше алгоритму). Единственное ограничение на абсолютное значение осталось на комментариях из-за их большого количества. Также я добавил несколько приятных плюшек, с которыми стало немного удобнее пользоваться

UPD2: Code

Полный текст и комментарии »

  • Проголосовать: нравится
  • +128
  • Проголосовать: не нравится

Автор Igorjan94, 9 лет назад, По-русски

UPD0: Спасибо огромное всем за такую оценку моего скромного творения! Это вдохновило меня продолжить заниматься улучшением, и теперь плагин научился парсить контест, создавать файловую структуру контеста, примитивно тестить программу на скаченных тестах, показывать список контестов (спасибо I_love_Hoang_Yen), а условие задачи парсится без ошибок. На гитхабе ведется changelog, думаю, что дублировать его здесь нет смысла, ибо тот кто заинтересован, обновит плагин и так.

С Днем Рождения, CodeForces! Этот сайт я посещаю чаще всего, ибо тут совмещается очень много полезных и интересных вещей, а главное, что все делается с юмором и постоянно улучшается. Вот и я решил улучшить жизнь некоторых пользователей :)

Не так давно я начал использовать vim как основную IDE. Сначала, как и предполагалось, я не оценил всех прелестей и продолжал писать в Code::Blocks'е и QtCreator'e, в зависимости от задач. Но, "наставив" кучу плагинов научившись им пользоваться чуть больше чем "как отсюда выйти" и "как собирать программу", я уже достаточно сильно ругаюсь на другие среды разработки. Стоит отметить, что данное высказывание верно лишь для С++ и, наверно, python'а (хотя тут ни в чем другом не писал, не могу сравнивать). Что касается Java, тут безусловно лидирует IDEA, хотя я не против писать и в Eclipse. Можно здесь расписать кучу преимуществ, которые есть у vim'a, но я остановлюсь на одном, которое родилось на днях, основанное на идеях (J|C)Helper'a.

Собственно плагин. Полная информация на странице github'a, здесь я приведу лишь скрины и ключевые моменты, что же такого можно сделать.

  • Смотреть положение контеста(друзья, официальные, неофициальные, комната)

Полный текст и комментарии »

  • Проголосовать: нравится
  • +292
  • Проголосовать: не нравится