16
\$\begingroup\$

Write a program or function which, given an input string and a standard deviation σ, outputs that string along the normal distribution curve with mean 0 and standard deviation σ.

Normal distribution curve

The y coordinate of each character c is:

enter image description here

where σ is given as input, and where x is the x axis coordinate of c.

  • The character in the center of the string has x = 0. If the string's length is even, either of the two middle characters can be chosen as the center.
  • Characters are separated by steps of 0.1 (e.g. the character to the left of the center one has x = -0.1, the one to the right of the middle one has x = 0.1, etc.).

Printing the string

  • Lines, like characters, are separated by steps of 0.1.
  • Each character is printed on the line with the y value that is closest to its own y value (if the value is precisely in between the values of two lines, choose the one with the biggest value (just like how round usually returns 1.0 for 0.5)).
  • For example, if the y coordinate of the center value (i.e. the maximum value) is 0.78 and the y coordinate of the first character is 0.2, then there will 9 lines: the center character being printed on line 0 and the first character being printed on line 8.

Inputs and outputs

  • You may take both inputs (the string and σ) as program arguments, through STDIN, function arguments or anything similar in your language.
  • The string will only contain printable ASCII characters. The string can be empty.
  • σ > 0.
  • You may print the output to STDOUT, in a file, or return it from a function (as long as it is a string and not say a list of strings for each line).
  • A trailing new line is acceptable.
  • Trailing spaces are acceptable as long as they don't make the line exceed the last line in length (so no trailing space is acceptable on the last line).

Test cases

σ    String

0.5  Hello, World!

     , W     
   lo   or   
  l       l  
 e         d 
H           !



0.5  This is a perfectly normal sentence

                tly                
              ec    n              
             f       o             
            r         r            
           e           m           
          p             a          
        a                l         
      s                    se      
This i                       ntence



1.5  Programming Puzzles & Code Golf is a question and answer site for programming puzzle enthusiasts and code golfers.

                                                d answer site for p                                               
                                      uestion an                   rogramming                                     
                      Code Golf is a q                                        puzzle enthusia                     
Programming Puzzles &                                                                        sts and code golfers.



0.3  .....................

          .          
         . .         

        .   .        

       .     .       


      .       .      

     .         .     
    .           .    
   .             .   
...               ...

Scoring

This is ,

                 nsw                 
                a   er               
              t                      
             s         i             
            e           n            
           t                         
         or               by         
       sh                   te       
so the                        s wins.
\$\endgroup\$
  • \$\begingroup\$ Related. Related. \$\endgroup\$ – Martin Ender Jul 8 '16 at 12:50
  • \$\begingroup\$ Related. \$\endgroup\$ – Fatalize Jul 8 '16 at 12:51
  • 1
    \$\begingroup\$ I think the last test case should have 3 dots in the top row, not 1. \$\endgroup\$ – addison Jul 8 '16 at 16:12
  • \$\begingroup\$ @addison I don't have my reference implementation on this computer but I don't know why Mego get's a different result. The result he obtains with his code seems very "blocky". Ignore that test case for the moment I guess. \$\endgroup\$ – Fatalize Jul 8 '16 at 16:24
  • 1
    \$\begingroup\$ @TheBikingViking I'll let that pass, that's fine. \$\endgroup\$ – Fatalize Jul 9 '16 at 16:39
2
\$\begingroup\$

Python 3 with SciPy, 239 233 bytes

from scipy import stats,around,arange
def f(s,t):
 l=len(t);p=[];y=around(stats.norm.pdf((arange(l)-l//2)*.1,scale=s),1)*10
 for i in range(l):p+=[[' ']*(max(y)-y[i])];p[i]+=[t[i]]+[' ']*(y[i]-y[0])
 for j in zip(*p):print(*j,sep='')

A function that takes input via argument of standard deviation s and string t, and prints the result to STDOUT.

How it works

from scipy import stats,around,arange  Import the statistics, rounding and range functions
                                       from SciPy
def f(s,t):                            Function with input standard deviation s and string
                                       t
l=len(t);p=[]                          Define the much-used length of t as l and initialise
                                       the print values list p
arange(l)                              Generate a list of integer x values in [0,l)...
...-l//2*.1                            ...and scale such that 0 is at the middle character
                                       and the x-step is 0.1
stats.norm.pdf(...,scale=s)            Generate a list containing the y values for each x
                                       value by calling the normal probability
                                       density function scaled with s...
y=around(...,1)                        ...round all values to 1 decimal place...
...*10                                 ...and multiply by 10 to give the vertical index of
                                       each character
for i in range(l):...                  For all characters in t...
p+=[[' ']*(max(y)-y[i])]               ..add the number of lines below the character as
                                       spaces...
p[i]+=[t[i]]+[' ']*(y[i]-y[0])         ...add the character and the number of lines above
                                       the character as spaces

This leaves p containing a list for each desired output line, but transposed.

for j in zip(*p):...                   For every output line in the transpose of p...
print(*j,sep='')                       ...print the output line

Try it on Ideone

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

Ruby: 273 254 Bytes

->n,s{j,o,g,r,l=-(n.size/2),[],0,{}
n.gsub(/./){(r[((2*Math::PI)**-0.5*10*Math.exp(-(j/1e1)**2/2/s/s)/s).round]||="")<<$&
j+=1}
r.sort.map{|y, c|o<<(l ?$/*(y-l-1):"")+(" "*g)+(c[0,(h=c.size)/2])+(" "*(n.size-g*2-h))+(c[h/2,h])
g+=h/2
l=y}
puts o.reverse}

A huge thanks to Kevin Lau for saving 18 bytes!

\$\endgroup\$
  • 1
    \$\begingroup\$ Lambdas don't need parens: ->n,s{... is fine. You don't need brackets when assigning multiple variables: o,g,r,l=[],0,{} works just fine. $/ can be used in place of ?\n. Order of operations means you don't have to put all your multiplies on line 5 in parens. puts automatically unfolds arrays and separates them with newlines when printing. n.gsub(/./){... beats out n.each_char{... by a bit because you can take out the |c| and put $& where any mention of c was. Make your hash values strings (start with ||="" not ||=[]) and you can change c[...]*"" to c[...] \$\endgroup\$ – Value Ink Jul 8 '16 at 20:22

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.