30
\$\begingroup\$

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:
        _______
       / #  #  
      /  #  #  
\    /   ##### 
 \  /       #  
  \/        #  
\$\endgroup\$
  • 3
    \$\begingroup\$ V is gonna do well in this one \$\endgroup\$ – caird coinheringaahing Jul 25 '17 at 21:09
  • 16
    \$\begingroup\$ a mathematician who really hates TeX, LaTeX etc I almost quit reading right there \$\endgroup\$ – Luis Mendo Jul 25 '17 at 23:04
  • 5
    \$\begingroup\$ You are working I almost quit reading right there \$\endgroup\$ – Arnauld Jul 26 '17 at 17:46

13 Answers 13

7
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ @StepHen Hm. It works but / would work too. Thanks. \$\endgroup\$ – HyperNeutrino Jul 25 '17 at 21:29
  • \$\begingroup\$ Same for i+l//2 \$\endgroup\$ – Stephen Jul 25 '17 at 21:31
  • \$\begingroup\$ The underscores need to stretch one character extra on either side. \$\endgroup\$ – Neil Jul 26 '17 at 0:15
  • \$\begingroup\$ 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])). \$\endgroup\$ – Jonathan Allan Jul 26 '17 at 2:14
6
\$\begingroup\$

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)

\$\endgroup\$
5
\$\begingroup\$

Charcoal, 32 bytes

WS⊞υιP⪫υ¶↖P×_⁺²⌈EυLι↙↙Lυ↑↖÷⁺¹Lυ²

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

WS⊞υιP⪫υ¶↖P×_⁺²Lθ↙↙Lυ↑↖÷⁺¹Lυ²
\$\endgroup\$
  • 3
    \$\begingroup\$ @LuisMendo Charcoal is getting old... \$\endgroup\$ – Erik the Outgolfer Jul 26 '17 at 10:29
  • \$\begingroup\$ @EriktheOutgolfer D: old how \$\endgroup\$ – ASCII-only Aug 10 '17 at 10:34
  • \$\begingroup\$ @ASCII-only Well SOGL is newer and better, so...no offense to Charcoal though it still wins a lot. \$\endgroup\$ – Erik the Outgolfer Aug 10 '17 at 10:38
  • \$\begingroup\$ @EriktheOutgolfer but how is it better :( \$\endgroup\$ – ASCII-only Aug 10 '17 at 10:54
  • \$\begingroup\$ IMO it's kinda like saying Haskell is newer and better so Haskell > C# although it still wins a lot \$\endgroup\$ – ASCII-only Aug 10 '17 at 10:55
5
\$\begingroup\$

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!

\$\endgroup\$
  • 2
    \$\begingroup\$ 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.) \$\endgroup\$ – officialaimm Jul 26 '17 at 6:20
  • 2
    \$\begingroup\$ @officialaimm, thank you for the welcome! To practice for future problems I have updated and included TIO link \$\endgroup\$ – Conner Johnston Aug 9 '17 at 0:10
3
\$\begingroup\$

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!

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

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
\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ @ETHproductions Sadly that won't work since U is an array and not a string. \$\endgroup\$ – Justin Mariner Jul 26 '17 at 1:05
  • \$\begingroup\$ Ah, darn it.... \$\endgroup\$ – ETHproductions Jul 26 '17 at 1:06
1
\$\begingroup\$

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`
)

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

Perl 5, 177 185 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!)
\$\endgroup\$
  • \$\begingroup\$ 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(..){..})... \$\endgroup\$ – Dada Jul 27 '17 at 11:31
  • \$\begingroup\$ Long time since I used perl, thanks! But I tried with x$f and couldn't get it to work :o trying again now... \$\endgroup\$ – Felix Palmen Jul 27 '17 at 11:34
  • \$\begingroup\$ Uh and I just found a bug in both versions ... give me some time to fix this ;) \$\endgroup\$ – Felix Palmen Jul 27 '17 at 11:44
0
\$\begingroup\$

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;}
\$\endgroup\$
0
\$\begingroup\$

Dyalog APL, 95 bytes

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

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
a[999],i,j,k,l,m,n,q;char c;pad(a){m=P;if(a&&!k){m-=1;}for(n=0;n!=m;n++){q=32;if((!a||k)&&n==c){c--;q=47;}else if((P-c+1)>j/2+1&&(P)/2-n==c-2){q=92;}p(q);}}int main(){k=i=j=0;x:if(read(0,&c,1)){if('\n'==(a[i++]=c)){if(!j){l=i;}j++;}goto x;}i--;if('\n'==a[i-1]){i--;}else{j++;}c=P-2;for(;k!=i;k++){if(!k||a[k]==10){if(a[k]==10){p(10);}pad(1);if(!k){l++;while(l-->0){p(95);}p(10);pad(0);}if(a[k]==10){continue;}}p(a[k]);}}
\$\endgroup\$
0
\$\begingroup\$

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!

\$\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.