ASCII texturing

23

6

Write a function or a full program that applies an ASCII texture to a 2d shape.

Inputs: shape, texture, dimensions(optionally).

  • Both Shape and Texture can be given by any convenient method (2d matrix, array of strings or string with newlines)
  • Shape data have a rectangular shape and contains 2 possible values: [truthy/falsey] binary/integer values (0/1 or n1/n2) or 2 different characters, just specify which one represent the shape parts [truthy] and which one represent the blank parts [falsey] and be consistent .

  • The texture has a square shape only (width ≡ height) and contains printable ASCII characters.

  • Optionally you can also pass dimensions of the matrices if needed.

Output: the shape with each truthy value substituted with the corresponding texture value (coordinates/indices mod texture size), the blank parts must be substituted with spaces.

  • The ratio is always 1:1
  • The entire shape must be covered and only the shape.
  • No offset, texturing must start at top-left corner (0,0) of the shape data with the origin of the texture also at the top-left corner.

Examples (using various shape formats in JSON)

Shape

[[0,0,1,1,0,0],
 [0,1,1,1,1,0],
 [0,1,1,1,1,0],
 [0,0,1,1,0,0]]

Texture

["/\\",
 "\\/"]

Output

["  /\  ",
 " /\/\ ",
 " \/\/ ",
 "  \/  "]

Shape

["        xxxxxxxx     ",
 "  xxxxxxxxxxxxxxxx   ",
 "    xxxxxxxxxxxxxxxx ",
 "  xxxxxxxxxxxxxxxxxxx",
 "xxxxxxxxxxxxxxxxxxxxx",
 "xxxxxxxxxxxxxxxxxxxxx",
 "xxxxxxxxxxxxxxxxxxxxx",
 "xxxxxxxxxxxxxxxxxxxxx"]

Texture

["[__]",
 "_][_",
 "[__]",
 "_][_"]

Output

["        [__][__]     ",
 "  [__][__][__][__]   ",
 "    [__][__][__][__] ",
 "  [__][__][__][__][__",
 "[__][__][__][__][__][",
 "_][__][__][__][__][__",
 "[__][__][__][__][__][",
 "_][__][__][__][__][__"]

Shape

[0,0,0,1]

Texture

["ab",
 "ba"]

Output

["   b"]

Shape

["11100001011010",
 "01111010101101",
 "01011011111101"]

Texture

["   ./]| |  / /.",
 "_|_|[]|/|_/\\_|/",
 "_|_|[/|_|_\\/_|.",
 "./_./]|_|//\\/./",
 "_|_|[]|/|_/\\_|/",
 "_|_|[]/ | \\/_|.",
 " /_  /|_|//\\/3/",
 "_|_|[]|/|_/\\_|/",
 "_|_|/ |_|_\\/_|.",
 "./_$/]|_|//\\/./",
 " |_|  |/|_/\\_|/",
 "_|_|[/|_|_\\$_|/",
 "_/  /]|_/ /\\///",
 "_|_/[]|/|/ \\_|/",
 "_|/|[/|_|_ /_||",
 " /_./]|_|  \\/|/"]

Output

(a surprise for you!)

Rules

  • Input/output can be given by any convenient method.
  • You can print it to STDOUT or return it as a function result.
  • Either a full program or a function are acceptable.
  • Extraneous whitespace are forbidden.
  • Standard loopholes are forbidden.
  • This is so all usual golfing rules apply, and the shortest code (in bytes) wins.

Sandbox post

AZTECCO

Posted 2019-11-14T19:35:23.040

Reputation: 2 441

Answers

16

APL (Dyalog Unicode), 20 12 bytesSBCS

-6 bytes through dzaima

Full program. Prompts stdin for:

  1. texture as a list of strings

  2. number of rows in shape matrix

  3. number of columns in shape matrix

  4. indices of falsies (to be blanks) in the shape matrix

All the s are supposed to be rectangles (they're not tofu). They symbolise a computer console which here means prompt for array input via stdin.

' '@⎕↑⎕⍴¨⎕⍴⎕

Try it online!

 prompt for texture as a list of strings; ["/\\","\\/"]

⎕⍴ prompt for number of rows in shape matrix (4) and use that to cyclically reshape the texture (this gives us enough texture lines); ["/\\","\\/","/\\","\\/"]

⎕⍴¨ prompt for number of columns in shape matrix (6) and use that to cyclically reshape each of the texture lines (this gives us enough characters in each texture line); ["/\\/\\/\\","\\//\\/\\","/\\/\\/\\","\\//\\/\\"]

 combine the list of lines into a character matrix;
  ["/\/\/\" 
   "\//\/\"
   "/\/\/\"
   "\//\/\"]

' '@⎕ prompt for indices for blanks ([[0,0],[0,1],[0,4],[0,5],[1,0],[1,5],[2,0],[2,5],[3,0],[3,1],[3,4],[3,5]]) and then place blanks at those indices;
   /\
   //\
   //
   /

Adám

Posted 2019-11-14T19:35:23.040

Reputation: 37 779

9

Canvas, 9 bytes

m⤢m⤢;n← ╋

Try it here!

Abusing that the input will be ASCII and so won't contain , but the shape is made of spaces and for easy overlapping and replacement. Alternative 12 bytes taking shape as space and #.

dzaima

Posted 2019-11-14T19:35:23.040

Reputation: 19 048

6

Japt, 10 bytes

ËmÈ?VgEY:S

Try it

ËmÈ?VgEY:S       U = shape as 2d array, V = texture as list of lines
Ë                Map each row, define E as row number
 mÈ                Map each element in these rows, define Y as element number
   ?                 Is the value a 1?
    VgEY               Get the character at texture[E,Y]
        :S           Else return a space if the value is a 0

Embodiment of Ignorance

Posted 2019-11-14T19:35:23.040

Reputation: 7 014

You don't need the space before the : – Shaggy – 2019-11-16T13:28:10.940

@Shaggy Somehow I missed that. Thanks! – Embodiment of Ignorance – 2019-11-16T19:01:21.263

5

J, 32 bytes

4 :'y}'' '',:x({.@]$($"1~{:))$y'

Try it online!

Some notes:

  • This was a rare case where I got a shorter solution with an explicit, rather than tacit, verb.
  • I wanted a solution that didn't prompt for input (ie, didn't want to just translate Adam's excellent APL solution into J).

Jonah

Posted 2019-11-14T19:35:23.040

Reputation: 8 729

3

Haskell, 51 49 bytes

  • The texture and shape are provided in the format used by the first example.
  • This works even if the texture isn't square or contains unprintables.
  • Dimensions do not need to be passed.
  • -2 bytes by abbreviating zipWith to z.
f=z(z(%)).cycle.map cycle
z=zipWith
_%0=' '
x%_=x

Try it online!

Joseph Sible-Reinstate Monica

Posted 2019-11-14T19:35:23.040

Reputation: 556

3

05AB1E, 11 bytes

εNUεiXèNèëð

Port of @EmbodimentOfIgnorance's Japt answer, so make sure to upvote him!

Inputs as defined in the first format of the challenge. Output as a character-matrix.

Try it online or verify all test cases. (Footer will pretty-print the character-matrix, feel free to remove it to see the actual output.)

Explanation:

ε          # Map over the rows of the (implicit) integer-matrix:
 NU        #  Push the map-index, and then pop and store it in variable `X`
   ε       #  Inner map over the cells of the current row:
    i      #   If the value of the current cell is a 1:
     Xè    #    Use variable `X` to index into the (implicit) input-list of strings,
           #    with automatic wraparound
       Nè  #    And then use the inner map index to index into this string
    ë      #   Else:
     ð     #    Push a space instead

Kevin Cruijssen

Posted 2019-11-14T19:35:23.040

Reputation: 67 575

3

J, 19 bytes

]]&' '"+]g"1~g=:$~#

Try it online!

Dyadic train. Left argument is texture, right argument is shape, 1 is blank, 0 is fill.

How it works

I extended the dyadic & trick to the "If" usage of ^:, i.e. boolean repetition amount. Also, an assignment =: can group the part of the train on its right, saving a pair of parens.

]]&' '"+]g"1~g=:$~#  Left argument: texture, Right argument: shape
                $~#  Repeat the texture's rows to fit the shape's rows
             g=:     Assign this sub-function to g
        ]g"1~        Use g to do the same on columns
]     "+             For each cell on the texture and shape,
 ]&' '                 Replace the texture's cell with ' ' if shape's cell is 1
                       Keep the texture if shape's cell is 0

Bubbler

Posted 2019-11-14T19:35:23.040

Reputation: 16 616

2

Julia 1.0, 68 bytes

f(s,t,n,Y,X)=[t[y,x] ? s[mod1(y,n),mod1(x,n)] : ' ' for y=1:Y,x=1:X]

Takes the shape as a 2d array of characters, the pattern as a array of Bools, and the dimensions (because length is long). Returns a character array via array comprehension.

Try it online!

gggg

Posted 2019-11-14T19:35:23.040

Reputation: 1 715

2

Charcoal, 16 bytes

Fθ«FΣιG→¹η¿›0ι⸿→

Try it online! Link is to verbose version of code. Takes input as newline-delimited strings. Explanation:

Fθ«

Loop over the shape.

FΣι

If the value is a 1...

G→¹η

... then draw a 1x1 polygon filled using the template. Conveniently in Charcoal the fill is always relative to the origin of the canvas. Unfortunately Charcoal can't draw zero-sized polygons or Oblongs of sides less than 2, otherwise I could save a couple of bytes here.

¿›0ι

If this is a newline...

⸿

... then move to the start of the next line of the canvas...

... otherwise move forward on the current line.

Neil

Posted 2019-11-14T19:35:23.040

Reputation: 95 035

2

Jelly, 13 bytes

JṁJ}ị⁸ṁ"⁹a@o⁶

Try it online!

A dyadic link taking a list of Jelly strings for the texture as its left argument and an integer matrix for the shape as its right argument. Returns a list of Jelly strings.

Nick Kennedy

Posted 2019-11-14T19:35:23.040

Reputation: 11 829

2

Icon, 100 97 bytes

procedure f(t,s)
i:=0&r:=|!t\*s&i+:=1&j:=0&c:=|!r\*!s&s[i,j+:=1]:=[" ",c][s[i,j]]&\z
return s
end

Try it online!

Uses 1 for spaces and 2 for textured in shape data.

Explanation:

procedure f(t,s)                   ; t - texture, s - shape data
    i:=0 &                         ; i is the row index
    r:=|!t\*s &                    ; repeats the rows of the texture as many times as the rows of the shape data  
    i+:=1 &                        ; next row
    j:=0 &                         ; j is the column index; reset to start
    c:=|!r\*!s &                   ; repeats the characters of each row of the texture as many times as the row of the shape 
    s[i,j+:=1]:=[" ",c][s[i,j]] &  ; modify the shape data ot " " or to texture
    \z                             ; z is not declared and thus causes Icon to backtrack 
    return s                       ; return the modified shape data
end

Galen Ivanov

Posted 2019-11-14T19:35:23.040

Reputation: 13 815

1

Python 2, 97 94 86 bytes

lambda S,P,w:[''.join([' ',P[j%w][i%w]][v]for i,v in E(s))for j,s in E(S)]
E=enumerate

Try it online!

3 bytes thx to frank

Takes the shape as S, a list list of 0/1;the texture P as a list of strings; and w as the width/height of P. Returns a list of strings.

Chas Brown

Posted 2019-11-14T19:35:23.040

Reputation: 8 959

1Texture is guaranteed to be square so you can just do i%len(P) – frank – 2019-11-14T21:48:14.440

@frank - ah thanks, I missed that! – Chas Brown – 2019-11-14T21:52:30.190

1

Ruby, 65 bytes

->s,p,w,h{s.zip(p*h).map{|a,b|a.zip(b*w).map{|x,y|x>0?y:' '}*''}}

Try it online!

Input: Matrix of 0 and 1, texture as 2d array of characters, size of the matrix (width and height).

G B

Posted 2019-11-14T19:35:23.040

Reputation: 11 099

1

Japt, 9 bytes

ËmÈù1VgEY

Try it

Shaggy

Posted 2019-11-14T19:35:23.040

Reputation: 24 623