You know nothing The things I do for "Chaos is a ladder" is a memorable line from the television series Game of Thrones.

The purpose of this challenge is to build a ladder from chaos, in ASCII art.

The challenge


  • Ladder width, W >= 3 (integer)
  • Step height, H >= 2 (integer)
  • Number of rungs, N >= 2 (integer).


A ladder with horizontal rungs and vertical rails, all 1 character wide. Ladder width (W) includes the two rails, and step height (H) includes the corresponding rung.

All rungs, including the uppermost and the lowermost, will have a piece of vertical rail of length H-1 directly above and below. The example will make this clearer.

The ladder will be made of printable, non-whitespace ASCII characters, that is, the inclusive range from ! (code point 33) to ~ (code point 126).The actual characters will be chosen randomly. Given the inputs, each of the random choices of characters must have nonzero probability. Other than that, the probability distribution is arbitrary.

Leading or trailing whitespace, either horizontal or vertical, is allowed.


Given W=5, H=3, N=2, one possible output is as follows.

x   :
g   h
t   T
6   <
8   T
5   g

Note that total height is H*(N+1)-1, as there are N rungs and N+1 vertical sections.

Aditional rules

  • Input means and format are flexible as usual. For example, you can input the three numbers in any order, or an array containing them.

  • Output may be through STDOUT or an argument returned by a function. In this case it may be a string with newlines, a 2D character array or an array of strings.

  • A program or a function can be provided.

  • Standard loopholes are forbidden.

  • Shortest code in bytes wins.

Test cases

For each W, H, N a possible output is shown.

W=5, H=3, N=2:

\   ~
:   K
5   u
0   _
#   r
7   X

W=3, H=2, N=2:

$ X
0 ]
j 9

W=12, H=4, N=5:

d          Y
P          `
5          3
D          x
`          O
*          H
p          p
x          (
2          ^
C          p
(          7
7          h
|          [
<          >
=          Q
O          +
p          e
n          j

W=20, H=5, N=3:

G                  %
o                  y
%                  3
-                  7
o                  }
U                  I
h                  y
a                  g
,                  U
N                  S
4                  c
5                  r
'                  h
h                  u
x                  $
6                  5    
  • \$\begingroup\$ can you add the (numerical) range for the ascii characters? \$\endgroup\$
    – Rod
    Sep 14, 2017 at 14:45
  • \$\begingroup\$ @Rod Good idea. Done \$\endgroup\$
    – Luis Mendo
    Sep 14, 2017 at 14:51
  • 1
    \$\begingroup\$ What kind of lower limit on the quality of randomness is there? I assume starting at a random point and incrementing modulo (126-33) wouldn't qualify because of obvious correlation between adjacent values. Or does it have to be capable of producing every possible sequence? (So an 8-bit linear congruential generator wouldn't work, because one character uniquely determines the next character?) \$\endgroup\$ Sep 14, 2017 at 23:50
  • \$\begingroup\$ @PeterCordes There is no problem with having some correlation, as long as every possible combination can occur. The approach you describe is, as you say, not valid because it introduces too strong statistical dependence between characters at different positions, making some combinations impossible \$\endgroup\$
    – Luis Mendo
    Sep 15, 2017 at 0:01
  • 1
    \$\begingroup\$ @PeterCordes Yes, I meant theoretically. Don't worry about RNG strength; you can assume the RNG is ideal. There's some meta consensus about that. I thought there was something more specific, but all I could find was this and this \$\endgroup\$
    – Luis Mendo
    Sep 15, 2017 at 0:41

24 Answers 24


Operation Flashpoint scripting language, 643 624 bytes

f={l=["""","!","#","$","%","&","'","(",")","*","+",",","-",".","/","0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?","@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","[","\","]","^","_","`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","{","|","}","~"];t=_this;w=t select 0;r={l select random 92};v="";s=v;i=2;while{i<w}do{i=i+1;v=v+" "};p={i=1;while{i<t select 1}do{i=i+1;s=s+call r+v+call r+"\n"}};k=0;call p;while{k<t select 2}do{k=k+1;i=0;while{i<w}do{i=i+1;s=s+call r};s=s+"\n";call p};s}

Ridiculously long because there is no way to create the characters from the character codes.

Call with:

hint ([5, 3, 2] call f)


The ladder is extra chaotic because the font is not monospaced.


f =
    l = ["""","!","#","$","%","&","'","(",")","*","+",",","-",".","/","0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?","@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","[","\","]","^","_","`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","{","|","}","~"];

    t = _this;
    w = t select 0;

    r =
        l select random 92

    v = "";
    s = v;

    i = 2;
    while {i < w} do 
        i = i + 1;
        v = v + " "

    p =
        i = 1;
        while {i < t select 1} do 
            i = i + 1;
            s = s + call r + v + call r + "\n"

    k = 0;
    call p;
    while {k < t select 2} do 
        k = k + 1;

        i = 0;
        while {i < w} do
            i = i + 1;
            s = s + call r
        s = s + "\n";

        call p

  • \$\begingroup\$ It seems as "\n" works, "\xa3" to get something like £ doesn't work? if you can use unicode escapes you might be able to trim that array of yours. \$\endgroup\$ Sep 15, 2017 at 9:45
  • \$\begingroup\$ How can I run this myself? :D \$\endgroup\$
    – Geeky I
    Sep 15, 2017 at 10:22
  • 22
    \$\begingroup\$ This just looks like a script was written and the spaces and newlines were removed. Is it only getting upvotes because of an image of a ladder or have I missed some clever golfing? \$\endgroup\$ Sep 15, 2017 at 10:51
  • \$\begingroup\$ @steadybox are you using contextual screenshots now after I requested a non-grassland screenshot on that one question xD? \$\endgroup\$ Sep 15, 2017 at 20:15
  • \$\begingroup\$ @Tschallacka \n is the only escape that is recognized. (And "" inside quotes to represent one ") \$\endgroup\$
    – Steadybox
    Sep 15, 2017 at 21:58

05AB1E, 29 bytes

Input taken in the order N, H, W


Try it online!


>*G                              # for N in [1 ... (N+1)*H)-1] do:
   NU                            # store N in variable X
     žQ                          # push a string of printable ascii
       ¦©                        # remove the first (space) and save a copy in register
         .R                      # pick a random character
           IÍF                   # W-2 times do:
              ð                  # push a space
               ®.R               # push a random ascii character
                  «              # concatenate
                   X²Ö           # push X % H == 0
                      è          # index into the string of <space><random_char> with this
                       }         # end inner loop
                        ®.R      # push a random ascii character
                           J,    # join everything to a string and print
  • \$\begingroup\$ This is a bit cheating. \$\endgroup\$
    – vdegenne
    Sep 14, 2017 at 23:43
  • 4
    \$\begingroup\$ @user544262772 why so? \$\endgroup\$ Sep 15, 2017 at 5:08
  • \$\begingroup\$ may you explain this a little bit? \$\endgroup\$
    – Mischa
    Sep 15, 2017 at 8:35
  • \$\begingroup\$ @MischaBehrend: Sure, I've added an explanation now. \$\endgroup\$
    – Emigna
    Sep 15, 2017 at 8:41
  • 3
    \$\begingroup\$ @user544262772 it can be quite challenging to make a well golfed answer in a golfing language, believe me, they are designed for golfing, but using them usually requires some thought (unless it's just "here's a built-in that does exactly what you want"). \$\endgroup\$ Sep 15, 2017 at 10:48

C, 95 bytes


R, 138 129 111 98 93 bytes

-13 bytes thanks to Neal Fultz!

-1 byte thanks to Robin Ryder

m[-H*1:N,3:W-1]=" "

Try it online!

Anonymous function; returns the result as a matrix.

Thanks to that Word Grids question, I've been thinking about matrices a lot more than usual. I observed that the rungs are in those matrix rows that are a multiple of the step height H (R is 1-indexed), and that the rails are the first and last columns, 1 and W. So I create a matrix of random ASCII characters, and replace those letters that didn't match those criteria with spaces, and return the matrix. TIO link prints it out nicely.

Neal Fultz suggested a different indexing for the space characters, [-H*(1:N),3:W-1], which replaces all characters except for those in rows of multiples of H: -H*(1:N) and not on the edge, 3:W-1 <==> 2:(W-1).

R, 121 bytes

function(W,H,N)for(i in 1:(H*N+H-1)){for(j in 1:W)cat("if"(!(i%%H&j-1&j-W),sample(intToUtf8(33:126,T),1)," "))

Try it online!

An improvement over the original matrix-based approach I started with; it's the same algorithm but for loops are shorter than constructing and printing a matrix (but not if I don't print it!)

  • \$\begingroup\$ m[-H*(1:N),3:W-1]=" " seems a little shorter - you can always replace testing row and col with a 2-d slice. \$\endgroup\$
    – Neal Fultz
    Sep 19, 2017 at 4:59
  • \$\begingroup\$ @NealFultz wow, that's quite excellent! Thank you! \$\endgroup\$
    – Giuseppe
    Sep 19, 2017 at 13:13
  • \$\begingroup\$ -1 byte by replacing sample(33:126,...) with 32+sample(94,...). \$\endgroup\$ May 18, 2019 at 17:15

Jelly,  24 23  22 bytes


A full program taking the three arguments W, H, N and printing the result.

Try it online!


Builds a 2d array mask of a single rung and its vertical sections below, repeats it N+1times and removes the top rung then places random characters or spaces depending upon the mask value.

«þỊoU$ẋ⁵‘¤Ḋ×94X€€+32ỌY - Main link: W, H (N is third input / 5th command line argument)
 þ                     - outer product (build a table using):
«                      -  minimum
                       -  ...note: þ implicitly builds ranges of W and H prior
  Ị                    - insignificant? (abs(z)<=1) - yields a W by H 2-d array,
                       -   all zeros except the left and top edges which are 1s
     $                 - last two links as a monad:
    U                  -   upend (reverse each row)
   o                   -   or (vectorises) - giving us our |‾| shape of 1s
         ¤             - nilad followed by link(s) as a nilad:
       ⁵               -   5th command line argument, N
        ‘              -   increment -> N+1
      ẋ                - repeat list - giving us our ladder-mask plus a top rung)
          Ḋ            - dequeue - remove the top rung
            94         - literal ninety-four
           ×           - multiply (vectorises) - replace the 1s with 94s
              X€€      - random for €ach for €ach - 0 -> 0; 94 -> random integer in [1,94]
                  32   - literal thirty-two
                 +     - add (vectorises) - 0 -> 32; random integers now from [33,126]
                    Ọ  - character from ordinal (vectorises)
                     Y - join with newlines
                       - implicit print

Perl 5, 81 bytes

80 bytes code + 1 for -p.

/ \d+ /;$_=(($}=(_.$"x($`-2)._.$/)x($&-1))._ x$`.$/)x$'.$};s/_/chr 33+rand 94/ge

Try it online!

  • \$\begingroup\$ the space after \d+ may be removed because of greedy match \$\endgroup\$ Sep 15, 2017 at 9:29

Charcoal, 34 32 bytes

E…¹×⁺¹NN⪫EIζ⎇∧﹪ιIη﹪λ⁻Iζ¹ §⮌γ‽⁹⁴ω

Try it online! Takes input in the order N, H, W. Verbose approximation (Plus(InputNumber(), 1) is currently broken on TIO). Explanation:


Map over the range 1..H*(N+1). This means that the rungs appear when i is a multiple of H.

Join the result of:


mapping over the implicit range 0..W:


if the column is not 0 or W-1 and the row is not a multiple of H then output a space;


otherwise, take the predefined ASCII character variable, reverse it (putting the space in 94th place), and print a random character from what is now the first 94. (Because Slice sucks.)


Join using the empty string. Final result is implicitly printed.

  • \$\begingroup\$ Not sure if it's helpful but you could draw the ladder and then peekall and map over random printable I think? EDIT It appears to be broken. Oops. \$\endgroup\$
    – ASCII-only
    Sep 15, 2017 at 13:29
  • \$\begingroup\$ I'll try to fix it (pretty sure it was working before) but I've been a bit busy so it might take a while \$\endgroup\$
    – ASCII-only
    Sep 15, 2017 at 13:37
  • \$\begingroup\$ @ASCII-only I assume you're thinking of NθGH↓θ→N↑θ*‖O↓F⁻N¹C⁰θ¿EKA§⮌γ‽⁹⁴«? Well, I bisected and commit a0a6316 broke it. \$\endgroup\$
    – Neil
    Sep 20, 2017 at 19:54
  • \$\begingroup\$ @ASCII-only Actually that's not quite true, there was an unrelated bug in Map where it used not is_command when it meant is_command. So you were supposed to write NθGH↓θ→N↑θ*‖O↓F⁻N¹C⁰θUMKA§⮌γ‽⁹⁴ if it hadn't been for that bug. \$\endgroup\$
    – Neil
    Sep 20, 2017 at 20:01

C (gcc), 141 131 114 109 107 bytes

Should be able to golf this down quite a bit...


Try it online!

  • \$\begingroup\$ can we edit i=1 in the global declaration? \$\endgroup\$ Sep 16, 2017 at 6:06
  • \$\begingroup\$ 106 bytes \$\endgroup\$
    – ceilingcat
    Oct 30, 2020 at 1:37

Perl 6, 76 73 bytes

->\h,\n,\w{map {chrs (roll(w,1..94)Z*1,|($_%%h xx w-2),1)X+32},1..^h*n+h}

Try it online!

Takes (h, n, w) as arguments. Returns a list of strings.


-> \h, \n, \w {  # Block taking arguments h, n, w
    map {
        # String from codepoints
             # Generate w random numbers between 1 and 94
             (roll(w, 1..94)
              # Set inner numbers on non-rungs to zero
              Z* 1, |($_%%h xx w-2), 1)
             # Add 32 to numbers
             X+ 32
    # Map h*n+h-1 row numbers (1-indexed)
  • \$\begingroup\$ Alternative 73 byter using xx and ++$ instead of map. Maybe you can find a place to golf off any bytes? \$\endgroup\$
    – Jo King
    Nov 5, 2018 at 11:27

PowerShell, 132 124 bytes

param($w,$h,$n)-join([char[]]((($a=('#'+' '*($w-2)+"#`n")*--$h)+'#'*$w+"`n")*$n+$a)|%{($_,[char](33..126|Random))[$_-eq35]})

Try it online!

We construct a ladder composed of only # first (example), then loop |%{...} through each character and if it's -equal to 35, we pull out a new Random character from the appropriate range. Otherwise we output (i.e., either a space or newline).


JavaScript (ES6), 117 115 bytes

A recursive function building the output character by character.

"Look Ma, no literal line-feed!"



let f =


O.innerText = f(5,3,4)
<pre id=O></pre>

  • \$\begingroup\$ Damnit! I was in the process of golfing mine down when I saw this. :\ You win again! :p \$\endgroup\$
    – Shaggy
    Sep 15, 2017 at 13:41
  • \$\begingroup\$ I finished golfing mine down (for now) - I drew the line at moving all the ternaries within String.fromCharCode, as I couldn't honestly say I'd come up with that myself after seeing this. Let me know if you feel mine is now too similar to yours. \$\endgroup\$
    – Shaggy
    Sep 15, 2017 at 15:32
  • \$\begingroup\$ @Shaggy No worries! (Actually, I saw your answer only after posting mine. If I had seen it earlier, I would probably have given up.) \$\endgroup\$
    – Arnauld
    Sep 15, 2017 at 15:42
  • 1
    \$\begingroup\$ Ah, it's the nature of the game! :) Combining our solutions gives 113 bytes, by the way \$\endgroup\$
    – Shaggy
    Sep 15, 2017 at 16:45

Python 2, 142 bytes

lambda w,h,n,e=lambda:chr(randint(33,126)):[e()+[eval(("e()+"*(w-2))[:-1])," "*(w-2)][-~i%h>0]+e()for i in range(h*-~n-1)]
from random import*

Try it online!

Saved bytes thanks to ovs!

  • \$\begingroup\$ @LuisMendo I think I fixed it now. \$\endgroup\$
    – Mr. Xcoder
    Sep 14, 2017 at 15:16
  • \$\begingroup\$ @LuisMendo It's my fault for not checking carefully. \$\endgroup\$
    – Mr. Xcoder
    Sep 14, 2017 at 15:18
  • \$\begingroup\$ 42 bytes \$\endgroup\$
    – ovs
    Sep 17, 2017 at 21:28
  • \$\begingroup\$ @ovs Thanks! You forgot a 1 in the front though >_> \$\endgroup\$
    – Mr. Xcoder
    Sep 17, 2017 at 21:29

Pyth, 33 bytes

VhEjtW!Nmsm?&d}kr1tQ\ Or\!C127Qvz

Try it online: Demonstration


Python 2, 114 bytes

lambda w,h,n:[[chr(32+randint(1,94)*(x%~-w*(y%h)<1))for x in range(w)]for y in range(1,h*-~n)]
from random import*

Try it online!


SOGL V0.12, 32 31 bytes


Try it Here!

Input in the order N, W, H.



     R  a function named "R", pushes a random character:
 ~       push "~"
  Δ      get the charasters from " " to "~"
   k     remove the 1st character
    ψ    choose a random character from that

I{e{R}¶bH{Re⁾⌡@R¶}}¹∑e⌡k  main program

I                         increase the 1st input - N
 {                }       N times do
  e                         push the variable e, which is here initialised to the next input - W
   { }                      E times do
    R                         execute R
      ¶                     push a newline
       bH                   push b-1, where b is initialised to the next input - H
         {       }          B-1 times do
          R                   execute R
           e⁾                 push e-2 aka width-2
             ⌡@               push that many spaces
               R              execute R
                ¶             push a newline
                   ¹∑     join the stack together
                     e⌡k  remove the first width characters

18 bytes without the random characters :/


Java 8, 203 188 168 133 132 130 128 126 bytes

W->H->N->{for(double i=0,j,q;++i<H*N+H;)for(j=W,q=10;j-->=0;q=i%H*j<1|j>W-2?33+Math.random()*94:32)System.out.print((char)q);}

Try it online!

  • \$\begingroup\$ 133 bytes: W->H->N->{for(int i=0,j;i++<H*N+H-1;){char c=10;for(j=W;j-->0;c=i%H<1|j>W-2|j<2?(char)(Math.random()*94+33):32)System.out.print(c);}} \$\endgroup\$
    – Nevay
    Sep 14, 2017 at 15:58
  • \$\begingroup\$ You are currently printing the result for W-1, the inner loop has to do an additional iteration (>=0 +1 byte). \$\endgroup\$
    – Nevay
    Sep 14, 2017 at 16:09
  • 1
    \$\begingroup\$ 132 bytes: W->H->N->{for(int i=0,j;i++<H*N+H-1;){char c=10;for(j=W;j-->=0;c=i%H*j<1|j>W-2?(char)(Math.random()*94+33):32)System.out.print(c);}} \$\endgroup\$
    – Nevay
    Sep 14, 2017 at 16:10
  • 2
    \$\begingroup\$ ;++i<H*N+H; : -2 bytes. \$\endgroup\$ Sep 15, 2017 at 9:24

Haskell, 226 220 211 190 bytes

import System.Random
a=mapM id
r w=a$c<$[1..w]
s w=a$c:(return ' '<$[3..w])++[c]
(w#h)0=b$s w<$[2..h]
(w#h)n=do{b$(s w<$[2..h])++[r w];(w#h)$n-1}

Try it online!

Saved 9 bytes thanks to Laikoni

Saved 21 bytes thanks to wchargin

Should be golfable (b$(s w)<$[2..h] and b$((s w)<$[2..h])++[r w]). I don't feel comfortable with IO and golfing.

  • \$\begingroup\$ You can use infix notation for t w h n= ...: (w#h)n= .... pure can be used instead of return. You can drop the parentheses around (d ' ')<$and (s w)<$. \$\endgroup\$
    – Laikoni
    Sep 14, 2017 at 20:36
  • \$\begingroup\$ @Laikoni I won't forget the infix notation next time! Thanks. \$\endgroup\$
    – jferard
    Sep 15, 2017 at 15:43
  • 1
    \$\begingroup\$ Save a bunch of bytes with c=randomRIO('!','~'), which also lets you inline d=return. Also, mapM id is one byte shorter than sequence. \$\endgroup\$
    – wchargin
    Sep 17, 2017 at 20:35
  • 1
    \$\begingroup\$ @wchargin Thanks. I learned something today! \$\endgroup\$
    – jferard
    Sep 18, 2017 at 16:05

JavaScript (ES6), 144 bytes


Creates the ladder out of # characters then replaces each one with a random ASCII char.

Test Snippet

let f=

;(W.oninput=H.oninput=N.oninput=B.onclick=_=>{let vals=[W.value,H.value,N.value].map(eval);D.innerText=vals.join`, `;O.innerText=f(...vals);})()
W: <input id=W type=range min=3 max=25 value=12><br>
H: <input id=H type=range min=2 max=25 value=5><br>
N: <input id=N type=range min=2 max=10 value=2><br>
<button id=B>Rerun</button> <code id=D></code>
<pre id=O></pre>

  • \$\begingroup\$ String.fromCharCode and Math.random in one solution - why does JavaScript hate us?! Came up with this for 137 bytes, which is very similar to yours, just without the array. I wonder now if a recursive solution might be shorter still; will investigate later. \$\endgroup\$
    – Shaggy
    Sep 15, 2017 at 10:12
  • \$\begingroup\$ Knocked another byte off that \$\endgroup\$
    – Shaggy
    Sep 15, 2017 at 16:49

JavaScript (ES6), 129 117 bytes

Unfortunately, while I was in the process of golfing this down, Arnauld beat me to a similar but shorter solution. By combining our 2 solutions, this can be 113 bytes

Includes a trailing newline.

(w,h,n)=>(g=c=>l?(c++<w?c%w>1&&l%h?` `:String.fromCharCode(94*Math.random()+33|0):`

Try it

(w,h,n)=>(g=c=>l?(c++<w?c%w>1&&l%h?` `:String.fromCharCode(94*Math.random()+33|0):`
label,input{font-family:sans-serif;font-size:14px;height:20px;line-height:20px;vertical-align:middle}input{margin:0 5px 0 0;padding:0 0 0 5px;width:100px;}
<label for=i>W: </label><input id=i min=3 type=number><label for=j>H: </label><input id=j min=2 type=number><label for=k>N: </label><input id=k min=2 type=number><pre id=o>


Japt -R, 42 41 40 37 34 28 25 bytes

Takes input in the order H,W,N.

;*°WÉ ÆJ²ùVXgJùU¹r,@EÅöÃé

Try it


QBIC, 76 bytes

[:*:+b-1|G=chr$(_r33,126|)~a%b\[:-2|G=G+@ `]][e|G=G+chr$(_r33,126|)]?_sG,1,e


[                       FOR a = 1 TO
 :                         input 1 (Height, now in var b)
  *                        times
   :                       input 2 (# of rungs, now in var c)
    +b-1|                  plus one bottom rung without crossbar
G=chr$(_r33,126|)       Assign to G a random char (_r is the RAND() function, chr$() is BASIC's num-to-char)
~a%b|                   IF we are not at a crossbar (the modulo returns anything but 0), 
  [:-2|G=G+@ `            add to G x spaces, where x is width (input 3, now 'e') - 2
                        Note that G is now either 'X' or 'X   '  (for rnd char X and W=5)
]]                      Close the spacing FOR, close the IF 
[e|                     FOR f = 1 to width
  G=G+chr$(_r33,126|)]     Append to G a rnd char
                        G is now either 'XXXXXX'  or 'X   XXXXX' (for rnd char X and W=5)
?_sG,1,e                PRINT the first w characters of G, and on to the next line

Sample run

Command line: 3 2 5
N   F
M   `
!   (
S   N
%   7
g   ,

MATL, 63 50 bytes

-13 bytes thanks to Luis Mendo


Try it online!

I'm still new to golfing in MATL (and I'm not super good at MATLAB for that matter), so I know this probably isn't close to optimal. Tips are welcome. Takes input in order N,H,W.

Here we go:

Q*qXJ                     # compute H*(N+1)-1, store as J
     *                    # multiply by W
      6Y2HY)              # push printable ASCII
            wT3$Zr        # sample uniformly with replacement
                  J3G3$e  # reshape to make a matrix of the appropriate shape.

We now have a matrix of random char.

J3G                       # push J,W
   &O                     # zero matrix, J x W
     l5LZ(                # assign 1 to first and last columns

Now there's also a logical matrix for the rails.

J:                        # push J, range, so 1...J
  HG                      # take second input (H)
    \~                    # mod and bool negate (so it's 1 for rows of multiples of H)
      3GTX"!              # repmat and transpose so we have 1's for rungs

Now we have 3 matrices on the stack:

  • Top: 0 for non-rung, 1 otherwise
  • Middle: 0 for non-rail, 1 otherwise
  • Bottom: random characters, -20

So we do the following:

+                         # add the top two matrices.
 g                        # convert to logical so 0->0, nonzero->1
   *                      # elementwise multiply
    c                     # convert to char, implicit output (0 -> space).
  • \$\begingroup\$ Here are a few quick tips: X" is 3$ by default. 6Y2 may be handy instead of 13:106...20+. ~~ is g. J3G&Ol5LZ( can be used instead of 1F3G2-Y"h1hJT3$X" \$\endgroup\$
    – Luis Mendo
    Sep 18, 2017 at 21:36
  • \$\begingroup\$ @LuisMendo Ah, I didn't quite make it through all the docs or I would have discovered that about X". In that last tip, 5L is [1 0] but I'm not sure how that's used in conjunction with Z( -- I get that it's assigning 1 to the first and last columns but I don't get how 5LZ( accomplishes that. I'll probably ping you in MATL CHATL sometime later about this so don't worry about that for now. \$\endgroup\$
    – Giuseppe
    Sep 18, 2017 at 22:37
  • 1
    \$\begingroup\$ Indexing is modular, so 0 is the same as "end". Z( assigns to columns. Of course, feel free to ping me in chat! \$\endgroup\$
    – Luis Mendo
    Sep 18, 2017 at 23:03

Powershell, 102 bytes


Less golfed test script:

$f = {

1..(++$n*$h-1)|%{       # for each lines of the ladder
    $l=$_%$h            # line number in a step
    -join(1..$w|%{      # make a line
    })                  # a random character if the line number in a step is a rung line or char position is 1 or width
                        # otherwise a space


&$f 5 3 2
&$f 3 2 2
&$f 12 4 5
&$f 20 5 3


0   {
H   S
G   ]
3   t
q   y
t   J
U h
_ i
I #
=          m
&          <
]          6
o          l
;          !
D          M
@          B
$          e
z          @
(          L
:          [
|          q
/          *
e          B
R          p
u          ~
`          l
J          h
v                  t
T                  -
v                  H
'                  Y
F                  U
?                  U
|                  Q
}                  T
<                  L
:                  }
*                  `
H                  =
j                  =
!                  p
V                  :
#                  w

Ruby, 71 bytes

EDIT: Oops I thought this was a new challenge because of the recent edit to fix a typo lol. I'm still leaving this up though because there's no Ruby answer for it yet.

->w,h,n{(1..h*-~n-1).map{|i|[*?!..?~].sample(x=i%h>0?2:w)*(' '*(w-x))}}

Try it online!


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.