How to resolve the algorithm Sierpinski carpet step by step in the JavaScript programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Sierpinski carpet step by step in the JavaScript programming language

Table of Contents

Problem Statement

Produce a graphical or ASCII-art representation of a Sierpinski carpet of order   N.

For example, the Sierpinski carpet of order   3   should look like this: The use of the   #   character is not rigidly required for ASCII art. The important requirement is the placement of whitespace and non-whitespace characters.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Sierpinski carpet step by step in the JavaScript programming language

Sierpinski Carpet:

  • The Sierpinski Carpet is a self-similar geometric fractal with infinite perimeter and zero area.
  • The carpet is created by starting with a solid square and repeatedly removing the middle third of each side of each square.
  • This process is repeated indefinitely, creating a pattern of smaller and smaller squares.
  • The Sierpinski Carpet was first described by the Polish mathematician Wacław Sierpiński in 1916.
  • The Sierpinski Carpet is an example of a fractal, which is a geometric pattern that is self-similar at all scales.

Implementation:

  • The Javascript implementation shown in the code creates a Sierpinski Carpet using a recursive algorithm.
  • The algorithm starts with a solid square represented by a string of black characters.
  • It then recursively replaces each black character with a string of three black characters and two white characters.
  • This process is repeated until the desired level of detail is reached.
  • The resulting string is then printed to the console or displayed as an html table.

Output:

  • The output of the algorithm is a string of characters that represents the Sierpinski Carpet.
  • The string can be printed to the console or displayed as an html table.
  • The table shows the carpet as a grid of black and white squares.

Applications:

  • The Sierpinski Carpet is a beautiful and interesting mathematical object.
  • It has been used in a variety of applications, including:
    • Art
    • Computer graphics
    • Mathematics education

Variations:

  • There are many variations of the Sierpinski Carpet.
  • Some variations include:
    • The Menger sponge
    • The Vicsek fractal
    • The Sierpinski triangle

Source code in the javascript programming language

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Sierpinski Carpet</title>
<script type='text/javascript'>

var black_char = "#";
var white_char = " ";

var SierpinskiCarpet = function(size) {
    this.carpet = [black_char];
    for (var i = 1; i <= size; i++) {
        this.carpet = [].concat(
            this.carpet.map(this.sier_top),
            this.carpet.map(this.sier_middle),
            this.carpet.map(this.sier_top)
        );
    }
}

SierpinskiCarpet.prototype.sier_top = function(x) {
    var str = new String(x);
    return new String(str+str+str);
}

SierpinskiCarpet.prototype.sier_middle = function (x) {
    var str = new String(x);
    var spacer = str.replace(new RegExp(black_char, 'g'), white_char);
    return new String(str+spacer+str);
}

SierpinskiCarpet.prototype.to_string = function() {
    return this.carpet.join("\n")
}

SierpinskiCarpet.prototype.to_html = function(target) {
    var table = document.createElement('table');
    for (var i = 0; i < this.carpet.length; i++) {
        var row = document.createElement('tr');
        for (var j = 0; j < this.carpet[i].length; j++) {
            var cell = document.createElement('td');
            cell.setAttribute('class', this.carpet[i][j] == black_char ? 'black' : 'white');
            cell.appendChild(document.createTextNode('\u00a0'));
            row.appendChild(cell);
        }
        table.appendChild(row);
    }
    target.appendChild(table);
}

</script>
<style type='text/css'>
    table {border-collapse: collapse;}
    td {width: 1em;}
    .black {background-color: black;}
    .white {background-color: white;}
</style>
</head>
<body>

<pre id='to_string' style='float:left; margin-right:0.25in'></pre>
<div id='to_html'></div>
    
<script type='text/javascript'>
    var sc = new SierpinskiCarpet(3);
    document.getElementById('to_string').appendChild(document.createTextNode(sc.to_string()));
    sc.to_html(document.getElementById('to_html'));
</script>

</body>
</html>

// Orders 1, 2 and 3 of the Sierpinski Carpet
// as lines of text.

// Generic text output for use in any JavaScript environment
// Browser JavaScripts may use console.log() to return textual output
// others use print() or analogous functions.

[1, 2, 3].map(function sierpinskiCarpetOrder(n) {

    // An (n * n) grid of (filled or empty) sub-rectangles
    // n --> [[s]]
    var carpet = function (n) {
            var lstN = range(0, Math.pow(3, n) - 1);

            // State of each cell in an N * N grid
            return lstN.map(function (x) {
                return lstN.map(function (y) {
                    return inCarpet(x, y);
                });
            });
        },

        // State of a given coordinate in the grid:
        // Filled or not ?
        // (See https://en.wikipedia.org/wiki/Sierpinski_carpet#Construction)
        // n --> n --> bool
        inCarpet = function (x, y) {
            return (!x || !y) ? true :
                !(
                    (x % 3 === 1) &&
                    (y % 3 === 1)
                ) && inCarpet(
                    x / 3 | 0,
                    y / 3 | 0
                );
        },

        // Sequence of integers from m to n
        // n --> n --> [n]
        range = function (m, n) {
            return Array.apply(null, Array(n - m + 1)).map(
                function (x, i) {
                    return m + i;
                }
            );
        };

    // Grid of booleans mapped to lines of characters
    // [[bool]] --> s
    return carpet(n).map(function (line) {
        return line.map(function (bool) {
            return bool ? '\u2588' : ' ';
        }).join('');
    }).join('\n');

}).join('\n\n');


(() => {
    'use strict';

    // sierpinskiCarpet :: Int -> String
    let sierpinskiCarpet = n => {

        // carpet :: Int -> [[String]]
        let carpet = n => {
                let xs = range(0, Math.pow(3, n) - 1);
                return xs.map(x => xs.map(y => inCarpet(x, y)));
            },

            // https://en.wikipedia.org/wiki/Sierpinski_carpet#Construction

            // inCarpet :: Int -> Int -> Bool
            inCarpet = (x, y) =>
                (!x || !y) ? true : !(
                    (x % 3 === 1) &&
                    (y % 3 === 1)
                ) && inCarpet(
                    x / 3 | 0,
                    y / 3 | 0
                );

        return carpet(n)
            .map(line => line.map(bool => bool ? '\u2588' : ' ')
                .join(''))
            .join('\n');
    };

    // GENERIC

    // range :: Int -> Int -> [Int]
    let range = (m, n) =>
            Array.from({
                length: Math.floor(n - m) + 1
            }, (_, i) => m + i);

    // TEST

    return [1, 2, 3]
        .map(sierpinskiCarpet);
})();


(() => {
    'use strict';

    // weave :: [String] -> [String]
    const weave = xs => {
        const f = zipWith(append);
        return concatMap(
            x => f(f(xs)(x))(xs)
        )([
            xs,
            map(x => replicate(length(x))(' '))(
                xs
            ),
            xs
        ]);
    };

    // TEST -----------------------------------------------
    const main = () => {
        const
            sierp = n => unlines(
                take(1 + n, iterate(weave, ['\u2588']))[n]
            ),
            carpet = sierp(2);
        return (
            // console.log(carpet),
            carpet
        );
    };


    // GENERIC ABSTRACTIONS -------------------------------

    // append (++) :: [a] -> [a] -> [a]
    // append (++) :: String -> String -> String
    const append = xs => ys => xs.concat(ys);

    // concatMap :: (a -> [b]) -> [a] -> [b]
    const concatMap = f => xs =>
        xs.reduce((a, x) => a.concat(f(x)), []);

    // iterate :: (a -> a) -> a -> Gen [a]
    function* iterate(f, x) {
        let v = x;
        while (true) {
            yield(v);
            v = f(v);
        }
    }

    // Returns Infinity over objects without finite length
    // this enables zip and zipWith to choose the shorter
    // argument when one is non-finite, like cycle, repeat etc

    // length :: [a] -> Int
    const length = xs => xs.length || Infinity;

    // map :: (a -> b) -> [a] -> [b]
    const map = f => xs => xs.map(f);

    // replicate :: Int -> String -> String
    const replicate = n => s => s.repeat(n);

    // take :: Int -> [a] -> [a]
    // take :: Int -> String -> String
    const take = (n, xs) =>
        xs.constructor.constructor.name !== 'GeneratorFunction' ? (
            xs.slice(0, n)
        ) : [].concat.apply([], Array.from({
            length: n
        }, () => {
            const x = xs.next();
            return x.done ? [] : [x.value];
        }));

    // unlines :: [String] -> String
    const unlines = xs => xs.join('\n');

    // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = f => xs => ys => {
        const
            lng = Math.min(length(xs), length(ys)),
            as = take(lng, xs),
            bs = take(lng, ys);
        return Array.from({
            length: lng
        }, (_, i) => f(as[i])(bs[i]));
    };

    // MAIN -----------------------------------------------
    return main();
})();


  

You may also check:How to resolve the algorithm FizzBuzz step by step in the Yorick programming language
You may also check:How to resolve the algorithm Averages/Pythagorean means step by step in the RPL programming language
You may also check:How to resolve the algorithm RIPEMD-160 step by step in the Common Lisp programming language
You may also check:How to resolve the algorithm Self-describing numbers step by step in the LiveCode programming language
You may also check:How to resolve the algorithm 21 game step by step in the Ruby programming language