Divisor skyline

46

6

For any positive integer k, let d(k) denote the number of divisors of k. For example, d(6) is 4, because 6 has 4 divisors (namely 1, 2, 3, 6).

Given a positive integer N, display a "skyline" in ASCII art using a fixed character, such that the height of the "building" located at horizontal position k is d(k) for k = 1, ..., N. See test cases below.

Rules

  • Any non-whitespace character may consistently be used, not necessarily # as shown in the test cases.
  • The algorithm should theoretically work for arbitrarily high N. In practice, it is acceptable if the program is limited by time, memory, data-type size or screen size.
  • Horizontally or vertically leading or trailing spaces or newlines are allowed.
  • Input and output can be taken by any reasonable means.
  • Programs or functions are allowed, in any programming language. Standard loopholes are forbidden.
  • Shortest code in bytes wins.

Test cases

N = 10:

     # # #
   # # ###
 #########
##########

N = 50:

                                               #  
                                   #           #  
                       #     #     #   # #     #  
                       #     #     #   # #     #  
           #     # #   #   # # #   #   # # ##  # #
           #   # # #   #   # # #   #   # # ##  # #
     # # # # ### # ### # ### # ##### ### # ### # #
   # # ### # ### # ### ##### # ##### ### # ### ###
 #################################################
##################################################

N = 200:

                                                                                                                                                                                   #                    
                                                                                                                                                                                   #                    
                                                                                                                       #                                               #           #                    
                                                                                                                       #                       #                       #           #                    
                                                                                                                       #                       #                       #           #           #        
                                                                                                                       #                       #                       #           #           #        
                                                           #           #           #     #     #           #           #     #     #       #   #     #     #   #       #           #           #     # #
                                                           #           #           #     #     #           #           #     #     #       #   #     #     #   #       #           #           #     # #
                                               #           #           #       #   #     #     #           #   #       #     #     #       #   #     #     #   # #     #       #   #           #     # #
                                   #           #           #           #       #   #     #     #   #       #   #       #     #     #       #   #     #     #   # #     #       #   #           #   # # #
                       #     #     #   # #     #     # #   #     #   # #     # #   #   # #     #   # # ##  # # # #     #     # # # #  ## # #   #     # # # #   # #  #  # #   # #   # # # #  ## #  ## # #
                       #     #     #   # #     #     # #   #   # #   # #     # #   #   # #     #   # # ##  # # # #     #     # # # #  ## # #   #     # # # #   # #  #  # #   # #   # # # #  ## #  ## # #
           #     # #   #   # # #   #   # # ##  # # # # #   #  ## # # # #  ## # #   #   # # #   # ### # ##  # # # # ##  #   # # # # #  ## # #   #  ## # ### #   # # ##  # ### ###   # # # # ### #  ## # #
           #   # # #   #   # # #   #   # # ##  # # # # #   #  ## # # # #  ## # ##  #   # # #   # ### # ##  # # # # ##  #   # # # # #  ## # #   #  ## # ### #   # # ##  # ### ###   # # # # ### #  ## # #
     # # # # ### # ### # ### # ##### ### # ### # ### ##### # ##### ### # ##### ### ##### ####### ### # ### # ### ####### ##### ### ##### # ######### # ##### ##### ### # ### ##### # ######### # ### # #
   # # ### # ### # ### ##### # ##### ### # ### ##### ##### # ##### ### # ##### ### ##### ####### ### # ### # ### ############# ### ##### # ######### # ##### ##### ### ##### ##### # ######### # ### # #
 #######################################################################################################################################################################################################
########################################################################################################################################################################################################

Luis Mendo

Posted 2017-05-07T16:31:21.547

Reputation: 87 464

Answers

12

Jelly, 9 bytes

Uses 0 instead of #.

RÆD0ṁz⁶ṚY

Try it online!

Leaky Nun

Posted 2017-05-07T16:31:21.547

Reputation: 45 011

25 minutes and 10 seconds :-) – Luis Mendo – 2017-05-07T16:37:10.107

13I was reading other stuff in the meantime... I'll be faster next time. – Leaky Nun – 2017-05-07T16:37:48.660

7

C, 99 95 92 91 90 bytes

c,l,i,j;f(n){for(j=n;j--;puts(""))for(i=0;i<n;c=!putchar(32|c>j))for(l=++i;l;c+=i%l--<1);}

See it work here.

2501

Posted 2017-05-07T16:31:21.547

Reputation: 748

7

Octave, 41 40 32 bytes

Thanks to @StewieGriffin saved 8 bytes.

@(N)" #"(sort(~mod(k=1:N,k'))+1)

Try it online!

Previous answers:

@(N)" #"(sort(~bsxfun(@mod,k=1:N,k')+1))

Try it online!

@(N)" #"(sort(ismember((k=1:N)./k',k))+1)

Try it online!

Explanation:

N=5;
d = (1:N)./(1:N)'    %divide each of numbers from 1 to N by 1 to N 
                     %a [N by N] matrix created
d =

   1.00   2.00   3.00   4.00   5.00
   0.50   1.00   1.50   2.00   2.50
   0.33   0.66   1.00   1.33   1.66
   0.25   0.50   0.75   1.00   1.25
   0.20   0.40   0.60   0.80   1.00

m = ismember(d,1:N)      %find divisors of each number
m =

  1  1  1  1  1
  0  1  0  1  0
  0  0  1  0  0
  0  0  0  1  0
  0  0  0  0  1

idx = sort(m)                  %sort the matrix

idx =

  0  0  0  0  0
  0  0  0  0  0
  0  0  0  1  0
  0  1  1  1  1
  1  1  1  1  1

" #"(idx+1)     %replace 0 and 1 with ' ' and '#' respectively


   #
 ####
#####

rahnema1

Posted 2017-05-07T16:31:21.547

Reputation: 5 435

1Very nice approach! – Luis Mendo – 2017-05-08T10:34:49.090

2Octave performs singleton expansion implicitly, so @(N)" #"(sort(~mod(k=1:N,k')+1)) saves you a few bytes :) You get a bunch of leading newlines though, I'm not sure what the rules are in that regard. – Stewie Griffin – 2017-05-08T18:22:20.120

1Same bytecount (32): @(N)['',35*sort(~mod(k=1:N,k'))]. – Stewie Griffin – 2017-05-08T18:33:17.980

@StewieGriffin Thanks! I didn't aware of that feature . Is mod(1:N,(1:N).') acceptable in MATLAB? – rahnema1 – 2017-05-08T18:55:48.167

2I think it is possible as of R2016b, but I can't test it myself unfortunately, since I don't have it. – Stewie Griffin – 2017-05-08T19:08:21.433

6

Haskell, 71 bytes

f takes an Int and returns a String.

f m|l<-[1..m]=unlines[[last$' ':drop(m-i)['#'|0<-mod n<$>l]|n<-l]|i<-l]

Try it online!

  • m is the N of the OP (Haskell variables must be lowercase.)
  • The abbreviation l=[1..m] is used in the nested list comprehensions for iterating through all of rows, columns, and potential divisors. This means some extra initial rows filled with whitespace.
  • n is column (also number checked), i is row.
  • ['#'|0<-mod n<$>l] is a list of '#' characters with length the number of divisors of n.

Ørjan Johansen

Posted 2017-05-07T16:31:21.547

Reputation: 6 914

6

Octave, 61 bytes

for i=1:input(''),p(1:nnz(~rem(i,1:i)),i)=35;end,[flip(p),'']

Explanation:

for i=1:input('')         % Loop, for i from 1 to the input value
 p(1:nnz(~rem(i,1:i)),i)=35;end,[flip(p),'']   
% Breakdown:
         ~rem(i,1:i)      % Return true if the remainder of i divided by any of the values
                          % in the vector 1 - i
     nnz(~rem(i,1:i))     % Check how many of them are non-zero
 p(1:nnz(~rem(i,1:i)),i)=35;end   % Assign the value 35 (ASCII for #) to rows 1
                                  % to the number of divisors of i, in column i
end,              % End loop
[flip(p),'']      % Flip the matrix, and concatenate it with the empty string

A few things I wish to highlight

  • Takes the input directly into the loop
    • Doesn't assign the input value to any variable
  • Doesn't initialize any array
    • It creates it on the fly, adding columns and rows as necessary
  • Automatically casts ASCII-value 0 to whitespace (ASCII-32)

What happens inside the loop (suppose input 6)

p =  35
p =
   35   35
    0   35
p =
   35   35   35
    0   35   35
p =
   35   35   35   35
    0   35   35   35
    0    0    0   35
p =
   35   35   35   35   35
    0   35   35   35   35
    0    0    0   35    0
p =
   35   35   35   35   35   35
    0   35   35   35   35   35
    0    0    0   35    0   35
    0    0    0    0    0   35

  1. Starts of as a single 35
  2. Expands one column and one row, to make room for the two divisors of 2
  3. Expands one column, to make room for 3 (only two divisors)
  4. Expands one column and one row, to make room for the 3 divisors (1,2,4)
  5. Expands one column, to make room for 5
  6. Expands one column and one row, to make room for the 4 divisors (1,2,3,6)

Finally we flip it, and converts it to a string, implicitly changing the 0 to 32:

warning: implicit conversion from numeric to char
ans =
     #
   # #
 #####
######

Stewie Griffin

Posted 2017-05-07T16:31:21.547

Reputation: 43 471

5

Python 3, 111 bytes

lambda n:'\n'.join([*map(''.join,zip(*['#'*sum(x%-~i==0for i in range(x))+n*' 'for x in range(1,n+1)]))][::-1])

Try it online!


This produces some leading vertical whitespace

ovs

Posted 2017-05-07T16:31:21.547

Reputation: 21 408

5

C#, 333 281 Bytes

using System.Linq;using C=System.Console;class P{static void Main(){var n=int.Parse(C.ReadLine());var v=new int[n];for(var k=2;k<=n;k++)for(var i=1;i<k;i++)if(k%i==0)v[k-1]++;for(var i=0;i<v.Length;i++)for(var u=v.Max()-v[i];u<v.Max();u++){C.SetCursorPosition(i,u);C.Write("#");}}}

With line breaks:

using System.Linq;
using C = System.Console;

class P
{
    static void Main()
    {
        var n = int.Parse(C.ReadLine());
        var v = new int[n];
        for (var k = 2; k <= n; k++)
            for (var i = 1; i < k; i++)
                if (k % i == 0)
                    v[k - 1]++;
        for (var i = 0; i < v.Length; i++)
            for (var u = v.Max() - v[i]; u < v.Max(); u++)
            {
                C.SetCursorPosition(i, u);
                C.Write("#");
            }
    }
}

While I'm sure this is possible shorter as well, I hope we'll achieve a shorter solution together ;)

Saved 52 Bytes with the help of raznagul

MetaColon

Posted 2017-05-07T16:31:21.547

Reputation: 391

1If you use an int-array instead of a list, you can save a lot of bytes from the using-statement. – raznagul – 2017-05-08T15:06:29.903

@raznagul updated it. – MetaColon – 2017-05-08T15:16:21.583

222 bytes: using System.Linq;using C=System.Console;n=>{var v=new int[n];for(var k=1,i;++k<=n;)for(i=1;i<k;)if(k%i++==0)v[k-1]++;for(var i=0,u;i<v.Length;i++)for(u=v.Max()-v[i];u<v.Max();){C.SetCursorPosition(i, u++);C.Write("#");}}; Compile to an Action, move the increments around and a couple of other minor tweaks. I haven't tested that but it should work. – TheLethalCoder – 2017-05-09T16:21:28.097

@TheLethalCoder I'll test it / update my answer tomorrow. – MetaColon – 2017-05-09T19:08:00.327

5

Mathematica, 99 bytes

{T=DivisorSigma[0,Range@#];Row[Column/@Table[Join[Table[,Max[T]-T[[i]]],$~Table~T[[i]]],{i,1,#}]]}&

for N=50

enter image description here

J42161217

Posted 2017-05-07T16:31:21.547

Reputation: 15 931

Are all those spaces (and newlines) necessary for the code to run? I've never programming Mathematica myself, but in most languages you could remove almost all of those spaces. – Kevin Cruijssen – 2017-05-08T10:40:57.930

this is my first golf. thanks for the tips – J42161217 – 2017-05-08T22:47:02.123

2

No problem, and welcome to PPCG! If you haven't yet, you might find Tips for golfing in <all languages> and Tips for golfing in Mathematica interesting to read through. :) Enjoy your stay.

– Kevin Cruijssen – 2017-05-09T07:14:58.117

The outer curly braces can be changed to round brackets to prevent them from showing in the output, and you can use some infix/prefix syntax to save 2 bytes: (T=0~DivisorSigma~Range@#;Row[Column/@Table[Join[Table[,Max@T-T[[i]]],$~Table~T[[i]]],{i,1,#}]])& – numbermaniac – 2017-05-21T02:13:02.343

5

APL (Dyalog), 19 bytes

⊖⍉↑'#'⍴¨⍨+⌿0=∘.|⍨⍳⎕

Try it online!

 get evaluated input (N)

 1...N

∘.|⍨ division remainder table with 1...N both as vertical and as horizontal axis

0= where equal to zero (i.e. it divides)

+⌿ sum the columns (i.e. gives count of divisors for each number)

'#'⍴¨⍨ use each number to reshape the hash character (gives list of strings)

 mix (list of strings into table of rows)

 transpose

 flip upside down

Adám

Posted 2017-05-07T16:31:21.547

Reputation: 37 779

5

Mathematica, 59 57 bytes

Rotate[Grid@Map[X~Table~#&,0~DivisorSigma~Range@#],Pi/2]&

enter image description here

Ian Miller

Posted 2017-05-07T16:31:21.547

Reputation: 727

Welcome to answering on PPCG, fellow Lego minifig :-) – Luis Mendo – 2017-05-08T11:01:15.687

1Now there's no turning back... – Luis Mendo – 2017-05-08T11:06:52.263

Welcome! Nice to see another Mathematica golfer. This answer isn't entirely valid though because you've hardcoded the input into the snippet. Answers need to be full programs or callable functions (which may be unnamed though). So this can be fixed at no cost by replacing 50 with # and appending &. You can save some bytes with infix notation as well: X~Table~#& and 0~DivisorSigma~Range@# – Martin Ender – 2017-05-08T11:14:47.617

@MartinEnder Thanks. I forgot that bit when I moved from testing to answering. And thanks for the hint about infixing. Its not something I normally use (as I don't really golf). – Ian Miller – 2017-05-08T11:30:05.510

I thought as much. It was more a tongue in cheek comment. Sorry for the confusion. – Ian Miller – 2017-05-08T11:58:21.900

5

Charcoal, 23 22 20 bytes

F…·¹N«Jι⁰Fι¿¬﹪ι⁺κ¹↑#

Try it online! Link is to verbose version of code. Edit: Saved 1 byte by looping k from 0 to i-1 and adding 1 inside the loop. Saved a further two bytes by not storing the input in a variable. Explanation:

F…·¹N       for (i : InclusiveRange(1, InputNumber()))
«           {
 Jι⁰         JumpTo(i, 0);
 Fι          for (k : Range(i))
  ¿¬﹪ι⁺κ¹     if (!(i % (k + 1)))
   ↑#          Print(:Up, "#");
            }

Edit: This 18-byte "one-liner" (link is to verbose version of code) wouldn't have worked with the version of Charcoal at the time the question was submitted: Try it online!

↑E…·¹N⪫Eι⎇﹪ι⁺¹λω#ω

Neil

Posted 2017-05-07T16:31:21.547

Reputation: 95 035

better explanation :P – ASCII-only – 2017-05-10T21:52:04.743

3

05AB1E, 12 bytes

Code:

LÑ€g'#×.BøR»

Explanation:

L             # Create the range 1 .. input
 Ñ            # Get the list of divisors of each
  €g          # Get the length of each element
    '#        # Push a hash tag character
      ×       # String multiply
       .B     # Squarify, make them all of equal length by adding spaces
         ø    # Transpose
          R   # Reverse the array
           »  # Join by newlines

Uses the 05AB1E encoding. Try it online!

Adnan

Posted 2017-05-07T16:31:21.547

Reputation: 41 965

Can't you use ζ instead of .Bø? Also, the character doesn't have to be # – Oliver Ni – 2017-08-09T13:27:38.993

ζ didn't exist back then. – Magic Octopus Urn – 2017-08-09T14:37:16.573

3

Japt, 34 33 16 14 bytes

Saved 17 bytes thanks to @ETHproductions

õ@'#pXâ l÷z w

Try it online!

Luke

Posted 2017-05-07T16:31:21.547

Reputation: 4 675

You can save a lot of bytes by just letting z do the padding: õ_â lã'#pX÷z w – ETHproductions – 2017-05-08T17:05:55.810

Didn't know that padded the strings automatically. Thanks! – Luke – 2017-05-08T18:51:01.107

3

Python 2, 101 bytes

N=input();r=range
for i in r(N,0,-1):print''.join('# '[i>sum(x%-~p<1for p in r(x))]for x in r(1,1+N))

Try it online!

This produces (a lot of) vertically leading whitespace. It prints a total of N lines, the great majority of which will typically be blank.

mathmandan

Posted 2017-05-07T16:31:21.547

Reputation: 943

2

J, 28 bytes

[:|:&.|.[('#',@$~1+_&q:)@-i.

Defines a monadic verb. Try it online!

Explanation

[:|:&.|.[('#',@$~1+_&q:)@-i.  Input is y.
                          i.  Range from 0 to y-1
        [                -    subtracted from y (gives range from y to 1).
         (             )@     For each of the numbers:
                   _&q:         Compute exponents in prime decomposition,
                 1+             add 1 to each,
          '#'  $~               make char matrix of #s with those dimensions,
             ,@                 and flatten into a string.
                              The resulting 2D char matrix is padded with spaces.
[:|:&.|.                      Reverse, transpose, reverse again.

Zgarb

Posted 2017-05-07T16:31:21.547

Reputation: 39 083

2

Brachylog, 34 bytes

⟦fᵐlᵐgDh⌉⟦↔gᵐ;D↔z{z{>₁∧0ṫ|∧Ṣ}ᵐcẉ}ᵐ

Try it online!

Leaky Nun

Posted 2017-05-07T16:31:21.547

Reputation: 45 011

2

PHP, 126 Bytes

for(;$n++<$argn;)for($c=$d=0;$d++<$n;)$n%$d?:$r[$n]=++$c;for($h=max($r);$h--;print"
")for($n=0;$n++<$argn;)echo$h<$r[$n]?:" ";

Try it online!

Jörg Hülsermann

Posted 2017-05-07T16:31:21.547

Reputation: 13 026

2

Alice, 33 bytes

I.!.t&w?t!aot&wh.Bdt.?-ex' +o&;k@

Try it online!

Input is (unfortunately) in the form of a code point. At least it reads a UTF-8 character, so you can use larger inputs than 255, but they're still limited and it's a pretty painful input format. For three additional bytes, we can read a decimal integer:

/
ki@/.!.t&w?t!aot&wh.Bdt.?-ex' +o&;

Try it online!

The non-whitespace character in the output is !.

Note that the solution also prints a ton of leading whitespace (it always starts with an empty line and then prints an NxN grid so for larger N, there will be many lines of spaces before the first !s.)

Explanation

I've used and explained the &w...k construction before (for example here). It's a neat little idiom that pops an integer n and then runs a piece of code n+1 times (consequently, it's usually used as t&w...k to run a loop n times, with t decrementing the input value). This is done by working with the return address stack (RAS). w pushes the current IP address to the RAS, and if we repeat it with & then the address gets pushed n times. k pops one address from the RAS and jumps back there. If the RAS is empty, it does nothing at all and the loop is exited.

You might notice that it's not trivially possible to nest these loops, because at the end of the inner loop, the stack isn't empty, so the k doesn't become a no-op. Instead, the IP would jump back to the beginning of the outer loop. The general way to fix this involves wrapping the inner loop in its own subroutine. But if we can arrange the nested loop such that the outer loop ends with the inner loop, we can actually make use of this behaviour and even save on one k!

So this construction:

&wX&wYk

Is a working nested loop which runs the XYYYXYYYXYYY... (for some number of Ys in each iteration). It's pretty neat that we can end both loops with a single k, because it will consume an outer address from RAS each time the inner addresses have been depleted.

This idiom is used in the program to run the loop over the output grid.

I         Read a character and push its code point as input N.
.!        Store a copy on the tape.
.         Make another copy.
t&w       Run this outer loop N times. This loops over the lines of the
          output, so the current iteration corresponds to a divisor count
          no more than i (i counting down from N).
  ?t!       Decrement the value on the tape. That means we'll actually have
            i-1 on the tape during the iteration.
  ao        Print a linefeed. Doing this now leads to the weird leading linefeed, 
            but it's necessary for the &w...&w...k pattern.
  t&w       Remember that we still have a copy of N on the stack. We'll also
            ensure that this is the case after each loop iteration. So this
            also runs the inner loop N times. This iterates over the columns
            of the output grid so it's j that goes from 1 to N and corresponds
            to the number whose divisors we want to visualise.
              At this point the stack will always be empty. However, operating
              on an empty stack works with implicit zeros at the bottom of
              the stack. We'll use the top zero to keep track of j.
    h         Increment j.
    .B        Duplicate j and push all of its divisors.
    dt        Push the stack depth minus 1, i.e. the divisor count of j.
    .         Duplicate the divisor count.
    ?-        Retrieve i-1 from the tape and subtract it. So we're computing
              d(j)-i+1. We want to output a non-whitespace character iff this
              value is positive (i.e. if i is no greater than d(j)).
    ex        Extract the most significant bit of this value. This is 1 for
              all positive values and 0 for non-positive ones. It's the shortest
              way (I believe) to determine if a value is positive.
    ' +       Add this to the code point of a space. This gives a 33, or '!',
              if the cell is part of the skyline.
    o         Output the character.
    &;        We still have all the divisors and the divisor count on the stack.
              We pop the divisor count to discard that many values (i.e. to
              get rid of the divisors again).
k         Return to the appropriate loop beginning to run the continue the
          nested loop.
@         Terminate the program.

Martin Ender

Posted 2017-05-07T16:31:21.547

Reputation: 184 808

1First Alice program with a single line ever? :-) – Luis Mendo – 2017-05-07T20:19:20.437

1@LuisMendo No, I think Leo has written a few Cardinal-only programs (and maybe I have as well... the quine and the Hello, World for example). Probably the most elaborate single-line program though. :) – Martin Ender – 2017-05-07T20:20:37.053

Hmm, my solution could save some bytes with "ton of leading whitespace" trick – quintopia – 2017-05-08T16:51:43.167

2

Actually, 25 bytes

R♂÷♂l;M' *╗⌠'#*╜@+⌡M┬♂ΣRi

Try it online!

22-byte version with a lot of leading newlines

;╗R⌠÷l'#*╜' *@+⌡M┬♂ΣRi

Try it online!

Leaky Nun

Posted 2017-05-07T16:31:21.547

Reputation: 45 011

Okay, the Readme on the github should be updated to include ÷l as the standard divisor counting function... – quintopia – 2017-05-08T17:03:10.493

2

R, 83 82 bytes

-1 byte thanks to MickyT

N=scan();m=matrix('#',N,N);for(i in 1:N)m[i,1:sum(i%%1:N>0)]=' ';write(m,'',N,,'')

Reads N from stdin.

N=scan()                        # read N
m=matrix('#',N,N)               # make an NxN matrix of '#' characters
for(i in 1:N)                   # for each integer in the range
    m[i,1:sum(i%%1:N!=0)]=' '   # set the first n-d(n) columns of row i to ' '
write(m,'',N,,'')               # print to console with appropriate formatting

Try it online!

Giuseppe

Posted 2017-05-07T16:31:21.547

Reputation: 21 077

1!=0 can be >0 – MickyT – 2017-05-10T22:47:23.490

1

Pyth, 16 bytes

j_.tm*\#/%LdSQ0S

Try it online!

Leaky Nun

Posted 2017-05-07T16:31:21.547

Reputation: 45 011

1

PHP, 99 bytes

for(;$d<$k?:$k++<$argn+$d=$n=0;)$k%++$d?:$r[--$n]=str_pad($r[$n],$k).H;ksort($r);echo join("
",$r);

prints one leading space; run as pipe with php -nr '<code>' or try it online.

breakdown

for(;$d<$k?:                    # inner: loop $d from 1 to $k
    $k++<$argn+$d=$n=0;)        # outer: loop $k from 1 to $argn, reset $d and $n
    $k%++$d?:                       # if $d divides $k
        $r[--$n]=str_pad($r[$n],$k).H;  # add one store to building $k
ksort($r);echo join("\n",$r);   # reverse and print resulting array

Titus

Posted 2017-05-07T16:31:21.547

Reputation: 13 814

1

SpecBAS - 149 bytes

1 INPUT n: DIM h(n)
2 FOR i=1 TO n
3 FOR j=1 TO i
4 h(i)+=(i MOD j=0)
5 NEXT j
6 NEXT i
7 FOR i=1 TO n
8 FOR j=51-h(i) TO 50
9  ?AT j,i;"#"
10 NEXT j
11 NEXT i

An array keeps track of number of divisors, then prints the right number of characters down to screen position 50.

enter image description here

Brian

Posted 2017-05-07T16:31:21.547

Reputation: 1 209

1

PowerShell, 101 bytes

((($d=1.."$args"|%{($x=$_)-(1..$_|?{$x%$_}).Count})|sort)[-1])..1|%{$l=$_;-join($d|%{' #'[$_-ge$l]})}

Less golfed test script:

$f = {

$d=1.."$args"|%{
    ($x=$_)-(1..$_|?{$x%$_}).Count
}                                     # $d is the Divisor count array
$maxHeight=($d|sort)[-1]
$maxHeight..1|%{
    $l=$_
    -join($d|%{' #'[$_-ge$l]})
}

}

@(
    ,(10, 
    "     # # #",
    "   # # ###",
    " #########",
    "##########")

    ,(50, 
    "                                               #  ",
    "                                   #           #  ",
    "                       #     #     #   # #     #  ",
    "                       #     #     #   # #     #  ",
    "           #     # #   #   # # #   #   # # ##  # #",
    "           #   # # #   #   # # #   #   # # ##  # #",
    "     # # # # ### # ### # ### # ##### ### # ### # #",
    "   # # ### # ### # ### ##### # ##### ### # ### ###",
    " #################################################",
    "##################################################")

    ,(200,
    "                                                                                                                                                                                   #                    ",
    "                                                                                                                                                                                   #                    ",
    "                                                                                                                       #                                               #           #                    ",
    "                                                                                                                       #                       #                       #           #                    ",
    "                                                                                                                       #                       #                       #           #           #        ",
    "                                                                                                                       #                       #                       #           #           #        ",
    "                                                           #           #           #     #     #           #           #     #     #       #   #     #     #   #       #           #           #     # #",
    "                                                           #           #           #     #     #           #           #     #     #       #   #     #     #   #       #           #           #     # #",
    "                                               #           #           #       #   #     #     #           #   #       #     #     #       #   #     #     #   # #     #       #   #           #     # #",
    "                                   #           #           #           #       #   #     #     #   #       #   #       #     #     #       #   #     #     #   # #     #       #   #           #   # # #",
    "                       #     #     #   # #     #     # #   #     #   # #     # #   #   # #     #   # # ##  # # # #     #     # # # #  ## # #   #     # # # #   # #  #  # #   # #   # # # #  ## #  ## # #",
    "                       #     #     #   # #     #     # #   #   # #   # #     # #   #   # #     #   # # ##  # # # #     #     # # # #  ## # #   #     # # # #   # #  #  # #   # #   # # # #  ## #  ## # #",
    "           #     # #   #   # # #   #   # # ##  # # # # #   #  ## # # # #  ## # #   #   # # #   # ### # ##  # # # # ##  #   # # # # #  ## # #   #  ## # ### #   # # ##  # ### ###   # # # # ### #  ## # #",
    "           #   # # #   #   # # #   #   # # ##  # # # # #   #  ## # # # #  ## # ##  #   # # #   # ### # ##  # # # # ##  #   # # # # #  ## # #   #  ## # ### #   # # ##  # ### ###   # # # # ### #  ## # #",
    "     # # # # ### # ### # ### # ##### ### # ### # ### ##### # ##### ### # ##### ### ##### ####### ### # ### # ### ####### ##### ### ##### # ######### # ##### ##### ### # ### ##### # ######### # ### # #",
    "   # # ### # ### # ### ##### # ##### ### # ### ##### ##### # ##### ### # ##### ### ##### ####### ### # ### # ### ############# ### ##### # ######### # ##### ##### ### ##### ##### # ######### # ### # #",
    " #######################################################################################################################################################################################################",
    "########################################################################################################################################################################################################")


) | % {
    $n,$expected = $_
    $result = &$f $n
    "$result"-eq"$expected"
    #$result    # uncomment this to enjoy the view of the Divisor skyline
}

Output:

True
True
True

mazzy

Posted 2017-05-07T16:31:21.547

Reputation: 4 832

1

SOGL V0.12, 8 bytes

∫Λ⁄╗*}⁰H

Try it here!

dzaima

Posted 2017-05-07T16:31:21.547

Reputation: 19 048

1

Wolfram Language (Mathematica), 46 44 bytes

Grid[PadLeft[0Divisors@Range@#-" "]+" "]&

Try it online! But maybe try it online! with ColumnForm instead of Grid, since Grid doesn't work in TIO. In Mathematica, it looks better:

Mathematica output

A third Mathematica solution... Divisors@Range@# finds all the divisors in the range we want, and then we multiply by 0 and subtract " ", making every divisor equal to -" ".

PadLeft adds zeroes on the left, creating a sideways skyline, whose orientation we fix with =\[Transpose]. Finally, adding " " to everything makes all entries either 0 or " ".

As an alternative, the 59-byte ""<>Riffle[PadLeft["X"-" "+0Divisors@Range@#]+" ","\n"]& produces string output.

Misha Lavrov

Posted 2017-05-07T16:31:21.547

Reputation: 4 846

1

Add++, 58 bytes

D,g,@,FL1+
D,k,@~,J
L,R€gd"#"€*$dbM€_32C€*z£+bUBcB]bR€kbUn

Try it online!

How it works

Our program consists of two helpers functions, g and k, and the main lambda function. g iterates over each integer, \$x\$, between \$1\$ and \$n\$ and returns \$d(x)\$ as defined in the challenge body, while k takes a list of characters and concatenates them into a single string.

The main lambda function generates \$A = [d(1), d(2), d(3), ..., d(n)]\$, then repeats the # character for each element of \$A\$. We then take \$\max(A)\$, and subtract each element in \$A\$ from this maximum, before yielding this number of spaces for each element and concatenating the spaces to the repeated hashes. Next, we transpose and reverse the rows, before joining each line on newlines. Finally, we output the skyline.

caird coinheringaahing

Posted 2017-05-07T16:31:21.547

Reputation: 13 702