How to Resolve Scaling Squared Strings in Java


The challenge

You are given a string of n lines, each substring being n characters long. For example:

s = "abcd\nefgh\nijkl\nmnop"

We will study the “horizontal” and the “vertical” scaling of this square of strings.

A k-horizontal scaling of a string consists of replicating k times each character of the string (except ‘\n’).

  • Example: 2-horizontal scaling of s: => “aabbccdd\neeffgghh\niijjkkll\nmmnnoopp”

A v-vertical scaling of a string consists of replicating v times each part of the squared string.

  • Example: 2-vertical scaling of s: => “abcd\nabcd\nefgh\nefgh\nijkl\nijkl\nmnop\nmnop”

Function scale(strng, k, v) will perform a k-horizontal scaling and a v-vertical scaling.

Example: a = "abcd\nefgh\nijkl\nmnop"
scale(a, 2, 3) --> "aabbccdd\naabbccdd\naabbccdd\neeffgghh\neeffgghh\neeffgghh\niijjkkll\niijjkkll\niijjkkll\nmmnnoopp\nmmnnoopp\nmmnnoopp"

Printed:

abcd   ----->   aabbccdd
efgh            aabbccdd
ijkl            aabbccdd
mnop            eeffgghh
                eeffgghh
                eeffgghh
                iijjkkll
                iijjkkll
                iijjkkll
                mmnnoopp
                mmnnoopp
                mmnnoopp

Task:

  • Write function scale(strng, k, v) k and v will be positive integers. If strng == "" return "".

The solution in Java code

Option 1:

public class Scale {
    public static String scale(String s, int k, int n) {
        String res="";
        for (String retval: s.split("\n")){
           String temp="";
           for (String l: retval.split("")){
               temp+=new String(new char[k]).replace("\0", l);
           }
           res+=new String(new char[n]).replace("\0", temp+"\n");
        }
        return res.trim();
    }
}

Option 2:

import java.util.stream.IntStream;

public class Scale {

    public static String scale(String strng, int k, int n) {
        String[] lines = strng.split("\n");
        StringBuilder result = new StringBuilder();
        IntStream.range(0, lines.length).forEachOrdered(lineNumber ->
                {
                    StringBuilder tmp = new StringBuilder();
                    lines[lineNumber].chars().forEachOrdered(c -> IntStream.range(0, k).forEach(h -> tmp.append((char)c)));
                    IntStream.range(0, n).forEach(j -> result.append(tmp).append("\n"));
                }
        );
        return result.toString().trim();
    }
}

Option 3:

class Scale {
  static String scale(String strng, int k, int v) {
    return strng.replaceAll("(\\w)", "$1".repeat(k))
                .replaceAll("(\\w+\\n)", "$1".repeat(v))
                .replaceAll("(\\n\\w+$)", "$1".repeat(v));
  }
}

Test cases to validate our solution

import static org.junit.Assert.*;
import org.junit.Test;

public class ScaleTest {

    private static void testing(String actual, String expected) {
        assertEquals(expected, actual);
    }
    @Test
    public void test() {
        System.out.println("Fixed Tests scale");
        String a ="abcd\nefgh\nijkl\nmnop";
        String r = "aabbccdd\naabbccdd\naabbccdd\neeffgghh\neeffgghh\neeffgghh\niijjkkll\n"
                + "iijjkkll\niijjkkll\nmmnnoopp\nmmnnoopp\nmmnnoopp";
        testing(Scale.scale(a, 2, 3), r);
        testing(Scale.scale("", 5, 5), "");
        testing(Scale.scale("Kj\nSH", 1, 2),"Kj\nKj\nSH\nSH");
    }
}