<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Rui Alves Blog]]></title><description><![CDATA[Tech-related Blog]]></description><link>https://blog.ruialves.me</link><generator>GatsbyJS</generator><lastBuildDate>Thu, 24 Mar 2022 17:01:37 GMT</lastBuildDate><item><title><![CDATA[The Return of the Jedi - Part 3]]></title><description><![CDATA[This is the final part of a multi-part post. If you haven't already, feel free to check out the other parts: Part 1 - Boosting my chess club…]]></description><link>https://blog.ruialves.me/the-return-of-the-jedi-3/</link><guid isPermaLink="false">https://blog.ruialves.me/the-return-of-the-jedi-3/</guid><pubDate>Mon, 26 Jul 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is the final part of a multi-part post. If you haven&apos;t already, feel free to check out the other parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Part 1 - &lt;a href=&quot;https://blog.ruialves.me/the-return-of-the-jedi-1&quot;&gt;Boosting my chess club&apos;s website with Cloudflare and Heroku&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Part 2 - &lt;a href=&quot;https://blog.ruialves.me/the-return-of-the-jedi-2&quot;&gt;Insights on my MSc Thesis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Part 3 - You&apos;re here!&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;I&apos;m finally an engineer! 🎉&lt;/p&gt;
&lt;p&gt;A couple of weeks ago, on the 12th of July, I finally defended my MSc thesis — The presentation went really well and I had a really nice and insightful discussion with the jury, managing to pull off a final grade of 20, which was pretty neat. With that, I&apos;ve finally graduated as a Computer Engineer with a final GPA of 19/20 — the hard work paid off!&lt;/p&gt;
&lt;p&gt;That being said, I&apos;m now starting a new big journey. Earlier today I arrived in London where I will be staying in the future to work for Palantir Technologies as a Software Engineer! I&apos;m really excited to start, and I&apos;m sure I will be facing a lot of interesting challenges and that I will learn plenty of new things.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;This wasn&apos;t much of a post, it was more of a status update than anything 😅 I&apos;m probably going to be busy with settling in during the near future, so I will likely not be posting anything in the meantime. I will be back once I have something interesting to write about, though 😋&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The Return of the Jedi - Part 2]]></title><description><![CDATA[Hey! This is the second part of a multi-part post. If you haven't already, feel free to check out the other parts: Part 1 - Boosting my…]]></description><link>https://blog.ruialves.me/the-return-of-the-jedi-2/</link><guid isPermaLink="false">https://blog.ruialves.me/the-return-of-the-jedi-2/</guid><pubDate>Sun, 04 Jul 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hey! This is the second part of a multi-part post. If you haven&apos;t already, feel free to check out the other parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Part 1 - &lt;a href=&quot;https://blog.ruialves.me/the-return-of-the-jedi-1&quot;&gt;Boosting my chess club&apos;s website with Cloudflare and Heroku&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Part 2 - You&apos;re here!&lt;/li&gt;
&lt;li&gt;Part 3 - &lt;a href=&quot;https://blog.ruialves.me/the-return-of-the-jedi-3&quot;&gt;Finally an Engineer and next steps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;For this second part, I want to focus on the stuff I&apos;m working on at the moment. Throughout the past months, I&apos;ve been working on my master&apos;s degree thesis — &lt;strong&gt;Towards the Partitioning and Operation of Web Applications leveraging Platform and Function as a Service&lt;/strong&gt; — I challenge and dare you to say the full name in one go, I double dare you! I know I certainly can&apos;t 😅&lt;/p&gt;
&lt;p&gt;Jokes aside, it has been pretty insightful to be researching and learning so much about cloud computing. Although I didn&apos;t have the chance to explore as many services and &quot;stuff&quot; as I wanted to, I certainly did learn a lot! Unfortunately, I can&apos;t provide a lot of information about my thesis at the present moment since I will be defending it in my final presentation on the 12th of July — The presentation is going to be public and &lt;a href=&quot;https://www.twitch.tv/feup_dei_sala2&quot;&gt;streamed on Twitch&lt;/a&gt;, so feel free to show up!&lt;/p&gt;
&lt;p&gt;Anyway, I think it should be alright if I share just a few insights. My work consisted of facilitating the partitioning and deployment of web applications into multiple cloud service models (namely PaaS and FaaS) in order to allow developers to optimise their applications by using the best that each model has to offer. Although this may sound cute and idyllic, it is not quite trivial since it poses a great deal of challenges in infrastructure management, system observability and monitoring, traffic routing, overall robustness, and a bunch of other things.&lt;/p&gt;
&lt;p&gt;That being said, my research in the past few months culminated in really-big-document-with-over-100-pages-dissertation and in the development of a &lt;a href=&quot;https://pypi.org/project/django-cloud-deployer/&quot;&gt;plugin package&lt;/a&gt; for &lt;code&gt;Python&lt;/code&gt; that works on &lt;code&gt;Django&lt;/code&gt; web applications. A quick disclaimer: the package itself is simply a proof of concept of my dissertation&apos;s key findings and still needs a lot of work in order to be fully robust, work with a multitude of cloud providers (at the moment, it only operates with &lt;code&gt;Azure&lt;/code&gt; and &lt;code&gt;Heroku&lt;/code&gt;), and to be of real use to the cloud development community. Additionally, I also synthesised a part of the key findings (mostly regarding traffic routing among distinct cloud service models) into a small scientific paper that should be published in a cloud-related conference in the near future (more on that later)!&lt;/p&gt;
&lt;p&gt;It is hard to work on other things while one is focused on something as &quot;big&quot; as an MSc thesis; However, in the meantime, I&apos;ve finally picked up some motivation and started to add a couple of features to my &lt;a href=&quot;https://chess.ruialves.me/&quot;&gt;personal chess website&lt;/a&gt;. Moreover, I&apos;ve started to learn a bit about &lt;code&gt;Kubernetes&lt;/code&gt;, something which has been in my backlog for ages now.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;In the following and final part, I&apos;m going to be writing about my future steps after finishing my degree in computer engineering — BIG things are coming...!&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The Return of the Jedi - Part 1]]></title><description><![CDATA[I'm back! This is my first time writing something here in months since I haven't had much time (nor motivation, to be honest) recently since…]]></description><link>https://blog.ruialves.me/the-return-of-the-jedi-1/</link><guid isPermaLink="false">https://blog.ruialves.me/the-return-of-the-jedi-1/</guid><pubDate>Sat, 03 Jul 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;m back! This is my first time writing something here in months since I haven&apos;t had much time (nor motivation, to be honest) recently since I&apos;ve been focusing on my thesis and a couple other things. Nevertheless, I&apos;ve got a bunch I want to write about, so I&apos;ll be breaking this post into different parts, so stay tuned!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Part 1 - You&apos;re here!&lt;/li&gt;
&lt;li&gt;Part 2 - &lt;a href=&quot;https://blog.ruialves.me/the-return-of-the-jedi-2&quot;&gt;Insights on my MSc Thesis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Part 3 - &lt;a href=&quot;https://blog.ruialves.me/the-return-of-the-jedi-3&quot;&gt;Finally an Engineer and next steps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;For the past few years, I&apos;ve been developing and maintaining my chess club&apos;s (Grupo de Xadrez do Porto) website in my free time, as I&apos;ve mentioned in a &lt;a href=&quot;https://blog.ruialves.me/a-meteoric-regret&quot;&gt;previous post&lt;/a&gt;. The website was developed using &lt;code&gt;Meteor&lt;/code&gt; and features a bunch of information about the club&apos;s activities, players, and a few other things. I initially started by hosting it using &lt;code&gt;AWS&lt;/code&gt; free tier, which offers a low-budget VPS. After the free tier terminated, the club decided to extend the &lt;code&gt;AWS&lt;/code&gt; hosting for another year.&lt;/p&gt;
&lt;p&gt;In terms of domain management, the club has been renewing the same domain for years and years now. Initially, the domain was being managed at &lt;a href=&quot;https://www.dns.pt/pt/&quot;&gt;dns.pt&lt;/a&gt;, which is terrible in terms of management flexibility. I &quot;upgraded&quot; the management to &lt;a href=&quot;https://www.dominios.pt/&quot;&gt;dominios.pt&lt;/a&gt; which, although it wasn&apos;t perfect, was surely a big improvement.&lt;/p&gt;
&lt;p&gt;However, in the end of the last year, it was brought to my attention by a &lt;a href=&quot;https://miguelpduarte.me/&quot;&gt;good friend&lt;/a&gt; that &lt;code&gt;CloudFlare&lt;/code&gt; was not only pretty neat for domain management, but also the first company to offer SSL/TLS protection free of charge and without bothersome configuration. Since I had some free time on my hands, I decided to go all-in with &lt;code&gt;CloudFlare&lt;/code&gt;, and I am very happy with the results. The process took less than a couple of hours, and I&apos;ve then started using &lt;code&gt;CloudFlare&lt;/code&gt; for my personal domain as well — It is a game-changer.&lt;/p&gt;
&lt;p&gt;While I was at it, I also decided to make some changes to the website itself. Since it was hosted in an &lt;code&gt;AWS&lt;/code&gt; IaaS, managing updates and adding new features was at times a bit cumbersome and not as automatic as I would like. After doing some digging around the &lt;em&gt;internets&lt;/em&gt;, I found out that &lt;code&gt;Heroku&lt;/code&gt; free tier features a &lt;code&gt;Meteor&lt;/code&gt; buildpack which facilitates the deployment process. I then created a staging instance to check if it was &quot;solid&quot; enough to hold up in production, and did a bit of load testing using &lt;code&gt;Locust&lt;/code&gt; to check if it held up with some traffic in its hands. Since we don&apos;t have (and won&apos;t have any time in the near future) a large number of people accessing the website, it proved to be more than enough. I have then deleted the &lt;code&gt;AWS&lt;/code&gt; instance and moved everything to &lt;code&gt;Heroku&lt;/code&gt;, and I now have a much easier time pushing updates and changes to production. Additionally, it was also quite easy to configure the custom domain in the &lt;code&gt;Heroku&lt;/code&gt; PaaS instance — I simply added the domain and received a DNS target that allowed me to create a CNAME record in &lt;code&gt;CloudFlare&lt;/code&gt;, easy peasy!&lt;/p&gt;
&lt;p&gt;Finally, I also added a couple of new features to the website&apos;s management dashboard. Firstly, I added the capability of bulk editing players info, which is pretty useful, specially in the beginning and ending of tournament-season. Additionally, I enhanced the updating of photos (some of the pictures were hard-coded, which was far from ideal 😬) and did some minor tweaks in styling here and there. I&apos;m finally &lt;em&gt;moderately&lt;/em&gt; happy with &lt;a href=&quot;https://www.gxp.pt&quot;&gt;the website&lt;/a&gt; 😅&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;In the following parts, I&apos;m going to be writing a little bit about some side projects, my thesis, and my future work plans.&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[I miss Programming!]]></title><description><![CDATA[It's been a while since I last wrote something, mainly because I've been dedicating most of my time to my MSc Thesis (more on that later…]]></description><link>https://blog.ruialves.me/i-miss-programming/</link><guid isPermaLink="false">https://blog.ruialves.me/i-miss-programming/</guid><pubDate>Wed, 24 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It&apos;s been a while since I last wrote something, mainly because I&apos;ve been dedicating most of my time to my MSc Thesis (more on that later). However, I&apos;ve been fiddling around with some side projects and background ideas.&lt;/p&gt;
&lt;h2&gt;Chess games page&lt;/h2&gt;
&lt;p&gt;Chess matches annotations follow a specific standard called &lt;a href=&quot;http://www.saremba.de/chessgml/standards/pgn/pgn-complete.htm&quot;&gt;PGN&lt;/a&gt;. Although my chess games pages already allowed exporting my games to this &lt;code&gt;PGN&lt;/code&gt; format, it didn&apos;t follow the metadata standards and wasn&apos;t fully compatible with &lt;code&gt;PGN&lt;/code&gt; readers. Thus, I took some time in adapting the &quot;Export Game to &lt;code&gt;PGN&lt;/code&gt;&quot; functionality to ensure it followed the standard.&lt;/p&gt;
&lt;p&gt;I had been using this functionality mostly to later import the match using &lt;a href=&quot;https://lichess.org/&quot;&gt;Lichess&lt;/a&gt; so that I could analyse it. Since this takes a lot of clicks, I decided to also add an &quot;Analyse with Lichess&quot; functionality that uses the &lt;a href=&quot;https://lichess.org/api#operation/gameImport&quot;&gt;Lichess API&lt;/a&gt; to export the match and quickly analyse it (using Lichess&apos; &lt;a href=&quot;https://stockfishchess.org/&quot;&gt;Stockfish&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Besides that, I fixed some small things here and there (mostly to improve UX a bit). I&apos;ve also integrated &lt;a href=&quot;https://analytics.google.com/&quot;&gt;Google Analytics&lt;/a&gt; in the website, which was actually fairly straightforward since &lt;code&gt;Gatsby&lt;/code&gt; (I&apos;m using &lt;code&gt;Gatsby&lt;/code&gt;, incidentally) features a plugin that automates most of this purpose. Although it provides some pretty cool insights, most of the stuff looks to me like a bunch of codswallop, to be honest 😅&lt;/p&gt;
&lt;p&gt;You can check this stuff out at &lt;a href=&quot;https://chess.ruialves.me/game/sim%C3%A3opintor-vs-ruialves-29-11-2019&quot;&gt;a match&apos;s page&lt;/a&gt; on my chess website.&lt;/p&gt;
&lt;h2&gt;MSc Thesis&lt;/h2&gt;
&lt;p&gt;My thesis is named &lt;em&gt;Annotation-Based Runtime Partitioning of Web Applications into FaaS&lt;/em&gt;. Basically, my premise is that if a cloud-based web application can automatically move parts of itself from IaaS/PaaS into FaaS and vice-versa at runtime, it should be able to improve stuff such as client latency and infrastructure costs — that is, Cloud-stuff goes beep boop.&lt;/p&gt;
&lt;p&gt;I&apos;m currently doing research on this domain and I&apos;ll be implementing a proof of concept plugin for the Django web framework, throughout the next few months, to validate my findings.&lt;/p&gt;
&lt;h2&gt;Competitive Programming&lt;/h2&gt;
&lt;p&gt;A few months ago I stopped doing &lt;a href=&quot;https://leetcode.com/&quot;&gt;LeetCode&apos;s&lt;/a&gt; daily challenges and competitions altogether and, meanwhile, I completed the &lt;a href=&quot;https://adventofcode.com/2020&quot;&gt;Advent of Code 2020&lt;/a&gt; challenge. Other than that, I&apos;ve been completely out of action in this type of stuff. A few days ago I started to miss it, so my plan is to pick up &lt;a href=&quot;https://www.codewars.com/&quot;&gt;Code Wars&lt;/a&gt; and some old &lt;a href=&quot;https://adventofcode.com/2016/&quot;&gt;AoC&lt;/a&gt; unfinished challenges that have been in my backlog for way too long.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Research work is weird and different from what I&apos;m used to. However, this is the last step in my MSc and, after this, I&apos;ll be doing more practical stuff for a lot of time, so I guess I&apos;ll do my best to enjoy the ride.&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Advent of Code 2020]]></title><description><![CDATA[Advent of Code is a Christmas-theme programming competition that takes place every year during the first 25 days of December. Usually, it's…]]></description><link>https://blog.ruialves.me/advent-of-code-2020/</link><guid isPermaLink="false">https://blog.ruialves.me/advent-of-code-2020/</guid><pubDate>Thu, 07 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://adventofcode.com/&quot;&gt;Advent of Code&lt;/a&gt; is a Christmas-theme programming competition that takes place every year during the first 25 days of December. Usually, it&apos;s your job to save Christmas!&lt;/p&gt;
&lt;p&gt;I&apos;ve been participating every year for the past five years, and I always end up getting addicted and spending a lot of time on the challenges, so this year I decided that I wouldn&apos;t be participating. Naturally, this resistance lasted a single day, and, except for day 1, I managed to solve all exercises in their publish-day.&lt;/p&gt;
&lt;p&gt;I wanted to share some insight into the challenges that I found interesting and enjoyed the most.&lt;/p&gt;
&lt;h2&gt;Day 10: Adapter Array&lt;/h2&gt;
&lt;p&gt;This challenge consisted of helping our hero to connect a set of &lt;em&gt;joltage&lt;/em&gt; adapters. Part 1 was pretty straight-forward. However, the second part was a bit more challenging. This was the first challenge that wasn&apos;t solvable using a brute-force solution (as visible in the leaderboard). I ended up using a &lt;code&gt;DFS&lt;/code&gt; + cache solution, although the challenge was screaming for dynamic programming:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;def dfs(joltages: ArrayBuffer[Long], i: Int): Long = {
    if (cache.contains(i)) return cache(i)

    cache(i) = (1 to 3).map(j =&gt; {
        if ((i + j &amp;#x3C; joltages.length) &amp;#x26;&amp;#x26; (joltages(i + j) &amp;#x3C;= joltages(i) + 3)) dfs(joltages, i + j)
        else 0
    }).sum

    cache(i)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Day 13: Shuttle Search&lt;/h2&gt;
&lt;p&gt;This one consisted of fixing a set of bus schedules. Similar to the previous one, part 1 was quite trivial. When reading part 2, I had some flashbacks of the Discrete Mathematics course I took about four years ago, specifically about the &lt;a href=&quot;https://en.wikipedia.org/wiki/Chinese_remainder_theorem&quot;&gt;Chinese Remainder Theorem&lt;/a&gt;. In short, it consists of finding a number &lt;code&gt;N&lt;/code&gt;, such that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;N = a (mod x)
N = b (mod y)
N = c (mod z)
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With a few tweaks and tricks, this can be applied to our problem. Assuming that the input is &lt;code&gt;17,x,13,19&lt;/code&gt; and that we want to find the earliest timestamp &lt;code&gt;T&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;T = 0 (mod 17)
T + 2 = 0 (mod 13)
T + 3 = 0 (mod 19)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;...and by applying a bit of mod-space algebra ...&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;T = 0 (mod 17)
T = 13 - 2 (mod 13) = 11 (mod 13)
T = 19 - 3 (mod 19) = 16 (mod 19)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Although after browing through the &lt;a href=&quot;https://www.reddit.com/r/adventofcode/&quot;&gt;AoC Reddit&lt;/a&gt; I found out that there were other ways of solving this, I&apos;m absolutely sure this is the coolest one 😎&lt;/p&gt;
&lt;h2&gt;Day 17: Conway Cubes&lt;/h2&gt;
&lt;p&gt;Although not difficult, this challenge took &lt;a href=&quot;https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life&quot;&gt;Conway&apos;s Game of Life&lt;/a&gt; to the next level by creating a 3-dimensional and 4-dimensional version in parts 1 and 2, respectively. Even though I&apos;m pretty happy about my solution, it doesn&apos;t need to be very efficient since the problem statement only asks for 6 iterations.&lt;/p&gt;
&lt;h2&gt;Day 18: Operation Order&lt;/h2&gt;
&lt;p&gt;This one consisted of evaluating a numeric expression. The twist is that operators have different levels of precedence, which was a bit counter-intuitive! I used a stack-based approach to solve it linearly, similarly to my solution for a &lt;a href=&quot;https://leetcode.com/problems/basic-calculator-ii/&quot;&gt;LeetCode Calculator Problem&lt;/a&gt; I had solved about a year.&lt;/p&gt;
&lt;h2&gt;Day 23: Crab Cups&lt;/h2&gt;
&lt;p&gt;In this challenge, the goal was to play a version of the cups game with a crab (yeap, it&apos;s a Christmas-themed competition). Part 1 had a very small-sized input, so it was solvable without the need for a very elaborate solution. However, the input size was much larger in part 2. Since I was pretty much expecting the differences in input size to be substantial between both parts, I tried to come up with an efficient solution from the start. &lt;/p&gt;
&lt;p&gt;This problem was, by nature, very similar to the &lt;a href=&quot;https://leetcode.com/problems/lru-cache/&quot;&gt;LeetCode LRU Cache&lt;/a&gt; problem I had solved a few months before.&lt;/p&gt;
&lt;h2&gt;Day 24: Lobby Layout&lt;/h2&gt;
&lt;p&gt;I find hexagonal grids to be very interesting for some reason (as do &lt;a href=&quot;https://uxdesign.cc/why-do-bees-love-hexagons-119cfd0d95a9&quot;&gt;bees&lt;/a&gt;, go figure!), so I really enjoyed this one. After reading the statement, I instantly remembered about a similar &lt;a href=&quot;https://adventofcode.com/2017/day/11&quot;&gt;Advent of Code 2017 Challenge&lt;/a&gt; I had solved a few years back, so I ended up using the same 2D-matrix coordinate representation I used back then:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;final val STEPS_DELTAS = Map(
    &quot;w&quot; -&gt; new Cell(-2, 0),
    &quot;e&quot; -&gt; new Cell(2, 0),
    &quot;sw&quot; -&gt; new Cell(0, 1),
    &quot;se&quot; -&gt; new Cell(1, 1),
    &quot;nw&quot; -&gt; new Cell(-1, -1),
    &quot;ne&quot; -&gt; new Cell(0, -1)
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, a &lt;a href=&quot;https://hugopeixoto.net/articles/advent-of-code-2020-week-3-4.html&quot;&gt;friend of mine&lt;/a&gt; pointed me to an article that actually uses a lot let space with a slightly different representation:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;final val STEPS_DELTAS = Map(
    &quot;w&quot; -&gt; new Cell(-1, 0),
    &quot;e&quot; -&gt; new Cell(1, 0),
    &quot;sw&quot; -&gt; new Cell(0, 1),
    &quot;se&quot; -&gt; new Cell(1, 1),
    &quot;nw&quot; -&gt; new Cell(-1, -1),
    &quot;ne&quot; -&gt; new Cell(0, -1)
)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;I solved all the challenges using &lt;code&gt;Scala&lt;/code&gt;, and I ended up improving my coding skills with this language quite a bit since I pretty much learned something new every other day. For me, this year&apos;s edition was the most enjoyable one by far, which motivated me to solve every challenge in their publish-day. I will be back next year with more Xmas-coding!&lt;/p&gt;
&lt;p&gt;Cheers, I (sincerely) hope that 2021 is better than 2020 for everyone!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SINF 2020 Programming Contest]]></title><description><![CDATA[A few months ago I was invited by the SINF - Semana de Informática (Informatics Week) organization team to organize and develop the…]]></description><link>https://blog.ruialves.me/sinf-2020-programming-contest/</link><guid isPermaLink="false">https://blog.ruialves.me/sinf-2020-programming-contest/</guid><pubDate>Fri, 13 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A few months ago I was invited by the &lt;a href=&quot;https://www.sinf.pt/&quot;&gt;SINF - Semana de Informática&lt;/a&gt; (Informatics Week) organization team to organize and develop the challenges for their annual Programming Contest.&lt;/p&gt;
&lt;p&gt;A bit of context: &lt;strong&gt;SINF&lt;/strong&gt; is an event organized by students for students, that takes place every year at FEUP, the Faculty of Engineering of the University of Porto, which aims to provide tech-related content and first-hand contact with tech companies to college students. The event has been organized by &lt;a href=&quot;https://ni.fe.up.pt/&quot;&gt;NIAEFEUP&lt;/a&gt; in the past 3 editions.&lt;/p&gt;
&lt;p&gt;Although I&apos;ve been a member of the organization team of this event in the past 2 editions, I was quite glad to take on a different role this time. This was my first time ever organizing a Programming Competition and creating new original problems, which was quite an interesting challenge! However, I must add that I got a lot of help from my friend &lt;a href=&quot;https://github.com/GuilhermeJSilva/&quot;&gt;Guilherme Silva&lt;/a&gt;, which not only was my beta tester but who also gave me a lot of feedback regarding how to structure and improve the problems. I would also like to thank Professor &lt;a href=&quot;https://web.fe.up.pt/~arestivo/page/&quot;&gt;André Restivo&lt;/a&gt; for taking the time to review the problem statements.&lt;/p&gt;
&lt;p&gt;The contest was held from the 8th to the 11th of November 2020 and featured a total of 6 original problems, which were released in pairs throughout the 3 days of competition. A total of 66 people from different parts of the country signed in and, in the end, a total of 5 people were able to solve all the problems!&lt;/p&gt;
&lt;p&gt;The problems were organized in a sort-of-ascending-difficulty-manner, and their main theme was to help the organization team solve problems that required the help of programming! Each of them was assigned a score based on its difficulty:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Scheduling the First Meeting&lt;/strong&gt; - 100 points (Easy), 88.89% success rate&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Minimizing Costs&lt;/strong&gt; - 275 points (Medium), 60.87% success rate&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;So many speakers&lt;/strong&gt; - 150 points (Easy), 75% success rate&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Grouping lecture themes&lt;/strong&gt; - 250 points (Medium), 94.12% success rate&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Organizing the workshop&lt;/strong&gt; - 250 points (Medium), 73.33% success rate&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Time to celebrate&lt;/strong&gt; - 350 points (Hard), 41.67% success rate&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More details about the competition can be found on the &lt;a href=&quot;https://www.hackerrank.com/contests/sinf-2020-programming-contest/challenges&quot;&gt;contest&apos;s Hackerrank page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Since doing it by hand would be not only a nightmare but also not reusable in the future, I developed a set of scripts to generate all the inputs and outputs. All of this and my proposed solutions for the problems can be found in my &lt;a href=&quot;https://github.com/xRuiAlves/SINF-2020-Programming-Competition&quot;&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I must say it was a lot of fun to get out of my comfort zone and accept this challenge and, for once, to be on the creating side of competitive programming. I hope I get the chance to do it again in the future!&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Scala, Hacktoberfest and my MSc Thesis]]></title><description><![CDATA[Learning Scala and Competitive Programming For a couple of months now, I've been wanting to learn Scala. I wanted to pick up something in…]]></description><link>https://blog.ruialves.me/scala-hacktoberfest-and-my-msc-thesis/</link><guid isPermaLink="false">https://blog.ruialves.me/scala-hacktoberfest-and-my-msc-thesis/</guid><pubDate>Sat, 07 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Learning Scala and Competitive Programming&lt;/h2&gt;
&lt;p&gt;For a couple of months now, I&apos;ve been wanting to learn &lt;code&gt;Scala&lt;/code&gt;. I wanted to pick up something in the functional programming spectrum, and Scala seemed like a very good choice (lots of support and documentation, cute syntax, ...). I was quickly amazed at how clean and tidy scala code looks. Moreover, I was pretty happy with the fact I could start by coding more OOP-java-like code (which is what I&apos;m used to) and slowly pivot towards the functional side.&lt;/p&gt;
&lt;p&gt;Right at the same time, I found out about &lt;a href=&quot;https://www.codewars.com/&quot;&gt;Code Wars&lt;/a&gt; (which is way too addictive incidentally) and start spitting out some cool one-liner solutions to the easier exercises while I got acquainted with the language. I also re-started &lt;a href=&quot;https://adventofcode.com/2019/&quot;&gt;Advent of Code 2019&lt;/a&gt;, which has a few nice problems that were cool to learn some new Scala concepts.&lt;/p&gt;
&lt;p&gt;On another note, I decided to drop LeetCode&apos;s daily challenges, since most of them are repeated and/or a bit too easy. I guess I might come back to them during the next month&apos;s challenges if I start to miss them 😛&lt;/p&gt;
&lt;p&gt;All in all, Scala seems to be pretty powerful and has a lot of ways of getting the same task done. As time goes by, I want to pivot towards the functional side of the scala spectrum as much as possible, since it was what got me into it in the first place.&lt;/p&gt;
&lt;h2&gt;Hacktoberfest&lt;/h2&gt;
&lt;p&gt;This year was my second time participating in &lt;a href=&quot;https://hacktoberfest.digitalocean.com/&quot;&gt;Hacktoberfest&lt;/a&gt;, an open to everyone month-long celebration of open source software that takes place every year during the month of October. &lt;/p&gt;
&lt;p&gt;Last year I decided to contribute to &lt;a href=&quot;https://github.com/tldr-pages/tldr&quot;&gt;tldr&lt;/a&gt; and joined two local Porto hubs to hack alongside other people, which was pretty cool (I also won a pair of &lt;a href=&quot;https://pbs.twimg.com/media/DbGA9NmWkAAm0if.jpg&quot;&gt;Sammy the Shark plush slippers&lt;/a&gt; that I am actually wearing right now).&lt;/p&gt;
&lt;p&gt;However, in 2020&apos;s edition my participation was fully remote (due to the current pandemic situation) and was more focused in contributing to some projects from &lt;a href=&quot;https://github.com/NIAEFEUP&quot;&gt;FEUP&apos;s Computer Engineering Student Branch&lt;/a&gt; (in which I&apos;ve been a member of the board for 2 years and member for almost 5 years now). Earlier in October, I was aiming to contribute to &lt;a href=&quot;https://github.com/lichess-org&quot;&gt;Lichess&lt;/a&gt;, a free and open-source internet chess server. However, since most of their services run in Scala, I didn&apos;t feel quite ready to dive into their codebase (which was another motivation for wanting to learn Scala!).&lt;/p&gt;
&lt;h2&gt;MSc Thesis: Automated API Refactoring for Edge Computing&lt;/h2&gt;
&lt;p&gt;As part of my last year in the &lt;a href=&quot;https://sigarra.up.pt/feup/en/cur_geral.cur_view?pv_curso_id=742&quot;&gt;Computer Engineering MSc&lt;/a&gt;, I am now working on my MSc thesis and dissertation, under the mentorship and guidance of Professor &lt;a href=&quot;https://sigarra.up.pt/feup/en/func_geral.formview?p_codigo=479881&quot;&gt;Tiago Boldt Sousa&lt;/a&gt;. I will be working towards implementing a web framework capable of self-inspection and self-organization, with the capacity of moving parts of its own API from cloud to edge computing, and vice-versa. &lt;/p&gt;
&lt;p&gt;I am quite happy with this topic, as it is a great opportunity to learn more about serverless computing models, as well as cloud and edge computing paradigms. Looking forward to investigating more about these subjects!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The &lt;a href=&quot;https://www.hackerrank.com/sinf-2020-programming-contest/&quot;&gt;SINF 2020 Programming Contest&lt;/a&gt; (the first programming contest I&apos;ve developed by myself) is starting tomorrow and will be up and running for 3 days, with new originals challenges every day! I&apos;m planning to write a bit about it (and maybe discuss some of the problems) in the near future.&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[So much to learn, so little time]]></title><description><![CDATA[This post will have a slightly different structure than usual since I want to share a bunch of things (without going into much detail into…]]></description><link>https://blog.ruialves.me/so-much-to-learn-so-little-time/</link><guid isPermaLink="false">https://blog.ruialves.me/so-much-to-learn-so-little-time/</guid><pubDate>Sat, 19 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This post will have a slightly different structure than usual since I want to share a bunch of things (without going into much detail into either of them). I can only start by saying this past month was a lot of fun, because I had a large amount of free time to work on a bunch of things that were on my backlog.&lt;/p&gt;
&lt;h2&gt;Organizing a Programming Competition&lt;/h2&gt;
&lt;p&gt;A few weeks ago I was asked by the &lt;a href=&quot;https://www.sinf.pt/&quot;&gt;SINF&lt;/a&gt; (a tech-related event for students) organization team to develop a set of programming challenges and host a competition for the event.&lt;/p&gt;
&lt;p&gt;I was very happy to accept the challenge and I&apos;ve come up with some pretty cool ideas that will, hopefully, make the competition challenging and fun, while at the same time being &quot;friendly&quot; for people who are just starting.&lt;/p&gt;
&lt;p&gt;The competition will last for 3 days and problems will be handed as daily challenges, so there&apos;s a lot of room for imagination!&lt;/p&gt;
&lt;h2&gt;Ethical Hacking is pretty cool&lt;/h2&gt;
&lt;p&gt;Being a nerdy nerd as I am, I&apos;ve always wanted to learn a bit about Ethical Hacking. Although I already had some concepts in mind that I have learned at college, I was mostly motivated to start it due to &lt;a href=&quot;https://miguelpduarte.me/blog/&quot;&gt;a friend&apos;s blog articles&lt;/a&gt;, in which he details his thought process when... &quot;hacking stuff&quot;.&lt;/p&gt;
&lt;p&gt;I decided to start an online course (so that I could learn about it in an &quot;organized&quot; way) and decided to pick &lt;a href=&quot;https://www.thecybermentor.com/&quot;&gt;The Cyber Mentor&lt;/a&gt;&apos;s course, since it had pretty good reviews. I&apos;m now about 35% through the course and I feel like I have learned a bunch. &lt;/p&gt;
&lt;p&gt;As suggested in the course&apos;s lectures, I&apos;m trying to take notes regarding methodologies and tools in an organized way. For that, I&apos;ve been using &lt;a href=&quot;https://zim-wiki.org/&quot;&gt;Zim Wiki&lt;/a&gt;. It is pretty user friendly and has a small learning curve (in terms of syntax). Although the wiki has no backup mechanisms, I&apos;ve implemented a small workaround using a Git repository and &lt;code&gt;anacron&lt;/code&gt; to periodically &quot;save&quot; changes.&lt;/p&gt;
&lt;p&gt;I&apos;m planning to dedicate some time to this and I&apos;m aiming to finish the course within the next couple of months. Then it&apos;s time to test what I&apos;ve learned in some CTFs! 😄&lt;/p&gt;
&lt;h2&gt;Improving my Chess Games app&lt;/h2&gt;
&lt;p&gt;As I&apos;ve mentioned in a previous blog post, I&apos;ve created and am currently maintaining a &lt;a href=&quot;https://chess.ruialves.me/&quot;&gt;Chess Games app&lt;/a&gt; where I share all my past chess games, so that I can analyze them at any time, to better understand my mistakes and help me improve my game.&lt;/p&gt;
&lt;p&gt;I had the idea of adding a chess engine live analysis to my board component to get an understanding of the computer&apos;s evaluation of given positions, while at the same time allowing the user to try on different possible moves on a given position. I&apos;m currently working on this and I&apos;m expecting to finish it within the next month!&lt;/p&gt;
&lt;h2&gt;Interview Preparation&lt;/h2&gt;
&lt;p&gt;Last but not least, I&apos;ve been devoting most of my time in the past weeks into preparing for an important interview I&apos;m having in the near future.&lt;/p&gt;
&lt;p&gt;I&apos;m taking it quite seriously, and the preparation has consisted mostly in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Solving Programming Challenges&lt;/strong&gt;, to brush up my problem-solving skills (I&apos;ve completed about &gt; 100 LeetCode problems in this process);&lt;/li&gt;
&lt;li&gt;Going through the &lt;strong&gt;Cracking the Coding Interview&lt;/strong&gt; book, to make sure I&apos;m ready to answer possible &lt;strong&gt;System Design&lt;/strong&gt; questions as well as possible;&lt;/li&gt;
&lt;li&gt;Analyzing my notes of &lt;strong&gt;Past Interviews&lt;/strong&gt;, to get a grasp of what I did well and what I need to work on;&lt;/li&gt;
&lt;li&gt;Taking some &lt;strong&gt;Interview Simulations&lt;/strong&gt;, which have been of great help by training me on how to answer &quot;unexpected questions&quot; (a special thanks to my friend &lt;a href=&quot;https://miguelpduarte.me/&quot;&gt;Miguel&lt;/a&gt; for taking the time and patience to sit with me for a few hours).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope everything goes well and that I have a good &quot;Return on Investment&quot; regarding my preparation! 😄&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;On a last note, I&apos;m starting my last year of my MSc in a couple of days. I&apos;m working on defining my Thesis theme, which will hopefully be very exciting to work on!&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[A Meteoric regret]]></title><description><![CDATA[About 2 years ago I was asked to build a new website for my chess club. In this article, I want to share a bit of my experience in…]]></description><link>https://blog.ruialves.me/a-meteoric-regret/</link><guid isPermaLink="false">https://blog.ruialves.me/a-meteoric-regret/</guid><pubDate>Thu, 13 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;About 2 years ago I was asked to build a new website for my chess club. In this article, I want to share a bit of my experience in developing a web app with &lt;a href=&quot;https://www.meteor.com/&quot;&gt;Meteor&lt;/a&gt; and why I&apos;ve come to regret that choice.&lt;/p&gt;
&lt;p&gt;Firstly, I&apos;ll share a few details about the project &lt;em&gt;per se&lt;/em&gt;. Before I started working on the project, the existing website was very 90&apos;s looking (with some blinking buttons) and had plenty of broken and empty pages. From what I understood, it was an &lt;code&gt;ASP.NET&lt;/code&gt; app that communicated with 4 &lt;code&gt;Microsoft Access&lt;/code&gt; databases (3 of them being empty for some reason). All of this was hosted without backup / version control in someone&apos;s home server. Although I can&apos;t be sure, my understanding is that new articles and posts were added by manually editing &lt;code&gt;HTML&lt;/code&gt; files via an &lt;code&gt;ssh&lt;/code&gt; connection. It was time for a change!&lt;/p&gt;
&lt;p&gt;The new website had two main requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A back office for the chess club management team, where someone without a technology background could easily manage articles, players, club activities, etc&lt;/li&gt;
&lt;li&gt;A clean fresh look to improve user experience, so that people would actually want to visit the website&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When I started tackling the project, I had been studying Computer Science for about 2 or 3 years and didn&apos;t have much experience in web development. Since this was a &quot;solo gig&quot;, I could choose whichever tech stack I wanted. After doing a bit of research (in hindsight, it was a very small bit), I thought that &lt;code&gt;Meteor&lt;/code&gt; was a very good option. I was mostly attracted by the fact I would be developing the whole app using only one programming language and by &lt;code&gt;Meteor&lt;/code&gt; using &lt;a href=&quot;https://graphql.org/&quot;&gt;GraphQL&lt;/a&gt; (I had read about it in some article and really wanted to give it a try). Moreover, I had only worked with relational databases, so I wanted to give &lt;code&gt;MongoDB&lt;/code&gt; a try. Although satisfying the &quot;client&apos;s&quot; needs was the priority, I saw this project as a big learning opportunity (and it was!).&lt;/p&gt;
&lt;p&gt;As of August 2020, the new website has been up for a little less than a year. The full development process took about 10/11 months. Due to budget limitations, the app is hosted in a &lt;code&gt;t2.micro AWS EC2&lt;/code&gt; and the &lt;code&gt;MongoDB&lt;/code&gt; database is hosted in &lt;code&gt;MongoDB Atlas&lt;/code&gt; (using their free tier, which is actually pretty good). I&apos;m using &lt;a href=&quot;https://www.dominios.pt/&quot;&gt;dominios.pt&lt;/a&gt; for DNS management (after a painful switching from &lt;a href=&quot;https://www.dns.pt/pt/&quot;&gt;dns.pt&lt;/a&gt;), but that&apos;s a story for another time.&lt;/p&gt;
&lt;p&gt;In the middle of having 2 years of studies, 3 internships and a bunch of side-projects, I ended up leaving the website untouched after deploying it (I didn&apos;t even set up SSL certificates). I&apos;m currently in the process of &quot;dockerizing&quot; the app and configuring SSL certificates to setup https.&lt;/p&gt;
&lt;p&gt;Now, let&apos;s get to why I&apos;ve come to regret the decision of choosing &lt;code&gt;Meteor&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;There is too much magic going on.&lt;/strong&gt; It does a lot for you, which can be a downside. There are many things that were built in order to work in a specific way out of the box and without being tweaked. It can be difficult (or even impossible) to configure a certain thing in a specific way (&lt;em&gt;e.g.&lt;/em&gt; Having custom authentication aspects or custom specific middlewares) and the community seems to value and prefer &quot;hacks&quot; that are not pretty nor maintainable to fix a known issue rather than adding support to fix it to the framework itself.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It is tightly-coupled with MongoDB.&lt;/strong&gt; Even though there&apos;s (supposedly, I haven&apos;t tried it myself) support for other &lt;code&gt;DBMSs&lt;/code&gt;, it was conceived in a way to be completely &lt;code&gt;MongoDB&lt;/code&gt; dependant, both as persistence storage and cache - if you want to avoid a bunch of hacking, you&apos;re pretty much stuck with &lt;code&gt;Mongo&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The lack of structure.&lt;/strong&gt; This is probably my biggest pain-point. Unlike other frameworks such as &lt;code&gt;Rails&lt;/code&gt;, &lt;code&gt;Phoenix&lt;/code&gt; or &lt;code&gt;Laravel&lt;/code&gt;, &lt;code&gt;Meteor&lt;/code&gt; lacks a decent structure with a clear separation of data, logics and views (which is really well defined in the aforementioned alternatives). In the long run, this makes a project quite hard to maintain.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Very, very slow build times.&lt;/strong&gt; Everything seems to take a lot of time, even if you&apos;re developing in a decent machine. Starting the development server, running tests, live-updating after applying changes, building for production - all these tasks take a lot more time than in other frameworks I&apos;ve tried before.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Small community support.&lt;/strong&gt; Although this is much more of a personal opinion than the former statements, there is a lot less community support than, for example, in the &lt;code&gt;Rails&lt;/code&gt; community. Even though there are experts in all languages, it&apos;s just way harder to find the help you&apos;re looking for.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Even though there are other things I&apos;m unhappy with (lack of basic core functionalities that can only be found in specific modules, unpredictability, etc), these are the biggest disadvantages to my eyes.&lt;/p&gt;
&lt;p&gt;Note that there are still plenty of perks in using &lt;code&gt;Meteor&lt;/code&gt; (such as being good for quick prototyping and relatively easy to learn). However, I don&apos;t feel they are enough to shift the &quot;scale&quot; to the positive side.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;In conclusion, I chose &lt;code&gt;Meteor&lt;/code&gt; for the wrong reasons, driven by lack of knowledge regarding alternatives. In the future, I should take more time choosing the ideal tech stack for the given scenario, which is a lot easier now since I have a bit more experience.&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Chess and Tech]]></title><description><![CDATA[Besides programming, Chess has been the only "hobby" that I've kept 100% active at throughout the past few years. It's fun, competitive…]]></description><link>https://blog.ruialves.me/chess-and-tech/</link><guid isPermaLink="false">https://blog.ruialves.me/chess-and-tech/</guid><pubDate>Tue, 04 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Besides programming, Chess has been the only &quot;hobby&quot; that I&apos;ve kept 100% active at throughout the past few years. It&apos;s fun, competitive, strategical, and virtually impossible to master - everything I like in a hobby!&lt;/p&gt;
&lt;p&gt;The past few weeks I&apos;ve been having fun coding stuff that automates some of the daily chess activities I usually do. These tasks involve annotating and publishing my chess games, keeping track of my current ratings (both online and &lt;a href=&quot;https://en.wikipedia.org/wiki/Glossary_of_chess#over-the-board&quot;&gt;over the board&lt;/a&gt;) and creating and hosting a bunch of weekly online tournaments for &lt;a href=&quot;https://lichess.org/team/grupo-de-xadrez-do-porto&quot;&gt;my chess club&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Chess games page&lt;/h2&gt;
&lt;p&gt;I started by making some changes to &lt;a href=&quot;https://chess.ruialves.me/&quot;&gt;my chess games page&lt;/a&gt;. I had to fix some package vulnerabilities that introduced breaking changes. After some minor tweaks here and there, I also added a small section displaying my online ratings using the &lt;a href=&quot;https://lichess.org/api&quot;&gt;Lichess API&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I already had a section featuring my over the board ratings, which was getting data from a &lt;a href=&quot;https://github.com/xRuiAlves/fide-ratings-scraper/&quot;&gt;scraper and API&lt;/a&gt; module I had developed to get ratings from FIDE&apos;s (the international chess federation) website since they don&apos;t expose a public API. However, some data appeared to be missing, so I decided to take a look at the scraper.&lt;/p&gt;
&lt;h2&gt;FIDE ratings scraper&lt;/h2&gt;
&lt;p&gt;As I&apos;ve mentioned, FIDE does not feature a public API. Thus, to get ratings and other info from players in a programmatic way, I decided to develop this scraper about a year ago. &lt;/p&gt;
&lt;p&gt;The missing data was due to a minor change FIDE made in a ratings HTML table section, which was quickly fixed by changing a query selector. However, the scraper&apos;s code was quite messy and needed a bit of a refactor, since the scraping logic was coupled with an express API I set up. Moreover, the test coverage was quite poor, so I also wanted to improve that.&lt;/p&gt;
&lt;p&gt;After separating the scraping logic and the API into different modules, I decided that I might as well add CLI interaction (which although is not my main use-case, it might be useful to someone) and &lt;a href=&quot;https://www.npmjs.com/package/fide-ratings-scraper&quot;&gt;publish the package on npm&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Lichess tournament creator&lt;/h2&gt;
&lt;p&gt;Throughout the past few months, I have been manually creating online tournaments for my chess club in Lichess. The tournaments always take place at the same time (Wednesdays and Saturdays) and have exactly the same format. Although this is not a very demanding task, I wanted to automate this process, and finding that Lichess had a public API was the &quot;kick&quot; I needed to get me started. I decided to build a CLI tool to create tournaments, which had basically two requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creating a tournament (either in Arena or Swiss format) with a set of specifications (duration, match time, etc) in a single command&lt;/li&gt;
&lt;li&gt;Creating tournaments in bulk from a given tournaments list input file (so that I could create a bunch of tournaments instantly, to save time)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They limit the number of tournaments a user can create daily (12 public tournaments), but creating tournaments for the following one and a half months was already pretty good for me. Although there are a bunch of settings a user can specify when creating a tournament, I didn&apos;t dive too much in adding all the features possible, since a simple version is enough to suffice my needs.&lt;/p&gt;
&lt;p&gt;I also &lt;a href=&quot;https://www.npmjs.com/package/lichess-tournament-creator&quot;&gt;published this package on npm&lt;/a&gt; and listed some of the future work, so maybe someone interested will take a look and contribute with some more features!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Regarding future plans, I&apos;d like to add &lt;a href=&quot;https://en.wikipedia.org/wiki/Chess_engine&quot;&gt;engine&lt;/a&gt; analysis to my chess games page. I would also like to start contributing to the &lt;a href=&quot;https://github.com/lichess-org/&quot;&gt;Lichess organization&lt;/a&gt; (although I&apos;m already a patron, I want to contribute with something other than my money 😛).&lt;/p&gt;
&lt;p&gt;In the meantime, feel free to take a look at my games page and/or at the packages I published:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://chess.ruialves.me/&quot;&gt;Chess games page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/fide-ratings-scraper&quot;&gt;fide-ratings-scraper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/lichess-tournament-creator&quot;&gt;lichess-tournament-creator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cheers!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Home Networking]]></title><description><![CDATA[Recently I decided to do a bit of a network setup improvement around my house. The main objective was to get a decent wi-fi coverage and…]]></description><link>https://blog.ruialves.me/home-networking/</link><guid isPermaLink="false">https://blog.ruialves.me/home-networking/</guid><pubDate>Thu, 30 Jul 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently I decided to do a bit of a network setup improvement around my house. The main objective was to get a decent wi-fi coverage and &quot;easy&quot; cable accessing in a few key rooms. The only thing that makes this endeavor far from trivial is that my house is about 60 years old, with about 15cm thick walls, and without any cable-supporting infrastructure whatsoever. I wanted to share a bit of what went well and wrong with my planning and implementation, as well as some lessons learned.&lt;/p&gt;
&lt;p&gt;Since I wanted to have the full hands-on experience, I decided I would assembly the cabling myself. I don&apos;t have gigabit ethernet at home (and I don&apos;t plan to have it anytime soon), so I decided to go with &lt;code&gt;cat5e&lt;/code&gt; cabling. I got myself an &lt;code&gt;RJ45&lt;/code&gt; crimping tool, an &lt;code&gt;FTP cat5e&lt;/code&gt; cable spool and a bunch of connectors. I picked up a wiring diagram from the internet (I used the &lt;code&gt;Type B&lt;/code&gt; standard since it seemed to be the most common one) and tried to build a short 1m cable, just to get acquainted with the process - happily for me, it worked quite well. I found &lt;a href=&quot;https://www.youtube.com/watch?v=lullzS740wI&quot;&gt;this video&lt;/a&gt; a bit helpful as well.&lt;/p&gt;
&lt;p&gt;Now for the planning part: I live in a 2 story house and my ISP&apos;s router is placed on the bottom floor. I found that if I added an Access Point to my house&apos;s upper floor I would get decent wi-fi coverage, and then I could add a few cables to each of the bedrooms for wired connections. My ISP&apos;s router is placed in the garage and its location can&apos;t be changed due to logistics reasons, so I had to drill a small 1cm hole in the wall so that the wire could pass through. After doing a bunch of measures, I found that I needed to build a 20m cable to connect the ISP&apos;s router to the place I would later on place a router on the top floor.&lt;/p&gt;
&lt;p&gt;I also wanted things to look as neat as possible, so I bought a bunch of wiring rails and installed them near to the ceiling. I didn&apos;t need a very good router since my ISP does not provide me a very good internet service anyway, so I ended up going with a budget option and got an &lt;code&gt;Asus AC750 RT-AC51U&lt;/code&gt; router.&lt;/p&gt;
&lt;p&gt;Now I only needed to add the cable and patch both ends to finish the process! - &lt;strong&gt;Not quite&lt;/strong&gt;. After placing the cable across the rails and patching both ends, the data connection was failing. I double-checked the &lt;code&gt;RJ45&lt;/code&gt; connectors I had set up, and they looked perfectly fine (both in wiring order and cable length). After debugging the cable across the rails, it looked like the cable&apos;s bending radius had been exceeded, causing the inner copper wires to break. Doing a bit of research, I found out I had made a bad choice when choosing the cabling type:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;FTP&lt;/code&gt; cables are shielded and commonly used in areas where the will likely be interference. However, the shielding causes &lt;strong&gt;cable flexibility loss&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UTP&lt;/code&gt; cables, being unshielded, offer more cable flexibility (at the cost of being more sensitive to interference).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, interference was not a problem at all in my situation. Moreover, the lack of cable flexibility actually caused my setup to break, so I decided to switch to &lt;code&gt;UTP&lt;/code&gt; cabling.&lt;/p&gt;
&lt;p&gt;In fact, installing the new cable was much easier (due to the increased wire flexibility) and everything went smoothly! Even with a few bumps on the road, at the end of the day, the new network setup works pretty well and I&apos;ve now got a fairly decent coverage around all the house. The main lesson here is that I should investigate more carefully before committing to a certain approach, especially when I&apos;m not familiar with the domain.&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[A tour around Competitive Programming]]></title><description><![CDATA[During the past year, I've been exploring the "competitive programming problems" world. It all started around October 2019, when I began…]]></description><link>https://blog.ruialves.me/a-tour-around-competitive-programming/</link><guid isPermaLink="false">https://blog.ruialves.me/a-tour-around-competitive-programming/</guid><pubDate>Sat, 25 Jul 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;During the past year, I&apos;ve been exploring the &quot;competitive programming problems&quot; world. It all started around October 2019, when I began studying for coding interviews at Amazon, Bending Spoons and, most of all, Palantir Technologies.&lt;/p&gt;
&lt;p&gt;I wanted to have a somewhat methodic and organized way of tracking my progress, while at the same time trying to keep focus on problem types that were common in large tech companies&apos; interviews. After trying out &lt;a href=&quot;https://leetcode.com/&quot;&gt;LeetCode&lt;/a&gt;, &lt;a href=&quot;https://projecteuler.net/&quot;&gt;Project Euler&lt;/a&gt; and &lt;a href=&quot;https://www.hackerrank.com&quot;&gt;Hackerrank&lt;/a&gt;, I particularly enjoyed the former, since most of the community seemed to have the same focus as I did. I started a &lt;a href=&quot;https://github.com/xRuiAlves/leetcode&quot;&gt;GitHub repository&lt;/a&gt; featuring all my solution proposals, which were developed using &lt;code&gt;Java&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As of the start of April, when I finished my interview process, I had solved &lt;strong&gt;41 easy&lt;/strong&gt;, &lt;strong&gt;119 medium&lt;/strong&gt; and &lt;strong&gt;8 hard&lt;/strong&gt; problems. I found that the &quot;repetitive&quot; process of solving similar problems (that is, problems that have analogous solutions) resulted in training my brain to quickly recognize how to solve a new problem, whether by identifying the most appropriate data structures for the given scenario or by applying the correct solving methodologies (dynamic programming, memoization techniques, etc).&lt;/p&gt;
&lt;p&gt;In the last 4 months I&apos;ve been less active, although I&apos;ve been tackling problems from the &lt;a href=&quot;https://leetcode.com/explore/other/card/30-day-leetcoding-challenge&quot;&gt;LeetCode monthly challenges&lt;/a&gt; every day, which started back in April. During this time, I also participated in a couple of contests, although I didn&apos;t do particularly well in either of them.&lt;/p&gt;
&lt;p&gt;Although there were many problems I enjoyed solving, I decided to pick two of them to share (not because they were particularly my favorites, but because they had something interesting by nature).&lt;/p&gt;
&lt;h2&gt;Problem 72 - Edit Distance [Hard]&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;Given two words word1 and word2, find the minimum number of operations required to convert word1 to word2. 
You have the following 3 operations permitted on a word:
- Insert a character
- Delete a character
- Replace a character
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I had implemented some &lt;code&gt;C++&lt;/code&gt; code in the past using a &quot;known&quot; algorithm to compute two strings&apos; edit distance. However, I wanted to try finding a solution by myself, without recurring to the literature (to simulate an interview-like situation). Based on the operations described in the formulation, this type of edit distance is also known as &lt;a href=&quot;https://en.wikipedia.org/wiki/Levenshtein_distance&quot;&gt;Levenshtein distance&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;After scratching my head for a while, I realized that this could be solved using - that&apos;s right - the dreadful &lt;strong&gt;dynamic programming&lt;/strong&gt; (for some reason, while studying algorithms in a curricular unit early on in college, I ended up getting the idea dynamic programming was very hard, although that&apos;s not the case at all).&lt;/p&gt;
&lt;p&gt;By using some extra space to help the process, I ended up using a matrix to solve the problem. The matrix width represents &lt;code&gt;word1&lt;/code&gt; and its height represents &lt;code&gt;word2&lt;/code&gt;. Each matrix cell &lt;code&gt;(i, j)&lt;/code&gt; value is the edit distance from the first &lt;code&gt;i&lt;/code&gt; characters of &lt;code&gt;word1&lt;/code&gt; to the first &lt;code&gt;j&lt;/code&gt; characters of &lt;code&gt;word2&lt;/code&gt;. Now I just needed to populate the matrix! After initializing all elements with 0 and filling the first row and first column with ascending values (which represent the edit distance of the word to an empty string), the edit distance is calculated using the following recurrence function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if word1[i] == word2[j]:    // The char is the same, no distance
    M[i, j] = M[i-1, j-1]
else:
    M[i, j] = 1 + min(
        M[i-1, j],          // Delete char at word1[i]
        M[i, j-1],          // Insert char in word2[j]
        M[i-1, j-1]         // Replace char in word1[i] by word2[j]
    )
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After iterating the full matrix, the edit distance is the value at &lt;code&gt;M[word1.size-1, word2.size-1]&lt;/code&gt;! The full solution may be found &lt;a href=&quot;https://github.com/xRuiAlves/leetcode/blob/master/Problems/72.%20Edit%20Distance/Solution.java&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Problem 210 - Course Schedule II [Medium]&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;There are a total of n courses you have to take, labeled from 0 to n - 1.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses.
There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I found this problem particularly fun to solve. The way I came up with the solution shows that, sometimes, you only fully understand the problem and get good ideas when you &quot;get your hands dirty&quot; and start coding. The first thing that caught my eye is that prerequisites could be modeled as connections in a directed graph and that the input may not lead to a valid course schedule - the courses could have requirement loops (direct or not).&lt;/p&gt;
&lt;p&gt;Finding if the input was valid or not was easily solved by applying a &lt;a href=&quot;https://en.wikipedia.org/wiki/Depth-first_search&quot;&gt;DFS&lt;/a&gt; starting at node 0 (the &quot;root&quot; of the graph) - If all nodes were visited without finding loops, the input could lead to a valid solution. That&apos;s when it came to my mind that applying the &lt;code&gt;DFS&lt;/code&gt; would actually get me &lt;strong&gt;the solution itself&lt;/strong&gt; if the input could lead to a valid course schedule!&lt;/p&gt;
&lt;p&gt;The order in which nodes are visited using a depth-first search consists of a &lt;a href=&quot;https://en.wikipedia.org/wiki/Topological_sorting&quot;&gt;Topological Order&lt;/a&gt; (or topological sorting) - which in this scenario represents a valid course schedule. The full solution may be found &lt;a href=&quot;https://github.com/xRuiAlves/leetcode/blob/master/Problems/210.%20Course%20Schedule%20II/Solution.java&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;As of the of July 2020, I have solved &lt;strong&gt;73 easy&lt;/strong&gt;, &lt;strong&gt;152 medium&lt;/strong&gt; and &lt;strong&gt;13 hard&lt;/strong&gt; problems. I&apos;ll keep solving problems from these monthly challenges for as long as I&apos;m having fun with them - which will likely be for a long time.&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Interview Scheduler]]></title><description><![CDATA[For the past nearly 4 years, I've been a member of FEUP's Computer Engineering Student Branch. Every year we go through a "recruitment…]]></description><link>https://blog.ruialves.me/interview-scheduler/</link><guid isPermaLink="false">https://blog.ruialves.me/interview-scheduler/</guid><pubDate>Fri, 24 Jul 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;For the past nearly 4 years, I&apos;ve been a member of &lt;a href=&quot;https://www.facebook.com/NIAEFEUP&quot;&gt;FEUP&apos;s Computer Engineering Student Branch&lt;/a&gt;. Every year we go through a &quot;recruitment season&quot;, in which about 30 or so of our active members interview around 50 candidates. And every year, we face the challenge of matching the availability of our members with the candidates to schedule the interviews. Although we&apos;ve been using &lt;a href=&quot;https://doodle.com/&quot;&gt;Doodle polls&lt;/a&gt; to query people about their availability, we do the matching almost entirely manually, using some &lt;em&gt;common sense&lt;/em&gt; heuristics.&lt;/p&gt;
&lt;p&gt;Thus, I decided to develop a &lt;em&gt;CLI&lt;/em&gt; tool to automate this process, calling it &lt;a href=&quot;https://github.com/xRuiAlves/interview-matcher&quot;&gt;interview-matcher&lt;/a&gt;. Although we have been scheduling the interviews with 2 interviewers and 1 candidate during the past few years, I wanted to design the tool in a way it is flexible enough to accommodate changes in the process, if needed.&lt;/p&gt;
&lt;p&gt;At first, the problem seemed to be a simple &lt;a href=&quot;https://en.wikipedia.org/wiki/Maximum_cardinality_matching&quot;&gt;Maximum Cardinality Matching&lt;/a&gt;. However, after thinking deeper about the subject, I realized it could not be treated as such:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This isn&apos;t a classic 1:1 matching problem. Instead, matching is made in an N:1 ratio, so formulating the availabilities as a standard &lt;a href=&quot;https://en.wikipedia.org/wiki/Bipartite_graph&quot;&gt;bipartite graph&lt;/a&gt; was out of the question;&lt;/li&gt;
&lt;li&gt;The interviewers are not matched directly to candidates. They&apos;re matched to candidates via option slots (&lt;em&gt;e.g.&lt;/em&gt; from 9:30 am to 10:00 am), which means there may be multiple ways to connect entities from the two parties;&lt;/li&gt;
&lt;li&gt;Finally, an interview matching is only considered feasible if they feature the total number of required interviewers (&lt;em&gt;e.g.&lt;/em&gt; if a 2:1 interviewers to candidate ratio is being used, an interview with only 1 interviewer will not be accepted).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another &lt;em&gt;non-functional&lt;/em&gt; requirement is that all interviewers should have a similar number of assigned interviews, in order to distribute work as much as possible.&lt;/p&gt;
&lt;p&gt;Even though this wasn&apos;t a &quot;classic&quot; problem, I had the feeling this could be formulated as a &lt;a href=&quot;https://en.wikipedia.org/wiki/Maximum_flow_problem&quot;&gt;Graph Maximum Flow Problem&lt;/a&gt;. The flow network needed to follow certain constraints:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each candidate may only be assigned to a single slot, and &lt;em&gt;vice-versa&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;Each slot must have an entering flow capacity of &lt;em&gt;N&lt;/em&gt; (where &lt;em&gt;N&lt;/em&gt; is the number of interviewers required for each interview).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To follow these constraints, I formulated the following flow network &lt;em&gt;schema&lt;/em&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/ztEygTA.png&quot; alt=&quot;Flow Network schema&quot;&gt;&lt;/p&gt;
&lt;p&gt;Note that edges that do not display a value have a weight of 1. The &lt;em&gt;infinity&lt;/em&gt; weighted edges from the source to the interviewers allow an interviewer to be assigned to more than one interview. The slot filters layer provides a way of having an entering capacity of &lt;em&gt;N&lt;/em&gt;, while ensuring the slot is only assigned to one candidate (due to the edge of weight 1 connecting every node in the slot filter layer to its respective node in the slot layer). &lt;/p&gt;
&lt;p&gt;Finally, this flow graph can be used to find a valid matching using an algorithm like &lt;a href=&quot;https://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm&quot;&gt;Ford-Fulkerson&lt;/a&gt;. To both converge towards a solution faster and to improve the final solution&apos;s quality, I used some heuristics when searching for flow augmentation paths:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prioritizing interviewers with less amount of work (to distribute interviews as evenly as possible);&lt;/li&gt;
&lt;li&gt;Prioritizing slot filters with the most output flow, to avoid having &quot;half-full&quot; slots;&lt;/li&gt;
&lt;li&gt;Prioritizing slots that flow towards candidates that don&apos;t have an assigned slot yet, to reach a feasible solution faster.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Although the output was near-optimal, it did not ensure optimal matching - a max flow algorithm focuses on (that&apos;s right) obtaining maximum flow from the source to the sink. Even with the prioritization heuristics, there&apos;s no certainty the matching will result in a similar number of interviews per interviewer!&lt;/p&gt;
&lt;p&gt;To mitigate this, I ended up adding an iterative optimization layer, featuring an &lt;em&gt;ad hoc&lt;/em&gt; algorithm that focuses on finding local optimizations to slowly improve the overall matching. To my surprise, applying this algorithm converged to the optimal solution quite fast! It focuses on trying to move slots from overworked interviewers to underworked ones.&lt;/p&gt;
&lt;p&gt;I&apos;m pretty happy with the final result. I have tested the tool with data inputs similar to the ones from previous years&apos; recruitment seasons, obtaining great results. I tried to use a &lt;a href=&quot;https://en.wikipedia.org/wiki/Test-driven_development&quot;&gt;TDD&lt;/a&gt; approach while developing, which proved to be quite productive and allowed me to avoid mistakes. I also had some fun setting up a cool CI pipeline to allow maintaining the tool in the future. Hopefully, someone will take a look at the project and find room for improvement!&lt;/p&gt;
&lt;p&gt;Finally, I decided to publish the tool as an &lt;a href=&quot;https://www.npmjs.com/package/interview-matcher&quot;&gt;npm package&lt;/a&gt;. I invite you to download it and try it out: &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ npm i -g interview-matcher
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cheers!&lt;/p&gt;</content:encoded></item></channel></rss>