Problem solving 1 draft

Last modified 1 months ago / Edit on Github
draft
This is a draft, the content is not complete and of poor quality!

This note contains questions/puzzle and algorithms to answer these problems. Most of the codes in this type of note are in Python or JS.

[Python] Count number of element in an array or properties of an object

For example,

countTheNumberOfLines([1, [1]]) // returns 3
countTheNumberOfLines({"x": 1, "y": [1]}) // returns 3
private countTheNumberOfLines(obj: any): number {
if (typeof obj === 'object') {
if (Array.isArray(obj)) {
let count = obj.length;
for (let i = 0; i < obj.length; i++) {
count += countTheNumberOfLines(obj[i]);
}
return count;
} else if (obj && typeof obj === 'object') {
let count = Object.keys(obj).length;
for (const key in obj) {
if (typeof obj[key] !== 'function') {
count += countTheNumberOfLines(obj[key]);
}
}
return count;
}
return 0;
}
return 0;
}

[Python] Make chunkers / windows

Split a sequence into windows with size and slide.

def chunker(seq, size, slide=None, exact_size=False):
if slide is None:
slide = size
if exact_size:
return [seq[pos:pos + size] for pos in range(0, len(seq), slide) if len(seq[pos:pos + size]) == size]
else:
return [seq[pos:pos + size] for pos in range(0, len(seq), slide)]
seq = [i for i in range(10)]

chunker(seq, 3)
chunker(seq, 3, exact_size=True)
chunker(seq, 3, slide=2)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
[[0, 1, 2], [3, 4, 5], [6, 7, 8]]
[[0, 1, 2], [2, 3, 4], [4, 5, 6], [6, 7, 8], [8, 9]]

Make all arrays equal in size, filled with np.nan,

def chunker2(seq, size, slide=None):
if slide is None:
slide = size
return [np.append( seq[pos:pos + size], np.repeat(np.nan, size-len(seq[pos:pos + size])) )
for pos in range(0, len(seq), slide)]
seq = [i for i in range(10)]

chunker2(seq, size=4, slide=2)
[array([0., 1., 2., 3.]),
 array([2., 3., 4., 5.]),
 array([4., 5., 6., 7.]),
 array([6., 7., 8., 9.]),
 array([ 8.,  9., nan, nan])]

[Python] Plot a grid of squares

Plot a square of NxN small other squares. Each one has a probability Pxi/N of being coloured, where i is the line where it stands.

N = 100
P = 0.5
im_size = 5

image = np.repeat(np.array(range(1,N+1)).reshape(N, 1), N, axis=1)

# LESS understandable but executing FASTER
image = (P/N * image) <= np.random.rand(N,N)

# MORE understandable but executing SLOWER
def bernoulli(num, P, N):
return 1-np.random.binomial(1, P*num/N)
vfunc = np.vectorize(bernoulli)
image = vfunc(image, P, N)

plt.figure(figsize=(im_size, im_size))
plt.imshow(image, cmap='gray')
plt.show()

Bernoulli squares

[JS] Find and replace text with span

Problem: given a sentence and an array containing words and their colors to be replaced in the sentence.

An example of inputs and outputs
const entities = [
{
"word": "test",
"color": "blue",
},
{
"word": "span",
"color": "yellow",
},
{
"word": "test",
"color": "red",
},
{
"word": "testing",
"color": "white",
},
{
"word": "span",
"color": "black",
}
];
var text = "Test testing test span test span.";

What we expect,

'<span style="color: blue">test</span> <span style="color: white">testing</span> <span style="color: red">test</span> <span style="color: yellow">span</span> test <span style="color: black">span</span>.'
Challenges
  1. "test" is different from "testing".
  2. There is "span" in the entities but there is also "span" in the replacement <span style="...">.
  3. Two same words "test" in entities will be replaced in 2 first different "test" in text.
Idea of the solution

What we need to find is the placement of found words in text when using String.replace(). For example, the color "red" of the second word "test" in entities should be used for the 2nd "test" in text (not "test" in "testing").

For ignoring the "test" in "testing", we use regex \btest\b.

A problem comes in is that there will be "span" of <span style=...> before we find and replace the text "span".

So, we have to determine from the beginning of the text, how many words have already been replaced (eg. it's 1 for the 2nd "test") and also how many words are added by the replacement (eg. it's 1 for "span" because after the first "test", there will be a "span" in <span style=...>).

Codes
let newText = text;
entities.forEach((entity, index) => {
// Count occurances of the same entity.word in entities before this one
const slice = entities.slice(0, index);
let countInEntities = 0;
slice.forEach(e => countInEntities += e.word === entity.word);

const re = new RegExp(`\\b${entity.word.toLowerCase()}\\b`, 'gi');

// Count in text without span
const countInText = [...text.toLowerCase().matchAll(re)].length;

// Count in new text
const countInNewText = [...newText.toLowerCase().matchAll(re)].length;

const whereToReplace = countInNewText - countInText + countInEntities + 1;

let t = 0;
newText = newText.replace(re, match =>
++t === whereToReplace
? `<span style="color: ${entity.color}">${zeroWidthSpace}${entity.word}</span>${zeroWidthSpace}`
: match
);
});
Support Thi Support Thi