Igorjan94's blog

By Igorjan94, history, 5 months ago, In English

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!

Full text and comments »

  • Vote: I like it
  • +97
  • Vote: I do not like it

By Igorjan94, 15 months ago, In English

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.

Full text and comments »

  • Vote: I like it
  • +10
  • Vote: I do not like it

By Igorjan94, history, 16 months ago, In English

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!

Full text and comments »

  • Vote: I like it
  • +15
  • Vote: I do not like it

By Igorjan94, 4 years ago, translation, In English

Today (March 19, 2020) first time count of registrations per round became greater than fantastic 18000. To be presice it was 18180 (just one more and it would be palindrome). But only one (!) year ago it became more than 10000, so, it increased almost twice. Yes, we are sick of sports programming and it's contagious.
Less words, more pictures:

Three notable things:

  • March, 2014: Black day. I've already forgot about it. Now with even with more than 10k participants codeforces has almost no queue in the beginning of contests;
  • September, 2015: The Second Revolution of Colors and Titles;
  • Upper envelope of this graph is combined contest, such as Hello/Goodbye/Global rounds.

Full text and comments »

  • Vote: I like it
  • +155
  • Vote: I do not like it

By Igorjan94, 5 years ago, In English

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)

Full text and comments »

  • Vote: I like it
  • +16
  • Vote: I do not like it

By Igorjan94, history, 6 years ago, In English

C++17 is now available on codeforces, community wants new edition of C++ tricks by HosseinYousefi, so, let's start!
Disclaimer: I have done only few examples of new features, which in my opinion are related to competitive programming. Feel free to comment and provide more real-world examples or ask to elaborate some features with more examples or explanations.

Fold expressions

  • I think that everybody knows, what reduce or fold means, but a c++11 example:
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
  • In C++17 there is also folding support for a template parameters list. It has the following syntax:
(pack op ...)
(... op pack)
(pack op ... op init)
(init op ... op pack)
  • For example, implement a template function that takes a variable number of parameters and calculates their sum.

Full text and comments »

  • Vote: I like it
  • +415
  • Vote: I do not like it

By Igorjan94, history, 8 years ago, translation, In English

Looking through recent actions, I caught up blogs with top 100 and top 228 comments. So, I decided to do the table, which will contain all the same info as blogs have, but which will be updating. The result is here : click
On page with comments there are comments, which has absolute value more then MAGICCOMMENTS(now it is 75). It should be updating one per 6 hours (server looks through recent action every half-hour and every 6 hours parses these blogs for rating of new or updated comments
On page with users there is sum of votes for all comments of user, if absolute value is more than MAGICUSERS(now it is 500). This page will be refreshing too rare only by hand by scanning all posts and comments again
(Votes for blogs aren't taken into consideration)

I'll be glad to here some criticism/comments/advice!

PS. Please, if you see any mistake in translation, PM me :)

UPD0: In first release I occasionally parsed only english comments, now all information should be relevant. Soon, there will be page will votes for posts.

UPD1: I've rewritten my code little more than comletely(even switched from python to java :) ), and now there is full statistics on blogs, comments and users (updated by mentioned algo). Only restrict on absolute value is on comments because of their count. Also I did some nice features for more convenient usage

UPD2: Code

Full text and comments »

  • Vote: I like it
  • +128
  • Vote: I do not like it

By Igorjan94, 9 years ago, translation, In English

UPD0: Thank you everybody for such appreciation of my plugin! It inspired me to continue improving it and now my plugin can parse contest, create file structure of it, has primitive testing on downloaded samples, shows list of contests (thanks to I_love_Hoang_Yen), problem statement is parsing correctly and so on. You can see changelog on github, I think I wont duplicate it here. Everybody who is interested in it, update plugin without any notification.

Happy birthday, CodeForces! This is my favorite site, cause here I can find lots of useful and interesting things. And everything is done with good sense of humor and is constantly upgrading. So I decided to improve some users' life too :)

I started using vim as main IDE for about one year ago. In the beginning, as was implied, I didn't estimate all advantages of it and coded in Code::Blocks or QtCreator, depending on problem. But later, when I installed all plugins knew how to use it, I don't like other IDE's. It is true only for C++ and, imho, python. What about Java, I use Intellij IDEA and Eclipse, but can redact small files in vim too. I can write big post about advantages of vim, but I'll tell only about one, which was "born" some days ago and is has the same idea as (J|C)Helper

Main page of plugin is on github, here I post only screens and main features of it.

  • Watch standings of contest(friends, official, unofficial, room)

Full text and comments »

  • Vote: I like it
  • +292
  • Vote: I do not like it