11
\$\begingroup\$

Consider the following 3x3 blocks which the marching squares algorithm would identify for every cell (with 0-based labeled ID):

0:
...
...
...

1:
...
...
\..

2:
...
...
../

3:
...
---
...

4:
..\
...
...

5:
/..
...
../

6:
.|.
.|.
.|.

7:
/..
...
...

8:
/..
...
...

9:
.|.
.|.
.|.

10:
..\
...
\..

11:
..\
...
...

12:
...
---
...

13:
...
...
../

14:
...
...
\..

15:
...
...
...

The goal of this challenge is given a 2D matrix of block ID's, draw the full contour plot by tiling these smaller cells together. Note that there are some repeated cases (ex.: 0 and 15 visually are the same)

Input

Your program/function should take as input a 2D rectangular matrix of integers in the range [0+a,15+a] (where a is an arbitrary integer shift of your choice; this allows you to use zero-based indexing or 1-based indexing for the blocks). This may be from any source desired (stdin, function parameter, etc.).

Output

Your program/function should output a single string representing the full contour plot. There should be no extra leading/trailing whitespace, but a single trailing newline is allowed. There should be no separation between adjacent blocks vertically or horizontally.

Note that you do not have to do any kind of special treatment for blocks which map to a "saddle"; just draw the block with the given ID as-is.

The output may be to any sink desired (stdout, return value, etc.)

Examples

All examples below use 0-based block ID's.

case 1:

2 1
4 8

......
......
../\..
..\/..
......
......

case 2:

15 13 12 14 15
13 8 0 4 14
11 1 0 2 7
15 11 3 7 15

...............
......---......
...../...\.....
.../.......\...
...............
../.........\..
..\........./..
...............
...\......./...
.....\.../.....
......---......
...............


case 3:

12 12 12 8 4
0 0 0 0 2
0 0 0 2 7
0 2 3 7 15

........./....\
---------......
...............
...............
...............
............../
............/..
...............
.........../...
........./.....
......---......
...../.........

case 4:

0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15

............
.........---
...\..../...
..\/...|./..
.......|....
...../.|....
/...|...\..\
....|.......
....|.\.....
............
---.........
...../\.....

case 5:

0 0 0 0 6 15 15
0 0 0 0 6 15 15
0 0 0 0 6 15 15
0 0 0 2 7 15 15
0 0 2 5 14 15 15
0 2 5 8 4 12 14
0 4 8 0 0 0 6
0 0 0 0 0 0 4

.............|.......
.............|.......
.............|.......
.............|.......
.............|.......
.............|.......
.............|.......
.............|.......
.............|.......
............/........
.....................
.........../.........
........./...........
.....................
......../../\........
....../../....\......
...............---...
...../../.........\..
.....\/............|.
...................|.
...................|.
....................\
.....................
.....................

Scoring

This is code golf; shortest code in bytes wins. Standard loopholes apply.

\$\endgroup\$
5
  • \$\begingroup\$ Related. \$\endgroup\$ Jun 26, 2017 at 5:53
  • 1
    \$\begingroup\$ Shouldn't the last test case have 3 more leading lines of the vertical bars? \$\endgroup\$
    – dzaima
    Jun 26, 2017 at 15:10
  • \$\begingroup\$ yes, fixed. Thanks! \$\endgroup\$ Jun 26, 2017 at 15:20
  • \$\begingroup\$ Should've used hexidecimal input. \$\endgroup\$ Jun 30, 2017 at 13:55
  • \$\begingroup\$ Cries internally. \$\endgroup\$ Jun 30, 2017 at 14:10

9 Answers 9

2
\$\begingroup\$

Mathematica, 353 326 bytes

s=Table[".",3,3];z=Reverse;l@0=l@15=s;y=s;y[[3,1]]="\\";l@1=l@14=y;y=s;y[[3,3]]="/";l@2=l@13=y;y=s;y[[2,All]]="-";l@3=l@12=y;y=l@4=l@11=z/@z@l@1;y[[3,1]]="\\";l@10=y;y=s;y[[All,2]]="|";l@6=l@9=y;y=l@7=l@8=z/@z@l@2;y[[3,3]]="/";l@5=y;StringReplace[ToString@Grid@Map[Column,Map[StringJoin,Map[l,#,{2}],{3}],{2}],{"\n\n"->"\n"}]&


input

[{{15, 13, 12, 14, 15}, {13, 8, 0, 4, 14}, {11, 1, 0, 2, 7}, {15, 11, 3, 7, 15}}]

\$\endgroup\$
1
  • \$\begingroup\$ Impressive, hard to do this in Mathematica. \$\endgroup\$ Jun 30, 2017 at 14:40
2
\$\begingroup\$

JavaScript (ES6), 195 bytes

a=>a.map((r,y)=>r.map((i,x)=>[...s='76843210_'].map((_,j)=>(o[Y=y*3+j/3|0]=o[Y]||[])[x*3+j%3]='.\\/-\\/|/\\'[[0,64,256,56,4,257,146,1,68][k=s[i-8]||i]>>j&1&&k])),o=[])&&o.map(r=>r.join``).join`
`

Test cases

let f =

a=>a.map((r,y)=>r.map((i,x)=>[...s='76843210_'].map((_,j)=>(o[Y=y*3+j/3|0]=o[Y]||[])[x*3+j%3]='.\\/-\\/|/\\'[[0,64,256,56,4,257,146,1,68][k=s[i-8]||i]>>j&1&&k])),o=[])&&o.map(r=>r.join``).join`
`

console.log(f([
  [ 2, 1 ],
  [ 4, 8 ]
]));

console.log(f([
  [ 15, 13, 12, 14, 15 ],
  [ 13,  8,  0,  4, 14 ],
  [ 11,  1,  0,  2,  7 ],
  [ 15, 11,  3,  7, 15 ]
]));

console.log(f([
  [ 12, 12, 12,  8,  4 ],
  [  0,  0,  0,  0,  2 ],
  [  0,  0,  0,  2,  7 ],
  [  0,  2,  3,  7, 15 ]
]));

console.log(f([
  [  0,  1,  2,  3 ],
  [  4,  5,  6,  7 ],
  [  8,  9, 10, 11 ],
  [ 12, 13, 14, 15 ]
]));

console.log(f([
  [  0,  0,  0,  0,  6, 15, 15 ],
  [  0,  0,  0,  0,  6, 15, 15 ],
  [  0,  0,  0,  0,  6, 15, 15 ],
  [  0,  0,  0,  2,  7, 15, 15 ],
  [  0,  0,  2,  5, 14, 15, 15 ],
  [  0,  2,  5,  8,  4, 12, 14 ],
  [  0,  4,  8,  0,  0,  0,  6 ],
  [  0,  0,  0,  0,  0,  0,  4 ]
]));

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

Mathematica, 173 bytes

StringRiffle[ArrayFlatten[ReplacePart[Table[".",16,3,3],{{2|11|15,3,1}|{5|11|12,1,3}->"\\",{3|6|14,3,3}|{6|8|9,1,1}->"/",{4|13,2,_}->"-",{7|10,_,2}->"|"}][[#]]&/@#],"\n",""]&

Try it at the Wolfram sandbox!

The "\n" should be replaced by an actual newline. The input is 1-indexed — for example, the third test case becomes {{13,13,13,9,5},{1,1,1,1,3},{1,1,1,3,8},{1,3,4,8,16}}. The output is a string.

The idea is basically the same as Jenny_mathy's answer — make the sixteen squares by taking a 3x3 grid of "."s and replacing some of the characters, then stitch the squares together — but using slightly shorter functions to do it. (Thanks to alephalpha for reminding me that ArrayFlatten exists!)

It's possible that this can be done in fewer bytes by making the squares cleverly instead of basically hardcoding them, but that would require much more effort…

\$\endgroup\$
2
  • \$\begingroup\$ @Jenny_mathy: Edited — is that what you wanted? \$\endgroup\$
    – Not a tree
    Jun 26, 2017 at 11:07
  • \$\begingroup\$ @Jenny_mathy, it seems to be working for me. I'm using 1-indexing, so you need to add 1 to every number; the test case becomes {{16,14,13,15,16},{14,9,1,5,15},{12,2,1,3,8},{16,12,4,8,16}}. If you tried that and it's still not working, could you tell me what problem you're getting? \$\endgroup\$
    – Not a tree
    Jun 26, 2017 at 11:15
2
\$\begingroup\$

Retina, 165 bytes

T`d`L`1\d
 |\bB\B

.+
X$&¶Y$&¶Z$&
%{`[XYZ]$

([XYZ])[69]
.|.$1
X[^4-B]
...X
X[4AB]
..\X
X[578]
/..X
Y[^369C]
...Y
Y[3C]
---Y
Z[03478BCF]
...Z
Z[1AE]
\..Z
Z[25D]
../Z

Try it online! Link includes second example. Explanation: The first two stages convert from decimal to hexadecimal, allowing the spaces to be deleted. The third stage then triplicates each line, giving each new line a separate marker. These markers then traverse the hex digits, converting them into the contour plot as they go, until they reach the end of the line, at which point they are deleted.

\$\endgroup\$
1
\$\begingroup\$

Python 2, 247 bytes

J='...'
print'\n'.join(map(''.join,sum([[sum([f[i*3:][:3]for i in j],[])for f in map(list,[J*4+'..\\/...|./../...|...\\..\\'+J*4,J*3+'---.......|........|.......---'+J*3,'...\\..../......../.|........|.\\'+J*3+'./\\.....'])]for j in input()],[])))

Try it online!

-1 byte thanks to LeakyNun

\$\endgroup\$
3
  • \$\begingroup\$ Please note that 10 and 5 are different. \$\endgroup\$
    – Leaky Nun
    Jun 26, 2017 at 2:21
  • \$\begingroup\$ @LeakyNun sigh I knew I had to have messed something up. Deleting until I fix it, maybe by tomorrow. \$\endgroup\$
    – hyper-neutrino
    Jun 26, 2017 at 2:22
  • \$\begingroup\$ @LeakyNun I've fixed the code, though now it's become extremely ugly and ungolfed. \$\endgroup\$
    – hyper-neutrino
    Jun 26, 2017 at 13:51
1
\$\begingroup\$

SOGL V0.12, 106 89 bytes

žj}² ³
ē0=?²
{ā;{"⁰9═‼pnk№Ο|╚φ;“2─6nwEX .9*3n²Xƨ.ƨ-¹╬-}²X"č7_#‘3n}² /33³\13³\31³/11žj}┼}O

Try it Here! (that has an extra byte for ease of input. This otherwise would expect the array already on stack)

\$\endgroup\$
2
  • \$\begingroup\$ Please make SOGL interpreter use monospace font >.< \$\endgroup\$
    – hyper-neutrino
    Jun 26, 2017 at 15:13
  • \$\begingroup\$ 10 slashes are wider than 10 periods. \$\endgroup\$
    – hyper-neutrino
    Jun 26, 2017 at 15:17
1
\$\begingroup\$

Python 2, 196 191 181 176 bytes

Try it online!

A function which takes an array of arrays of ints and returns a string:

J=''.join;N='\n'.join
f=lambda I:N(N(J(J('\/|-.'[C/16-2]*(C%16)for C in map(ord,'o!j1cSe!f1g1aAbAbAa1h1iAbAbAc!c!d!iSk1f!k'))[c*9+3*j:][:3]for c in r)for j in[0,1,2])for r in I)

EDIT: saved 5 bytes by assigning J,N; another 10 bytes because I forgot the input is already assumed to be an array of arrays of ints; and then another 5 bytes saved by smarter slicing...

The concatenated string of all 16 3x3 cells (144 bytes, omitting linebreaks) is run-length-encoded to the 41 byte string:

o!j1cSe!f1g1aAbAbAa1h1iAbAbAc!c!d!iSk1f!k

where each RLE element (cellType, length) is encoded to the character chr(32+16*cellType+length) (it is handy that the maximum run is 15; and that ord(' ')==32 is divisble by 16). When decoding, we take '\/|-.'[cellType] as the printable character.

Nothing particularly clever after that...

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 61 bytes

v•2mßklJFΘõÿ|åU‚ιØØ•6B5¡∊¶¡110bTǝ.BJ3ô3ôyèøJ»}»4ÝJð«"\./-|."‡

Try it online!


The first half of the pattern can be compressed as:

5
11111105
1111111125
1113335
1105
2111111125
141141145
25

The second half would need to be:

25
141141145
11011105
1105
1113335
1111111125
11111105
5

We can just vertically mirror the first half, and insert binary 110 (1101110) in for the 2111111125.


Next we take this pattern and split on fives, then pad it with ones:

1 = 111111111
2 = 111111011
3 = 111111112
4 = 111333111
5 = 110111111
6 = 211111112
7 = 141141141
8 = 211111111
9 = 141141141
A = 110111011
B = 110111111
C = 111333111
D = 111111112
E = 111111111

Now we have our building blocks, the last parts just replace the matrix entries with the appropriate building blocks, zip together the rows and print to the user with replaced symbols:

0 = .........
1 = ......\..
2 = ......../
3 = ...---...
4 = ..\......
5 = /......./
6 = .|..|..|.
7 = /........
8 = /........
9 = .|..|..|.
A = ..\...\..
B = ..\......
C = ...---...
D = ......../
E = .........

Can post formal operation explanation if anyone wants it, thanks.

\$\endgroup\$
1
\$\begingroup\$

Jelly, 64 bytes

“¡_ḟ5⁸ṫ⁺Y"⁷ƘzƬɼ¥@TR/ṖQ½3yİ>ẎḄT¥⁹iḟQ¬Ɠl¹µŒ’ṃ“/-\|.”s3s3ṙ9ị@³ZY$€Y

Try it online!

This uses a naive compression and could probably save many bytes with run-length encoding.

How it Works

“¡_ḟ5⁸ṫ⁺Y"⁷ƘzƬɼ¥@TR/ṖQ½3yİ>ẎḄT¥⁹iḟQ¬Ɠl¹µŒ’ṃ“/-\|.”s3s3ṙ9ị@³ZY$€Y
“¡_ḟ5⁸ṫ⁺Y"⁷ƘzƬɼ¥@TR/ṖQ½3yİ>ẎḄT¥⁹iḟQ¬Ɠl¹µŒ’ encodes the integer 4591777158889232952973696500124538798606476761349931038636020730336909822188496590423586252520
ṃ“/-\|.”                   - convert to base 5 and index into the string to get "/......../.........|..|..|...\...\....\.........---.........../......\.................\........../...---.....\....../......./.|..|..|."
        s3s3               - split every 9 characters into a 3x3 square submatrix       
            ṙ9             - rotate left by 9 to line up the submatrix for 1 with index 1
              ị@³          - index the input into this
                 ZY$€Y     - format
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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