# I give you ascii-art, you make it pseudo-3d

Do you know the optical effect of a tridimensional hand painted whit horizontal lines? Examples

This challenge consists of making something like that effect with ascii, and transforming one 2d input into a "3d" output.

## The algorithm

To perform this transformation, you first replace all 1 with a ¯ and all 0 with a _. In order to make things more realistic, you should replace a ¯ that does not have another ¯ before it with /, and a ¯ that does not have another ¯ after it with \.

Some examples:

Input:
001111100

Output:
__/¯¯¯\__

Input:
0110
1111

Output:
_/\_
/¯¯\


^ In this case, there are multiple lines, so apply this to all lines.

Input:
000000000000000000000000000000000
000000111100000000000001111100000
000000111110000000000111111000000
000000111111000000011111100000000
000000111111000001111110000000000
000000011111100011111100000000000
000000111111111111111100000000000
000000111101111111011110000000000
000000111100111110011110000000000
000000111111111111111110000000000
000000111111111111111110000000000
000000001111111111110000000000000
000000000001111100000000000000000
000000000000000000000000000000000

Output:
_________________________________
______/¯¯\_____________/¯¯¯\_____
______/¯¯¯\__________/¯¯¯¯\______
______/¯¯¯¯\_______/¯¯¯¯\________
______/¯¯¯¯\_____/¯¯¯¯\__________
_______/¯¯¯¯\___/¯¯¯¯\___________
______/¯¯¯¯¯¯¯¯¯¯¯¯¯¯\___________
______/¯¯\_/¯¯¯¯¯\_/¯¯\__________
______/¯¯\__/¯¯¯\__/¯¯\__________
______/¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\__________
______/¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\__________
________/¯¯¯¯¯¯¯¯¯¯\_____________
___________/¯¯¯\_________________
_________________________________


Exceptions / rules:

• The input will never have a single positive cell in a row (e.g. 00100)

• You can consider other characters for the input. However, it should only be two characters and not the same characters that the output uses. For instance:

Valid input:    0001111000 # two characters, different from the output
Valid input:    aaiiaiiaaa # two characters, different from the output
Valid input:    ,€€€€,,,,, # two characters, different from the output
Invalid input:  0001223000 # four different characters are used.
Invalid input:  ___1111___ # invalid, because the output uses underscores.
Invalid input:  ///\\\\/// # both slash and backslash are used by the output.

• The output must use the four characters described above and only those four. Alternatively, you may use - instead of the macron (¯)

• The macron (upper character) has a codepoint of 175, but you may count it as one byte.

This is , so the shortest code in bytes wins.

• I like the test cases, but could you also describe the algorithm? (if I'm understanding correctly, change 1s to macrons, 0s to underscores, _¯ to _/, and ¯_ to \_) – Wezl May 17 at 14:59
• This isn't "ascii-art" as a macron (¯) isn't ASCII. Additionally, you should provide an explanation as when to convert to / and . It seems to be at the first and last 1s of each row, but that isn't clear – caird coinheringaahing May 17 at 15:03
• I think this is a cool challenge, but unfortunately it's underspecified right now. A description of the actual algorithm to generate the output is needed. Also, ^; it's fine to include that but it can't be ascii-art in that case and I'd recommend allowing answers to include it for 1 byte, or just use - or something – hyper-neutrino May 17 at 15:07
• I've fixed the spec for you since I think it's quite obvious what you mean, so I've reopened this. Please let me know if anything is incorrect with this. For the future, I would definitely recommend using the Sandbox; it's a good way to get great ideas like this into clearly formatted great challenges. +1 to this though! – hyper-neutrino May 17 at 15:34
• The test case 1111 -> /¯¯\  does not match the spec from the first paragraph. It implies there is another rule like "for the first and last characters, convert ¯ to / and \ . Is that correct? – Jonah May 17 at 15:41

# sed 4.2.2, Score 25

26 bytes, but scoring ¯ as 1, as per note in challenge.

s|1(1*)1|/\1\\|g
y/01/_¯/


Try it online!

# Jelly, 16 bytes

Ż<ƝoḤU)⁺ị“\/Ø-_”


Try it online!

Uses hyphens instead of macrons. Takes a good deal of inspiration from hyper-neutrino's answer, so don't forget to send him some votes. Feels like there's got to be some way to shave a byte off the string at the end, with the right replacement for oḤ...

      )            For each line,
⁺           twice:
Ż                  prepend a 0,
Ɲ                then for each pair of neighboring elements
<                 is the second greater than the first?
o               Replace zeroes with corresponding elements of
Ḥ              the line doubled,
U             and reverse.
ị          Modular 1-index into
“\/Ø-_    "\/Ø-_".
(0 -> _, 1 -> \, 2 -> /, 4 -> -)


# Retina 0.8.2, 26 19 bytes

1(1*)1
/$.1$*¯\
0
_


Try it online! Link includes test cases. Edit: Saved 7 bytes with inspiration from @DigitalTrauma. Explanation:

1(1*)1
/$.1$*¯\


Replace a run of 1s with a run of ¯s between / and \.

0
_


Replace 0s with _s.

(Note that Retina uses the ISO-8859-1 code page, so ¯ is 1 byte anyway.)

• @DigitalTrauma Thanks, I've actually used a more Retina-y approach for the same byte count. – Neil May 17 at 17:46

# Perl 5 (-p -Mutf8), 25 bytes, score 24

s|1(1*)1|/\1\\|g;y;01;_¯


Try it online!

Same as Digital Trauma's sed answer, except the trick using semicolon delimiter the last character can be removed.

# ///, 80 bytes

/0/_//1/a//aaa/a-a//-aa/--a//aa-/a--//-a-/---//a-/\\\/-//-a/-\\\\//aa/\\\/\\\\/


Try it online!

Uses - instead of the macron, as it is allowed.

I'm marking it as 80 bytes because of the required newline at the end of the input.

# Python 3.8 (pre-release), 80 bytes (but actually 79 because ¯ is counted as a 1 byte char in this challenge)

import re
while r:=re.sub:print(r(*"0_",r(*"1¯",r("1(1*)1",r"/\1\\",input()))))


Try it online!

Because we love re.sub :)

## Old solution : 94 bytes (but actually 93, you know the song ...)

I don't know why but I thought a pure vanilla python solution would beat a solution using regex ... I was wrong.

while r:=str.replace:print(r(r(r(r(f"0{input()}0","10","\\0"),"01","0/")[1:-1],*"1¯"),*"0_"))


Try it online!

Nothing too crazy here, just a few str.replace, and some str.replace and even more str.replace

# Jelly, 18 bytes

ŒgḤ1¦€N0¦€)ị“-/\_”


Try it online!

Inputs a matrix of 0 and 1s, outputs a list of lines. Uses - instead of a macron

## How it works

ŒgḤ1¦€N0¦€)ị“-/\_” - Main link. Takes a matrix M on the left
)        - Over each row R in M:
Œg                 -   Group adjacent equal elements in R
€             -   Over each group G in R:
Ḥ                -     Double:
1¦              -     The first value
€         -   Over each group G in R:
N            -     Negate:
0¦          -     The last value
For zeros, these are left unchanged.
For ones, the first becomes 2 and the last -1
“-/\_” - Yield the string "-/\_"
ị       - Index, 1 based and modularly. This means that:
1 or -3 -> -
2 or -2 -> /
3 or -1 -> \
4 or  0 -> _

• – hyper-neutrino May 17 at 15:31
• (+1) how did you answer? – Recursive Co. May 17 at 15:31
• @ophact I didn't reload the page – caird coinheringaahing May 17 at 15:32
• @cairdcoinheringaahing but, once, I was writing an answer to an SO question which was closed while I was typing. Inspecting and trying to make the button clickable did not seem to work and so I could not post. – Recursive Co. May 17 at 15:33

# Jelly, 18 bytes

Ż;0ṡ3Ḅ)ị“_./__\-_”


Try it online!

Uses - instead of the macron

Ż;0ṡ3Ḅ)ị“_./__\-_”  Main Link; takes a matrix of bits and outputs a list of lines
)             For each row
Ż                   Prepend 0
;0                 Append 0
ṡ3               Get overlapping slices of length 3
Ḅ              Convert from binary
// basically, the center of the 3-slice is the character itself
// and we need the left and right context to determine if it needs
// to be changed. So ___, __-, -__, and -_- (0, 1, 4, 5) become _,
// _-- (3) becomes /, --_ (6) becomes \, and --- (7) stays as -
ị“_./_.\-_”  index into "_./_.\-_", so 1=_ 3=/ 4=_ 5=_ 6=\ 7=- 0=_
// note that Jelly is 1-indexed and indexes wrap around


# JavaScript (ES6), 54 bytes*

* by counting the macron as 1 byte, as allowed in this challenge

s=>s.replace(/./g,(c,i)=>'_/¯\\'[c*=!+s[i+1]-~s[i-1]])


Try it online!

# Excel (Insider Beta), 139 96 bytes

=LET(s,LAMBDA(t,x,y,SUBSTITUTE(t,x,y)),s(s(s(s(s(A2,101,"\_/"),10,"\_"),0&1,"_/"),0,"_"),1,"-"))


Had to spend quite a few bytes shortening the SUBSTITUTE function. Originally, I thought you had to adapt to any two characters which is what I did below.

=LET(s,LAMBDA(t,x,y,SUBSTITUTE(t,x,y)),a,LEFT(A2),b,LEFT(s(s(A2,a,""),"
","")),s(s(s(s(s(A2,b&a&b,"\_/"),b&a,"\_"),a&b,"_/"),a,"_"),b,"-"))


# 05AB1E, 24 bytes

εγεS¬·0ǝR¬(0ǝR}˜"_¯/\"sè


Try it online! Takes input as a list of lines of ones and zeros and outputs as a list of lists of characters in each line.

εγεS¬·0ǝR¬(0ǝR}˜"..."sè  # trimmed program
# implicit input...
ε                        # with each element replaced by...
è  # list of characters in...
"..."s   # literal...
è  # with indices in...
˜     s   # flattened...
γ                       # list of groups of consecutive equal elements in...
# (implicit) current element in map...
ε                      # with each element replaced by...
R           # reversed...
R                # reversed...
S                     # list of characters in...
# (implicit) current element in map...
ǝ                 # with element at index...
0                  # literal...
ǝ                 # replaced with...
¬                    # first element of...
S                     # list of characters in...
# (implicit) current element in map...
·                   # doubled...
ǝ           # with element at index...
0            # literal...
ǝ           # replaced with...
¬              # first element of...
R                # reversed...
S                     # list of characters in...
# (implicit) current element in map...
ǝ                 # with element at index...
0                  # literal...
ǝ                 # replaced with...
¬                    # first element of...
S                     # list of characters in...
# (implicit) current element in map...
·                   # doubled...
(             # negated
}         # exit map
# (implicit) exit map
# implicit output


R} can also be a }í with no change in functionality: Try it online!

# Pip-rl, 21 "bytes"

gR+X1'/.TM_.'\TRt"¯_"


Try it online!

### Explanation

g                      With -r flag, g is a list of all lines from stdin
R                     In each line, replace
+X1                   regex match of one or more 1's
with this callback function:
TM_              Trim the first and last characters from the match
'/.                 Prepend /
.'\           Append \
TR       Transliterate
t      10
"¯_"  into ¯_
Autoprint, one list element per line (-l flag)


# VyxalaṠD, 21 bytes

-1 from Aaron Miller

ƛĠƛ⌊ḣ$NpṫdJ_¯\/$İ;f


Try it Online!

Heavily inspired by @caird coinheringaahing's Jelly answer.
Outputs a list of lines containing a list of characters in each line. Uses the actual macron!

ƛĠƛ⌊ḣ$NpṫdJ_¯\/$İ;f
ƛ                       For each line of (implicit) input...
Ġƛ                ;     For each group of consecutive characters...
⌊                      Convert each character to an integer (so double and negate work)
N                   Negate...
ḣ$p the first element of the group. d Double... ṫ J the last element of the group. İ Index each element... _¯\/$          in "_¯\/" (negative indices start from the back)
f    Flatten the list of groups to a lists of chars

• 21 bytes – Aaron Miller May 18 at 17:27
• You may as well use the D flag and add an overline... – A username May 31 at 5:51

# J, 48 44 43 41 bytes

'_^/\'{~(>./@,+:@g&.|.,:3*g=.1=2-/\,&0)"1


Try it online!

# AWK, 56 bytes, 54 by the rules

gsub(0,"_")gsub(1,"/\\")gsub(/\\\//,"¯")gsub("/¯","/")


Try it online!

Substitutes: all 0 to _; all 1 to /\; all \/ to ¯; and, finally, all /¯ to /.

# AWK, 52 bytes, 51 by the rules

gsub("01","0/")gsub(10,"\\0")gsub(0,"_")gsub(1,"¯")


Try it online!

Thanks to DLsoc for a 52 bytes/51 characters version.

• @DLosc Nice! The simpler, the better! Thanks for sharing that. I'll edit my answer, giving credit to your code. I tried using another algorithm, but with no success. – Pedro Maimere May 18 at 15:54

# 05AB1E, 17 bytes

γε¬i¦¦…/ÿ\]JT„¯_‡


I/O as a multiline string.

Try it online.

Explanation:

γ           # Split the (implicit) input-string into equal adjacent parts
#  i.e. "0110\n1111" → ["0","11","0","\n","1111"]
ε          # Map each part to:
¬         #  Get its first character (without popping)
i        #  If this is a 1:
¦¦      #   Remove two characters from this string
…/ÿ\  #   Surround it with leading "/" and trailing "\"
]          # Close both the if-statement and map
#  → ["0","/\","0","\n","/11\"]
J         # Join everything back together
#  → "0/\0\n/11\"
T   ‡    # Then transliterate the characters "1" and "0"
„¯_     # to the characters "¯" and "_"
#  → "_/\_\n/¯¯\"
# (after which the result is output implicitly)


# Charcoal, 20 bytes

ＷＳ⟦⪫Ｅ⪪ι0∧κ⪫/\×¯⁻Ｌκ²_


Try it online! Link is to verbose version of code. Explanation:

ＷＳ⟦


Loop over each input string and print each output on a new line until an empty line is reached. (String array input format would have saved a byte.)

⪫Ｅ⪪ι0∧κ⪫/\×¯⁻Ｌκ²_


Split each string on 0s, then replace each (non-empty) run of 1s with a run of ¯s wrapped in / and \, finally joining with _s.

# Stax, 19 bytes

√E6∙²δ♪₧♂─Ç,áR0Z◄@╖


Run and debug it

A regex based solution similar to the Pip and sed answers. Takes a full multiline string.

# JavaScript (Node.js), 71 65 61 bytes

n=>n.replace(/./g,(e,i)=>+e?+n[i+1]?+n[i-1]?'-':'/':'\\':'_')


Try it online!

## How it works

Replaces every letter. For each letter in question: if the numerical representation is falsy (0) then replace with _, otherwise use a simple ternary to find the correct character to use. Uses - instead of macron, you know, just because. Saved 6 bytes by reorganizing and removing assignment to unused a variable. Then saved 4 thanks to a username by entirely getting rid of variables.

• Why the b? -4 bytes – A username May 18 at 5:33
• @Ausername thanks, did not realize that b was unused. – Recursive Co. May 18 at 5:36

# Mathematica, 74 bytes

StringReplace[#,{"101"->"\_/","01"->"_/","10"->"¯\\","0"->"_","1"->"¯"}]&