While the "Dynamic programming and recursion" section hosts this problem, the
optimal solution does not use recursion. Many cite the Fibonacci problem as a
quintessential dynamic programming question. I assume these people expect an
answer like:
```python
def fib(n):
cache = {0: 0, 1: 1}
def do_fib(n):
if n in cache:
return cache[n]
else:
cache[n - 1] = do_fib(n - 1)
cache[n - 2] = do_fib(n - 2)
return cache[n - 1] + cache[n - 2]
return do_fib(n)
```
The cache turns the runtime of the classic Fibonacci solution...
```python
def fib(n):
if n in {0, 1}:
return n
return fib(n - 1) + fib(n - 2)
```
... from O(2^n) to a O(n). But both the cache itself and the additional stacks
that the runtime allocates for each recursive call create an O(n) space
complexity.
InterviewCake wants the answer to be solved in O(n) time with O(1)
space. To achieve this, instead of solving fib(n) from the top-down, we solve it
from the bottom-up.
I found this problem to be satisfying to solve.
While the idea of managing the hosts at a per-user level appeals much more to me
that running this as root and managing /etc/hosts, I haven't been able to get it
to work.
TL;DR:
- Write FromJSON instances to decode rules.json file
- Prefer Text to String and use the OverloadedStrings language extension
- Read /etc/hosts and append the serialized rules.json to the end
Notes:
- I can remove some of the FromJSON instances and use GHC Generics to define
them for me.
TODO:
- Define the systemd timer unit for this to run
- Ensure script can run with root privileges
1. I should be using NixOS/nixpkgs-channels instead of NixOS/nixpkgs
2. Instead of refactoring everything, I'm supporting <unstable> and pointing it
to NixOS/nixpkgs-channels
I needed <unstable> to get a more recent version of the Data.Time Haskell
package.
I'd like to ensure that my /etc/hosts file blocks websites at certains times. I
use this to allow / disallow websites at various times of the day.
TODO:
- Add project README
- Add tests
- Publish
- Create a Nix derivation
- Run as a systemd timer unit
- Figure out if I can run this as a user rather than root
I think it might be a good idea to version control my habits, so that I can
audit them as they change.
I'm publishing these on my website, so that I can refer to them wherever I had
internet.
Problem:
prettier-js waits for rjsx-mode. rjsx-mode only runs on .js files. As such,
the hook that installs prettier-js-mode for *all* of my frontend hooks, which
includes more than just js files, does not install until a javascript file is
opened.
Solution:
Do not conditionally load prettier-js.
Bonus:
Remove the .js mode from rjsx.
briefcase's top-level .gitignore ignores node_modules, so I never noticed that
it was missing from my boilerplate .gitignore. I don't *really* need to add it
to that .gitignore, but if I want to cleanly eject directories from this
monorepo, it makes sense to keep the .gitignore files local to each project.
Problem:
Prettier was not running when I saved Emacs buffers.
Why?
- prettier-js-mode needs needs node; lorri exposes node to direnv; direnv
exposes node to Emacs; lorri was not working as expected.
Solution:
Now that I'm using nix-buffer, I can properly expose node (and other
dependencies) to my Emacs buffers. Now Prettier is working.
Commentary:
Since prettier hadn't worked for so long, I stopped thinking about it. As such,
I did not include it as a dependency in boilerplate/typescript. I added it
now. I retroactively ran prettier across a few of my frontend projects to unify
the code styling.
I may need to run...
```shell
$ cd ~/briefcase
$ nix-shell
$ npx prettier --list-different "**/*.{js,ts,jsx,tsx,html,css,json}"
```
...to see which files I should have formatted.
Lorri does not cleanly integrate with my corporate device, which cannot run
NixOS. To expose dependencies to Emacs buffers, I will use nix-buffer.el, which
reads its values from dir-locals.nix. To easily expose dependencies from my
existing shell.nix files into dir-locals.nix, I wrote a Nix utility function.
Write a function to find a duplicate item in a list of numbers. The values are
in the range [1, n]; the length of the list is n + 1. The solution should run in
linear time and consume constant space.
The solution is to construct a graph from the list. Each graph will have a cycle
where the last element in the cycle is a duplicate value.
See the solution for specific techniques on how to compute the length the cycle
without infinitely looping.
By default Parcel prefixes output paths with /. So when Chrome loads
wpcarro.dev/goals it attempts to get the CSS and JS and other assets from
wpcarro.dev/ instead of wpcarro.dev/goals/. Using the --public-url ./ option
makes Parcel output relative paths, which should work better for my needs.
After deploying the version of this application that built everything in the
browser, which originally was the impetus for the entire project, I learned that
the babel in-browser transformer won't work. I'm not sure why, but I need to
move on from this project and do other work.
I ported the code to my boilerplate/typescript, which works. Wahoo!
Parcel uses process.env to expose environment variables. Since process.env is a
Node concept and this boilerplate is for TypeScript projects, we need
@types/node to support these Node types.
I used the boilerplate/typescript project as a starting point. This project
fetches and renders books that I'm defining in a Contentful CMS that I created.
I would like to support boilerplate code for ReasonML, TypeScript,
ClojureScript, and Elm projects before I specialize in any of these
frameworks. All of my projects should use TailwindCSS.
All of this boilerplate should offer:
- Same command to start developing
- Same API to build and deploy
- TailwindCSS support
- Basic boilerplate for components, state, and routes
This TypeScript boilerplate is not complete, but I would like to commit the
progress in case I do not return to this for awhile.
Write a function that returns the shortest path between nodes A and B in an
unweighted graph.
I know two algorithms for finding the shortest path in a *weighted* graph:
- Use a heap as a priority queue instead of the regular queue that you would use
when doing a BFT. This is called Dijkstra's algorithm. You can also use
Dijkstra's algorithm in an unweight graph by imaginging that all of the
weights on the edges are the same value (e.g. 1).
- Map the weighted graph into an unweighted graph by inserting N nodes between
each node, X and Y, where N is equal to the weight of the edge between X and
Y. After you map the weighted graph into an unweighted graph, perform a BFT
from A to B. A BFT will always find the shortest path between nodes A and B in
an unweighted graph.
I had forgotten that a BFT in an unweighted graph will always return the
shortest path between two nodes. I learned two things from InterviewCake.com's
solution:
1. I remembered that a BFT in an unweighted graph will return the shortest
path (if one exists).
2. I learned to use a dictionary to store the edge information and then
back-tracking to reconstruct the shortest path.
- Create ./website directory
- Add a sitemap to wpcarro.dev
- Move covid-uk directory to sandbox directory
TODO: Next sandbox, blog, and learn in the website directory
Right now my website is serving at sandbox.wpcarro.dev, but I would rather
people view it at sandbox.wpcarro.dev/covid-19.
I previously tried to accomplish this with the following Nginx configuration:
```nix
locations."/covid-19" = {
root = briefcase.covid-uk;
}
```
I am now trying `alias = ...` instead of `root = ...`. I got the idea from this
SO question, https://stackoverflow.com/questions/10631933/nginx-static-file-serving-confusion-with-root-alias.
- Prefer hosting on sandbox.wpcarro.dev; I would prefer to host it at
sandbox.wpcarro.dev/covid-19, but I haven't figure out how to use Nginx to do
serve locations like /covid-19 yet.
- Splice the src directory: When I develop locally and index.html exists within
./src, I cannot access ./node_modules because ./node_modules is in a parent
directory. I could fix this if I used a bundler like Parcel or Webpack, but I
do not want to set that up at this time.
- Introduce Tailwind for CSS. This complicates my build a bit as well. For now,
I'm including output.css even though ideally I should not version-control this
file. I haven't figured out how to `yarn install` and run commands like `npx
tailwindcss build styles.css -o output.css` in a Nix derivation yet. Hopefully
I will learn and refactor this.
- Add some content about why I made this chart
- Add some content about some of my covid-19 predictions
- Add a footer to the webpage
- Delete timeseries.json and prefer fetching the published data instead
I was having trouble tracking the growth of corona virus cases in the UK.
Thankfully someone is publishing some daily COVID data as JSON. I downloaded
that data manually and plotted it using the chart.js library as a programming
exercise with Mimi.
Now I'm attempting to deploy to https://wpcarro.dev/covid-uk.
TODO(wpcarro): Prefer the live API data instead my soon-to-be-stale downloaded.
After some toil, I finally support basic ReasonML starter code.
I'm adding it to the nut-score directory because I would like to make a simple
webpage that render some nutritional facts about nuts with respect to the
ketogenic diet.
I'm not sure if I should include or exclude te .bs.js files.
See the README.md for more information.
It has been awhile since I have written a tutorial. I have spent 2-3 hours
working on this post, but I think I need to spend another 2-3 hours before I
publish it.
I expect to be able to write these posts faster as I practice.
I would like to create a few resources that I can reuse in each article for
things like:
- "Let's Learn Nix" reproducibility: Where I list all of the tutorials'
dependencies: nix version, <nixpkgs> version, OS type and version, etc.
- Haskell type signature convention for Nix
- Ad hoc vs. declarative configuration for Nix
- Troubleshooting Nix: <nixpkgs> search, nix repl, searching the Nix codebase