# Square root of ASCII art

You are working as an intern for a mathematician who really hates TeX, LaTeX, etc. So much so that he has decided to abandon all typesetting whatsoever and make you do all the formatting in ASCII. You got tired of this after a while and decided to start automating parts of it, starting with square roots.

Here's how a square root is made:

###  this is the input
###
###

_____  put a row of underscores stretching one character off either side on top
###
###
###

_____  put a diagonal of slashes in front going the height of the input
/ ###
/  ###
/   ###

_____ put a diagonal of backslashes in front of that, going up half of the input's height rounded up
/ ###
\  /  ###
\/   ###


And that's it!

### Rules

You are to make a program or function that takes in a string, list of strings (i.e. lines), or array of characters, and outputs the input transformed according to the description above (not necessarily by the exact same order or process)

You may assume that the input is rectangular if preferred. Trailing whitespace is neither required nor disallowed.

This is , so the shortest answer in bytes wins.

### Examples:

Input:
40
Output:
____
\/ 40

Input:
____
\/ 40
Output:
________
/   ____
\/  \/ 40

Input:
/|
|
|
_|_
Output:
_____
/ /|
/   |
\  /    |
\/    _|_

Input:
#  #
#  #
#####
#
#
Output:
_______
/ #  #
/  #  #
\    /   #####
\  /       #
\/        #

• V is gonna do well in this one Jul 25, 2017 at 21:09
• a mathematician who really hates TeX, LaTeX etc I almost quit reading right there Jul 25, 2017 at 23:04
• You are working I almost quit reading right there Jul 26, 2017 at 17:46

# SOGL V0.12, 27 bytes

1w⁄2+╔*00žl»╚;lH╚@Κ№↕h┼№↕;┼


Try it Here! (→ added for ease-of-use; the program expects the input on stack)

# Python 2, 196 bytes

x=Q=input()
l=len(x)
k=(l+1)/2
q=l+k
x=[[' ']*(q+1)+list(y)for y in x]
for i in range(k):x[i+l/2][i]='\\'
for j in range(l):x[j][q-j-1]='/'
print'\n'.join([' '*q+'_'*(2+len(Q[0]))]+map(''.join,x))


Try it online!

-2 bytes thanks to Step Hen

-13 bytes thanks to Jonathan Allan

• @StepHen Hm. It works but / would work too. Thanks. Jul 25, 2017 at 21:29
• Same for i+l//2 Jul 25, 2017 at 21:31
• The underscores need to stretch one character extra on either side.
– Neil
Jul 26, 2017 at 0:15
• You can take input as a list of strings (Python 2's input() evaluates the raw input). Also '_'*len(Q[0])+'__' is '_'*(2+len(Q[0])). Jul 26, 2017 at 2:14

# Python 3, 138 147 Bytes

def f(l):h=len(l);w=len(l[0]);c=int(h/2);print('\n'.join([(h*2-c)*' '+w*'_']+[(i*' '+'\\'+(h-i-1)*2*' '+'/'+i*' ')[c:]+s for(i,s)in enumerate(l)]))


Variable 'l' is a list of strings, each string a line. Readable Version:

def f(l):
height = len(l)
width = len(l[0])
half_height_floor = int(height / 2)

print((height * 2 - half_height_floor) * ' ' + width * '_')

for (index, line) in enumerate(l):
#build a V based on the location of the line
#surrounding V whitespace
outer_space = index * ' '

#inner V whitespace
inner_space = (height - index - 1) * 2 * ' ' #inner v space

#complete V
v = outer_space + '\\' + inner_space + '/' + outer_space

#left half_height_floor chars removed
v_chopped = v[half_height_floor:]

print(v_chopped + line)


Forms a square root symbol with a complete V then shaves off the left accordingly.

Try it Online!

• Hi, Welcome to PPCG. Nice first answer, but this is a snippet, since it is assuming the variable l as input. You must also include the part where l is input, either as a function parameter or input() function, etc. (P.S. your answer also seems to be lacking a few white-space-padding.) Jul 26, 2017 at 6:20
• @officialaimm, thank you for the welcome! To practice for future problems I have updated and included TIO link Aug 9, 2017 at 0:10

# Charcoal, 32 bytes

ＷＳ⊞υιＰ⪫υ¶↖Ｐ×_⁺²⌈ＥυＬι↙↙Ｌυ↑↖÷⁺¹Ｌυ²


Try it online! Link is to verbose version of code. 29-byte version that assumes rectangular input:

ＷＳ⊞υιＰ⪫υ¶↖Ｐ×_⁺²Ｌθ↙↙Ｌυ↑↖÷⁺¹Ｌυ²

• @LuisMendo Charcoal is getting old... Jul 26, 2017 at 10:29
• @EriktheOutgolfer D: old how Aug 10, 2017 at 10:34
• @ASCII-only Well SOGL is newer and better, so...no offense to Charcoal though it still wins a lot. Aug 10, 2017 at 10:38
• @EriktheOutgolfer but how is it better :( Aug 10, 2017 at 10:54
• IMO it's kinda like saying Haskell is newer and better so Haskell > C# although it still wins a lot Aug 10, 2017 at 10:55

# Python 2,  131  130 bytes

x=input()
n=len(x)
s=" "
for v in[s*2*n+"_"*(2+len(x[0]))]+[s*i+"\\"+s*2*(n+~i)+"/"+s*-~i+r for i,r in enumerate(x)]:print v[n/2:]


A full program taking a list of lines as input with the rectangular-only allowance (actually that the first line is one of the longest).

Try it online!

# Java 8, 244 bytes

A very long solution, but probably close to the shortest for Java. This lambda takes lines of input as a String[] and returns a String. All lines must have the same length.

Based on the example outputs, I assumed that there's no need to append a space to each line in the input, so the program doesn't.

Thanks to Jonathan Allan for reminding me about the ~ operator.

l->{int h=l.length,w=l[0].length(),a=h/2,i=w+3,x=h+a+h%2;String s="",t=s;for(;--i>0;)t+="_";for(;i++<x;)s+=" ";t=s+t;for(i=0;i<h;)t+="\n"+s.substring(0,i<a?x+~i:i-a)+(i<a?"":"\\"+s.substring(0,(h+~i)*2))+"/"+s.substring(0,i+1)+l[i++];return t;}


Try It Online

## Ungolfed

l -> {
int
h = l.length,
w = l[0].length(),
a = h / 2,
i = w + 3,
x = h + a + h % 2
;
String
s = "",
t = s
;
for (; --i > 0; )
t += "_";
for (; i++ < x; )
s += " ";
t = s + t;
for (i = 0; i < h; )
t +=
"\n"
+ s.substring(0, i < a ? x + ~i : i - a)
+ (i < a ? "" : "\\" + s.substring(0, (h + ~i) * 2))
+ "/"
+ s.substring(0, i + 1)
+ l[i++]
;
return t;
}


## Acknowledgments

• -2 bytes thanks to Kevin Cruijssen

# Vyxala, 67 bytes

L3*½⌈ð*₴⁰hL⇧\_*,ƛ¥⁰L½⌊-:0≥[:ð*\\+₴⁰L½⌈ε‹|_⁰L½⌈]&›ð*₴⁰L¥εð*\/¥ð*++₴,


Try it Online!

Don't ask how it works. It's a giant mess.

# Vyxal, 40 32 bytes

ẏṘ\\$꘍øm↵:IǏfL:£Nvȯ$Z¥?hL⇧\_*꘍p⁋


-8 bytes from porting 05AB1E

# Japt, 46 bytes


l *2
£Vç hY'\ h~Y'/ +S+XÃuVç +'_p2+Ug l¹msV/4


Leading newline is part of the program. Input and output is an array of strings representing lines.

Try it online! using the -R flag to join the resulting array with newlines.

• @ETHproductions Sadly that won't work since U is an array and not a string. Jul 26, 2017 at 1:05
• Ah, darn it.... Jul 26, 2017 at 1:06

## JavaScript (ES6), 140 bytes

Takes input as an array of strings / returns an array of strings.

a=>[a[0].replace(/./g,'_'),...a].map((r,y)=>[...a,...a].map((_,x)=>x-y+1|y-.5<l/2?l*2-x-y?' ':'/':'\\',c=y?' ':'_').join+c+r+c,l=a.length)


### Test cases

let f =

a=>[a[0].replace(/./g,'_'),...a].map((r,y)=>[...a,...a].map((_,x)=>x-y+1|y-.5<l/2?l*2-x-y?' ':'/':'\\',c=y?' ':'_').join+c+r+c,l=a.length)

console.log(
f([
'40'
]).join\n
)

console.log(
f([
'  ____',
'\\/ 40 '
]).join\n
)

console.log(
f([
'/| ',
' | ',
' | ',
'_|_'
]).join\n
)

console.log(
f([
'#  # ',
'#  # ',
'#####',
'   # ',
'   # '
]).join\n
)

# Perl 5, 177185 160 bytes

$s=$f=int((@t=<>)*1.5+.5);print" "x$f;print"_"x length$t[0];print"_
";$b=-int(@t/2);for(0..$#t){--$s;print$_==$s?"/":$_==$b?"\\":" " for 0..$f;print$t[$_];++$b}  Try it online! Changelog: • needed more bytes to fix a bug (it assumed a square input first) • fixed another bug and used some tips from comments (thanks Dada!) • Shortened to 132 bytes. I let you have a look at what I did. The big lines: <> instead of <STDIN>, print" "x$f instead of for(1..$f){print" "}, using xxx for yyy instead of for(yyy){xxx}, using $_ in the for loop instead of explicit variables (for$i(..){..})... – Dada Jul 27, 2017 at 11:31 • Long time since I used perl, thanks! But I tried with x$f and couldn't get it to work :o trying again now... Jul 27, 2017 at 11:34
• Uh and I just found a bug in both versions ... give me some time to fix this ;) Jul 27, 2017 at 11:44

# C (clang), 169 151 bytes

-18 thanks to @ceilingcat

#define P printf("%*c"
i;k;f(**l,c){P,i=c+c-c/2,32);for(k=strlen(*l)+3;--k;)P,1,95);for(;P,1,10),k<c;P"%s",k,32,*l++))P,i-k-P,k++<c/2?0:k-c/2,92),47);}


Try it online!

## C++, 291 bytes

The function assumes that all the strings in the vector passed as parameter have the same length

#include<vector>
#include<string>
#define S std::string
#define T size()
void f(std::vector<S>&c){c.insert(c.begin(),S(c[0].T+1,'_'));int i,j=0;for(i=1;i<c.T;++i){c[i]='/'+S(i,' ')+c[i];if(i>=c.T/2)c[i]='\\'+S((c.T-i-1)*2,' ')+c[i];}for(auto&a:c)j=j>a.T?j:a.T;for(auto&a:c)a=S(j-a.T,' ')+a;}


# Dyalog APL, 95 bytes

{((' '/⍨y+x),'_'/⍨2+⊃⌽⍴⍵)⍪⍉(x-y)↓⍉(⊖(x(-x)↑⌽y y⍴'\',' '\⍨y←⌈x÷2),x x⍴'/',' '\⍨x←⊃⍴⍵),' ',⍵,' '}


Try it online!

C, 485 bytes

This program takes up to 999 characters from standard input and reads them into an array. It prints them 1 at a time to standard output with the changes your challenge indicated. It assumes the input is rectangular.

#include<stdio.h>
#define p(a)putc(a,stdout);
#define P j+j/2+1


# Perl 5, 159 bytes

@a=map{$m=(y///c)>$m?y///c:$m;$_}<>;$_=$"x($l=@a/2-.5).'\\/'.$"x@a;for$i(1..@a){$a[-$i]=$_.$a[-$i];s| \\|\\ |;s|/ | /|;$i>$l&&y/\\/ /}chop;say$_.'_'x++$m,\$/,@a


Try it online!

# Canvas, 26 bytes

Ｌ├_×；∔ｒ↔ｌ╷＼ ；∔＋ｌ½：／； ＊；∔＋↔


Try it here!

# 05AB1E, 35 bytes

ā<R'\úíº.c.BD2äĆ˜g©δ.£søIнgÌ'_×®úš»


Input as a rectangular list of strings-lines (rectangular isn't completely necessary, as long the first line is the longest).

Explanation:

ā             # Push a list in the range [1, (implicit) input-length]
<            # Decrease each by 1 to the range [0, length)
R           # Reverse it to the range (length, 0]
'\        '# Push string "\"
í       # Reverse each, so the spaces are trailing
º      # Mirror each line
.c    # Centralize (implicitly joins by newlines)
.B  # Box it (split on newlines, and add trailing spaces)
D             # Duplicate it
2ä           # Split it into two equal-sized parts (where the first is longer
# for odd-length lists)
Ć          # Enclose: append its own head
˜         # Flatten
g        # Pop and push the length
©       # Store it in variable ® (without popping)
δ      # Map over each string:
.£    #  Only leave the last ® amount of characters
s             # Swap so the input-list is at the top
ø            # Create pairs of the two lists
Iн          # Push the first line of the input-list
g         # Pop and push its length
Ì        # Increase it by 2
'_×    '# Pop and push a string of that many "_"
®ú   # Pad ® amount of leading spaces
š  # Prepend it to the list
» # Join each inner list by spaces, and then the strings by newlines
# (after which the result is output implicitly)


2äĆ˜g could alternatively be gD;î+ for the same byte-count (length; duplicate; halve; ceil; sum together): try it online.