Chaos is an ASCII ladder

43

4

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

Input

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

Output

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.

Example

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

x   :
g   h
q$UO{
t   T
6   <
bUZXP
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
ke:[E
5   u
0   _
8Fr.D
#   r
7   X


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

$ X
Mb)
0 ]
(T}
j 9


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

d          Y
P          `
5          3
p$t$Ow7~kcNX
D          x
`          O
*          H
LB|QX1'.[:[F
p          p
x          (
2          ^
ic%KL^z:KI"^
C          p
(          7
7          h
TSj^E!tI&TN8
|          [
<          >
=          Q
ffl`^,tBHk?~
O          +
p          e
n          j


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

G                  %
o                  y
%                  3
-                  7
U'F?Vml&rVch7{).fLDF
o                  }
U                  I
h                  y
a                  g
;W.58bl'.iHm\8v?bIn&
,                  U
N                  S
4                  c
5                  r
F3(R|<BP}C'$=}xK$F]^
'                  h
h                  u
x                  $
6                  5    

Luis Mendo

Posted 2017-09-14T14:41:17.417

Reputation: 87 464

can you add the (numerical) range for the ascii characters? – Rod – 2017-09-14T14:45:34.827

@Rod Good idea. Done – Luis Mendo – 2017-09-14T14:51:05.170

1What 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?) – Peter Cordes – 2017-09-14T23:50:25.107

@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 – Luis Mendo – 2017-09-15T00:01:27.143

Every possible 2-character sequence sounds reasonable. Requiring that every possible sequence (for the whole thing) has non-zero probability is actually a pretty strong requirement. Most C implementations have a pretty week rand() function (e.g. standards for other functions that interact with it make it hard to use more state). I wouldn't be surprised if the C answers using 33+rand()%93 or similar can't produce some sequences on x86 gcc + glibc. I think using a library RNG satisfies your intent, though. Is there a meta question about RNG strength? (In x86 asm I'd use rdrand :) – Peter Cordes – 2017-09-15T00:27:23.197

1

@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

– Luis Mendo – 2017-09-15T00:41:53.113

Answers

6

Jelly,  24 23  22 bytes

«þỊoU$ẋ⁵‘¤Ḋ×94X€€+32ỌY

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

Try it online!

How?

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

Jonathan Allan

Posted 2017-09-14T14:41:17.417

Reputation: 67 804

34

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)

Output:

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

Unrolled:

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
}

Steadybox

Posted 2017-09-14T14:41:17.417

Reputation: 15 798

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. – Tschallacka – 2017-09-15T09:45:32.250

How can I run this myself? :D – Geeky I – 2017-09-15T10:22:58.320

22This 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? – Jonathan Allan – 2017-09-15T10:51:56.447

@steadybox are you using contextual screenshots now after I requested a non-grassland screenshot on that one question xD? – Magic Octopus Urn – 2017-09-15T20:15:27.877

@Tschallacka \n is the only escape that is recognized. (And "" inside quotes to represent one ") – Steadybox – 2017-09-15T21:58:28.647

@GeekyI You'll need the game, version 1.85 or higher. No other way unfortunately :D – Steadybox – 2017-09-15T22:00:01.800

@JonathanAllan Not much to be done about golfing this further. I agree that there other answers with cleverer golfing more deserving of the upvotes. – Steadybox – 2017-09-15T22:04:03.883

@MagicOctopusUrn Did it with this one before that already :)

– Steadybox – 2017-09-15T22:08:07.510

14

05AB1E, 29 bytes

Input taken in the order N, H, W

>*GNUžQ¦©.RIÍFð®.R«X²Öè}®.RJ,

Try it online!

Explanation

>*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

Emigna

Posted 2017-09-14T14:41:17.417

Reputation: 50 798

This is a bit cheating. – vdegenne – 2017-09-14T23:43:45.863

4@user544262772 why so? – Jonathan Allan – 2017-09-15T05:08:10.107

may you explain this a little bit? – Mischa – 2017-09-15T08:35:39.577

@MischaBehrend: Sure, I've added an explanation now. – Emigna – 2017-09-15T08:41:30.050

@JonathanAllan not really cheating you know but, this is a language that's built for golf coding, so the final code is sure short. But this is more for fun than just a real challenge right ? – vdegenne – 2017-09-15T10:42:11.390

3@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"). – Jonathan Allan – 2017-09-15T10:48:08.767

@JonathanAllan I understand. But yeah, it's more a show-off of what everyone's language has in the gut, their features, weaknesses or strong-points, than a real challenge, because if everyone use a golf-code-oriented language, everyone wins I guess. – vdegenne – 2017-09-15T13:40:38.903

@user544262772 Please look at some other answers on this website, you'll see that languages designed for code golf are often used. These languages were made for code golfing, that's totally right to use them. – A.L – 2017-09-16T17:00:01.020

13

C, 95 bytes

f(w,h,n,i){++w;for(i=0;i++<w*~(h*~n);)putchar(i%w?~-i%w%(w-2)*((i/w+1)%h)?32:33+rand()%94:10);}

orlp

Posted 2017-09-14T14:41:17.417

Reputation: 37 067

8

R, 138 129 111 98 93 bytes

-13 bytes thanks to Neal Fultz!

-1 byte thanks to Robin Ryder

function(W,H,N){m=matrix(intToUtf8(32+sample(94,W*(h=H*N+H-1),T),T),h)
m[-H*1:N,3:W-1]=" "
m}

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)," "))
cat("\n")}

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

Giuseppe

Posted 2017-09-14T14:41:17.417

Reputation: 21 077

m[-H*(1:N),3:W-1]=" " seems a little shorter - you can always replace testing row and col with a 2-d slice. – Neal Fultz – 2017-09-19T04:59:57.543

@NealFultz wow, that's quite excellent! Thank you! – Giuseppe – 2017-09-19T13:13:59.483

-1 byte by replacing sample(33:126,...) with 32+sample(94,...). – Robin Ryder – 2019-05-18T17:15:01.343

6

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!

Dom Hastings

Posted 2017-09-14T14:41:17.417

Reputation: 16 415

the space after \d+ may be removed because of greedy match – Nahuel Fouilleul – 2017-09-15T09:29:16.483

6

C (gcc), 141 131 114 109 107 bytes

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

i,j,c;f(w,h,n){for(i=1;i<h*n+h;i+=j==w)printf(i%h?i++,j=0,"%c%*c\n":"%c",++j^w?c^8:10,w-2,c=33+rand()%94);}

Try it online!

cleblanc

Posted 2017-09-14T14:41:17.417

Reputation: 3 360

can we edit i=1 in the global declaration? – Mukul Kumar – 2017-09-16T06:06:46.813

6

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:

E…¹×⁺¹NN

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:

EIζ

mapping over the implicit range 0..W:

⎇∧﹪ιIη﹪λ⁻Iζ¹ 

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.

Neil

Posted 2017-09-14T14:41:17.417

Reputation: 95 035

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. – ASCII-only – 2017-09-15T13:29:51.900

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 – ASCII-only – 2017-09-15T13:37:17.437

@ASCII-only I assume you're thinking of NθGH↓θ→N↑θ*‖O↓F⁻N¹C⁰θ¿EKA§⮌γ‽⁹⁴«? Well, I bisected and commit a0a6316 broke it. – Neil – 2017-09-20T19:54:41.427

@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. – Neil – 2017-09-20T20:01:38.913

6

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.

Explanation:

-> \h, \n, \w {  # Block taking arguments h, n, w
    map {
        # String from codepoints
        chrs
             # 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)
    1..^h*n+h
}

nwellnhof

Posted 2017-09-14T14:41:17.417

Reputation: 10 037

Alternative 73 byter using xx and ++$ instead of map. Maybe you can find a place to golf off any bytes? – Jo King – 2018-11-05T11:27:27.330

5

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!

Mr. Xcoder

Posted 2017-09-14T14:41:17.417

Reputation: 39 774

@LuisMendo I think I fixed it now. – Mr. Xcoder – 2017-09-14T15:16:50.500

@LuisMendo It's my fault for not checking carefully. – Mr. Xcoder – 2017-09-14T15:18:10.647

42 bytes – ovs – 2017-09-17T21:28:30.177

@ovs Thanks! You forgot a 1 in the front though >_> – Mr. Xcoder – 2017-09-17T21:29:54.023

5

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

AdmBorkBork

Posted 2017-09-14T14:41:17.417

Reputation: 41 581

5

JavaScript (ES6), 117 115 bytes

A recursive function building the output character by character.

"Look Ma, no literal line-feed!"

(w,h,n)=>(g=x=>y<h*n+h-1?String.fromCharCode(x++<w?x%w>1&&-~y%h?32:Math.random()*94+33|0:10)+g(x>w?!++y:x):'')(y=0)

Demo

let f =

(w,h,n)=>(g=x=>y<h*n+h-1?String.fromCharCode(x++<w?x%w>1&&-~y%h?32:Math.random()*94+33|0:10)+g(x>w?!++y:x):'')(y=0)

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

Arnauld

Posted 2017-09-14T14:41:17.417

Reputation: 111 334

Damnit! I was in the process of golfing mine down when I saw this. :\ You win again! :p

– Shaggy – 2017-09-15T13:41:54.790

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. – Shaggy – 2017-09-15T15:32:23.990

@Shaggy No worries! (Actually, I saw your answer only after posting mine. If I had seen it earlier, I would probably have given up.) – Arnauld – 2017-09-15T15:42:45.837

1

Ah, it's the nature of the game! :) Combining our solutions gives 113 bytes, by the way

– Shaggy – 2017-09-15T16:45:41.447

4

Pyth, 33 bytes

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

Try it online: Demonstration

Jakube

Posted 2017-09-14T14:41:17.417

Reputation: 21 462

3

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!

Roberto Graham

Posted 2017-09-14T14:41:17.417

Reputation: 1 305

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);}} – Nevay – 2017-09-14T15:58:18.117

You are currently printing the result for W-1, the inner loop has to do an additional iteration (>=0 +1 byte). – Nevay – 2017-09-14T16:09:26.870

1132 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);}} – Nevay – 2017-09-14T16:10:25.117

2;++i<H*N+H; : -2 bytes. – Olivier Grégoire – 2017-09-15T09:24:56.083

3

SOGL V0.12, 32 31 bytes

 ~ΔkψR
I{e{R}¶bH{Re⁾⌡@R¶}}¹∑e⌡k

Try it Here!

Input in the order N, W, H.

Explanation:

 ~ΔkψR

     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 :/

dzaima

Posted 2017-09-14T14:41:17.417

Reputation: 19 048

3

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!

Lynn

Posted 2017-09-14T14:41:17.417

Reputation: 55 648

3

Haskell, 226 220 211 190 bytes

import System.Random
a=mapM id
b=(putStr.unlines=<<).a
c=randomRIO('!','~')
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.

jferard

Posted 2017-09-14T14:41:17.417

Reputation: 1 764

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)<$. – Laikoni – 2017-09-14T20:36:02.593

@Laikoni I won't forget the infix notation next time! Thanks. – jferard – 2017-09-15T15:43:15.820

1Save a bunch of bytes with c=randomRIO('!','~'), which also lets you inline d=return. Also, mapM id is one byte shorter than sequence. – wchargin – 2017-09-17T20:35:25.123

1@wchargin Thanks. I learned something today! – jferard – 2017-09-18T16:05:50.577

2

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

Shaggy

Posted 2017-09-14T14:41:17.417

Reputation: 24 623

2

JavaScript (ES6), 144 bytes

(w,h,n)=>Array(n+1).fill(("#".padEnd(w-1)+`#
`).repeat(h-1)).join("#".repeat(w)+`
`).replace(/#/g,_=>String.fromCharCode(33+Math.random()*94|0))

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

Test Snippet

let f=
(w,h,n)=>Array(n+1).fill(("#".padEnd(w-1)+`#
`).repeat(h-1)).join("#".repeat(w)+`
`).replace(/#/g,_=>String.fromCharCode(33+Math.random()*94|0))

;(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>

Justin Mariner

Posted 2017-09-14T14:41:17.417

Reputation: 4 746

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. – Shaggy – 2017-09-15T10:12:38.557

Knocked another byte off that – Shaggy – 2017-09-15T16:49:59.703

2

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):`
`)+g(c>w?!--l:c):``)(0,l=h*++n-1)

Try it

o.innerText=(f=
(w,h,n)=>(g=c=>l?(c++<w?c%w>1&&l%h?` `:String.fromCharCode(94*Math.random()+33|0):`
`)+g(c>w?!--l:c):``)(0,l=h*++n-1)
)(i.value=5,j.value=3,k.value=2);oninput=_=>o.innerText=f(+i.value,+j.value,+k.value)
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>

Shaggy

Posted 2017-09-14T14:41:17.417

Reputation: 24 623

1

QBIC, 76 bytes

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

Explanation

[                       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   `
Bj#=y
!   (
S   N
q(.Ho
%   7
g   ,

steenbergh

Posted 2017-09-14T14:41:17.417

Reputation: 7 772

1

MATL, 63 50 bytes

-13 bytes thanks to Luis Mendo

Q*qXJ*6Y2HY)wT3$ZrJ3G3$eJ3G&Ol5LZ(J:HG\~3GTX"!+g*c

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

Giuseppe

Posted 2017-09-14T14:41:17.417

Reputation: 21 077

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" – Luis Mendo – 2017-09-18T21:36:21.033

@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. – Giuseppe – 2017-09-18T22:37:02.027

1Indexing is modular, so 0 is the same as "end". Z( assigns to columns. Of course, feel free to ping me in chat! – Luis Mendo – 2017-09-18T23:03:18.447

1

Powershell, 102 bytes

param($w,$h,$n)1..(++$n*$h-1)|%{$l=$_%$h
-join(1..$w|%{[char](32,(33..126|Random))[!$l-or$_-in1,$w]})}

Less golfed test script:

$f = {

param($w,$h,$n)
1..(++$n*$h-1)|%{       # for each lines of the ladder
    $l=$_%$h            # line number in a step
    -join(1..$w|%{      # make a line
        [char](32,(33..126|Random))[!$l-or$_-in1,$w]
    })                  # 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

Output:

0   {
H   S
']UxR
G   ]
3   t
q^R8O
q   y
t   J
U h
YQZ
_ i
3#D
I #
=          m
&          <
]          6
8nmuyw2'Y7%+
o          l
;          !
D          M
Fn[zGfT";RYt
@          B
$          e
z          @
@J[1|:-IS~y<
(          L
:          [
|          q
zBow0T0FnY8)
/          *
e          B
R          p
9{d2(RacBdRj
u          ~
`          l
J          h
v                  t
T                  -
v                  H
'                  Y
IS7{bx2&k@u7]o}>[Vq?
F                  U
?                  U
|                  Q
}                  T
:wv1wEfc6cS;430sigF|
<                  L
:                  }
*                  `
H                  =
L8k5Q/DQ=0XIUujK|c6|
j                  =
!                  p
V                  :
#                  w

mazzy

Posted 2017-09-14T14:41:17.417

Reputation: 4 832

1

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!

Value Ink

Posted 2017-09-14T14:41:17.417

Reputation: 10 608