Commit graph

117 commits

Author SHA1 Message Date
William Carroll
0ccaa22032 Solve "find duplicate" using a graph
This problem is unusually difficult, but the solution is elegant.
2020-11-21 13:35:05 +00:00
William Carroll
847aad2a14 Implement the Levenstein "edit distance" algorithm
This is the mother of dynamic programming algorithms in my opinion. It computes
the minimal "edit distance" between two input strings where an edit is
considered one of:
  - inserting a character into `a`
  - deleting a character from `a`
  - substituting a character in `a` with a character from `b`

It took me awhile to grok the algorithm, but I implemented this from my
understanding of something that I read ~3 nights prior, so I must've understood
what I read. Good news!
2020-11-20 21:59:18 +00:00
William Carroll
f652ea0be6 Solve "count islands" problem
This morning, I attended the "Interview Club" and was asked this question by the
interviewer in front of ~20 FTEs. While I struggled to fully solve it during the
abridged (i.e. 20 minute) timeslot, I completed the problem afterwards.

Here is my solution.
2020-11-20 21:32:22 +00:00
William Carroll
fa717e8a6f Re-implement suffix_tree function
Create a suffix tree from an input string. This implementation uses a stack to
control the flow of the program.

I expected this attempt to be easier than my first attempt, but surprisingly, it
was similarly difficult. It took me ~30-45 minutes to successfully implement
this function, and I'm still not pleased with the final result.
2020-11-19 21:12:36 +00:00
William Carroll
1088e4143d Implement a suffix tree
While it took me awhile to implement, this exercise was definitely worth
doing. I think there should be a more elegant way to construct the tree using
maybe a stack, but I couldn't find it.

All of this was part of a larger effort to search a string for a variety of
patterns. The solution is to compile the string into a suffix tree and then
search the suffix tree for each of the patterns.

I'm glad I didn't gloss over this exercise.
2020-11-19 00:35:23 +00:00
William Carroll
c0268ed31a Refactor random-choice
Prefer initializing `result` to an empty array of size `m`, which makes the
algorithm a bit more elegant.
2020-11-17 23:54:54 +00:00
William Carroll
751b5327a9 Solve algorithms dealing with randomness
Tonight I learned that random sample where each element in the sampling corpus
has an equal likelihood of being chosen is a brand of algorithms known as
"reservoir sampling".

- Implement random.shuffle(..)
- Implement random.choice(..)

Surprisingly, candidates are expected to encounter problems like this during
interviews.
2020-11-17 22:28:24 +00:00
William Carroll
572fb0fe5f Solve "nearby words" function
Given an input like "gello" suggest an correction like "hello".

This is a proof-of-concept problem for writing a simplistic auto-correction
algorithm for a mobile device.
2020-11-16 17:17:28 +00:00
William Carroll
6989c3a91a Implement the Rabin Karp string matching algorithm
This algorithm is pretty interesting because it runs in linear time with respect
to the length of the `corpus` string. It does this by using a sliding window
hash. This hash -- because it's a sliding window -- runs in constant time for
each iteration; we're only adding and subtracting one character each time and
not re-hashing the whole "window".

When our hashes match, only then do we compare the "window" to the
`pattern`. String comparisons are linear because they compare each character to
each character one at a time. But because we only compare strings when are
hashes match (a check which runs in constant time), this spares us the
performance hit.
2020-11-16 17:14:08 +00:00
William Carroll
a2fa88f561 Prefer mutative variant of delete for HashTable
Instead of calling `filter(..)`.
2020-11-16 17:13:39 +00:00
William Carroll
a457a81bbb Add another solution to the "move zeroes to end" problem
Support the optimally performance solution of which I'm aware.
2020-11-16 17:13:03 +00:00
William Carroll
ff08b723db Solve "find pairs for sum"
I have encountered this problem 3x in the wild thus far:
  1. www.InterviewCake.com
  2. Cracking the Coding Interview
  3. www.Pramp.com
2020-11-16 17:12:05 +00:00
William Carroll
92ab94943e Start working on the "Hard" problems
Firstly, implement a function that adds two arguments together... without using
the `+` operator. I need to drill this problem. Thankfully I took a Coursera
course that taught me how to make a half-adder and a full-adder, but the
recommended solution for this is a bit more difficult.
2020-11-16 17:10:57 +00:00
William Carroll
30f4d6f4a4 Implement a simple hash function and hash table
I was always curious how hashing functions were implemented, so I read about the
"polynomial rolling hash function", and I decided implementing it would be a
good exercise. After writing that, writing a hash table was simple.
2020-11-16 00:35:01 +00:00
William Carroll
363519273a Find the intersection (if any) between two linked lists
As with most linked list questions, this one involves an arcane trick from the
neck-bearded playbook.
2020-11-15 17:42:44 +00:00
William Carroll
c8330adfcb Solve "Move Zeroes to End"
Write a function to modify an array of integers in-place such that all of the
zeroes in the array are at the end, and the order of the other integers is not
changed.
2020-11-15 13:51:46 +00:00
William Carroll
09cd819a70 Include re-roll strategy for rand7
After seeing the solution that my book advocated, I implemented it using
recursion.
2020-11-14 17:36:04 +00:00
William Carroll
5820f6f459 Solve rand7
Write a random number generator for [0,7) using only a random number generator
for [0,5). Ensure the results are uniformly distributed.
2020-11-14 17:26:00 +00:00
William Carroll
a0e9e2b310 Solve unsorted-substring a second time
This solution operates in O(n) time instead of O(n*log(n)) time, which
surprisingly isn't *that* big of a difference...

Consider a size of n of 10M...
  1) ~10s
  2) ~0.5s

So, yes, the O(n*log(n)) will take 100x longer to complete, but for an enormous
input size of 10M elements, it can still complete in under a minute. The
difference between that and the second, faster, algorithm, is just 9s.
2020-11-14 15:28:23 +00:00
William Carroll
48fde5f278 Solve unsorted-substring
Write a function that returns the indices demarcating a substring, which if
sorted, would make the entire array sorted.
2020-11-14 15:08:25 +00:00
William Carroll
47c5c6ac05 Partially implement a Heap
Defining the insert (or "siftup") function described in the "Programming Pearls"
book.
2020-11-14 14:08:58 +00:00
William Carroll
c841527f61 Write encoded XML parser and pretty-printer
Write a function that reads a string of compressed XML and outputs the
decompressed version.

Note to self: Now that I'm growing more comfortable writing parsers, I'd like to
become equally comfortable writing pretty-printers.
2020-11-14 14:00:00 +00:00
William Carroll
bfd2180e6b Solve tic-tac-toe checker
Write a function that verifies whether or not a tic-tac-toe board is valid.
2020-11-13 17:45:07 +00:00
William Carroll
1b3f1b99f5 Solve box-stacking problem
Write a function to compute the highest stack of boxes that can be created from
a list of boxes.
2020-11-13 16:57:47 +00:00
William Carroll
7672049e1c Solve N queens
After a five year hiatus, I decided to attempt to solve the famous N queens
problem again. This time, instead of modeling the chess board using a
`[[Bool]]`, I'm using `[Integer]` where the `Integer` indicates which column has
a queen. This is a bit lighter in RAM.
2020-11-13 16:56:02 +00:00
William Carroll
14f6169fcf Document subset of BNF for regex engine
Adding some documentation for my future self.
2020-11-13 16:55:39 +00:00
William Carroll
aa66d9b83d Add coding exercises for Facebook interviews
Add attempts at solving coding problems to Briefcase.
2020-11-12 14:37:29 +00:00
William Carroll
69b6bda01b Style habit screen to accommodate footer
Add spacing to the bottom to make space for the footer.
2020-11-12 11:19:30 +00:00
William Carroll
2290aac2a8 Tweak styles
Add spacing to help the app breathe.
2020-10-11 16:47:31 +01:00
William Carroll
767fed75c3 Support multiple HabitTypes
I could have and should have broken this change into smaller pieces, but when I
came up for air, I had changed too much, and most of the changes are
intermingled. Oh well... this is an exciting change!

Include habits for:
- Morning
- Evening
- Payday (the 25th)
- First of the Month
- First of the Year

Since the Morning and Evening routines might be a bit noisy, I'm excluding them
from the output using a flag, `include{Morning,Evening}`, which I support in the
UI to toggle their visibility.

I made *much* more progress on this app that I expected to today, and I *think*
-- short of supporting a database and a server -- I'm close to
being *completely* finished.

Wahoo!
2020-10-11 16:40:10 +01:00
William Carroll
abf1875934 Support Msg to clear all completed tasks
Add a simple button to clear all completed tasks.
2020-10-11 15:39:01 +01:00
William Carroll
79cf42abd5 Render time remaining in UI
Show the number of minutes remaining before completing all of the tasks.
2020-10-11 15:17:20 +01:00
William Carroll
5684608fed Move tailwind function into Utils module
Instead of accepting `List (String, Int)`, accept `List Strategy` where
`Strategy` defines whether or not the string of selectors should be applied to
the element.

I'm also renaming it `class` so I can just use `Utils.class`; `tailwind` has
little to do with the function itself.
2020-10-11 14:59:42 +01:00
William Carroll
1c8a8f5d2c Expand Habit type
Include:

- habitType: Daily, Weekly, Yearly... what's the trigger?
- minutesDuration: Estimation of how long it'll take to complete
2020-10-11 14:58:49 +01:00
William Carroll
05d52e403c Tweak styles
- Change header to blue
- Change habit to gray when completed
- Prefer app font for footer instead of monospaced font
2020-10-11 10:24:11 +01:00
William Carroll
0a15ea7366 Create UI module for common components
Create UI.elm to house components like `button`, which is a simple HTML button
with `focus:outline-none` applied as a `class`, which is an accessibility
feature that I don't need for this touch-screen application.

I like this pattern more than my more opinionated patterns for UI modules in Elm
where I'd define all of the arguments as a record type (i.e. kwargs).
2020-10-11 10:15:03 +01:00
William Carroll
106457de4b Prefer handwritten font
Use the Google Fonts API to fetch a handwritten font, which gives the app a
modicum of personality. There are more "best practices" ways to do this, such
as:

- Download the font once, and include it in the bundle
- Extend the Tailwind configure to recognize the font
- Ditch the inline <style> block

But I don't need the performance benefits that the first bullet provides. And
the second two bullets are more relevant for a larger application with more than
one font. So I think in this case, the easiest solution is best.

Also:
- Use `container` and `mx-auto` to constrain content for wide screens
2020-10-11 10:09:15 +01:00
William Carroll
19fbdad1c0 Support viewing different days
Allow users to browse the habits of the other days of the week.
2020-10-10 18:20:24 +01:00
William Carroll
487232d1aa Ensure weekday is updated
This ensures us that our view is consistent within ~1 minute of reality.
2020-10-10 17:34:14 +01:00
William Carroll
7d425de48d Tweak styles
- Increase font size for header
- Prefer a bulleted list
- Reduce horizontal padding
2020-10-10 17:31:34 +01:00
William Carroll
bfbe7dc988 Add a footer
With personal information and information about the project's stack.
2020-10-10 17:31:00 +01:00
William Carroll
df8e45681d Remove Nap from Saturday; prefer Yin Yoga
Since Warm Yin Yoga is at 15:00, it's difficult to attend that *and* nap.
2020-10-10 17:30:22 +01:00
William Carroll
9d331f3077 Begin working on Habit Screens project
Created a small MVP for digitizing my weekly habits. Much more to come.

Lots of things happening:

- Copied the boilerplate to get started
- Added a brief project-level README
- Outlined my ambitions in design.md

See README and design.md for more context on this project.
2020-10-10 17:04:24 +01:00
William Carroll
0f160a8029 Ignore comments in output for grocery export
TL;DR:
- Ignore lines starting with "#"
- Tidy up the code
2020-10-03 11:00:11 +01:00
William Carroll
a7aef84408 Update my grocery list for Bermondsey London
I haven't updated this list since I was living in Dargow, Germany over the
summer. Now that I've settled down, and I'm situated in the London Bridge area,
I'm updating the list.
2020-10-03 11:00:05 +01:00
William Carroll
33890d8a8b Move scratch/brilliant into //assessments
Where it belongs...
2020-08-20 11:26:32 +01:00
William Carroll
0c71fc9d1d Drop support for dir-locals.nix, <nixpkgs>, etc.
In the spirit of Marie Kondo, I'm tidying up!

TL;DR:
- Prefer .envrc `use_nix` and delete all dir-locals.nix files
- Remove ~all references to <nixpkgs>, <unstable>, <depot> and prefer
  referencing each with briefcase.third_party.{pkgs,unstable,depot}
- Delete nixBufferFromShell function since I was only using that in
  dir-locals.nix files
2020-08-20 11:26:32 +01:00
William Carroll
59f7481411 Revise previous opinions about absolute paths GT <bracket-notation>
Unforeseen problem: `buildkite-agent` runs its builds in a separate directory,
so if I want the `nix-build` command to build the newly checked out code, I need
to set <briefcase> to the CWD.
2020-08-20 11:26:31 +01:00
William Carroll
2da4b12266 Consume buildHaskell functions
Use the newly defined `buildHaskell` function for a few of my existing Haskell
projects. So far, it works as intended!
2020-08-12 16:28:39 +01:00
William Carroll
bba3f16c43 Prefer snake-shift instead of a row-by-row shift
Per the assignment's instructions, the `Shift n` operation should treat
the *entire keyboard* like a cycle and shift that. I was erroneously
treating *each row* like a cycle and shifting those one-by-one.

This change fixes that. In addition, it also:
- Updates README.md with expected inputs and outputs
- Updates test suite
- Adds `split` dependency to {default,shell}.nix
2020-08-12 12:03:35 +01:00