Monday, June 28, 2021

Leetcode, 46 - Permutation

How to solve Leetcode, 46 permutation?

Let's see a easy way to solve with tree breadth first solution.

For example : [1, 2, 3]

The approach : take an item each time to insert into in between array.

1: [ [1] ]
   Insert the first number.

2: [ [1] ]
    ^   ^

   Insert 2 before and after 1.
   [[2,1],[1,2]]


3: 
    [
      [3,2,1],[2,3,1],[2,1,3],
      // place 3 around and between [ 2,1 ]
                                     ^ ^ ^
      [3,1,2],[1,3,2],[1,2,3]
      // place 3 around and between [ 1,2 ]
                                     ^ ^ ^
    ]

Hope this approach is easy to understand.

 

var permute = function(nums) {

  //init results with first numbers
  let results = [[nums[0]]];

  //loop through the rest of numbers
  for (let i = 1i<nums.length;i++) {
    let num = nums[i];
    let tmp=[];

    //loop through each item in the results
    for (let j=0;j<results.length;j++) {
      let result = results[j];

      //insert the current number around/in-between
      for (let k=0;k<=result.length;k++) {
        let head = result.slice(0,k);
        let tail = result.slice(k);
        tmp.push([...headnum, ...tail]);
      }
    }
    results = tmp;
  }
  return results;
};

       

 






Thursday, June 24, 2021

List

Create Empty List
JS Python
let arr = [];
arr = []

Create list with size:
let arr = new Array(5);
arr = [None] * 5


Add an item at the end
arr.push(1);
arr.append(1);

Add an item at the begin:
arr.unshift(2);
arr.splice(0, 0, 2);
arr[:0]=[2]
arr.insert(0,2)

Add items inside:
arr.splice(2,0,3,4);
arr[1:0]=[3]

Add 2 arrays:
let arr3 = arr1.concat(arr2);
arr3 = arr1 + arr2
arr = [...arr, ...otherArr];
arr = [*arr, *otherArr]
arr.extend(otherArr)

Delete Items at the end
arr.pop();
arr.pop()

Delete items at the begin:
arr.splice(0,1);
arr[0:1]=[]

Delete items at the begin and return the deleted item
arr.shift();
arr.pop(0)

Delete Items inside (delete one item in index 1):
arr.splice(1,1);
arr[1:2]=[]
arr.pop(1)

Initial values:
arr = new Array(5).fill(0);
arr = [0] * 5

Range:
[...Array(5).keys()].map(i=>i+5);
list(range(5,10)

Get first item:
arr[0]
arr[0]

Get last item:
arr.slice(-1)[0];
arr[-1]

Get first N items:
arr.slice(0, N);
arr[0: N]

Is list?
Array.isArray(arr)
isinstance(arr, list)

String to list:
arr = s.split("");
arr = [...s];
arr = list(s)

List to string
s = arr.join("");
s = "".join(arr)

Tuesday, June 22, 2021

Leetcode question 57

LeetCode Insert Interval :

Here is my solution. It's break a loop into three sections:

1. Find the new begin number to construct new interval.

2. Find the new end number to construct new interval.

3. Append the remaining items into new interval.

Hope this make sense.
Also, hope those if/else conditions can be more straight forward.


/**
 * @param {number[][]} intervals
 * @param {number[]} newInterval
 * @return {number[][]}
 */
 var insert = function(intervalsnewInterval) {
    let begin = newInterval[0];
    let end = newInterval[1];
    let result = [];
    let tmpInterval = [];
    let len = intervals.length;
    let i = 0;

    if (len == 0) {
        return [newInterval]
    }

    // 1. insert begin position
    for (i = 0i < leni++) {
        let interval = intervals[i];
        if (begin <= interval[0]) {
            tmpInterval[0] = begin;
            break;
        } if (begin > interval[0] && begin <= interval[1]) {
            tmpInterval[0] = interval[0];
            break;
        } else if (begin > interval[1]) {
            result.push(interval);
            if (i===len-1){
                result.push(newInterval);
            }
        }
    }

    // 2. insert end position
    for (; i < leni++) {
        let interval = intervals[i];
        if (end < interval[0]) {
            tmpInterval[1] = end;
            result.push(tmpInterval);
            break;
        } else if (end <= interval[1]) {
            tmpInterval[1] = interval[1];
            result.push(tmpInterval);
            i++;
            break;
        } else if (end > interval[1]) {
            if (i===len-1) {
                tmpInterval[1] = Math.max(interval[1], end);
                result.push(tmpInterval);
            }
            continue;
        }

    }

    // 3. remaining interval
    for (; i < leni++) {
        let interval = intervals[i];
        result.push(interval);
    }

    return result;
};

Try to get one step further. Now, just put newInterval into array in order.
Then swap the end number.
The logic in here is getting more straight forward.

/**
 * @param {number[][]} intervals
 * @param {number[]} newInterval
 * @return {number[][]}
 */
 var insert = function(intervalsnewInterval) {
    
    let len = intervals.length;
    // base cases
    if (len == 0) {
        return [newInterval]
    }
    if (newInterval[1] < intervals[0][0]) {
        return [newInterval, ...intervals];
    }
    if (newInterval[0] > intervals[len-1][1]) {
        return [...intervalsnewInterval];
    }

    // merge newInterval into interval in order, 
    // but the end number
    let found = false;
    let tmpIntervals=[]
    for (let i=0i<leni++) {
        let interval = intervals[i];
        if (!found && newInterval[0] <= interval[0]) {
            tmpIntervals.push([...newInterval]);
            found = true;
        }
        tmpIntervals.push([...interval]);
    }
    if (!found) {
        tmpIntervals.push([...newInterval]);
    }

    // fix the end number by swapping
    let last = tmpIntervals[0];
    let result = [last];
    for (let i=1i<tmpIntervals.lengthi++) {
        let interval = tmpIntervals[i];
        if (interval[0]<=last[1]) {
            last[1] = Math.max(last[1], interval[1]);
        } else {
            last = interval
            result.push(last);
        }
    }
    return result;
};







Sunday, June 20, 2021

Two diminsion array

Initial two dimension array with 0L

 > arr = Array(2).fill(Array(10).fill(0));
[
  [
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0
  ],
  [
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0
  ] 

However, assign a data that populate all rows in that position.

> arr[1][2]=3;
3
> arr
[
  [
    0, 0, 3, 0, 0,
    0, 0, 0, 0, 0
  ],
  [
    0, 0, 3, 0, 0,
    0, 0, 0, 0, 0
  ]
]


Initial two dimension array with sequence number:

 > arr = Array(2).fill(Array(10).fill(0)).map((a,i)=>a.map((b,j)=>i*10+j));
[
  [
    0, 1, 2, 3, 4,
    5, 6, 7, 8, 9
  ],
  [
    10, 11, 12, 13, 14,
    15, 16, 17, 18, 19
  ]
]

Reassigning a data is fine in here.

 > arr[1][2] = 77;
77
> arr
[
  [
    0, 1, 2, 3, 4,
    5, 6, 7, 8, 9
  ],
  [
    10, 11, 77, 13, 14,
    15, 16, 17, 18, 19
  ]
]



Saturday, June 19, 2021

Node.js end event

Another practice of hankerrank today, this is the problem in windows :

process.stdin.on('end', function() {...}

 The fix is :

process.on('SIGINT', function() {
...
exit(0);

 And, use CTRL+C to end the process.

Wednesday, June 09, 2021

AWS Labmda

Looking at my  lambda error. Dose aws lambda support node.js ES6?

 

2021-06-09T00:50:21.381Z    undefined    ERROR    Uncaught Exception     {
    "errorType": "Error",
    "errorMessage": "Must use import to load ES Module: /var/task/lambda.js\nrequire() of ES modules is not supported.\nrequire() of /var/task/lambda.js from /var/runtime/UserFunction.js is an ES module file as it is a .js file whose nearest parent package.json contains \"type\": \"module\" which defines all .js files in that package scope as ES modules.\nInstead rename lambda.js to end in .cjs, change the requiring code to use import(), or remove \"type\": \"module\" from /var/task/package.json.\n",
    "code": "ERR_REQUIRE_ESM",
    "stack": [
        "Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /var/task/lambda.js",
        "require() of ES modules is not supported.",
        "require() of /var/task/lambda.js from /var/runtime

...
 

In the package.json,

{

    "type":"module"

}

This is how I get my ES6 import syntax work in node.js, but not serverless.

To resolve this issue, install esm package npm install esm.
Also remove "type":"module" in package.json.



Tuesday, June 08, 2021

Elasticsearch

I have my elasticsearch in my window services. I only start up this service when I need it.

To see all elasticsearch index in the local, open browser to
http://localhost:9200/_cat/indices?v

To view a particular index data, open browser to
http://localhost:9200/[index name]/_search

For example: my earthquakes data
http://localhost:9200/earthquakes/_search
The data is in hits.hits.

 

Use bulk function to insert multiple records.
To avoid the data duplication when inserting, apply the same _id.

    let body = earthquakes.flatMap(
        obj => [{ index: { _index: INDEX_id: obj.id } }, obj]
    );
    let results = await client.bulk({ 
        refresh: true,
        body
    });

Wednesday, June 02, 2021

Django & celery

RSS project with Django and Celery

The repository is in https://github.com/ccapeng/rss_django

Some quick notes about of how to apply celery task work on windows. That took me a while to get it right.

1. The latest celery issue I have in the runtime

ModuleNotFoundError: No module named 'grp'

The solution is to rollback the early version: 

pip uninstall celery
pip install celery==5.0.5

 

2. The project is rss with one app feed.

To learn how to move around task to app, please check the project.

To run worker on windows,
celery -A feed worker --loglevel=info -P solo

Not celery -A feed worker --loglevel=info

Not celery -A feed worker --loglevel=info -P eventlet
This command come out threading error messages on windows.

To start scheduler,

celery -B feed beat


3, For Windows support, you can check with community discussion at

https://www.reddit.com/r/django/comments/lmilwl/the_proper_way_to_get_celery_to_work_on_windows/