Hello everyone and welcome to Speedcubing on Emacs. First of all a little bit about myself. My name is Vassilij Schneidermann, online I go by VasaMasa, I'm 31 years old, I work in information security and I do consulting and hacking and stuff like figuring out how to break into other people's computers and how to secure the systems basically. You can reach me by email, I do have a self-hosted code repository thingy going on, I have a blog and you can find me in some other places online, like IRC for example. So about the talk itself, I used to be into the Rubik's Cube when I was in school, I forgot about it though because these cubes were not very good, but recently I did find some cheap looking cube at a shop, did not pay terribly much for it and it was so, so much better than my old cube, it was unreal. And so this motivated me to get back into this really weird kind of hobby and for this you need to be good at producing a truly random scramble and timing your attempts to get any better at it. There is of course existing software to do the scrambling for you and the recording and the timekeeping and such, but all the good options seem to be either web or mobile, for example the SCS timer software or the TwistyTimer app on Android and to my surprise I did not found a single decent option inside Emacs, so this is basically a case study how to do better and for this I wanted to make use of all the cool new Emacs features that appeared like the SVG library, Trangent, the library used for the maggot style interfaces and the recently added Escalade mode. And most importantly it was about having fun. So here's a full list of prior art, I will not go into detail about this, but basically we have things solving very different parts of this, but not all of it. For example we have several, we have a timer, we have several solvers, we have some scramblers, we have some whole cube simulators including a 3D one, we have something for making it easier to enter your algorithms in the notation, but nothing that does all of those things in one package which kind of surprised me. So I present the WCA prep package. So the name, I found it difficult to come up with a good name and so I looked and I saw, well there's this world cube associations that holds these competitions where you compete and they do this for the Rubik's cube but also a few others, so there's like a standardized list of events they have for this, there is a standard notation for this and rules and everything. And the goal of my package is basically to help prepare myself for such a competition and in fact a week ago I went to my first one which was wild, but pretty cool. So for this reason I chose this name WCA prep because it helps me prepare for this kind of competition and this limited the scope significantly, so I have a scrambler, visualization of the scramble, timer and statistics. I excluded pretty much everything else I've seen, so for this reason I only tried to focus on some very basic puzzles I can solve comfortably and did not want to do anything else that may complicate things significantly. So no other kinds of puzzles, no stimulation, no solving, no exotic events and no specialized scrambles that are only good for like practicing specific algorithms. So at this point the organizer should hopefully show a small video I've prepared, a one minute video showing how I actually use this to solve a cube and to time myself. Okay, so building this thing there were several challenges, the first one was how do I even represent the state of a Rubik's cube and for this there are many possible recommendations, no obvious best solution. I did not, what helped me was that I did not have to like programmatically solve this thing, so I picked the easiest possible representation which is just an array of every single face like this. For a 3x3 cube you have 9 facelets on one side, so times 6 sides you would have 54 elements in this array. So with this representation it's very simple but it's kinda weird to do scrambles with this, but otherwise it worked very, very well. In the future I plan to learn some group theory, pick a better representation and do this in a much, much more elegant way without compromising speed too much. Yes, once I had the representation the scrambling itself should not be too hard and for this it's important to consider that basically if you do a face turn you end up swapping some facelets with other facelets, that's the easiest way to think about this. To determine which one goes into which one's position, it was pretty confusing to figure this out and for this I went through a few papers and I found one which suggested to just build a cube out of paper, number every facelet and turn it and keep track of which facelet moved into which position. And programmatically the CLRotateF macro was very, very useful for doing this kind of in-place swapping you need for this operation. So in the future group theory will hopefully make this a bit less awkward. Here's a photo of this paper cube I made along with a real cube and as you can see mathematically speaking they are the same thing, they just look very, very different. So the scramble algorithm itself, I pondered how this would even be done in the competitions. They do this in a very, very elaborate way, they generate a random cube, they try to solve it and if it's solvable they use these solution moves to turn into a scramble basically. And they also make sure to canonicalize the moves, so if you have subsequent moves that can be simplified they do simplify these as much as possible. For example if you have two subsequent rotations in one direction it's turned into a different kind of rotation, so 90 and 90 equals 180. And the other ELLIS scrambles I looked at, they generate random moves, some of them to canonicalize, not all of them. And this one tries to do the best loaf I think that is generating random moves, canonicalizing and repeating until enough have been generated. For the visualization I had to figure out something not too complicated. For this I tried to figure out where every facelift would end up in the puzzle view when you would unfold it. And for this I did not consider the facelift orientation, this may be important later for some other puzzles where you can end up with very twisted faces, but for simple cubes it's not a problem. My initial prototype used colored text, but later I used the SVG library and it turned out to be easy enough to use actually. Currently I have hard-coded face color mappings, but I plan to replace this so that theming is possible. For example, if you happen to have a cube that does not have the same color mappings as I do, then you should be able to fix this. Next challenge was to build a beautiful intuitive UI with Stringent. And the reason why I chose this is because it would be kind of self-documenting and maggot style and everyone knows how maggot works basically. And since Stringent has become part of Emacs, there is really no reason to not try it out. The problem was documentation is difficult to understand, it's very abstract and high level and it's hard to figure out, okay, I want to do something, how am I supposed to do this? I did find Stringent Showcase, which has lots of examples, but they don't really feel finished and not realistic enough. When I tried to use the package, I got plenty of unhelpful error messages when using it incorrectly. I did manage to figure it out, but I plan to find more actual examples of it to have like an executable reference basically and try to improve my use of it. For the bookkeeping, I used SQLite. This is a very recent addition to Emacs, it only appeared in the current major version. It's still very early days. I found some oddities, one of them turned out to be a bug in the transaction macro. Like basically, if you do an SQL transaction and an error happens, then every helper I found does a rollback on an error. But this one did not, it actually committed on an error and this was very weird to figure out. I reported a bug, LA was nice enough to send me a patch. We did some patch review and she ended up fixing it properly. So yes, there's still a lot to be done there and yeah, the API is very basic. You don't have convenience helpers like fetch the first row or fetch the first value or anything, but they're easy enough to write yourself. And the biggest challenge with this bookkeeping part was figuring out a decent schema, like how to organize data correctly so that it would not be awkward to manipulate. And with this, you can finally build a package that remembers its state properly and don't have to run into foot guns with Lisp style serialization, deserialization. So yes, that concludes it so far. So what did I learn from this exercise? Well, there are still plenty of packages for Emacs to be written. If you think everything you can think of or you need has already been written well, guess what? No. These are just things that could need your help. These cubes do not require advanced mathematics, contrary to what you may think. Yes, you can apply advanced mathematics to them if you want to, but you don't have to. And what surprised me about this is basically group theory. I've heard of it before. It seemed to be a meme basically because it has been like mostly Haskell people being very excited about this and it seemed kind of like divorced from reality basically. But this puzzle, it actually proves that yes, it has its use. It definitely has. You just have to find the right problem matching it and yeah. So yeah, once I understand it better, the topic I expect to like write better code. So these new Emacs features, they work well enough. There are some rough edges. They definitely need more testing. So please, please, everyone. If you write Elasp, please try Escalade or Trangent or anything else that looks cool and shiny. Report bugs. Find ways to improve the menu thing and yeah, I'm sure that if we do this, then Emacs will continue to get even better. So yeah, what's next for this package? Well, I could, there are lots of obvious UI improvements and testing to be done. I basically want to reach feature parity with a twisty time app, which this is very much inspired by. I want nice looking stats like graphical ones instead of just a simple list of times. And I want support for more puzzles, of course, not just the simple queues, but as I progress learning these puzzles, I want to have Emacs supporting me for this, but generally it's a very open ended package. And this concludes the talk. Thank you very much.