Understand the application of mathematics in programming from a problem

Time:2022-3-10

Write in front

Because of the power failure in the test room these two days, there is nothing to do these two days. What are you doing idle? Think about not trying to write another article to nag. So there is today’s article.

Origin of question selection

Last month, someone in the community asked such a question——How to simplify the JS judgment made me dizzy

const isDel = (op, o) => {
    let fal = false;
    if (op.is_show_lock && op.is_show_sf && op.is_show_bz) {
        if (o.is_lock && o.is_sf && o.is_bz) {
            fal = false;
        } else {
            fal = true;
        }
    } else if (op.is_show_lock && op.is_show_sf) {
        if (o.is_lock && o.is_sf) {
            fal = false;
        } else {
            fal = true;
        }
    } else if (op.is_show_lock && op.is_show_bz) {
        if (o.is_lock && o.is_bz) {
            fal = false;
        } else {
            fal = true;
        }
    } else if (op.is_show_sf && op.is_show_bz) {
        if (o.is_sf && o.is_bz) {
            fal = false;
        } else {
            fal = true;
        }
    } else if (op.is_show_lock) {
        if (o.is_lock) {
            fal = false;
        } else {
            fal = true;
        }
    } else if (op.is_show_sf) {
        if (o.is_sf) {
            fal = false;
        } else {
            fal = true;
        }
    } else if (op.is_show_bz) {
        if (o.is_bz) {
            fal = false;
        } else {
            fal = true;
        }
    }
    return fal;
};

It can be seen that the main logic of this code is to judge the final result output Boolean value according to several fields. The final answer given by the author is——

const isRemove = (op, o) => (op.is_show_lock && !o.is_lock) || (op.is_show_sf && !o.is_sf) || (op.is_show_bz && !o.is_bz)

So how do I simplify it? When I see the above long list of logical judgments, it is obvious that there are too many fields to be reused. My first feeling is that it should be simplified by Boolean algebra, which involves two knowledge points,Boolean algebraThe law of andBoolean algebraic operation law, there is no need to repeat the theoretical knowledge of these two. You can click the link to view or use the customary search engine to search and consult relevant materials. Let’s get straight to the point.

simplify

First of all, we will review the code of the following topic. We can see that there are few conditions that satisfy true [PS: because false includes not only the conditions in if, but also the conditions that do not satisfy else, which is the bug when the author answered wrong for the first time], then list all Boolean expressions that satisfy true as follows:

op.is_show_lock && op.is_show_sf && op.is_show_bz && !(o.is_lock && o.is_sf && o.is_bz) || 
op.is_show_lock && op.is_show_sf && !(o.is_lock && o.is_sf) ||
op.is_show_lock && op.is_show_bz && !(o.is_lock && o.is_bz) ||
op.is_show_sf && op.is_show_bz && !(o.is_sf && o.is_bz) || 
op.is_show_lock && !o.is_lock ||
op.is_show_sf && !o.is_sf ||
op.is_show_bz && !o.is_bz

A field is just a representation, so letters can be used instead to simplify the expression. Assumptions:

op.is_show_lock -> A
op.is_show_sf -> B
op.is_show_bz -> C
o.is_lock -> a
o.is_show_lock -> b
o.is_show_lock -> c

And because it should be expressed as mathematical language, in Mathematics:

&& -> ·
|| -> +
! -> ′

Thus, the code is expressed as the following Boolean Algebra:

A · B · C · (a · b · c)′ + 
A · B · (a · b)′ +
A · C · (a · c)′ +
B · C · (b · c)′ + 
A · a′ +
B · b′ +
C · c′

The next step is to apply the Boolean operation law to this Boolean algebra to simplify it and get the final optimal Boolean algebra.

step

  1. Morgan’s Law (a) ′, b) ′ (b) ′ = a

    A · B · C · (a′ + b′ + c′) + 
    A · B · (a′ + b′) +
    A · C · (a′ + c′) +
    B · C · (b′ + c′) + 
    A · a′ +
    B · b′ +
    C · c′
  2. Distribution law: a · (B + C) = (a · b) + (a · C), (a + b) · C = (a · C) + (B · C)
    From the results of step 1, we can see that allabcAlla′b′c′, then we’ll do another replacement here, each expressed asxyz; Then according to the distribution law:

    A · B · C · x + A · B · C · y + A · B · C · z + 
    A · B · x + A · B · y +
    A · C · x + A · C · z +
    B · C · y + B · C · z + 
    A · x +
    B · y +
    C · z
  3. Commutative law: a + B = B + A, a · B = B · A. associative law: (a + b) + C = a + (B + C), (a · b) · C = a · (B · C)
    It can be seen from step 2 that there are two sub items with common algebraic formula, such as:A · B · x,A · x; According to the exchange law and combination law, they can be combined. Here, take these two as examples:
    A · B · x + A · x
  4. Zero one law (unitary law): a + 0 = a, a · 1 = a
    A · B · x + A · x · 1
  5. Distribution law: a · (B + C) = (a · b) + (a · C), (a + b) · C = (a · C) + (B · C)
    A · x · (B + 1)
  6. Finite element law (polar element law): a + 1 = 1, a · 0 = 0
    A · x
  7. According to the calculation of 3 ~ 6 steps, theA · B · x + A · x = A · x , repeat the above steps to calculate the other two subalgebras, and finally get the algebraic formula:

    A · x +
    B · y +
    C · z

    So far, the Boolean algebra can no longer be optimized, so it can be converted into the following code according to the original agreement:

    (op.is_show_lock && !o.is_lock) || 
    (op.is_show_sf && !o.is_sf) || 
    (op.is_show_bz && !o.is_bz)

Write at the end

In my five years as a developer, I haven’t encountered the subject yet, and the probability of this kind of code should be relatively small. Even if I encounter it, most people may use other schemes in the answer, but most of them can’t escape the cycle, and the complexity changes directly from O (1) to o (n). Although the final impact is minimal, it’s harmless to understand other better schemes, Readability is also improved. Readers can try this technique if they encounter such code.