Neeldhara
https://www.neeldhara.com/blog.html
quarto-1.2.262Sat, 26 Nov 2022 18:30:00 GMTLetters with Pandoc
https://www.neeldhara.com/blog/pandoc-letters/index.html
Letter-writing season is around the corner. I recently adapted this pandoc workflow for generating PDF letters by only editing a markdown file. I only made the following minor changes to the original:

Included the fontawesome5 package so I could add icons alongside the phone number, email, and website in the letterhead.

Changed ThisULCornerWallPaper to CenterWallPaper and added wpYoffset and wpXoffset so I could get a left margin on the logo (I suppose this could also be done by offsetting the logo in the letterhead.pdf file).

Here’s what the output looks like with some random sample content:

The markdown is very simple to edit — most of the information is up in the YAML header, and it looks like this:

author: Fyodor Michailovitch Dostoevskycity: Moscowfrom:- By the Vladimirkirche- care of Pryanischnikof, Grafengasse.affiliation1: Add an affiliationaffiliation2: Potential Additional Informationcontact:- \faPhone \ +91 79 1234 1729- \faGlobe \ https://www.google.com- \faEnvelope \ nobody@nowhere.comto:- Michael- Someplace- with an addresssubject: An Updatesalutation: My dearesttoname: brothercustomdate: 1838-8-9

Write the body of the letter in markdown as usual, and generate the PDF by running:

For your first use, you would want to update the images for the letterhead and the signature, and optionally customize the fonts to your liking. Fork this repo to make your own!

]]>pandocworkflowslatexhttps://www.neeldhara.com/blog/pandoc-letters/index.htmlSat, 26 Nov 2022 18:30:00 GMTThe Only Fair Ranking of IITs
https://www.neeldhara.com/blog/iit-rankings/index.html
Don’t like the ranking? Try again.

The program takes all the available knowledge in the universe and extrapolates a score for each IIT using state of the art algorithmic techniques (i.e., deep guessing). To resolve ties, the program also computes a secondary score which is a random number. The program next computes a weighted average of the two scores - the weight assigned to the first score is based on its scientific value and merit, and is thus zero, and the remaining weight is assigned to the secondary score (i.e., 1). The program then sort and output the departments in decreasing ordering of their weighted scores.

Inspiration Check this page for a ranking of computer science departments.

]]>fundahttps://www.neeldhara.com/blog/iit-rankings/index.htmlWed, 23 Nov 2022 18:30:00 GMTExportober 2022
https://www.neeldhara.com/blog/exportober/2022-tracker/index.html

The Leaderboard

The Tweets

What was this about again?

You can find the original announcement here and more specifics clarifying the format (or the lack of it) here. Here’s the short version:

Put up a piece of content everyday between 1st October and 30th October, with the possibility of skipping one day per week;

Post a link to your content on Twitter with #exportober

That’s it, actually. 🤷♀️

Psst. It’s quite fine to sign up even if you’re reading this after the 1st of October. The automated tracking exercise here will stop after the 15th of November, so you can be a part of this by just contributing in this window. It certainly does’t have to be daily and it doesn’t have to be 30 things, although I found those to be useful default targets to work with for myself.

]]>exportoberhttps://www.neeldhara.com/blog/exportober/2022-tracker/index.htmlThu, 06 Oct 2022 18:30:00 GMTSKJ
https://www.neeldhara.com/blog/skj/index.html
This is the text of a short speech I gave at the farewell event for Prof. Sudhir Jain as he left IITGN for BHU.

You can find out more about Prof. Jain’s own take on the cultural foundations of IIT Gandhinagar here, where he is in conversation with Achal Mehra.

Canadian astronaut Chris Hadfield has said that leadership is not about glorious crowning acts. It’s about keeping your team focused on a goal and motivated to do their best to achieve it, especially when the stakes are high and the consequences really matter. It is about laying the groundwork for others’ success, and then standing back and letting them shine. If that sounds familiar, I think it’s because we have lived this experience at IIT Gandhinagar, thanks to Prof. Jain.

Our guiding principles have been often unconventional — whether it’s about having students first, or choosing to trade short-term gains for the long-term vision. They have sometimes led to decisions that would seem quite inexplicable to anyone who did not have the context. Some of you might remember how early we started the undergraduate program in Computer Science, for example. Ok, so for the record, we started it quite late, at least according to conventional wisdom.

Crucially, these core values have always been articulated in collaboration, with inputs from all stakeholders, which is what enables our shared conviction in them once they have been established.

Prof. Jain’s vision for IIT Gandhinagar is as precise as it’s bold – he knew exactly what needed to be done for this place to emerge as a model institution. He had recently shared with us his roadmap for IITGN from a dozen years ago. This roadmap committed not to vague ideas but concrete goals, complete with numbers for metrics that are fraught with uncertainty. It’s absolutely stunning how everything panned out almost exactly according to plan!

Our narrative has many collaborators, including our students, faculty, and staff. And while some of us are relatively inexperienced, Prof. Jain’s trust in everyone has been hugely empowering. It manifests in many concrete ways – starting from wanting for students to be recognized as adults, to turning young colleagues into decision-makers… and this is why all of us have a deep sense of ownership for IITGN.

An environment that gives all of us the freedom to experiment and the leeway to fail is extremely enabling. This has led to a wide spectrum of wins, many that are quantifiable and others that are less tangible. If you want to get a sense of how good the times have been, just look around – the sheer beauty and the attention to detail that the campus embodies is an excellent symbolism for the inclusive, thoughtful, and innovative leadership that we have experienced. When it comes to how far we have come, I could go on… pretty much forever, so I’ll defer you to the website for more details.

It is impossible to imagine IITGN without you. This is your brainchild through and through. Despite knowing that you’ll not be distancing in spirit, we will miss having you nurture the institution in the hands-on manner that you have always done. Your passion for the IITGN mission – of being a breakout university while operating within the limitations and strengths of the IIT system – is contagious. I am sure you plan to double down on this even though you may have a few distractions going forward.

I recently watched Maanaadu, a movie based on the idea of a time loop. In such stories, the plot involves the protagonist experiencing the same day over and over again, and their goal, typically, is to find an exit. If there is one day that we could put into a time loop, it would be today, and there would be no need to get out of it.

In the meantime – on behalf of all of us, thank you.

Thank you for your commitment, trust, and friendship; for listening patiently, for leading tirelessly, and for fighting the good fight through tough times, and for the good times through tough fights – ok, I’m going to be out of time, here, clearly – so let me just say, thank you for everything.

]]>iitgnhttps://www.neeldhara.com/blog/skj/index.htmlThu, 22 Sep 2022 18:30:00 GMTExternal Communications
https://www.neeldhara.com/blog/comms/index.html
I finish seven years at IIT Gandhinagar today.

This year, I also concluded my stint with the Department of External Communications, which feels about as long. Indeed, little did I know that a casual remark that I had made during my interview^{1}, about wanting to be a writer for as long as I can remember, was carefully noted — and magically my service responsibilities would end up being related to my childhood dream. A few days after I joined, I met Achal Mehra, who introduced me to Connections: a four-page newsletter that went places every quarter. In my mind, that conversation kickstarted my collaboration with what everyone fondly calls “comms”. Seven years later, I’m here to report that the journey has been fun and fulfilling in equal measure.

Through this post, I’d like to introduce you to the comms team: if you have been to IITGN for an event, read about us in the press, have recieved a newsletter from us, visited our website, or followed our social media: these are the folks who work behind the scenes on these fronts. Being a part of this gang has been a huge inspiration: everyone is talented but always willing to learn; their hard work is driven by a sense of ownership; and there’s plenty of wit to help beat the heat :)

Here’s collection of some randomly chosen memories: my hat-tip to a stellar team.

Hatim

Hatim joined us in the summer of 2018 and worked with us for four years. This summer, he moved on to join the design unit at ISDM as a Graphic Designer and Video Editor.

Hatim has had a creative flair from the get go. He’s been a part of several exciting projects, including being the person behind the visuals for Alok Kanungo’s book, Glass Crafts in Northern India. Also, here’s a cool trailer he put together very quickly for the ACM-W India Grad Cohort that I was involved in organizing in 2020.

Dilip

Dilip joined us in the summer of 2018. He had a distinct passion for developing mobile and web applications, and indeed, he’s been a huge asset to the web vertical of the team. He’s been relentless in learning new things and has been writing on Medium too.

When we were organizing the ACM-India Annual event and the team was freaking out over having upwards of 1000 registrations, Dilip wrote a mobile app for us — literally overnight — which allowed us to send all participants a QR code that they simply had to show to get through physical registration. It saved us a ton of time. You can find out more about Dilip here.

Tej

Tej joined us in the winter of 2016 as a web developer and has been my officemate. Tej is among the first points of contact for all new faculty at IITGN: their institutional profile pages are set up even before they actually set foot on campus. Tej’s name is synonymous with “website”. If anyone needs one done, whether it’s for their lab, or an event, he’s always been an email away. True to an appropriate mispronouciation of his name^{2}, Tej has remarkable turnaround times, and seems to get things done as fast as you can spell them out.

One of my most memorable projects with Tej (along with Dilip, Divyangi, and the rest of the team) is the revamp of the main IITGN website. We went from this:

to this:

in about a year. Despite several very well-intended warnings about how crazy this was, the team picked up the project with cautious courage, and pulled it off. I think I can say with some confidence that the IITGN website is easy on the eyes, and things are not hard to find.

Apeksha

Apeksha joined us in the summer of 2019, just on the heels of completing her MTech in Biological Engineering at IITGN, and stayed with the team for a year. At the time of joining, she was an avid consumer of popular science material, and aspired to make the research at IITGN more broady accessible with her writing. She was a freelance writer already, and was looking for an opportunity to spend some time writing full-time. Her stint with us resulted in a number of articles, and her growth during the time has been remarkable. You can find her writing on her Medium blog.

The ACM-W India Grad Cohort event we did in 2020 was a virtual one, and in the tradition of Grad Cohorts, was not recorded. I am grateful that Apeksha stepped up at the time, offered to attend all the sessions, and wroteupcomprehensivesummaries.

She has now joined the Ph.D. program in the Humanities and Social Sciences and is currently researching cognitive aspects of science communication with Frederick Coolidge.

Dhara

Dhara joined us in the summer of 2018, and immediately got to work on managing our social media channels. She also streamlined the process of collecting information: a lot of what we do revolves around robust archival, and IITGN being a happening place does not make this easy! We get dozens of emails every day announcing events of varying scales, updates of various kinds.

Anticipating that the volume would only get worse, we devised a system for manually cataloging every bit of news in a bunch of Airtable bases. The long-term vision was that the Airtable API exposes this data to anyone who needs it: the web team could draw from it and filter appropriately to display upcoming events, an archival team could write a report generating app that used this as the backend, and so forth. We even had a web app developed by a team of undergraduates that pulled data from these bases to show off upcoming events on a big screen.

Dhara now manually curates information from these databases and runs a weekly internal newsletter collating what’s happened and what’s coming up at IITGN: this has been a major value addition for many. She also serves up the raw data needed for our public quarterly newsletter and annual reports based on this system, which saves everyone a lot of time. Apart from all of this, she is in the driver’s seat for all our majorsocialmediachannels, and then some… and magically manages to stay on top of everything. You can find her writing on Medium.

Divyangi

Divyangi joined us in the summer of 2018 and worked with us for three years until the summer of 2021. She was a wizard when it came to scripting for automating tasks, and quickly became the go-to person for departments who were looking to improve their workflows.

IITGN runs on the Google ecosystem. Divyangi figured out several nice ways of bringing data from spreadsheets to frontends, generating reports, and so forth. She even ran a workshop on Google scripts and related tools as a part of an initiative coordinated by our Staff Development Cell.

Among the many projects Divyangi was involved in, one of my favorites was the backend for our rather popular Summer Research Internship Program. The website is powered by WordPress, and provides various interfaces for both interns and mentors to keep track of their applications during the application phase (this runs into tens of thousands of records), and progress during the internship (updates from interns and feedback from mentors are all managed from here). Divyangi, together with Dilip, deeply customized the WordPress instance to provide a number of features that help with running a large-scale program smoothly, with most of the tedious tasks completely automated.

Chandni

Chandni joined us in the summer of 2019 for a year. She was already a very talented photographer at the time of joining us. As our events and activities grew in number and scale, we found very valuable support in Chandni’s presence. Check out her Instagram here!

Vandana

Vandana joined us in the summer of 2017 in the role of a Communications and Media Officer for a year. During this time, she was working closely with local press and media, and ensuring that our stories are filed with them on a regular basis.

Vandana was already passionate about writing and had a keen eye for detail. She filled an important void at the time she joined and immediately setup various important foundations in the context of this role. She expanded our style guide, made a press kit, and developed a starting database of journalists that we could work with: these are all tools that the whole content team uses regularly to this day.

Her spirit of volunteerism meant that a lot of our content got reviewed and improved across the board: on the website, on our brochures, and so forth. This was also the time when we launched what I think is our best-kept secret: IITGN’s news blog. Vandana, along with the rest of the team, setup a careful pipeline to ensure that everything we capture across press and social media gets a permanent home on the blog. She continues to pitch in remotely, even after moving on from her onsite role with us on campus.

Shivangi

Shivangi joined us in the summer of 2018 in the role of a Communications and Media Officer, picking up from where Vandana left off. She has been synonymous with media and press at IITGN, and is currently our main interface with the press. She has substantially expanded on our network of partners in press, and ensures that we have the visibility we deserve in the local and national news, and even beyond. She is especially diligent about ensuring that regionally-focused news is appropriately translated in the local languages whenever appropriate, a widely appreciated effort.

Shivangi’s style has been remarkably proactive: if anything at IITGN is newsworthy, she makes sure it’s covered. She draws on her substantial experience in the field to bring nuanced insights to the table, and these have served us very well in our overall communications and outreach strategy.

Beyond coordinating stories for the press, Shivangi also comprehensively tracks IITGN’s presence in the news and other public domains, is closely invovled in the production of the quarterly newsletter and annual reports, and our social media activities as well. Shivangi is, unsurprisingly, an amazing writer, and here’s a performance of hers in a SDC event that was among my favorites.

Gaurav

Gaurav has been around for longer than I have, and he is a founding member of the team. He is among the most versatile people I know: not only does the scope of his work at IITGN go well beyond communications, even within communications his skills span a very wide range: he’s behind the camera, he’s the person behind the design and layouts for some of our best print collaterals, he’s directed and produced a number of videos, and I could go on and on.

I’ve freely relied on his mentorship: much of the growth that has happened within the team, especially in terms of creative efforts, is thanks to Gaurav’s experience and guidance.

If you pick up any of our booklets, there’s a good chance that Gaurav has been involved in engineering the layout and design. Among them, I’ll single out a couple for you to sample: the World Class Faculty brochure looks especially lovely in print, and the 10 on 10 brochure has a bold aesthetic that was a crowd favorite when it was released for our 10-year celebration.

Devarsh

Devarsh joined us in the summer of 2017, with a background in creative film-making and theatre. He quickly became the go-to person when it came to anything to do with video or photography. Over the years here, he’s grown leaps and bounds in his craft and understanding of all aspects of the process — both work that happens on the field and in post.

Our YouTube presence was in its nascent stages when Devarsh joined. He’s single-handedly worked on our channel in mission mode from the get go, and it is largely thanks to his efforts that we have a fairly systematic video respository of most major events and talks on campus.

Devarsh has been involved in several memorable projects. Here’s a video that he shot for our first virtual convocation, which also happened to be among the first virtual convocation events to be held in India (as far as we know).

Nostalgia

Some of the early members of the team are not pictured. Apart from everyone above, I had the good fortune to have worked with: Ritu (among other things, was the curator for all the early editions of the quarterly newsletter, Connections, and our annual reports), Dayanand (our first communications and media officer), Maria (our first social media intern), and Khushbu (who took over from Maria and preceded Dhara on managing social media).

It would be remiss of me to not give a shout out to the faculty support we have enjoyed over the years. Several colleagues have played major roles in helping out on all aspects of our responsbilities. A special thanks to Achal Mehra, who brought extensive experience to the table, and has been forever generous with his time and advice, and Vasco Trigo, whose inputs for the whole team were extremely timely and valuable.

I’ll also take this opportunity to thank friends at the Communications department at Duke University — they hosted us in the very early days, and their detailed and candid tour of various operational aspects was massively helpful in setting up a lot of the foundations back here.

I walked into this gig more or less by accident. I should confess here that I didn’t have a 5-year vision from which I could work backwards to nicely chunked milestones. There were no OKRs or KPIs or whatever else the pros do. A few times, it’s occurred to us that we should have targets, strategies, and systems^{3}. While we never articulated any as far as I can remember, I think we did have a tacitly shared goal: it was to ensure that everyone got what they needed from comms, and that we didn’t make any mistake twice. My biases notwithstanding, I would say we have largely succeded :)

Most people at IITGN know by now that ambushing me in a corridor is more effective than email, and meanwhile, the team gets things done by some magic that remains a mystery to me.↩︎

If you haven’t played it yet, you might want to go ahead and give it a shot first. Most people figured out the mechanics without any explicit instructions. A couple of things that may not be immediately clear, but typically discovered quickly within a few moves:

The edges are labeled with conditions, and can be used only if all of the said conditions are met.

The bunny or dog icons may sometimes cover up what kind of location they are at. You can drag them away to find out!

Multiple animals can occupy the same spot at a time.

It is possible to get into a dead end, a situation from where no legal moves are possible. In the verison of the game that is available at the time of this writing, the game offers no sign that you might be in this situation. This may however change.

After winging it on the puzzle, several questions seemed natural:

So the last question may strike you as a bit left-field, but that’s what I’m going to ramble about for the rest of this post :) It turns out that the answer is in the affirmative, and here is a lovely reduction by @lokshtanov showing as much.

The Reduction

Let’s just set up the game as a computational problem just to be sure that we agree on the abstraction. In fact, we’ll be working with a simpler version that we will call BunnyCarrot.

BunnyCarrot

In the BunnyCarrot problem, the input is a simple undirected graph , subsets and of indicating the initial positions of bunnies and carrots, and a (possibly empty) instruction for every , which is a collection of conditions, at least one† of which must be true for the edge to be “active”.

The question is if there is a sequence of movements of bunnies along active edges such that at the end of the sequence, every bunny is located at one of the vertices from .

† In the original version of the problem, we need all conditions associated with an edge to be satisfied, not at least one. The construction that we will describe can be easily adapted to this setting as well, but is simpler to describe for this variant :)

We are going to show that BunnyCarrot is NP-complete by reducing from 3SAT. So let be a collection of 3SAT clauses over variables . The reduced instance of BunnyCarrot corresponding to looks like this:

What we have here is the following in terms of the structure of graph:

a path on vertices, with the left most vertex in and the rightmost one in ;

a pair of vertices for every , and an edge between them, where all the ’s are in ’ — the vertex represents the literal while the vertex represents the literal ;

a pair of vertices and in , with adjacent to all ’s and adjacent to all ’s.

Now here be the instructions associated with the edges:

the edge to the -th vertex on is active only if there is a bunny on at least one of the literals present in the clause ;

the edges between and are active only when there is a bunny on the leftmost vertex of ; and

finally, the edges incident on and are active only when there is a bunny on the rightmost vertex of .

The Forward Direction

We first claim that we can “win” this game if has a satisfying assignment. Indeed, let be a truth assignment that satisfies all the clauses of . Then:

If , move the bunny on to .

Move the bunny on the leftmost vertex of the path to the rightmost vertex: note that all edges are active because is a satisfying assignment.

Move all bunnies on ’s to and those on ’s to .

The Backward Direction

Now suppose there is a winning sequence of moves . We will show that we can extract from this sequence a satisfying assignment for , which will firmly establish the equivalence of the generated instance of BunnyCarrot with the OG hard instance .

Note that to begin with, all the blue edges are inactive. Now, in the sequence , let us say that a step is key if it involves a bunny moving along the first edge of the path and critical if it involves a bunny moving along the last edge of the path .

Suppose the -th step is the first critical step in . Further, suppose that the -th step is the last key step to occur before the -th step. Notice that there must be at least one key step before a critical step — we must begin before we can end :)

Now, for all steps after the -th step and before the -th step, note that edges incident to and are inactive for all . This implies that every step between the -th and -th steps involves a bunny moving along , and in particular, every edge in is crossed at least once in this phase of the game.

Let us note the positions of the bunnies who are on the ’s and ’s after the -th step is executed. Observe that this naturally translates to an assignment on the variables as follows:

We argue that must in fact be a satisfying assignment.

Assume to the contrary: suppose some clause is, in fact, not satisfied by .

Then, we claim that the edge connecting the -th and -th vertices is not active.

As an example, suppose . Since does not satisfy , it must be the case that:

— and hence there is a bunny on ;

— and hence there is a bunny on ;

— and hence there is a bunny on .

However, the condition for the edge to the -th vertex on to be active is simply that there is a bunny present on at least one of the literals present in the clause , i.e, one of , or . However, because of the structure of the graph, and the fact that all edges incident on and are inactive at all times before the first critical step, observe that:

If there is a bunny on , there is no bunny on .

If there is a bunny on , there is no bunny on .

If there is a bunny on , there is no bunny on .

By our assumption that falsifies , all the premises above are true! So there is an edge on the path that is not active between the -th and -th steps, which violates our understanding that every edge was crossed between these steps. This is a contradiction, and hence must indeed be a satisfying assignment.

I’ll just remark here that this construction can be modified so that every vertex in the graph has constant degree, and there is only one vertex in . It can also be modified to change the “or” condition on the edges to an “and”, by simply separating the conditions out along multiedges.

Food for thought

Here are some more questions :)

What’s the complexity of this game when the underlying graph has some simple structure (e.g, a tree)?

Does the problem get harder if we introduce attacking entities like wolves?

Can we come up with an algorithm that runs in polynomial time on instances where there is a valid winning sequence of constant length?

Is the problem hard even for a constant number of bunnies?

I’ll pose some how/what/why questions in the context of teaching.

How

The last couple of decades, especially the last few years, have seen dramatic changes in how information is communicated. A lot of learning happens in online communities, for instance, question-and-answer websites like Quora and StackExchange. Thanks to folks who invest time on these platforms, expert help seems to be nearer than ever before. Specialized and snark-free communities on Discord/Slack/Telegram are enabling peer-to-peer learning at global scale.

I keep hearing that Quora is not what it used to be, but as long as Thomas Cormen is an active user, I am positive it remains a valuable resource.

Books are beginning to be injected with exciting new technology: CodeMirror makes code interactive and runnable, while tools like PythonTutor can help with visualizing what happens behind-the-scenes when code is executed. Saywhatyouwant about JavaScript, but the interactivity that it brings to the written medium has helped make reading less passive. Some of my favorite interactive texts include Seeing Theory, Probabilistic Models of Cognition, courses on Brilliant, Mathigon, and essays from Nicky Case, Minute Labs, and others on Explorables.

The name “PythonTutor” is slightly misleading, since the website also lets you visualize code snippets written in C, C++, Java, and JavaScript.

And finally there are the online courses. At the time of this writing, it has been just a little over two decades since MIT’s Open Course Ware opened to the public. The early hype around MOOCs roughly coincided with my years in college and graduate school. As far as I remember, it was quite the thrill to have free-flowing access to online lectures — “taught by the best” — for several of the courses I was supposed to be doing as a part of my curriculum.

All this is to say that I walked into a career involving a substantial teaching component with plenty of hesitation. The delivery was/is still largely confined to classroom settings in broadcast mode. It is not entirely clear what this format has to offer over YouTube. Basic interactivity is being increasingly solved with questions built into video players. Peer learning is quite doable with WhatsApp/Slack/Discord groups and local chapter meetups. Scale in the context of assessments is somewhat addressed by peer evaluation. And then there are all the things you can do on YouTube that you can’t do with traditional lectures: find a teacher whose style resonates, find an accent you understand, replay, play at 2x, 0.5x, binge watch, don’t watch…

So: what’s the incentive for anyone to show up in a classroom at a fixed time, especially when said time is 8AM? This question became particularly relevant during the pandemic years: once the novelty wore off, almost nobody† showed up to lectures. If I was a student, I’d likely do the same. This remains largely an open problem in my mind, but here are some pointers that have kept me motivated about the conventional format.

† Shout out to those of you accounting for the “almost”, thank you!

Classroom = theatre. I am increasingly treating it as a ground for practicing standup and magic skills. I should admit that this isn’t easy for a clinically shy person like myself, but I got used to making a fool of myself fast — that’s served well. I imagine that some of the fun that comes out performance-first lectures is hard to recreate with recordings and notes.

Totally. It's almost always a performance, irrespective of the class size. And the more you rehearse, the better it goes. At least that's what works for me.

In a classroom setting, I can nudge the audience to discover things for themselves. As far as I know, the interactivity in online materials can help with validating understanding, but not as much with developing it from first principles. My hope is for learners to walk out of a classroom with the confidence that they came up with parts of the material in the textbook on their own.

Again, this is hard to do in time-bound fashion, given that a lot of this kind of understanding comes from brooding and hours of messing around. I can only hope to convince the audience that the process is worth the trouble.

The opportunity to show that you care. For learners who may have struggles with and beyond the materials — classrooms, labs, and office hours afford opportunities for us to offer help.

This was a late realization for me personally: for the longest time, my own sense of self-doubt did not allow me to see that I could potentially be useful to someone else. While self-doubt remains, I have started to compartmentalize it enough to show up for others.

All this said, I believe online and remote formats have substantial potential for making quality education accessible at scale, and that it is only a matter of time before classrooms in their most conventional forms either become obsolete or a ruse.

I am going to attend college lectures from now on just to increase my attention span. The goal will be to sit for an hour without sleeping or getting distracted from mobile notifications.

It is also increasingly challenging to formulate a curricula gets people to the bleeding edge starting from the foundations. For instance, there is a growing sentiment that Machine Learning is the new Algorithms (or maybe not). On the other hand, the extent of involvement of “mathematics” in introductory CS courses is also upfordebate.

How much theory is needed for competence in practice? How crucial is it to develop competencies that don’t have an immediately visible ROI? How frequently do we rewrite the textbooks based on developments in industry?

I once read a collection of answers to the question of what every computer science graduate should know on a Q&A site. As an aspiring graduate myself, I figured I should know what I should know. Unfortunately, I remember it as a mostly unnerving experience: it was a list that started with Voronoi diagrams and ended with incompleteness theorems, and a lot of things in between.

From the other side of the fence, for whatever it’s worth — the answer to this question remains elusive, mainly because I think it’s a context-heavy issue. For better or worse, there is a growing interest in computer science, and it will likely remain a non-trivial challenge to find an approach that is both maximally inclusive and sufficiently useful. I can only hope that between ruthless efficiency in teaching things driven purely by need and a curriculum flooded with random adventures, we can find an balance appropriate to our contexts!

Why

Given that everything that needs to be explained has more or less been done and dusted really well on the interwebs, personally, this is hardest question of the lot. Not from my own POV, that’s the easy bit - as pointed out here, it’s fun to go through the idea exchange process with a captive audience, and in my experience at least one party is sufficiently triggered at the end of it (hopefully in a good way).

The satisfaction that you get when you are able to explain a concept to someone who did not know it earlier is immense. Sometimes it could be straightforward, and sometimes it could be frustrating. But the end point is always the same - a smile on the faces of those students. Money can buy all the books, but can’t buy that smile.

I am just not sure if we create enough of a net positive in a traditional classroom setup from a ROI perspective. Given the few good things that the internet has brought us, perhaps it is time to think beyond classrooms and focusing on making existing resources more accessible to everyone who’s interested.

]]>fundahttps://www.neeldhara.com/blog/on-teaching/index.htmlSun, 04 Sep 2022 18:30:00 GMTSolo Chess
https://www.neeldhara.com/blog/solo-chess/index.html
Putting this thread in one place.

🧵 on our latest at FUN 2022 with @NRAravind1 and Harshil.

Have you tried Solo Chess @chesscom yet? It’s addictive — and NP-complete* even when you’re dealing only with rooks!

*when appropriately generalized

So this is a single-player, peg-solitaire-ish chess variant, where you have to clear board by making a sequence of valid captures, albeit starting with unorthodox — and even unrealistic — positions.

To begin with the boards start easy, with a few pieces at a time. Notice, even in the early games, how some positions have just one solution while others may have several.

From initial plays, you sense that it has a very Hamiltonian-Path-ish vibe, and feels like you’re trying to find a path in some graph 😅

We started with a variant that was simultaneously a generalization and specialization:

n pieces 😎

♖’s only

1D boards 🙈

This, it turns out, is case so special that its trivial - you can sweep all rooks to the extreme left or extreme right of the board, and any position is winning even if every rook can capture exactly once. Less trivial though: how many ways there are to win? 🤔

We also ask what happens if every rook had a designated number of captures left. Imagine you have a 1D board and three kinds of rooks:

red rooks cannot move

blue rooks can move at most once

green rooks can move at most twice

We show that such 1D boards can be cleared if and only if then number of green rooks is at least the number of red rooks. This ties nicely with the intuition that every immovable rook needs to be picked up by a rook that can help another one (i.e, > one move left).

This generalizes naturally to rooks with a designated number of moves left, where said number can be anything between 0 and d. Since no other chess piece moves sensibly* across a 1D board, we decided to move on 2D boards from here.

Kings + rooks is an easy exercise.

So if you are still playing with red, blue, and green rooks, then the problem of checking if a given 2D configuration can be cleared up according to solo chess rules turns out to be NP-complete.

No Hamiltonian Path though — this one was from bipartite dominating set 😎

Bishops are much the same as rooks, by a 45-degree tilt of the board.

⚠️ Still open though: what about the case when all pieces have at most two moves left, which is closer to the original spirit of the game?

We don’t know yet, although we’d bet it’s hard, I think.

When playing with queens only, however, we can gadget in the behaviors of red and blue pieces. So we do have that Generalized Solo Chess with just queens that can all move at most twice is NP-complete.

What about pawns? Let’s get clarifying assumptions out of the way:

white pawns only

regular captures only since there’s no premise for en passant captures

In solo chess, pawns are (heavily) constrained bishops: they can only move upwards and to a neighboring diagonal square. Knowing that bishops were hard, but pawns felt simple — we didn’t have a bet either way. 🤔

We were pleasantly surprised that the case of pawns is tractable, even when each pawn has a designated* number of moves!

*at most two.

The algorithm is linear time, too.

Next: what about knights? We don’t know yet!

❓ What’s the complexity of solo chess when played only with knights?

Knights are special because we don’t have to worry about obstructions. So the game can be described by a more general token game on graphs:

We do show that Graph Capture is hard by a reduction, again from bipartite dominating set. This might hint at the hardness for Solo Chess played with knights only, but we are not betting on this yet.

I think these preliminary explorations have left us with more questions than answers:

optimization versions (e.g, clear at least k pieces)

other constraints (e.g, on distance moved)

special cases (e.g, O(1) pieces per row/column)

n x c boards, constant c

While at it, I’m also curious about how @chesscom generates these puzzles, and if they have a mechanism for generating ones that have unique solutions. Also, is it true that if you throw “enough” pieces on the board, it’s solvable WHP?

Shout out to the skak package for making it easy to bring chess pieces to TikZ. We expect to put up a preprint on ArXiV soon. 👀 Meanwhile, we welcome comments and feedback — and if you read this far, thanks very much!

]]>expositiontwitterthreadhttps://www.neeldhara.com/blog/solo-chess/index.htmlWed, 23 Mar 2022 18:30:00 GMTEight Self-Sabotaging Behaviors
https://www.neeldhara.com/blog/eight-self-sabotaging-behaviors/index.html
Putting this thread in one place.

🧵 @fortelabs recently finished the opening keynote on the Second Brain summit, which incidentally has a great lineup including a panel discussion on PKM through the lens of ADHD. Ironically, I didn’t quite take notes but I think the themes also feature in this short video:

The live session was fun because of a super engaged chat — everyone had great suggestions for managing some of these (surprisingly common?) behaviors.

I’ll not share the premise (it’s self-explanatory + there’s the video), but the discussion involved three parts:

why it’s an issue;

why-do-we-do-this-to-ourselves;

how do we not keep doing it 😀

I’ll share a tweet-length summary of my takeaways.

Caveat I: 280 chars! Twitter isn’t the platform for nuance. 😅

Caveat II. Should go without saying, but all of this gyaan needs to be tempered with context, which was a frequently used word throughout the session!

Starting over (again and again)

⚠️ Not learning from previous mistakes.

🤔 False sense of accomplishment, dopamine hit from a clean slate, FOMO (new tools).

💡 Start simple, iterate slowly, resist looking at shiny new objects.

Feeling guilty

⚠️ Can’t win when you are at war with yourself.

🤔 Probably comes from knowing you’ll trip again.

💡 Extend to yourself the same courtesy and patience you’d show to a friend, consider replacing guilt with curiosity.

Perfectionism

⚠️ Not making mistakes is a risky way to live.

🤔 Feeds ego, sense of control and safety, and you think you push yourself harder with lofty standards.

💡 Aim for B+, fail in public and value it — can be a relief to not have to keep up with the perfect image.

Do all the research first

⚠️ When overdone, really procrastination in disguise.

🤔 Creates an illusion of getting work done. Paranoia associate with diving in without preparation.

💡 Second brains are not for archival, but production. Iterate often. Timebox research.

Going big

⚠️ Ambition dominates the public discourse around goal-setting. Big goals are not problematic until they get in the way.

🤔 Ego boosted, creates a potentially misguided sense of being inspired.

💡 Break things down, take incremental (read: realistic!) steps.

Doing it all yourself

⚠️ Potentially limiting.

🤔 A desire for respect or credit, and the sense that nobody can do this as well as me.

💡 Delegate when appropriate, especially when looking to scale and/or diversify.

Comparing yourself to others

⚠️ Potentially depressing.

🤔 Self-pity, and an excuse to not even try.

💡 Compare to past you. Read your old journal entries. (Also, journal.)

Postpone gratification

⚠️ For something to be sustainable, it needs to be fun!

🤔 Traditional positive quality.

💡 Enjoy the journey because nobody knows the destination. Live in the moment, find joy in the small things, be present. Also, music for instant gratification!

]]>fundatwitterthreadhttps://www.neeldhara.com/blog/eight-self-sabotaging-behaviors/index.htmlMon, 14 Mar 2022 18:30:00 GMTKidney Exchanges
https://www.neeldhara.com/blog/kidney-exchanges/index.html
This post is based on an excellent (chalk and board!) talk that Palash Dey gave at IIT Gandhinagar today. This is his joint work with Arnab Maiti, to appear as an extended abstract at AAMAS 2022 (preprint here).

Background

Kidney paired donation or paired exchange allows donors to donate their kidneys to compatible patients with the understanding that their patients receive medically compatible kidneys in turn. The central problem in this setting is the clearing problem — which involves matching patients to donors in such a way that a maximum number of patients receive compatible kidneys. We introduce a directed graph as a convenient abstraction for this question, where:

each node represents a patient-donor pair, and

we introduce a directed edge if the kidney of the donor is compatible with the patient .

Observe that a cycle in this directed graph naturally represents a sequence of feasible exchanges within the cycle. For example, imagine that we have a three-cycle with the edges:

Then we have the following compatible donations:

is assigned the kidney of donor

is assigned the kidney of donor

is assigned the kidney of donor

This accounts for all the patients and donors involved in this cycle and motivates the following question:

Given a directed graph, what is the largest number of vertices that can be covered by a disjoint union of cycles?

While a positive answer to this question will “resolve” all the needs in the system, consider that exchanges along a cycle of length involve simultaneous operations to mitigate the risks involved with donors potentially backing out of the exchange agreements.

This motivates the following refinement of the previously posed question:

Given a directed graph, what is the largest number of vertices that can be covered by a disjoint union of cycles, where each cycle is of length or less?

If the exchanges are restricted to swaps, that is, , the problem reduces to finding a maximum matching. However, the problem is NP-complete already when (see Theorem 1, Abraham, Blum, and Sandholm; EC 2007).

We now generalize the model a little further to account for the presence of altruistic donors, who are donors without a matching patient and are willing to donate to any compatible patient. To account for the presence of such donors, we modify our graph representation as follows:

Each node either:

represents a patient-donor pair or

represents an altruistic donor

The edges are as follows:

We have a directed edge if the kidney of the donor is compatible with the patient .

We have a directed edge if the kidney of the donor is compatible with the patient .

In this setting, note that we can also facilitate exchanges along paths as well, with the paths starting at the altruistic donors. For instance, if we have the path:

Then we have the following compatible donations:

is assigned the kidney of donor

is assigned the kidney of donor

is assigned the kidney of donor

is assigned the kidney of donor

Note that in this situation, the donor is relieved from any obligation to donate to a patient. We now update our problem statement to reflect the presence of altrustic donors and the possibility of facilitating exchanges along paths:

🤝 Optimal Kidney Exchange Along Short Paths and Cycles

Input. A directed graph , where are source vertices; and positive integers , and .

Output. Yes if and only if there is a collection of cycles of length at most each and a collection of paths of length at most each such that the cycles and paths altogether covers nodes outside of .

The main claim in the context of this problem is the following:

There exists a that decides Optimal Kidney Exchange Along Short Paths and Cycles.

An Algorithm for OKE

Here’s a high-level description of the algorithm (perhaps best approached with some prior familiarity with color coding). To begin with, notice that we may assume without loss of generality that and — intuitively, this is because if the permitted cycle and path lengths are longer than the number of patients we hope to cover, then we can simply look for cycles or paths of length directly to begin with — if we find one, then we are done, and if none exist, then we “might as well” set and/or to .

Now, if there is a solution that accounts for at least patients, there is also one that involves at most patients and in particular, also at most paths. Such a solution engages at most nodes from . Therefore, if there is a solution, then there is one that spans vertices.

As is standard for color coding, we guess the correct value of and randomly partition the vertex set into parts. The hope is that each part contains exactly one vertex from the solution (this is a so-called “colorful solution”). The probability that a random partition is a lucky one is , which turns out to be at least . This implies that repetitions ensure a constant success probability.

Given that the partition is indeed a lucky one, we can recover the solution using the following dynamic programming semantics. For and , let be TRUE if and only if there is a colorful solution spanning at least nodes outside in , where denotes the subset of vertices colored with colors from .

The recurrence is based on isolating one path or cycle by guessing the set of colors involved in said component and using table lookups to figure out if this can be extended to a full solution.

In particular, we have:

,

where

and

.

Here, we have that:

is TRUE if and only if the vertices of can be covered with a cycle of length .

is TRUE if and only if the vertices of can be covered with a path of length .

The truth values of and can be determined directly using standard approaches to finding colorful paths and cycles in time that is single-exponential in .

To claim the overall running time, note that:

The total number of entries in the table is and each entry can be computed in time

Therefore, the algorithm outputs the correct decision in time with probability at least ,

By repeating times, we find the correct decision with constant success probability.

The overall running time is .

Other Results

As Palash mentioned in his talk, the preprint has more, and here are some highlights of the other results that were established:

Optimal Kidney Exchange Along Short Paths and Cycles is FPT also when parameterized by the treewidth of the underlying graph maximum length of path maximum length of cycle allowed and the number of vertex types^{1} when .

A Monadic second-order formula for the problem is also presented, where the length of the formula is upper bounded by a function of .

The problem admits a polynomial kernel with respect to the number of patients receiving kidneys maximum degree when is a constant.

On the other hand, the problem does not admit any polynomial kernel parameterized by the number of patients receiving kidneys maximum degree (under standard assumptions).

A -approximation algorithm is presented for the case when only cycles of length at most 3 are allowed and no paths are allowed.

Pointers

Some discussion that came up during the talk:

The so-called dual parameter , which in this case corresponds to the number of patients who were “left out”, is perhaps a natural parameter to study as well.

The notion of a patient without a matching donor seems complementary notion of altrusitic donors. Such patients would be the last vertices on paths kickstarted by altruistic donors. However, this notion likely does not manifest in practice.

If you’d like to dig deeper, be sure to check out the preprint! A few additional pointers:

This work closely builds on the works of Xiao and Wang (IJCAI, 2018), who proposed an exact algorithm with running time where is the number of vertices in the underlying graph. They also show an FPT algorithm parameterized by the number of vertex types if we do not have any restriction on the length of cycles and chains.

Lin, Wang, Feng, and Fu (Algorithms, 2019) studied the version of the kidney exchange problem which allows only cycles and developed a randomized parameterized algorithm with respect to the parameter being (number of patients receiving a kidney, maximum allowed length of any cycle).

Alvin E. Roth was awarded the Nobel Prize in Economic Sciences 2012 (along with Lloyd S. Shapley) in part for his pioneering contributions to the theory and practice of kidney exchange — his biographical account indicates that he had started anticipating the problem even before it emerged as a legal practice. His talk at Simons Institute surveys “fifteen years of history” in the kidney exchange problem, with an emphasis on the game-theoretic aspects. (h/t: Rohit’s blog on this topic.)

Footnotes

Dickerson, Manlove, Plaut, Sandholm, and Trimble. (EC 2016) introduced the notion of “vertex type” and showed its usefulness as a graph parameter in real-world kidney exchange instances. Two vertices is said to have the same vertex type if their neighbourhoods are the same.↩︎

]]>expositionhttps://www.neeldhara.com/blog/kidney-exchanges/index.htmlThu, 24 Feb 2022 18:30:00 GMTWomen in Mathematics
https://www.neeldhara.com/blog/women-in-mathematics/index.html
Here’s a list of books — in no particular order — about women in mathematics (broadly interpreted) largely taken from this thread. The links are mostly to versions of the books on Amazon India. Unfortunately many of them are rather expensive, but hopefully it’s a handy list to share with a librarian you know! Do leave a comment below if you have any additions.

]]>bookslisthttps://www.neeldhara.com/blog/women-in-mathematics/index.htmlSun, 20 Feb 2022 18:30:00 GMTOn the Communication Complexity of Equality
https://www.neeldhara.com/blog/communication-complexity-equality/index.html
These are some quick sketchnotes based on this lecture by Ryan O’Donnell, a part of the playlist for the awesome CS Theory Toolkit course. You can walk through the arguments below.

I should mention that while the Schwartz-Zippel-DeMillo-Lipton lemma is invoked in the notes below, one could make do with just the fact that over any field , any degree polynomial has at most roots, as pointed out by @dsivakumar — thanks!

In the fourth slide from the end, why [DeMillo–Lipton]–Schwartz–Zippel Lemma? You only need that number of roots of a polynomial (over Z mod q) of degree n is no more than n. You don't need D-L/S/Z, which gives a general version for multivariate polynomials, right?

]]>sketchnoteslecturenoteshttps://www.neeldhara.com/blog/communication-complexity-equality/index.htmlSun, 03 Oct 2021 18:30:00 GMTTwo approaches to the 15 puzzle
https://www.neeldhara.com/blog/15-puzzle/index.html
Presenting the 15 puzzle:

This is a sliding puzzle having 15 square tiles numbered 1–15 in a frame that is 4 tiles high and 4 tiles wide, leaving one unoccupied tile position. Tiles in the same row or column of the open position can be moved by sliding them horizontally or vertically, respectively. The goal of the puzzle is to place the tiles in numerical order.

According to Wikipedia, Johnson & Story (1879) used a parity argument to show that half of the starting positions for the -puzzle are impossible to resolve, no matter how many moves are made. We are going to explore two approaches* parity-based argument to show that the puzzle shown here on the right is unsolvable.

*I do believe the two proofs are essentially the same with slight differences of language.

Common to both approaches is the idea of associating a permutation with every state of the puzzle. For the purposes of this discussion, we will think of a permutation simply as a sequence of elements. To turn the grid layout into a sequence, you could, for instance, line up the rows next to each other, in other words, read off the numbers from left-to-right and top-to-bottom:

So we think of every puzzle state as a permutation over the set , where we use to denote the blank space. For a particular sequence and an index , we will use to refer to the element that is at the position in the sequence .

A couple of definitions in the context of permutations will be useful:

An inversion is a pair of elements that is out of their natural order. More precisely, if we have indices such that , then the pair indulges in an inversion. Note that the starting state of our puzzle here has exactly one inversion.

A transposition of locations and **is essentially a swap of the elements at positions and of a given permutation. So this is an operation performed on a permutation. Let’s say this again with more explicit notation — if we start with , then the permutation obtained from by a transposition of and is given by the following:

The identity permutation, which we will denote by , is special — it’s the following sequence:

It turns out that every permutation can be obtained from the identity permutation by a sequence of transpositions. This is not terribly hard to see — start with the identity permutation, and repeat the following until the permutation at hand is the one you want to see: find a location that’s messed up in the current permutation, i.e, it doesn’t have the element you need in there. Find where the element is in the current permutation, and if that’s location , you could perform a transposition between and . This fixes up the location . In every step, you fix at least one location, and never mess up anything else: so at the end of at most steps (assuming you are working with a sequence of elements), you would be done. 🎉

For example, suppose the permutation you want to obtain is 3,4,2,1. Here is how the argument above would play out:

1,2,3,4. The first location is messed up, so swap 1 and 3.

3,2,1,4. The second location is messed up, so swap 2 and 4.

3,4,1,2. The third location is messed up, so swap 1 and 2.

3,4,2,1. Now we are done.

Note that this may not be the only way of performing a sequence of transpositions that can morph into — there may be various roads to . However, it turns out that no matter what route you take to transform , the number of steps you perform will always have the same parity. So specifically, it’s not possible for you to have a series of, say, seventeen transpositions that turn into , and for me to have a series of forty-two transpositions that do the same. We will take this as a cute exercise for the reader as given.

This partitions the set of all permutations into two categories:

even permutations: those permutations that are reachable from the identity with an even number of transpositions

odd permutations: those permutations that are reachable from the identity with an odd number of transpositions

The fact from the previous paragraph above makes this classification unambiguous.

Alright, so now we have all the terminology we need to get to the argument about why the puzzle state we started with is unsolvable. We can roll up our sleeves and get started.

The first line of argument is based on this Numberphile video, and is also the one described in this 1999 American Math Monthly article by Archer. We begin with the observation that every move in the game is really a transposition behind the scenes. In particular, let’s say that we are currently in state and we perform some move and move to state . Let’s say the permutation associated with was and the permutation associated with is . It’s not hard to see that:

can be obtained from with a single transposition.

Now, note that the permutation corresponding to our target state is the following:

In terms of the game state, notice that the final state has the blank tile at the bottom-right corner, just like we had at the start state. This means that in a hypothetical sequence of moves that morphs the initial game state into this solved state, we must have performed:

an equal number of left and right moves; and

an equal number of up and down moves.

If this is not the case — imagine the blank tile traveling through the board as you perform the moves — if the number of times you moved in opposite directions did not exactly cancel, it would be impossible for the blank location to be back at it’s original location.

So in any winning sequence, the number of moves performed must be even. This implies that the permutation corresponding to the start state, in particular, can be obtained from the identity permutation with an even number of transformations. That makes the starting permutation an even permutation.

However, the permutation corresponding to the start state that we have been handed out is clearly an odd permutation: it can be obtained from the identtiy permutation by a transposition of the elements at the 14-th and 15-th positions. So, well, no dice! This shows that every solvable state that places a blank tile at the bottom-right corner must correspond to an even permutation. This does not automatically imply that all such states associated with even permutations are solvable* — it just shows that states with blank tiles at the bottom-right corner corresponding to odd permutations are firmly out of reach.

*It does turns out that all even permutations are in fact solvable.

The second approach is based on the notion of inversions. This one is based on the Strong Induction lecture in the MITOCW course on Mathematics for Computer Science. For this proof I’ll actually switch to the version of the puzzle because I don’t know how to extend it to the 15-puzzle the case analysis is more manageable for this version:

As we said before, the permutation associated with the starting point of the puzzle has exactly one inversion, while the permutation associated with the solved state, which is the identity permutation, has no inversions. So, when you make a move in the puzzle, what happens to the number of inversions?

As before, let’s say that we are currently in state and we perform some move and move to state . Let’s say the permutation associated with was and the permutation associated with is . Let us say that a pair of elements is affected by a move in the game if the relative order of and is different in the permutations and . Now we have the following:

if we perform a row move, the relative order of all elements corresponding to numbers remains the same — in particular, all affected pairs involve — so the number of inversions in is exactly the same as the number of inversions in .

if we perform a column move, typically the element that is being moved, say , ends up effectively jumping over two other elements, say and . In this case the following scenarios arise:

Neither nor is an inversion in .

In this case, both and emerge as new inversions in , and the total number of inversions in is two more than the total number of inversions in .

Both and are inversions in .

In this case, neither nor are inversions in — they both get fixed! So the total number of inversions in is two less than the total number of inversions in .

While is an inversion in , is not.

In this case, you fix some, you spoil some — so in , is not an inversion any more, but emerges as a new inversion; so the changes cancel and the number of inversions in is exactly the same as the number of inversions in .

While is not an inversion in , is one.

As before, you fix some, you spoil some just the other way now — so in , is a new inversion, but is no longer one; so the changes cancel again and the number of inversions in is exactly the same as the number of inversions in .

The long and short of all this is that after every move, the number of inversions either remains the same or changes by two. So no matter how many moves you perform, a state whose associated permutation has an odd number of inversions is going to remain inaccessible.

Tada!

So there we have it… I have a feeling that a little bit of language connecting transpositions and inversions will really make these proofs quite identical, at least for the case — although I did worry that the first approach seemed to rely rather explicitly on the location of the blank tile while the second one didn’t. It is quite possible that the first one actually demonstrates more than I’m giving it credit for!

Meanwhile, to be honest, I haven’t thought much about pushing the second line of attack to the case — it seems already that the statement about the change in the number of inversions is no longer true and the change itself is no longer two: in particular, it could apparently go up or down by three or one instead, since the element involved in the action, is now potentially jumping over three other elements, , , and … so this, at least from an immediate consideration, doesn’t quite take us where we want to go.

Possibly one has to work with a somewhat different invariant, maybe a notion of inversions that involve triples instead of pairs? Any comments on this would be very welcome, and I’ll have an update once I understand this a little better!

]]>puzzlesexpositionhttps://www.neeldhara.com/blog/15-puzzle/index.htmlSat, 02 Oct 2021 18:30:00 GMTSam I Am
https://www.neeldhara.com/blog/cp/sam-i-am/index.html
This is mostly about solving Sam I Am (UVa 11419); en route, we will end up discovering Kőnig’s theorem, which is a delightful fact about the special relationship shared by vertex covers and maximum matchings in bipartite graphs.

The Problem

Here’s an abridged version of the problem statement.

Sam is facing a temple which can be described by a grid and he has the locations of all enemies in the temple (each location can be thought of as the intersection of a row and a column in this grid).

All of a sudden, he realizes that he can kill the enemies without entering the temple using the great cannon ball which spits out a gigantic ball bigger than him killing anything it runs into and keeps on rolling until it finally explodes.

But the cannonball can only shoot horizontally or vertically and all the enemies along the path of that cannon ball will be killed.

Sam wants to know the minimum number of cannon balls and the positions from which he can shoot the cannonballs to eliminate all enemies from outside that temple. >

Some initial observations with an example

So to begin with, we have a grid with some cells identified as locations where Sam’s enemies are positioned, and here’s an example:

Conveniently for us, the enemies don’t move around.

We want to hit all of these locations, and what we have at our disposal is giant cannon balls which can destroy all enemies that are positioned on a single row, or a single column. For example, if we were obsessed about only firing along rows, we would need four cannon balls to tackle ’em all, like so:

If Sam was superstitious about shooting along columns only, then he would again need four of these cannon balls to take care of everything:

However, our friend Sam is smart, not superstitious! And if there is anything that he is obsessed about, it is ruthlessly optimal destruction! In other words, he wants to fix everything up, but while using the smallest number of cannon balls possible… and if that means mixing up ranks and files, so be it — notice that you can manage with just three once you combine the use of both axes:

And for this example in particular, notice that three cannon balls are necessary, because we have at least three enemies positioned at locations that share neither a row nor a column, implying that no row-fire or column-fire can handle more than one of these locations at once:

So for this example, we know that:

three cannon balls are necessary &

three cannon balls are sufficient.

In general, let’s say that two enemy positions are mutually independent if they are on different columns and on different rows. Let be the size of a largest collection of mutually independent positions. Then it is clear that:

cannon balls are necessary to handle all enemy locations;

because any fires that handle all enemy locations must in particular handle these mutually independent ones, and each individual fire can get to (at best) one of them — by definition of what it means for two positions to be mutually independent. So if we have a valid solution involving cannon balls, then .

What is a less obvious, but considerably fascinating, is the fact that:

there is always a strategy to hit all locations using just cannon balls. 🤯

A striking situation, no pun intended — the obvious estimate of what is needed turns out to be enough as well! The easy lower bound has a matching upper bound ❤️

An auxiliary graph

Alright, I think that’s enough with the advertising.

How does this work?

Let’s construct the following graph associated with the grid and the information about enemy positions:

Introduce a vertex for every row in the grid; say for . These are the row vertices.

Introduce a vertex for every column in the grid; say for . These are the column vertices.

Introduce the edge , if and only if the location at the intersection of the row and the column corresponds to an enemy position.

Observe that:

Any matching in (a collection of mutually disjoint edges) corresponds to a collection of mutually independent enemy positions back in the grid.

What we are looking for is a smallest-sized subset of such that every edge in has at least one of its endpoints in . Such a subset is called a vertex cover.

So our claim in the language of grids now translates to:

📝 The size of a maximum matching in is equal to the size of a minimum vertex cover in .

in the language of graphs. Keep in mind that as graphs go , happens to be a bipartite graph; which is to say that its vertex set can be parittioned into two parts† such that every edge has exactly one endpoint in each part.

† In this example, these parts correspond to subsets of row vertices and column vertices.

Bring in the flows

Is this much ado for nothing? We seem to have done some translation work, but there’s no proof of this bold claim in sight just yet… 😬

Fair. So here’s a roadmap for what we plan to do next:

Use the graph as the basis of a flow network.

Recall the maxflow-mincut duality.

Profit. Show the duality that we are interested in by hooking it up the known one.

So first things first: we are going to setup a flow network around the graph , and here’s a partial picture of what it looks like:

Here’s the official description of how we build this up:

Start with the graph , and orient every edge between a row vertex and a column vertex so that every such edge originates from the row vertex and latches on to the column vertex.

We assign infinite capacities to all the edges in . Go unlimited on the originals! We will even dub these edges original edges going forward.

Add a source vertex and add unit-capacity edges for every row vertex . We will call these edges the row selectors.

Add a target vertex and add unit-capacity edges for every column vertex . We will refer to these edges as column selectors.

That’s it, that’s the flow network based on , where I’m using to denote the capacity function. Now let’s stare at any valid integral flow in this network — what does it pull out from the middle? 🤔

Let’s make the following quick observations in the context of a valid integral flow in :

The flow on any edge from (i.e, an original edge) is either zero or one. Indeed, if , then we violate conservation constraints at both endpoints of .

For any row or column vertex, at most one original edge incident to it is used by the flow . In other words, for all but at most one original edge incident to any row or column vertex. Again, if not, combined with the fact that is integral and that the row and column selectors have unit capacity, we will violate conservation constraints on the vertex under consideration.

Based on these observations, we have that the set of original edges for which forms a matching in back in , and in particular, if was maximum flow, then this set would correspond to a maximum-sized matching. Now, let’s look at the corresponding mincut by building the residual graph:

Edges in the residual graph that have a residual capacity of zero are not shown. Also, the original edges that were used by have infinite residual capacity but their corresponding back-edges have unit capacity, but this distinction is not emphasised in the picture because it’s not particularly relevant to our discussion.

and considering what vertices are reachable from :

The vertices reachable from are marked green, while all remaining vertices are marked red.

In the residual graph, I would like to draw your attention to:

row vertices that are unreachable from ,

column vertices from where it is impossible to reach .

We will refer to these vertices as the misfits — they are highlighted for you in the picture below:

Now roll up your sleeves for some magic. Let’s pull up the cut — which we know is in fact a mincut — obtained by considering the set of vertices reachable from the residual graph corresponding to the maxflow . In pictures, note how we have attracted some column vertices to the -side, and pushed away some row vertices to the -side:

Note that this is a minimum cut, that is to say, the total capacity of the edges crossing the cut is as small as possible — which means that, in particular, the total capacity is at least (or should that be at most?) finite, and that implies, even more particularly, that none^{1} of the original edges cross this cut.

^{1} Remember how their capacities were infinite? So they just cannot afford to cross a minimum-capacity cut.

So every original edge is confined to the -camp or the -camp; but note that every original edge is an edge between a row vertex and a column vertex; so if you put two and two together, you see that, in fact, every edge must be incident to a misfit vertex. This means that the misfits are what we were looking for all along — they form a vertex cover of !

So at least we have some solution. Is this the best we can hope for?

Why yes!

Note that every misfit vertex contributes exactly one unit-capacity edge to the minimum cut: the misfits on the -side are incident to column selectors, and these edges connect with on the other side; while misfits on the -side are incident to row selectors, and these edges connect with , which is again on the opposite end. So every misfit vertex contributes exactly one edge to the minimum cut — and there are no other edges that cross the cut, so we have the following sequence of equalities:

size of the proposed solution = #misfits

#misfits = capacity of the minimum cut

capacity of the minimum cut = value of the maximum flow

value of the maximum flow = size of a maximum matching back in

size of a maximum matching back in = lower bound on our solution

Therefore, we have proposed a solution whose cost matches a lower bound on it, making it optimal! With a slight adjustment of language (dropping misfits in favor of vertex cover), the sequence of inequalities above also shows that the size of a minimum vertex cover in a bipartite graph equals the size of a maximum matching in the graph.

This was the relationship I’d promised to cover when we started, and it goes by Kőnig’s theorem in case you’d like to find out more — the argument we came up with here isn’t perhaps the traditional proof, and this is a fact that can be established in several different ways, all fun in their own way ❤️

]]>cplecturenoteshttps://www.neeldhara.com/blog/cp/sam-i-am/index.htmlThu, 30 Sep 2021 18:30:00 GMTNew Mac
https://www.neeldhara.com/blog/new-mac/index.html
Here’s a list of 50 things^{1} (with occasional additional context) that I install whenever I’m setting up macOS from scratch.

via Setapp

Bartender

Keeps the menubar clean. Very handy!

Better Touch Tool

I really need to leverage this a lot more, but even simple actions like swipe down with three fingers to close a tab, or tip-tap right left to move between tabs is pretty awesome already. Also use four-finger double tap to make the mouse pointer larger when it’s lost between screens… I’d guess this app can probably subsume a lot of the functionality offered by apps like Keyboard Maestro and Alfred.

iStat Menus

Good-looking stats in the menubar 👍️

Yoink

Has to be one of the best shelf apps out there. I know that there are a bunch of others in this space right now (👀, Filepane), however I have been using Yoink for so long that I haven’t considered switching. My common use-cases:

Alfred actions to send-to-Yoink

Using Yoink to stash away screenshots before the floating image disappears

A KM shortcut that can send any Finder item to Yoink

CleanMyMac

Mostly to keep track of file sizes via the Space Lens.

Alternative if using only this feature: Daisy Disk

Default Folder X

Use this all the time to stash away stuff where it belongs to keep Downloads clutter-free. Also the Alfred DFX collection is handy for finding recent items even if not 100% reliable.

Timing

Use this to supplement manual time-tracking. Do not use it to its full potential at all, I think a little investment with setting up the right projects etc. can go a long way.

Dropzone

I mostly use this as a longer-term stash than Yoink. I think there are some very nice possibilities here, but the only things I’ve done with it so far include:

uploading images online

opening a finder path in a terminal (superseded by an Alfred shortcut)

dropping files in select locations

URL shortening

Permute

Handy for all kinds of (bulk) file conversions.

Text Sniper

Impressive OCR “from anywhere”.

Swish

Intuitive gestures for window management. Pretty confident all this can be done in Better Touch Tool (above), but the actions are inspiring, and I’m lazy, so yeah, this is explicitly installed.

Downie

Use this for downloading videos from Youtube for offline viewing/listening. Fairly robust.

IconJar

Icon collection, enough said. 🎁

Sip

Handy 🎨 color picker.

World Clock Pro

Visually appealing world-clock, nice for scheduling stuff across timezones, great screensaver option as well.

Dash

Documentation lookup, handy that it works inside VS Code (via an extension).

MindNode

Lovely mindmaps.

PDFPen

Although I mostly use Preview, PDFPen is useful for quickly rearranging and removing pages. Not sure about the several other features claimed, I find that it sadly crashes more often than not, so not my default application.

TextSoap

Occasional use, but very useful when I do need it for some pesky hidden-unicode-character-removal exercise.

MathKey

Niche app - on the rare occasion that I have a complicated LaTeX formula to write, I can write it in the iOS version of this app and receive it on the Mac (I don’t think the desktop app is even necessary for this; the iOS purchase can be bypassed by using the Mac app via Sidecar, but this is where I discovered the app so it makes the list).

Marked

Powerful previews for Markdown documents. Lots of interesting export features.

ChronoSync Express

This helps with keeping certain folders in sync, and setting up some backup schedules. Nothing that can’t be done with a few scripts (?) and/or Time Machine, but I did end up setting (and forgetting) a few things in here.

General

Notion

I’m (admittedly* experimentally) using Notion as my primary PKM tool, and it’s also where I am keeping most of my public-facing content (including this blog). My usage of Notion is gradually expanding in scope to include time/task/finance tracking as well. Too slow.

*and also admittedly yet-again, after a fairly committed detour through Obsidian, Craft, and VSCode extensions for several months…

Bibdesk

Fairly robust reference management that has most of what I need — priority features include speed, reliability, flexibility in generating citekeys and decent auto-filing of papers added to the database (popular free and paid alternatives that I’ve tried briefly: Zotero, Mendeley, Setne, Papers, Readcube, JabRef, Bookends).

Incidentally, if you are into Obsidian and Zotero, you might enjoy this video.

MacTeX

LaTeX and related tools, including TeX-friendly IDEs and reference management tools.

Xcode Tools, pandoc, and homebrew

Need these to work with code.

Contexts

The app that I miss the first when on a machine that doesn’t have it, next to Alfred. Makes window switching much more search and keyboard-driven.

Alfred

Apart from using it as a launcher (even for files), I almost use Alfred as a Finder replacement. Here are some of my favorite Alfred workflows:

Menubar Search

Simple Folder Search (only search for folders)

Case Switch (combined with send-text-to-Alfred below, this can be quite nifty)

Symbols Search (unicode goodness)

Send to Yoink

Quit Applications

Send text to Alfred (double-tap the option key)

Color

Currency Exchanges

Keyboard Maestro

Really elaborate shortcut/automation app. I’ve only scratched the surface with my use cases, but one of the things I really dig about my setup is simulating keypress sequences.

The way I do this is to activate a macro group for one action with one keyboard shortcut (e.g, CMD + ;) and then have all macros within that have one-letter or one-letter + one-modifier triggers - basically very easy triggers. This way, I only have to remember a bunch of high-level shortcuts for things in various categories, and from there it’s just a letter (and the same letter can be overloaded in different contexts).

As a concrete example, I have a macro group called launchers, and a shortcut within that for launching chrome. So something like CMD+L followed by c would launch Chrome. Although I have to confess that I mostly launch stuff through Alfred still (at the cost of one or two extra keystrokes).

Keypress-sequence-triggers are native to Better Touch Tool and since BTT supports AppleScript, you could also run KM macros from BTT. I haven’t quite tried this yet.

Fast snippet expansion - faster than TextExpander (one of the main competitors in this space) in my experience. Recent updates have some rad features, which of course I’m yet to explore and exploit!

1Password

Reasonably user-friendly and robust password management. Syncs to iOS, but I haven’t managed to leverage it so much on iOS. 1Password is ideal for storing confidential information nicely (IDs, bank stuff, and the like) - if used only for passwords I suppose the Keychain does a good job too.

Fantastical and Calendar

Fantastical is a nice (but expensive!) calendar app, mostly use it because of the calendar sets feature that keeps my time blocking calendars separate from the official one that is public within the organization. Of late, I especially like the way you can join online meetings from the notifications.

Having said that, I realized that much of what I was doing with Fantastical was overkill and I’ve switched to the default calendar app for now, and it’s one paid subscription less^{2} to have.

Ok so I am back on Fantastical, because I am kind of

VS Code

This is where I am supposed to be spending most of my time, perhaps next only to Craft/Notion. A few things from my VSCode workflow:

Use different themes for different file types (I mostly dabble in LaTeX, C++, Python, JavaScript, and Markdown)

Little utility extensions save a lot of time: e.g, sort lines, increment value at cursor, file management, etc.

Multicursor-powered find and replace is amazing.

Workspaces are handy and I usually launch them from Alfred.

Hook

Looks very promising for cross-linking stuff across apps that have a common context (say, a project). I really need to explore this more!

Stream Deck (best with accompanying hardware)

Particularly useful for switching OBS scenes although I use it less than I thought I would!

In particular, I want to explore their VSCode and KM integrations.

If without the physical device, Streamdeck does have a nice iOS app that simulates the hardware, but the pricing is based on a subscription model.

Google Chrome

I can’t make up my mind between Chrome/FF/Brave/Safari. I mostly switch between Chrome and Safari, with a mild preference for Chrome because of it’s more comprehensive extensions space, but I often end up with Safari as default for speed and privacy.

Readkit

Use this for RSS, although I’ve mostly migrated away to DEVONthink. Still looking for a nice stand-alone RSS reader though, Readkit doesn’t always render everything the way I expect, sadly.

OBS

For recording and live-streaming videos. Also useful as a virtual camera for meeting apps.

Screenflow and Camtasia

For recording videos, lots of features, still finding my way around them.

Slack and Discord

Online communities. I sometimes wish there was a native app for discourse too (is there?)

Keynote

Presentations - main alternative: Beamer + LaTeX + pgf/TikZ; or one of the JS-based slide generator tools from Markdown files (I did use react.js for one entire term).

DEVONthink

Use this fairly minimally (especially relative to the possibilities). At the moment DT indexes a couple of key finder folders and pulls in information from a lot of RSS feeds and even Twitter accounts. I try to review the stuff that automatically piles up in DT regularly, but — at the moment — it’s mostly a dumping ground and… messy.

Microsoft Teams, Skype, and Zoom

Use this for classes and online meetings.

Office suite: Word/Powerpoint/Excel

Use it only to open files I receive.

Fruitjuice

Useful battery health monitoring, discovered the app from a MPU podcast episode IIRC.

Mathsnip

Surprisingly good LaTeX-aware OCR.

Webapps

YNAB

Budgeting and finance management.

Gmail

Until I setup Mailmate again, I’m checking email in my browser. 🙈

GSuite (Docs, Sheets, Slides, and Calendar)

I use these when others use them.

Zapier, IFTTT, Integromat

A few automations here and there, still on my bucket list to take full advantage here. Integromat has been great for tracking Exportober contributions, incidentally!

Omissions

(aka stuff I used to use but don’t use as much now.)

Karabiner Elements. I was quite taken in by the possibilities offered by “God Mode”, but I realised that I prefer sequential shortcuts - like the ones I managed to setup in KM - to ones powered by arbitrary combinations of simultaneous keypresses.

Mailmate. Will very likely be back in the workflow soon!

Things. Retired when I switched to “Notion for Everything”. That said, Things is absolutely awesome!

Ulyssess. Replaced by Notion → Craft → Obsidian → Notion.

Bear. Replaced by Notion → Craft → Obsidian → Notion.

Sublime Text. Replaced by VSCode.

2Do. Replaced by Things a long time ago, but a really nice app!

Shift. Combines many windows in one, basically. Not sure if it was sufficiently useful, living without it and not missing it much.

IM+. Similar to Shift in scope, although this one is available on Setapp.

What’s on your list? Do share in the comments below!

Footnotes

NB. This list does not include fonts and scripts — that’s for a separate round up in due course.↩︎

I have nothing against paid subscriptions for software in general, but Fantastical’s pricing for the feature set does seem to have an unclear cost-benefit tradeoff, at least for users like me. I haven’t missed much since moving on.↩︎

You can find the original announcement here and more specifics clarifying the format (or the lack of it) here. Here’s the short version:

Put up a piece of content everyday between 27th September and 30th October, with the possibility of skipping one day per week;

Post a link to your content on Twitter with #exportober

That’s it, actually. 🤷♀️

📝 If you’d like to participate you can sign up below; and if you’d like to help, please encourage everyone participating by checking out the tweets coming in above!

Psst. It’s quite fine to sign up even if you’re reading this after the 27th of September. The automated tracking exercise here will stop after the 30th of October, so you can be a part of this by just contributing in this window. It certainly does’t have to be daily and it doesn’t have to be 30 things, although I found those to be useful default targets to work with for myself.

Sign up!

While you can participate simply by using #exportober in your tweets, it’ll be great if you could explicitly enter your Twitter username in the form below, so we can check in on each other! 🤝

While I’m not going to write a Twitter bot that will send you daily reminders over DM, I do hope to create a separate page for each registered participant at the end of the challenge that shows off just their entries in one place, so it’s helpful to know who you are 😀

In a massively impulsive move nudged by some Twitter feedback, I recently launched the Exportober challenge.

The TL;DR version:

Put up a piece of content* everyday between 27th September and 30th October, with the possibility of skipping one day per week;

Post a link to your content on Twitter with #exportober

That’s it, actually. 🤷♀️

Anyone else procrastinating on starting a blog, CS or otherwise? Would you be interested in being held mutually accountable for a few weeks to overcome the initial inertia?

Do let me know! I’ll try to setup something systematic-looking if there’s interest 🙂

I was deliberately vague about the terms-and-conditions that goes with the piece of content piece above. The rules I mentioned were minimal: since there are no restrictions of age, keep the content SFW and generally legal. Other than that, anything goes, for example:

Can I doodle? Yes.

Can I meme? Yes.

Can I make a comic? Yes.

Can I quip? Yes.

Can I tweet a thread? Yes.

Can I tweet a single tweet? Yes.

Can I song and/or hum and/or dance? Yes.

Can I react? I am unfamiliar with this genre, but yeah, why not?

Can I just quote? Uhh, ok-fine, sure — maybe be sure to include a reaction?

Can I commit? Yes, please! Oh, you mean — can it be a GitHub commit? Right, yeah, sure.

One a day is a lot! (Unless tweets count). I used to blog regularly but not even one a week at its peak, I think.

in case anyone is looking for inspiration, in true student fashion, i am already planning on cheating by turning all the math puns i have in mind to comics ['ring arthur and his knights of the round table' but where ring arthur is a noncommutative ring without unity]

As you can see, there are no restrictions on format or length or quality. It can be whatever you want, and however long or short you want it to be. The point is to get into the habit of putting a bit of yourself into something tangible that you’d want to share.

So while you could technically schedule thirty pieces of Harry Potter trivia in advance — that would kind of defeat the purpose.

Is this for me? #whybother with #exportober

In general, I imagine only you would know if this is for you — this may not be a priority or a point of interest for you right now, but if you’re reading this, possibly your interest is at least mildly piqued?

What this is about is setting aside some time for yourself and to participate alongside friends who’re in it for fun and profit:

We often avoid taking action because we think "I need to learn more," but the best way to learn is often by taking action.

The profit bit is the hope that we trick ourselves into making this a bit of a regular habit for life.

Longer term, you may or may not want to be sharing or publishing on a daily basis. But hopefully, longer term, you are engaged with the process on a regular basis.

Personally, there’s almost nothing that I do consistently on a daily basis, not counting the things one needs to do continue being alive. I’d like to see if I can change that a bit^{1}, and apparently doing such things bit by bit — and with some public commitment — is a good idea, hence the micro-nature of the challenge.

So overall I’ve gotten to a point where I’m just afraid to even think about putting something together because I think it’s an unrealistic commitment of time.

I’m also really bad at chunking - everything I do of this sort manifests at the wrong end of an all-nighter 🙈

I want to be in, but I stoop no lower than meaningful masterpieces…

Hmm. One way that you could still make this work for you is to build out your masterpiece bit by bit. If it’s a tutorial, you could plan it out in advance and work through one coherent section a day. If it’s a sketch, you could share your partial progress as you go along, and even put it together in a timelapse at the end? That would be great to see!

There are some types of long-form content that aren’t naturally amenable to this type of chunking; say you want to put together a video exposition, make an origami sculpture, or crochet a Klein bottle. In this situation, you could either use the challenge to document your process and progress; or you could just claim to engage in #exportoberlite with a reduced frequency of production — say once a week, or one masterpiece at the end — you’ll just have to still tweet it out so I can catalog it ❤️

I really don’t like the illusion that there is one process for making and that it involves writing every day. Thinking is work to. So is reading. So is doing things that seem unrelated to writing. Our brains are always thinking about what we’re making, whether we’re typing or not

Also, while on the subject of masterpieces, there’s the parable of the pots. On the other hand, everyone does have their own process, and the idea isn’t to force a format: this process is temporary, flexible, and optional 🙌

This sounds like fun, but I have no idea what to make.

Oooh. Maybe just ping on Twitter if you are in this situation. I do imagine that there are folks who have more ideas than they can handle, so if you have the bandwidth, it’ll even out nicely! For some starter inspiration, just in case it is useful, here are some of the post types that I’m planning for the duration of this challenge, in roughly increasing order of desperation:

Lecture notes for classes/talks I’m teaching and/or attending.

Highlights from whatever podcasts I’m tuned into.

Clean up draft essays from previous lives.

Random doodles. And VSCode keyboard shortcuts.

Hot takes on inconsequential debates.^{2}

I also have a few black holes nurtured over time — I’m looking at you, all my Read-It-NeverLater apps, the starred section in my RSS app, my YouTube watchlist, and relatives. Maybe about time to go down some of these rabbit holes with the excuse of commentary to follow.

So yes, that’ll be all for now! Let’s see how this goes 🤞 Meanwhile, please hop on and spread the word for all of us? Thank you! 🎉

PS. You might be curious about what participating will look like. I’m trying to setup a separate page for each participant in the challenge that will pull in all your tagged tweets. I’ll share a preview soon!

Footnotes

c.f. the next section for a different perspective.↩︎

Let me know if you want prompts.↩︎

]]>exportoberhttps://www.neeldhara.com/blog/exportober/about/index.htmlThu, 23 Sep 2021 18:30:00 GMTMoving Blocks at CTIS 2021
https://www.neeldhara.com/blog/moving-blocks-ctis/index.html
I am very excited about third conference on Computational Thinking in Schools (CTiS2021)^{1}, a CSpathshala event, that’s coming up from the 29th September to 2nd October 2021 at School of Scholars, Nagpur.

Some background from the conference website:

The CTiS (Computational Thinking in Schools) conference is an annual event organised by the ACM (Association of Computing Machinery) and the CSpathshala community. It aims to bring together teachers, educators and researchers to discuss issues of curriculum, pedagogy, policy and implementation, related to bringing computational thinking to schools.

CTiS2021 aims to provide a platform for teachers, educators and experts to share their best practices as well as challenges faced in implementing computational thinking in education. The discussions will focus on integrating CT activities (both plugged and unplugged) in various school subjects, on student learning outcomes and on disseminating findings of CT based experiments or classroom research conducted by teachers and educators across the country.

Our 4-day conference features key note speakers, Hal Abelson, MIT, USA, Manish Jain, IIT Gandhinagar, Patricia Ordóñez, University of Puerto Rico Río Piedras and Wolfgang Slany, TU Graz, Austria. The conference also features a workshop on CT and inclusion, conducted by Supriya Dey, Vision Empower and Manohar Swaminathan, Microsoft Research, Bengaluru and presentations of selected abstracts with sessions on implementation of computational thinking, fun activities and innovative examples used by teachers in classrooms!

Needless to say, I’m looking forward to this very exciting program! As a PC member, I also know that the contributed content is fantastic as well, and the aim of this little writeup is to offer a glimpse into this section of the conference.

In particular, I want to share with you a puzzle that was described by Rema Nair, who teaches Computer Science at the Mallya Aditi International School in Bangalore, grades 9-12.

To begin with, we have an equal number of blue and green boxes positioned as follows:

🟦 🟦 🟦 🟩 🟩 🟩

So the blue boxes are lined up first from left to right, followed by a space that’s exactly enough to fit one box, and then we have the green boxes lined up after the space. The goal is to arrive at the following position, which is essentially what you would have if the blue and green boxes were to switch positions:

🟩 🟩 🟩 🟦 🟦 🟦

The moves of the boxes are subject to the following rules:

The boxes from the left (i.e, the blue ones) can only move towards the right, and the boxes from the right (i.e, the green ones) can only move towards the left.

Boxes can move forward one space, or move two spaces by jumping over/moving past another box of a different colour (never over a box of the same colour).

The moves are to be made in one direction only.

The puzzle is solved when the two sets of boxes have switched positions.

So how would you get the boxes to switch positions? Are there multiple ways to do it successfully? If so, which strategy leads to the smallest number of moves? This should be a fun conversation-starter in class — and beyond!

This is a great activity with actual boxes in a physical setting, but for now, here’s a quick version that you can try out right here, thanks to Polypad by Mathigon* - be careful to not overlap the boxes one on top of the other, they will end up merging! You can always refresh this page to reset 😀

*Note that the numbers on the boxes are immaterial; notice that given the constraints on the directions, the relative ordering of the numbers is fixed anyway.

Enjoy playing for now, and join us at CTiS to meet Rema (and other participants).

Footnotes

Registration is free but mandatory. The deadline is 28th September. Please head over here to register!↩︎

📝 Update: You can now track everyone’s progress from here!

You can also check out a little more about the format, intent and background here.

As you can see — at least at the time of this writing — this is a blog under construction with some mild ambition, going by the long list of empty categories on the homepage.

I’ve heard a lot about the effectiveness of something something public something something accountability, so I’m going to give this a shot: if there’s anyone else who wants a bit of a jumpstart and encouragement for getting into the habit of putting stuff out there, this is for you!

Presenting the EXPress yOuR Thoughts, i.e, export, challenge.

Here be some rules, or not, make this your own!

Put something out there — could be an essay, a video, a sketchnote, some code, a piece of music, a photograph — I think the only criteria is that this should be something you put together that you feel compelled to share, and something that can be accessed via a public URL. I suppose quotes and curated round-ups are good too, but ideally you want this to be something that has a bit of you in it.

Share it on Twitter with #exportober (umm, the export challenge in October 😬 … it had to be something that wasn’t already taken so I can scrape it off and put it up in one place, and everyone participating can keep an eye out on others participating — the general hope is that everyone finds themselves encouraged by everyone else 🎉).

I’m going to find a way of listing everything that comes up starting 27th September. This gives you five weeks until the end of October. Try and get something up everyday - this puts the challenge in the Export Challenge 😀 That said, allowing ourselves one cheat day per week means that we all hopefully end up with 30 things by the 30th of October. Yays 🤞

Since I’ll hopefully find a way of tracking all the content tagged this way and automatically pushing it to a page where we can find it all in one place, please don’t put up anything illegal or damaging. Other than this, practically anything goes, but please do respect the basic idea, which is is to build up some positive vibes and keep this a fun exercise!

So I hope you spend the coming week getting setup — figure out what you want to do and how you’ll do it, and maybe even cheating a little and preparing some buffer content for the rainy days? We’ve already had some great suggestions for tools you can use to get started:

GitHub pages is great for this. I don't use Markdown, but it still works as a quick, lightweight publishing system, automatic ssh setup, etc. Since I store the content on GitHub anyway, everything is nicely unified.

Throw in your Twitter username in the form below to add your name to the list of people who are thinking about will be participating! The list will evolve automatically below, and I’ll probably clean it out of spurious entries manually every so often.

Thanks to everyone who participated! The form is no longer relevant, but you can check out the posts by looking for #exportober on Twitter :)

]]>exportoberhttps://www.neeldhara.com/blog/exportober/2021/index.htmlSat, 18 Sep 2021 18:30:00 GMTEnvelope Budgeting with Notion
https://www.neeldhara.com/blog/envelope-budgeting-notion/index.html
YNAB (c.f. r/YNAB) (short for You Need a Budget) is a budgeting application that lets you track and manage your finances. Like most apps in this category, it provides a slick interface to enter all your transactions. YNAB is more than just cataloging transactions and tracking account balances, though. The design here revolves around (and goes beyond) what is called envelope budgeting, which basically boils down to this:

Give every dollar a job.

You can dig a little deeper into how YNAB works by looking up their four rules here. I am going to try and create an envelope budgeting system in Notion that is loosely inspired by my use of YNAB.

To be clear, I don’t expect to stop using YNAB, nor do I expect to replicate many of its sophisticated features. Also, there are some nice envelope budgeting systems on Notion already! For instance, you might want to check out the one here by u/sff_fan_17 or the one here by Ben Smith. These are really neat, but the only reason I’m not just duplicating one of them is that what I have in mind looks slightly different from the setups here. In particular, I would like the transactions to be dated and tied to specific accounts, and I would also like the system here to account for all the inflows and outflows in my actual system. Neither of these templates feature a hierarchy of categories either, which is something that we will attempt to do here.

In the first template above, I think the total income is mentioned separately, outside of the database system; and the budget covers a part of the total available income. There are explicit instructions on how to update this month-to-month, so do check this out — perhaps it works for what you might have in mind! The second template explicitly accounts for inflows, and is apparently based on this Google sheet. It does seem that the transactions are missing information about accounts and dates, which could be a little limiting if you wanted to generate a report or a dashboard for a particular period of time. Again, a great starting point, and if it resonates with your kind of setup, it’s definitely worth duplicating and playing with. Both templates are free to access and replicate.

Incidentally, if you don’t use Notion and are hesitant to try YNAB, you could take a look at their guide to building your own budgeting template — this does not require using YNAB at all and can even be made to work pen and paper. Many people have also recreated YNAB’s core features using their own favourite tools, the most popular among which appears to be Google sheets — see, for example: Aspire Budget (c.f. r/aspirebudgeting) — I have not tried this myself, but it appears to be very feature-rich and neat overall.

That said, onto our own YNAB-esque budgeting template in Notion! We’re on our way to something that looks like this:

If you want to just skip ahead and play with the template, you can duplicate it by following this link:

There are three key pieces to this setup: the first is the categories (these are the labels on the envelopes, if you like), the second is the actual transactions that take take place, and the third is a list of accounts that you have (could be bank accounts, credit accounts, virtual wallets, and so on). You would want the transactions database to be linked to both categories and the accounts. More on the exact table designs below. I’m going to assume some familiarity with Notion terminology, if this is your first time with Notion then some of this may not make sense right away, but if you could just look up how Notion databases work — especially the relational aspect — then I think you’d have all you need to follow along!

Budgeting Categories

It may be natural for this table to just have one row for each category. You probably want to have a small number of higher-order categories (e.g: monthly supplies, services, maintenance, health, investments, etc.) and smaller, more specific ones under these broad umbrellas (e.g, services would likely have sub-categories along the lines of internet, phone, electricity, water, etc.). You can do this by setting up a relation property to the table itself, and have it sync two-way, like so:

If you want to see just the higher-order categories nicely, you can setup a gallery view with a filter for the main category to be empty, which would look like this (I’ve disabled the preview and added some icons from notion.vip):

Next, we want to specify a budget for each of these categories. We can do this directly for the lower-order categories first. Then, we can have the main category budgets calculated automatically by rolling up the budgets of the corresponding child categories and adding up their budget values. To have a clean view of the budget, you could add a formula column that just adds up the values from the direct budgets and the rollup, like so:

You can add two dummy properties with the text Budgeted: and Remaining: for each row, and set them to show along with the budget in the Gallery view so you get something like this:

There are two natural questions at this point:

How do we know that we have budgeted what we actually have?

How do we know what amounts are remaining at any given point of time in the month?

To address both of these questions, we will need to flesh out the transactions database, link it to the categories and come back to this. But before that, let’s do a quick detour with an accounts database just to setup the foundation we need for the transactions database.

Accounts

For this demonstration, I am just going to add two accounts — one savings bank account and one credit card account:

The most natural property we want for the Accounts database would be a balance column. Instead of maintaining this manually, we will just link this with the transactions database and derive the balance by rolling up the relevant transactions.

Transactions

You might want to optionally add a memo property that lets you add a quick note or explanation for the transaction. However, given that each database entry is also a page, you could also quite flexibly add all the additional information you want to the page corresponding to any transaction. Meanwhile, you might also want to setup relations to other parts of your Notion setup if you find anything relevant — for instance, if you have a books database, or an inventory database, and so on. That said, we’re going to keep it simple here, and here’s an example transaction:

You’ll notice that I’ve linked to both the child and the parent category for this transaction. It would be nice if the parent category was pulled up automatically — and this is possible with a formula, but as far as I know the formula will not actually link the transaction to the main category. So for now, we assign both categories manually. 🤷♀️

One quick thing to do now is to go back to the Accounts database and add a rollup property that takes on the sum of the amounts property from the related transactions table, and once done, the balances show up nicely in the gallery view:

Now we go back to our categories database and rename the relational column to transactions and add a rollup that collects all expenses from the transactions that happened in a particular category, so this is what it looks like:

Now add a formula column available that simply adds up the budget and the expense columns so you can find out how much of your budget is still available for use. My formula looks like this:

prop("Final Budget") + prop("Expenses")

Note that it might feel more natural to subtract expenses, but my expenses are already negative amount transactions, so I just need to bundle it all together.

Just for fun, you could also add a status column that visually indicates how much of your budget you have left. The progress-bar style of the status property here is inspired by this guide, and the formula I used requires a couple of auxiliary columns that calculate the percentage and determine if a half-star should be used or not based on the value of the decimal part. It also first checks that the available balance is in fact positive, if not, it’s going to display a suitably scary warning emoji. I won’t bore you with the specifics here, but you can find the formula in the template that I’ve linked to at the end of this post.

So now we are at a point where the remaining amounts are calculated based on the transactions. However, we still have to think about how to link the budgeted amounts to the actual money available. In fact, speaking of money available, I haven’t really touched upon how to handle transactions that are not expenses; i.e, transactions with a positive amount value and that reflect money coming into the system as opposed to leaving it. These are, of course, just regular transactions — but what category do we assign them to? All the ones we have so far really capture spends, not inflows…

So, it turns out that YNAB would take all this money and automatically categorize it as unassigned, or to be budgeted. We can mimic this by creating a special category called to be assigned, and have all income-type transactions categorized as such. Typically this would be transactions corresponding to a salary, client payments, refunds, credit from interest, and so forth.

Notice that the so-called expenses^{1} that are now accumulating in this category is actually the total amount of money that came into the system. Incidentally, if you were to just look at the sum of the balance column in the accounts database, that’s the net amount of money in the system at any given point of time.

^{1} Remember that the expenses column just rolled up the transaction amounts in a particular category.

You also don’t need to budget separately for credit card payments, because your credit card bill is composed of transactions that were already budgeted for! Even if they were items corresponding to, say, credit card fees, you probably categorized them under Services, for example. So we won’t have a separate budget for credit card bill payments (although I should mention that YNAB does this explicitly and handles it automatically).

Alright, so it seems like we are nearly there, except that our current situation is the following:

The amount the to be assigned category is a true reflection of incoming funds.

The amounts that we added to our category budgets were setup manually and generally divorced from the reality in the transactions database.

For example, let’s say I want to budget 750 for ebooks this month. I could do this by adding a dummy transaction that debits an amount of 750 to the to be assigned category and credits it to the ebooks category. What this means is that when we roll up the amounts from all transactions, we directly obtain the amount remaining for us to spend!

So for the very first month, when we have a clean slate, we just have a bunch of such transactions — these won’t have any explicit account associated with them because they aren’t real transactions; and in fact you can always filter your transactions table so that you only see the meaningful ones by setting the condition that the accounts column should be non-empty.

Meanwhile, here is how we do the budgets for our categories all over again, this time via these virtual transactions:

If you go to the to be assigned row in the categories table and look at the rollup value in the expenses column, then you’ll see that it corresponds to either the amount of money that’s still assigned (these are dollars — or in my case, rupees — that don’t have a job yet), or, in case you happen to have overshot the budget, the amount by which you are falling short. In the former situation, the available amount will be a positive number, while in the latter, it’ll be negative.

Ideally, we just want this number to be zero, indicating that everything has been assigned appropriately. To achieve this:

If your budgets have collectively overshot the amount of money available, re-adjust them them — specifically, reduce some of the amounts — so that this is no longer the case. Of course, I am saying this from a theoretical standpoint; if your situation is that you have real expenses that you don’t have real money for, then you would want to plan for this by bringing the differential amount of money into the system via a loan, and then planning the repayment by budgeting for it as well. Dealing with debt is beyond the scope of this discussion, but I think the YNAB blog, book, and videos go into this at length.

If you have money left over, you could either add it to your budgets, giving yourself some extra wiggle room; but I prefer to budget for fixed amounts generally, so in this situation I’ll just add this amount to something I call a Miscellaneous or Scratchpad category. It’s something you can borrow from if you fall short later, it has no particular semantics. Some people like to sweep off any excess money into deposit accounts, and if you do this, then you might want to create those accounts in the system and enter those transactions to get rid of this positive balance.

At the end of this, you are in a situation where all money is nice and assigned. Since we started off by specifying budgets manually, we should go back and fix some formulas in our database of categories. In particular, here’s what I did to simplify things:

Remove the Available column (previously this was the difference of the manually set budget and the rolled up expenses).

Rename Expenses to Available, since the rollup now just reflects what’s truly available.

I’m going to leave the manually added budgets in — although we won’t use them to calculate what’s truly available any more, they will help us plan our budgets going forward.

Everything so far should make sense for an initial setup, but what do we do when we have new incoming transactions that need to be assigned to categories? I generally like to do the budgeting exercise once at the start of every month, so any intermediate positive transactions into the system will either remain in the To be assigned category, or if you are OCD about wanting that that category to be set to zero always, you can always push this number out into your scratchpad.

At the start of the month (this could be another day and a different frequency; but I do recommend being consistent for simplicity), we need to refuel the categories with the funds available. There are two kinds of things that could happen here, broadly speaking:

For categories that represent a plan to save up to something, like a vacation, or a category where you feel like you want to have a certain amount of money set aside every month irrespective of how much you spent in the last month, you just want to push budget amount of money into that category via the virtual transactions we discussed earlier.

For other categories, which I like to think of as those having rolling budgets, you want to only assign the difference between what was budgeted and what was spent… and hopefully this is a non-negative quantity!

You could setup a checkbox to indicate which categories have rolling budgets and which ones do not, and then this formula:

will tell you how much you should budget for next month.

In this example, Ebooks are not a rolling category, so even though I need only 628.95 to meet the original budget, I’ll still set aside the full 750, and the amount that will be available will be 871.05. On the other hand, Phone is a rolling category, and presumably my phone-related expenses in the current month added up to 420, so the recommendation is to budget 420 next time so you’ll still have 500 available total.

The Process After Setting Up

There are two main times that you’ll interact with this budget: whenever a transaction is made, and once every X days to reset the budgets for the individual categories.

Adding transactions is reasonably easy, although admittedly it’s probably not as smooth as a specialized app that might have a Siri command to do this for you or a widget that let’s you quick-add things. However, it’s not too bad, especially if you enter it right away. You could also potentially automate this via API integrations, or enter your transactions in your regular app and export them as a CSV and import them into the Notion system once every so often.

The budgeting bit is going to be a little more work, especially if you work with a gazillion categories. The formulas will guide to you what needs to be done, but those virtual transactions still need to be added manually. On YNAB, you can do what I described above (adding the deficit to rollup categories and the originally intended budgets to the others) in one click — and there are other options too, for example, you may have moved to a new location and you’re still getting the hang of what you’ll need to set aside for groceries, so YNAB will offer to budget what you spent last month, or your average expenses from the last six months, and so on. Here, since you are assigning things manually, you can definitely tweak as you go; the next month column is just a suggestion.

You can probably prepare a CSV file with the default budget amounts and just merge this in at the start of every month if your expenses are super predictable, and just adjust the entries that need adjusting. This will save you some time, but remember that the categories still need to be linked to manually. It’s not too bad for something that happens once a month and that will hopefully bring you some sense of control and awareness 😇

Perhaps also try and not have a gazillion categories and sub-categories, at least to begin with — it helps to keep things simple, especially when starting out.

Common Pitfalls

Here are a couple of mistakes I made frequently, even while just setting up this template!

Forgetting that transaction amounts corresponding to expenses should be recorded as negative numbers! If this happens very very frequently to you, you could also set this up a little differently — have a checkbox to indicate if a transaction is an expense or an inflow, and always enter a positive number reflecting the amount, and let a formula do the work of adding the sign!

Forgetting to add the parent category — this can mess up the views of what’s available in the high-level categories and cause the numbers to not tally. So if you need to debug your numbers, check for whether you have added both categories to your transactions or not!

Dashboards

Most of the action here is happening in the Transactions database. You could create linked copies of this database anywhere you like and filter things out to see what you want. For instance, if you want to keep tabs on the transactions in specific accounts, you could have this on your account pages:

You could filter out transactions for a particular month, a particular category (either a top-level category or an atomic one), and so on. I think there’s plenty you can do here, but I am not sure how much of this can be automated. For instance, you might want to generate — or have over email — a monthly report of your expenses across various categories and how did relative to your estimated budgets. This should be possible by leveraging the API and tools like Integromat/Zapier/Automate.io - but I haven’t really explored the possibilities here.

Missing Features

It would be nice to have a gallery view of the months of the year showing spends and budgets in each (high-level?) category. For this though I’d need the rows to correspond to months, columns corresponding to categories, which pull up transactions that happened in a particular month from said category.

Even if I manually linked the transactions database to this calendar one, and made sure each transaction was linked to the correct row, I don’t see how I can split up those transactions across categories, since it’s not possible to add a filter to relational columns or rollups as far as I know. It’s a similar bottleneck going through the Categories database as well. This information is of course implicit in the system, I just can’t think of a neat way of visualizing it.

This is possible to do for the current month though:

YNAB also has more sophisticated category types — apart from budgets that roll or accumulate, you could have categories that aim to have a certain amount of funds assigned by a certain date and so on. For those who are freelancers with incomes spread over the days of the month, I think YNAB has a lot of little features that allow for a more flexible way of budgeting, which I’m not super familiar with because I’m not in this situation. This is just to say that this setup here may be both limiting and feeing because of how much of the setup is manually done. At least that’s my optimistic view right now 😀

Finally, YNAB also has an option to reconcile accounts, which is when you declare that the numbers in YNAB match the book balance according to your bank or credit card agency. This is a neat little thing that I like to check off every so often. Here, I suppose you could just glance through the balances on the Accounts database (remember the gallery view from earlier?), but it won’t have the same song-and-dance-y feeling — but maybe this could be a recurring task that you can check off, and hopefully that will feel good 😅

So that’s about it! I’d love to hear any feedback on this, and suggestions for improving the setup would be very welcome too. You can duplicate the template from here.