13
\$\begingroup\$

Your task is to, given a map as input, zoom it out or in, depending on the scale. Note that the scale given is the scale by which to zoom out, so a scale between 0 and 1 will actually zoom in.

For example, given the following (badly made) map:

..____....
../OOO\...
..\OO/\...
..........

And a scale factor of 2, you should first separate it into 2x2 sections:

.. | __ | __ | .. | ..
.. | /O | OO | \. | ..
----------------------
.. | \O | O/ | \. | ..
.. | .. | .. | .. | ..

And in each section find the most common character:

.__..
.....

Note that there was an ambiguous section:

__
OO

I chose to use _ for this section, but using O would have been perfectly acceptable too.

If, for example, you were given the scale factor of 4, you would split it into 4x4 sections, like so:

..__ | __.. | ..
../O | OO\. | ..
..\O | O/\. | ..
.... | .... | ..

As you can tell, the map doesn't perfectly fit into 4x4 sections, but that's fine, as we can just lower the size of the section at the side.

Also, whenever we need to cut off our maps, we cut off at the bottom or on the right side.

The resulting map would look like so:

...

What an interesting map!

For scale factors below 1, such as 0.5, the process is simpler as we zoom in instead. Take this map:

./O\.
.\O/.

Zooming with a scale of 0.5:

..//OO\\..
..//OO\\..
..\\OO//..
..\\OO//..

Note that whenever your zoom factor is less than 1, the following will always be true: 1/(zoom factor) % 2 == 0. When it is above 1, the only guarantee you have is that it will be a whole number. When it is 1, the map should stay the same.

Examples:

4
/OO\
|OO|
|OO|
\OO/

O


0.25
ABCD

AAAABBBBCCCCDDDD
AAAABBBBCCCCDDDD
AAAABBBBCCCCDDDD
AAAABBBBCCCCDDDD

1
My zoom
should
not change

My zoom
should
not change

You may also take the map as a newline-separated array.

\$\endgroup\$
  • 2
    \$\begingroup\$ I think you should've waited some more in the Sandbox. \$\endgroup\$ – Erik the Outgolfer May 9 '17 at 15:11
  • \$\begingroup\$ @JonathonAllan No it wouldn't, on that section there are more . than O. We cut off on the right and bottom side. \$\endgroup\$ – Okx May 9 '17 at 15:11
  • \$\begingroup\$ Ah, by "we cut off at the bottom or on the right side" you mean that the top-left of the map is always the top-left of a section? \$\endgroup\$ – Jonathan Allan May 9 '17 at 15:17
  • \$\begingroup\$ @JonathanAllan Yes. \$\endgroup\$ – Okx May 9 '17 at 15:23
  • \$\begingroup\$ OK, the word "or" is misleading :) \$\endgroup\$ – Jonathan Allan May 9 '17 at 15:30
7
\$\begingroup\$

Mathematica, 105 bytes

If[#<1,ArrayFlatten[#2/.n_String:>Table[n,1/#,1/#]],Map[First@*Commonest,#2~Partition~UpTo@{#,#},{2,3}]]&

The input is (scale, array of characters). The scale must be an integer or an exact fraction.

Explanation

If[#<1, ..., ... ]

If the first input is less than 1...

#2/.n_String:>Table[n,1/#,1/#]

Replace all Strings in the second input into a square array, with length 1/(first input)

ArrayFlatten[ ... ]

Flatten the result into a 2D array.

If[#<1, ..., ... ]

If the first input is not less than 1...

#2~Partition~UpTo@{#,#}

Partition the (second input) into partitions whose width/length are at most (first input).

Map[ ..., ... ,{2,3}]

Map onto level 2 and level 3...

First@*Commonest

The composition of the Commonest function (finds the commonest element in a list) and First (take the first element; in case there are multiple commonest elements).

\$\endgroup\$
2
\$\begingroup\$

Python, 191 182 180 bytes

lambda m,s,j=''.join,i=int:[j((lambda p:max(p,key=p.count))(j(g[i(x*s):-i(~x*s//1)]for g in m[i(y*s):-i(~y*s//1)]))for x in range(-i(-len(m[0])//s)))for y in range(-i(-len(m)//s))]

Call _(map, scale_factor), where map is an array of lines, and it returns an array of lines.

Though this answer has already been beaten, I want to explain it, as it doesn't special case where the scale factor is less than one.

It makes a h by w matrix, where h = ceiling(map height / scale factor), and w = ceiling(map width / scale factor).

For every index (x, y) in the matrix, do:

  • Take a submatrix from the coordinates int(x * scale factor), int(y * scale factor) to ceil((x + 1) * scale factor), ceil((y + 1) * scale factor).
  • Put the most common character in that submatrix at (x, y).

Try it online!

Try test cases

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.