30 September 2020

Min-Max Driving Sim

I have always wanted a driving sim, especially after reading about fellow driver/instructor Ian Korf's positive experiences, but don't have much space and didn't want to spend a crazy amount of money.

To give you a sense of the driving sim landscape: on the low end, you have wheels without any force feedback (around the $99 mark) to 6-axis full motion sims for >$60k, which are not dissimilar what professional drivers use for training.

Here's what I got:

ComponentPrice (includes shipping & tax)
VendorWhen Purchased
WheelSimXperience Accuforce$1055.64simxperience.comJul 2020
ComputerDell Inspiron 3670$402.37Dell OutletDec 2018
GPUZotac GTX 1080 mini$369.00eBayFeb 2019
PedalsFanatec Clubsport v3$356.60eBayJun 2019
SeatPlayseat Challenge$242.93AmazonJul 2020
VR HeadsetLenovo Explorer$99.00B&H Photo VideoNov 2018
Power SupplyEVGA 500 W1$43.29AmazonJan 2019
Total$2568.83

I optimized for great driver inputs, e.g. the wheels and pedals. I figured that direct drive is the way to go, and read good things about the Accuforce. Popular alternatives included the OSW (OpenSimWheel) and the Fanatec Podium 1 & 2. I decided against hydraulic pedals (>$1+k, unless you mod your Logitech G920 brake pedal). Looking at options half an order of magnitude lower, the Fanatec Clubsport was the popular choice.

I wanted the sim rig to take up the smallest amount of space and be easy to move, while having a solid mount between the seat and pedals so that the pedals won't slide away from me during braking. The Playseat Challenge was the obvious choice. It even has mounting holes, which are compatible with the Accuforce!

I didn't want to spend very much money or effort on the PC, so I went with a refurbished Dell with passable specs. This unit has a 6-core i5-8500, 8GiB RAM, 1TB spinner, and integrated graphics. Obviously I needed a better GPU to drive the VR headset, so I went with a GTX 1080 (not Ti). It turns out that the current generation of consumer desktops are barely wider than a mATX board, so I need a shorter version of a full-size GPU. Finally, I needed a beefier PSU that the Dell's 300W unit.

If I insisted on building the PC myself, then the components (at the time of purchase, late 2018), would have not been much cheaper. The CPU retailed for $192, motherboard $80, memory $35, disk $40, for a total of $347, which is ~$20 less than the Dell cost before sales tax. (Obviously I would sit the parts on a piece of cardboard instead of getting a case, as well as ditching the optical drive and WiFi, if not integrated into the motherboard)

Finally, for an immersive experience, I went with the (now discontinued) Lenovo Explorer VR headset. I wanted something with at least a 1440x1440 eyepiece resolution since I had a bad experience with the first Oculus Rift, which had an eyepiece resolution of 1080x1280 -- I got extremely nauseous trying to focus on a blurry-to-my-20/13-vision image.

So there you have it! A solid setup, which fits conveniently into any corner:

For its inaugural drive, I spent an hour playing Assetto Corsa driving at the WeatherTech Raceway Laguna Seca in various cars (30min in a NA Miata, then a bit in a McLaren 570S, and the rest in a Porsche GT4 Clubsport). Works pretty well!

Its next upgrade will likely be a yoga mat since the Accuforce's vibrations are felt throughout the Playseat chassis.

06 September 2020

Codeforces Round #668 (Div. 2) Postmortem

Trying a different format with problem-by-problem breakdowns, which hopefully will be more useful when I review my postmortems. I will also backfill the postmortems.

A: I first implemented the metric computation (sort sums of adjacent elements) without having any idea of how to create a different permutation to achieve the same metric. Then I realized that reversing the input preserves the adjacent sums. I won't complain about a 0:02 submission.

B: If the first nonzero element were negative, then we have to incur cost equal to its magnitude. I thought this was it, but some sample inputs didn't pass. Then I noticed that if the first nonzero element were positive, we can add the magnitude to negative terms later in the array, which existed because of the constraint that all elements sum to 0 and that the sum stays 0 after every operation. I quickly patched my solution to keep a reserve from the magnitude of positive elements and using the reserve to decrease the cost of negative elements before incurring their costs. Again, not complaining about a 0:08 submission.

C: This is where I started to struggle. Having the same number of 0s as 1s in every K subarray is the same as the subarray sum equal to K/2. I got hung up on the "system of equations" representation, where every question mark was a variable (question mark at i would be a_i), which seemed extremely hard to solve. Then I thought that I can just look at the number of equations and the number of variables, which seemed sketchy, but I YOLO-ed and incurred a WA.

At about the 0:55 mark, I realized that the system of equations implied that a_i = a_j for i = j mod K. Facepalm. I quickly coded this solution for a 1:02 submission. RIP

D: Clearly, if B is at most DA away from A, then A can reach B in the first move and win. From the problem statement, I inferred that their 10^100 limit meant that either A will reach B in finite time, or B can always move to stay DA away from A. I quickly realized that the best chance of B dodging A is on the diameter of the tree, since in no other scenario will B have the space to run away from A. This implied that if A can go from the center(s) to the ends of the diameter in DA, then A can catch B.

I made the assumption that if DA > DB (it seemed intuitive), then A will be able to reach B eventually because B will run out of space. Thinking that these three criteria were sufficient, I submitted at 1:31 for my first WA on D. Given feedback that my solution failed pretest 2, I came up with the following counterexample to my solution:

1---2---3---4---5---6
        ^           ^
        A           B
DA = 2, DB = 3

My solution would incorrectly say that A never reaches B, while after two moves, A will first move from 3 to 5 and B will move from 6 to 3, letting A move from 5 to 3 on the third move. This really tripped me up, leading me to think about the relative difference between DA and DB. I tried that if the relative difference is larger than the half the diameter of the tree, then A cannot catch B, for another WA at 1:44. Finally, as a last ditch attempt, I thought that if DB is twice or more than DA and if the diameter is greater than twice DA, then A cannot catch B, for my third and final WA at 1:59.