Amer

November 24, 2020

Brain is too tired to do any LeetCode tonight. LeetCode challenges are fun but feel pointless. I don’t want to get burned out, so taking a break today.

LeetCode #1664: Ways to Make a Fair Array

class Solution {

    /**
     * @param Integer[] $nums
     * @return Integer
     */
    function waysToMakeFair($nums) {
        $len = count($nums);
        $ans = 0;
        
        $leftOdd = 0;
        $rightOdd = 0;
        $leftEven = 0;
        $rightEven = 0;
        
        for ($i=0; $i<$len; $i++) {
            if ($i%2 === 0) 
                $rightEven += $nums[$i];
            else
                $rightOdd += $nums[$i];              
        }
        
        for ($i=0; $i<$len; $i++) {
            if ($i%2 === 0) 
                $rightEven -= $nums[$i];
            else
                $rightOdd -= $nums[$i];
            
            if ($leftEven + $rightOdd === $rightEven + $leftOdd) $ans++;
            
            if ($i%2 === 0)
                $leftEven += $nums[$i];
            else
                $leftOdd += $nums[$i];
        }
        
        return $ans;     
    }
}

This seems simple but initially I went down wrong path, trying to use way too many arrays. I gave up and looked at https://leetcode.com/problems/ways-to-make-a-fair-array/discuss/944567/Java-O(N)-and-constant-space-beats-100-easy-solution. My solution is basically transpilation of it in PHP.

Ref: https://leetcode.com/problems/ways-to-make-a-fair-array/

Level up as a Software Engineer

I have been team lead for last couple of years. After team lead, you usually need to decide if you want to grow in people management path or follow individual contributor’s path. However, both of these paths mean writing less code and working at abstract levels. I am happy writing code. It still pays pretty well and it is very satisfying at the end of the day.

I have been hooked on problems at LeetCode.com, it feels great to relearn various algorithms. Of course, LeetCode.com is used primarily by job seekers but it is good site to level up as programmer. And it doesn’t hurt that it will prepare you for whiteboard interview questions.

Another area I have been interested in is Data Science. At work, I have asked for data science projects and also using for building some basic algorithmic trading strategies. I will probably sign up for DataCamp or some other Data Science course soon.

I think a software engineer with data science skills will be interesting next step in my career.

Link

Linux on the iPad isn’t a reality yet, at least not like on a desktop platform. With hardware becoming more and more powerful every year, obsolete iPadsshould be allowed to continue to serve a purpose. Obsolete iPads could be affordable personal computers and useful for project builds. We believe Linux is the key to bring new life to these devices.

LeetCode 200: Number of Islands

class Solution {

    /**
     * @param String[][] $grid
     * @return Integer
     */
    function numIslands($grid) {
        $count = 0;
        
        for ($i=0; $i<count($grid); $i++) {
            for ($j=0; $j<count($grid[$i]); $j++) {
                if ($grid[$i][$j] == "1") {
                    $count++;
                    // zero out rest of 1s
                    $this->zeroOut($grid, $i, $j);
                }
            }
        }
        
        return $count;
    }
    
    function zeroOut(&$grid, $i, $j) {
        if ($i<0 || $i>=count($grid) || $j<0 || $j>=count($grid[$i]) || $grid[$i][$j] == "0")
            return;
        
        $grid[$i][$j] = "0";
        
        $this->zeroOut($grid, $i-1, $j);
        $this->zeroOut($grid, $i+1, $j);
        $this->zeroOut($grid, $i, $j-1);
        $this->zeroOut($grid, $i, $j+1);
    }
}

I had to watch some YouTube videos for solution. Initially, I was creating over-complicated solutions to track islands.

Ref: https://leetcode.com/problems/number-of-islands/

LeetCode 88: Merge Sorted Array solution

class Solution {

    /**
     * @param Integer[] $nums1
     * @param Integer $m
     * @param Integer[] $nums2
     * @param Integer $n
     * @return NULL
     */
    function merge(&$nums1, $m, $nums2, $n) {
        if ($n == 0) {
            return;
        }
        
        if ($m == 0) {
            for ($i=0; $i<$n; $i++) {
                $nums1[$i] = $nums2[$i];
            }
        }
        
        $i = 0;
        $j = 0;
        
        while ($i<$m && $j<$n) {
            if ($nums1[$i]<=$nums2[$j]) {
                $i++;
            } else {
                $this->array_insert($nums1, $i++, $nums2[$j]);
                $m++;
                $j++;
            }   
        }
        
        while ($j < $n) {
            $nums1[$i++] = $nums2[$j++];
        }
        
    }
    
    function array_insert(&$arr, $i, $num) {
        $endArr = array_slice($arr, $i);
        $arr[$i] = $num;
        
        for ($x=$i+1; $x<count($arr); $x++) {
            $arr[$x] = array_shift($endArr);
        }
    }
}

Not very clean but this will do for now. Ref: https://leetcode.com/problems/merge-sorted-array/

LeetCode #73: Set Matrix Zeroes

class Solution {

    /**
     * @param Integer[][] $matrix
     * @return NULL
     */
    function setZeroes(&$matrix) {
        $rowsToZeroOut = [];
        $colsToZeroOut = [];
        for ($i=0; $i<count($matrix); $i++) {
            for ($j=0; $j<count($matrix[$i]); $j++) {
                if ($matrix[$i][$j] === 0) {
                    $rowsToZeroOut[] = $i;
                    $colsToZeroOut[] = $j;
                }
            }
        }
        
        foreach($rowsToZeroOut as $r) {
            for($i=0; $i<count($matrix[$r]); $i++) {
               $matrix[$r][$i] = 0; 
            }
        }
                
        foreach($colsToZeroOut as $c) {
            for($i=0; $i<count($matrix); $i++) {
               $matrix[$i][$c] = 0; 
            }
        }
    }
}

Results:

Runtime: 52 ms, faster than 13.33% of PHP online submissions for Set Matrix Zeroes. Memory Usage: 19.8 MB, less than 80.00% of PHP online submissions for Set Matrix Zeroes.

TypeError: require.extensions.hasOwnProperty is not a function

While playing with https://github.com/alexa/interactive-adventure-game-tool, I ran into following error:

> interactive-adventure-game-tool@1.0.0 start /Users/amer/alexa/interactive-adventure-game-tool
> node node_modules/gulp/bin/gulp.js

/Users/amer/alexa/interactive-adventure-game-tool/node_modules/require-dir/index.js:97
            if (!require.extensions.hasOwnProperty(ext)) {
                                    ^

TypeError: require.extensions.hasOwnProperty is not a function
    at requireDir (/Users/amer/alexa/interactive-adventure-game-tool/node_modules/require-dir/index.js:97:37)
    at Object.<anonymous> (/Users/amer/alexa/interactive-adventure-game-tool/gulpfile.js:1:85)
    at Module._compile (module.js:660:30)
    at Object.Module._extensions..js (module.js:671:10)
    at Module.load (module.js:573:32)
    at tryModuleLoad (module.js:513:12)
    at Function.Module._load (module.js:505:3)
    at Module.require (module.js:604:17)
    at require (internal/module.js:11:18)
    at Liftoff.handleArguments (/Users/amer/alexa/interactive-adventure-game-tool/node_modules/gulp/bin/gulp.js:116:3)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! interactive-adventure-game-tool@1.0.0 start: `node node_modules/gulp/bin/gulp.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the interactive-adventure-game-tool@1.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/amer/.npm/_logs/2018-01-02T05_12_24_832Z-debug.log

The solution was to update require-dir to version 0.3.2 in package.json and run npm install again.

Setup Outgoing Email on Lightsail Ubuntu VPS

I followed instructions here: https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-postfix-as-a-send-only-smtp-server-on-ubuntu-18-04

Everything seemed okay but email were not getting delivered. Logs showed me that smtp connections were timing out:

tail -f /var/log/mail.log
May  3 12:28:10 postfix/smtp[3160]: connect to gmail-smtp-in.l.google.com[172.217.197.27]:25: Connection timed out
May  3 12:28:10  postfix/smtp[3160]: connect to alt1.gmail-smtp-in.l.google.com[2800:3f0:4003:c00::1a]:25: Network is unreachable
May  3 12:28:40 postfix/smtp[3160]: 4984C41A1E: to=<xxxx@gmail.com>, relay=none, delay=3246, delays=3186/0.01/60/0, dsn=4.4.1, status=deferred (connect to alt2.gmail-smtp-in.l.google.com[2a00:1450:400b:c00::1a]:25: Network is unreachable)

However, I could ping any of above ip addresses just fine.

Next step was to see if ip address of my VPS was blacklisted in RBLs, I used https://mxtoolbox.com/blacklists.aspx. None of my ip addresses were in any black list.

Port 25 was open in firewall, both on server and in Lightsail’s networking UI.

After spending another hour or so troubleshooting, I found this thread: https://forums.aws.amazon.com/thread.jspa?threadID=316397. It seems AWS/Lightsail have recently started to throttle outgoing emails, but by throttling they meant completely blocking it. You need to open a support ticket to remove these limits here: https://console.aws.amazon.com/support/contacts?#/rdns-limits

So I submitted my request, hopefully, this will resolve the issue.

UPDATE: It worked, now my VPS can send outgoing emails.

Link

Unlike engineers, engineering managers have no natural source of power. In previous lives many of them ran the machines themselves, but there came a time when they’ve traded their role as craftsmen for the management track. Sometimes it’s because they weren’t good craftsmen in the first place and knew it limits their earning capacity. Sometimes they were good craftsmen who were seduced by the siren song of social status among the normies. Sometimes they genuinely wanted to support engineers in their work. But in every case, they can no longer fix the machines. Their power has to come from elsewhere.

Source: Parallel tracks – spakhm’s newsletter

Link

“You heal a fear much like you heal a cut on your hand. If you ignore a cut on your hand, it will get infected. But it will heal itself if you pay attention to it and give it time. Same with a fear. First, recognize its existence—what kind of fear is it? Is it fear of poverty, of loneliness, of rejection? Then use common sense. Don’t let the fear get infected. Often we burn 70 percent of our emotional energy on what we fear might happen (90 percent of which won’t happen). By devoting our energy to our other emotions, we will heal naturally.”

— What Should I Do with My Life?: The True Story of People Who Answered the Ultimate Question by Po Bronson
https://a.co/fO8jPuZ

Link

When you write about your work, it makes all of us smarter for the effort, including you. Done well, this kind of sharing means you’re contributing signal, instead of noise. But writers are made, n…

Source: Writing Is Thinking – A List Apart

Link

Tips and techniques for driving in sandy conditions. Knowledge to acquire before hitting the beach or dunes in your vehicle to avoid getting stuck because it is very easy to get stuck in sand. Avoid joining the ‘digging club’.

Source: How to Drive on Sand Without Getting Stuck