1

I want to solve Bliffoscope Data Analysis Problem using javascript. I have following question.

This is SlimeTorpedo

       +
       +
      +++
    +++++++
    ++   ++
   ++  +  ++
   ++ +++ ++
   ++  +  ++
    ++   ++
    +++++++
      +++

This is TestData

              + +    +              ++           +       +++    +     +
 +  ++     +   + ++++    + +       +         +          +  +   +++     +++ +
     +            + +   ++      ++  ++    + ++       +     +      +  +   +
+   ++      +  ++       +          + +       ++        ++  +           +
 ++++++ + +    +   ++  +  +   +   +  ++      +         +                     +
  + +   +      +               +      ++     +  ++            +   +    + +
+++   + ++   +  +            +  +++       + +       ++                     +
  +++++  +      +                            +  + +            +   +  +
 +   +   +              +    +      +            +  +   +      +    +     +
 ++    +              +     +       ++   +          +       +           ++

There is one question already similar to this but in Java. This question is asked here.

How can I solve this in JavaScript.

UPDATE

I tried following solution.

    const fs = require('fs');

    let torpedo = [], starship = [], testData = [];
        // counter = -1;

    function getTorpedoData(fileName, type) {
        let counter = -1;

        return new Promise(function(resolve, reject) {
            fs.readFile(fileName,'utf8', (err, data) => {

                if (err) {
                    reject();
                } else {
                    for (let i = 0; i < data.length; i++) {
                        if (data[i] == '\n' || counter === -1) {
                            torpedo.push([]);
                            counter++;
                        } else {
                            torpedo[counter].push(data[i]);
                        }
                    }
                }

                console.log(data);

                resolve();
            });
        });
    }

    function getTestData(fileName, type) {
        let counter = -1;

        return new Promise(function(resolve, reject) {
            fs.readFile(fileName,'utf8', (err, data) => {

                if (err) {
                    reject();
                } else {
                    for (let i = 0; i < data.length; i++) {
                        if (data[i] == '\n' || counter === -1) {
                            testData.push([]);
                            counter++;
                        } else {
                            testData[counter].push(data[i]);
                        }
                    }
                }

                console.log(data);

                resolve();
            });
        });
    }

    let score = 0;

    getTorpedoData('./SlimeTorpedo.blf', 'torpedo').then((data) => {
        getTestData('./TestData.blf', 'testData').then(() => {
            torpedo.forEach((torpedoArray, torpedoIndex) => {
                torpedoArray.filter((contents) => {
                    if (contents === '+') {
                        testData.forEach((testDataArray) => {
                            testDataArray.filter((dataContents, dataIndex) => {
                                // console.log(dataContents);
                                if (dataContents === '+') {
                                    if (torpedoIndex === dataIndex) {
                                        score++;
                                    }
    //                              console.log(score);
                                }
                            });
                        });
                    }
                });
            });
        });
    });

I creating 3 arrays torpedo, starship and testData. I read all these files and put them in multidimensional array(above). Then I am trying to find compare the indexes if torpedo array in testData array. However, there is something I am doing wrong. How can I fix it?

[Edit by Spektre]

Test results for test data (both this and the one from @greybeard link):

Bliffoscope data

Red mean mismatch and Yellow mean match. Score is incremented for match and decremented for mismatch. x counts from zero to rightwards and y counts from zero downwards but your data was enlarged by empty line so you can count from 1 instead ...

Spektre
  • 49,595
  • 11
  • 110
  • 380
Om3ga
  • 30,465
  • 43
  • 141
  • 221
  • this is really unclear to me ... what is test data (what it represents and how it is organized)? What is what you want to achieve? And what exactly is wrong? If it is identical problem to the linked QA then why post new question? What method of search have you used (or should we analyze your uncommented code and guess what you had in mind?) In current state I would vote Close (if it would not be the bounty in place) – Spektre Dec 20 '16 at 08:31
  • 1
    Can you include a link to a decent presentation of the problem (or turn a block quote in this question into one)? I've found no better than [bliffoscope data analysis problem](http://www.roseindia.net/answers/viewqa/Java-Interview-Questions/27275-bliffoscope-data-analsys-problem.html) ([github](https://github.com/mehmettugrulsahin/bliffoscope-angular2)). – greybeard Dec 20 '16 at 10:31
  • @Spektre If you look into this link https://stackoverflow.com/questions/14246120/locate-an-ascii-art-image-inside-a-body-of-text-with-a-certain-toleration-for-er . This is what I want but in javascript. – Om3ga Dec 20 '16 at 14:14
  • @2619 and what is the problem with your current code? – Spektre Dec 20 '16 at 17:42
  • 2
    `there is something I am doing wrong` [`"It doesn't work" is not a problem statement`](http://meta.stackoverflow.com/a/253788/3789665) – greybeard Dec 20 '16 at 19:27
  • @Spektre my current code does not increment the value of `score`. However, I am also skeptical about the logic I am following. – Om3ga Dec 20 '16 at 22:42
  • I am still waiting for help on this question. Anyone who can help. – Om3ga Dec 21 '16 at 16:05
  • @2619 and we are waiting for more info about what and how are you doing what you are doing (or at least you are think you are doing it) ... otherwise is this just Why is this code not working question type ... – Spektre Dec 21 '16 at 21:16
  • @2619 also provided test data is wrong as the torpedo is larger then your map by 1 line in y axis making any match impossible – Spektre Dec 23 '16 at 11:13
  • @2619 looks like incrementing score on match and decrementing on miss match works (handling out of bounds map/torpedo positions as neither (no score change)) working for both your copied data and also for the data in the graybeard link (will add images into your question shortly) – Spektre Dec 23 '16 at 12:15

1 Answers1

6

Are you looking for something like this (Fiddle)?

    
    // Create our images: torpedo (object) and background (context)

var object = "    +\n    +\n   +++\n +++++++\n ++   ++\n++  +  ++\n++ +++ ++\n++  +  ++\n ++   ++\n +++++++\n   +++",
    context = "              + +    +              ++           +       +++    +     +\n +  ++     +   + ++++    + +       +         +          +  +   +++     +++ +\n     +            + +   ++      ++  ++    + ++       +     +      +  +   +\n+   ++      +  ++       +          + +       ++        ++  +           +\n ++++++ + +    +   ++  +  +   +   +  ++      +         +                     +\n  + +   +      +               +      ++     +  ++            +   +    + +\n+++   + ++   +  +            +  +++       + +       ++                     +\n  +++++  +      +                            +  + +            +   +  +\n +   +   +              +    +      +            +  +   +      +    +     +\n ++    +              +     +       ++   +          +       +           ++ ";


    var c = document.getElementById("test_canvas"),
        ctx = c.getContext("2d"),
        scale = 10;

// Draw a pixel on canvas
function draw_pixel(x, y, fill_style) {
    ctx.fillStyle = fill_style;
    ctx.fillRect(x * scale, y * scale, scale, scale);
}

// Receive an array of coordinates, draw pixels
function draw_image(serialized_image, fill_style) {
    for (var i = 0, len = serialized_image.length; i < len; i++) {
        draw_pixel(serialized_image[i][0], serialized_image[i][1], fill_style);
    }
}

// Receive a text string, turn it into an array of coordinates of filled in pixels
function serialize_map(char_map) {
    var x = 0,
        y = 0,
        c,
        map = [];
    for (var i = 0, len = char_map.length; i < len; i++) {
        c = char_map[i];
        if (c == '+') {
            map.push([x, y])
        }
        x += 1;
        if (c == '\n') {
            x = 0;
            y += 1;
        }
    }
    return map;
}

// Find number of intersections between two images
function array_intersect() {
    var a, d, b, e, h = [],
        f = {},
        g;
    g = arguments.length - 1;
    b = arguments[0].length;
    for (a = d = 0; a <= g; a++) {
        e = arguments[a].length, e < b && (d = a, b = e);
    }
    for (a = 0; a <= g; a++) {
        e = a === d ? 0 : a || d;
        b = arguments[e].length;
        for (var l = 0; l < b; l++) {
            var k = arguments[e][l];
            f[k] === a - 1 ? a === g ? (h.push(k), f[k] = 0) : f[k] = a : 0 === a && (f[k] = 0);
        }
    }
    return h;
}

// Translate the coordinates of a serialized image
function translate(coords, ix, iy) {
    return [coords[0] + ix, coords[1] + iy];
}

// Find in which position the object has more intersections with the background
function get_best_position(context, object) {

    // Calculate image dimensions
    context_width = context.sort(function(a, b) {
        return b[0] - a[0];
    })[0][0];
    context_height = context.sort(function(a, b) {
        return b[1] - a[1];
    })[0][1];
    object_width = object.sort(function(a, b) {
        return b[0] - a[0];
    })[0][0];
    object_height = object.sort(function(a, b) {
        return b[1] - a[1];
    })[0][1];

    // Swipe context, store amount of matches for each patch position
    similaritudes = [];
    for (var cx = 0; cx < context_width; cx++) {
        for (var cy = 0; cy < context_height; cy++) {
            translated_object = object.map(function(coords) {
                return translate(coords, cx, cy);
            })
            intersection = array_intersect(context, translated_object);
            // console.log(translated_object);
            similaritudes[intersection.length] = [cx, cy];

        }
    }
    // Return position for which number of matches was greater
    return similaritudes.slice(-1)[0];
}

// Parse our images from the text strings
var serialized_context = serialize_map(context);
var serialized_object = serialize_map(object);

// Find best position for our torpedo
var best_position = get_best_position(serialized_context, serialized_object);

// Translate torpedo to best position
positioned_object = serialized_object.map(function(coords) {
    return translate(coords, best_position[0], best_position[1]);
});

// Draw background and torpedo 
draw_image(serialized_context, "gray");
draw_image(positioned_object, "rgba(0, 255, 0, 0.5)");
<canvas id="test_canvas" width="800" height="120" style="border:1px solid #000000;">
</canvas>
Ivan Chaer
  • 6,980
  • 1
  • 38
  • 48