26
\$\begingroup\$

(Essentially the inverse of Find the needle in the haystack)

Given two tuples, (w, h) and (x, y), generate a haystack composed of a single random printable ASCII character of w width and h height with a needle made of a different random printable ASCII character at (x, y) when measured from the upper-left.

For example, when given (5,4) for the width and height, and (3,1) (zero-indexed) for the location of the needle, a possible haystack could be the following:

#####
###N#
#####
#####

Another possibility could be

*****
***$*
*****
*****

among hundreds of others.

Rules and Clarifications

  • Input and output can be given by any convenient method. This means you can take input as a list of list of integers, as a single string, as two integers via command-line and a tuple via function argument, etc.
  • You can print the result to STDOUT or return it as a function result.
  • Either a full program or a function are acceptable.
  • You can choose whether the (x, y) tuple is zero-indexed or one-indexed, but please specify in your solution which you're using.
  • You do not get to pick which characters to use. That's part of the challenge - randomly selecting the characters.
  • Every possible output for a given input must have a non-zero chance of appearing, but the randomness doesn't need to be uniform.
  • The haystack is guaranteed to be at least 2x2 in size, so it's unambiguous which is the needle and which is the hay.
  • There is only ever one needle, and it's only ever one character in size, and it's guaranteed to be within the boundaries of the haystack.
  • Standard loopholes are forbidden.
  • This is so all usual golfing rules apply, and the shortest code (in bytes) wins.
\$\endgroup\$
  • \$\begingroup\$ Can we return a flat list of characters? \$\endgroup\$ – TFeld Oct 16 '19 at 15:02
  • 4
    \$\begingroup\$ Obligatory xkcd about the choice of the characters. Applies to a few early answers... :p \$\endgroup\$ – Arnauld Oct 16 '19 at 15:34
  • 2
    \$\begingroup\$ @Arnauld I don't know what was the magic here, but I completely read the challenge as I can use any ASCII printable characters "that I like", instead of "random", and it is funny another person also did same exact thing! I didn't mean to implement the random in such a beautiful way :P \$\endgroup\$ – Night2 Oct 16 '19 at 16:17
  • 1
    \$\begingroup\$ @UnrelatedString Yes and yes? Those are standard I/O rules. \$\endgroup\$ – AdmBorkBork Oct 17 '19 at 12:23
  • 1
    \$\begingroup\$ @TaylorScott Yes, that's covered in the opening paragraph. The two characters need to be different. \$\endgroup\$ – AdmBorkBork Nov 18 '19 at 13:34

33 Answers 33

12
\$\begingroup\$

JavaScript (Node.js),  122 120 106  103 bytes

Recursively builds the output character by character. The coordinates are 0-indexed.

(w,h,x,y)=>(s=new Date%9023,g=X=>Y<h?Buffer([X-w?(x-X|y-Y?s+1:s%96)%95+32:13])+g(X<w?X+1:!++Y):'')(Y=0)

Try it online!

How?

Problem

To generate the haystack and the needle, we could either:

  • generate a random haystack and process some loop to generate a random needle until it's different from the haystack
  • shuffle the whole range of printable characters and pick the first 2 of them

Unfortunately, both approaches are rather lengthy in JS.

Solution

We use instead a method that guarantees to generate 2 distinct characters with a single random number and without any loop.

We pick a random seed \$s\$ in \$[0..9022]\$ and define the haystack \$h\$ and needle \$n\$ as:

$$\begin{align}&h=(s+1)\bmod 95\\ &n=(s\bmod 96)\bmod 95\end{align}$$

(we then need to add \$32\$ to turn them into printable ASCII codes)

Basically, \$h\$ follows the pattern:

$$1,2,3,...,94,0,1,2,3,...$$

while \$n\$ follows the pattern:

$$0,1,2,3,...,94,\color{red}0,0,1,2,3,...$$

The sequences are progressively shifted relative to each other because of the extra \$0\$ in the needle pattern.

This code shows that it does eventually lead to all possible pairs \$(h,n)\$ with \$h\neq n\$ (there are \$95\times 94=8930\$ of them).

And because we need only one random number, we can afford to use the current timestamp in milliseconds as our entropy source with new Date%9023 instead of the longer Math.random()*9023.

Commented

(w, h, x, y) => (      // w = width, h = height, (x, y) = coordinates
  s = new Date % 9023, // s = random seed in [0..9022]
  g = X =>             // g = recursive function taking X
    Y < h ?            //   if we've not reached the end of the grid:
      Buffer([         //     append the next character:
        X - w ?        //       if we haven't reached the end of the line:
          ( x - X |    //         if this is not the position of the needle:
            y - Y ?    //
              s + 1    //           append the haystack character
            :          //         else:
              s % 96   //           append the needle character
          ) % 95 + 32  //
        :              //       else:
          13           //         append a linefeed
      ]) +             //
      g(X < w ? X + 1  //     append the result of a recursive call
              : !++Y)  //     with either (X+1, Y) or (0, Y+1)
    :                  //   else:
      ''               //     stop recursion
)(Y = 0)               // initial call to g with X = Y = 0
\$\endgroup\$
  • 1
    \$\begingroup\$ Never seen new Date be used to generate a random seed before. Cool. \$\endgroup\$ – Daniel Vestøl Oct 17 '19 at 12:00
  • 2
    \$\begingroup\$ @DanielVestøl, it's a common tactic in challenges where "random" is un(der)specified. \$\endgroup\$ – Shaggy Oct 17 '19 at 23:30
6
\$\begingroup\$

Jelly, 14 13 bytes

p/⁼€ịØṖẊ¤s⁸Ḣ¤

Try it online!

-1 byte thanks to Unrelated String

Returns a list of lines. The last line in the Footer section displays it as a square. Takes input as [w, h] and [y, x], where x and y are 0-indexed.

How it works

p/⁼€ịØṖẊ¤s⁸Ḣ¤ - Main link. Takes [w, h] on the left and [y, x] on the right
p/            - Reduce Cartesian product over the arguments.
                This yields a list of co-ordinates from (1, 1) to (h, w)
   €          - Over each list:
  ⁼           -   Is it equal to [x, y]?
              - This yields a list where every element except 1 is 0
        ¤     - Create a nilad:
     ØṖ       -   Printable ASCII characters
       Ẋ      -   Shuffled
    ị         - Index into the shuffled characters, replacing 1 with the first char in the shuffled list and 0 with the last. Therefore, the two characters will be distinct
            ¤ - Create a nilad:
          ⁸   -   Yield [w, h]
           Ḣ  -   Extract w
        s     - Split the list of characters into rows of length w
              - Implicitly output
\$\endgroup\$
  • 1
    \$\begingroup\$ -1 byte if you take [y, x] instead of [x, y] so you can drop the U \$\endgroup\$ – Unrelated String Oct 17 '19 at 12:29
  • 1
    \$\begingroup\$ @UnrelatedString Huh, weird. That didn't work for me when I first posted it, but is now. Thanks! \$\endgroup\$ – caird coinheringaahing Oct 17 '19 at 12:34
6
\$\begingroup\$

Excel VBA, 128 118 106 94 96 bytes

-12 bytes inspired by agtoever
-12 bytes thanks to Taylor Scott, VBA extraordinaire
+2 bytes and -1 bug thanks to Taylor's unnecessary, intimidating, and much appreciated work

Sub n(w,h,x,y)
a=94*Rnd
[A1].Resize(h,w)=Chr(a+32)
Cells(y,x)=Chr(32+(a+93*Rnd+1)Mod 95)
End Sub

Input and output are one-indexed. Output is to the top left cell range of the active sheet.

a=94*Rnd+32: (126-32)*Rnd+32 gives a number between 32 and 126, inclusive.

Range(~)=Chr(a): Fills all the cells with the ASCII character.

Cells(y,x)=Chr(~): Fills just that one cell with the other ASCII character.

(a+62*Rnd)Mod 95+32: {(a+[94-32]*Rnd) Mod (126-32+1)}+32 gives a random number between 32 and 126 inclusive that is not the same as a. (I can't prove that mathematically but 100 million tests showed no collisions.)

Example output:

enter image description here

\$\endgroup\$
  • \$\begingroup\$ Shorter: b=Chr(Asc(a)+1+95*Rnd Mod 127) instead of the do-while loop. \$\endgroup\$ – agtoever Oct 20 '19 at 6:53
  • \$\begingroup\$ Oh. And then you can just insert that statement in Cells(y,x)=... instead of assigning it to b. \$\endgroup\$ – agtoever Oct 20 '19 at 6:55
  • 1
    \$\begingroup\$ @agtoever I tried that when I was trying to get the previous suggestion to work. As written, b ends up in the range 0-126 instead of 32-126 although it's always unique from a. I massaged it a bit to get the most recent edit, which had 0% failure rate over 100 million runs. \$\endgroup\$ – Engineer Toast Oct 22 '19 at 14:17
  • 1
    \$\begingroup\$ You can get down to 94 bytes if you use [A1].Resize(h,w)=Chr(a) \$\endgroup\$ – Taylor Scott Nov 14 '19 at 22:36
  • 1
    \$\begingroup\$ The 62 in the needle declaration didn't quite sit well with me, so I went and checked the math - it looks like as written it does avoid all possible collisions of a and b, but, it also fails to give 31 expected b values for every a value. I did work out a solution to this should only cost you two bytes - a=94*Rnd, Chr(a+32) and Chr(32+(a+93*Rnd+1)Mod 95) should give you everything you need. Uh, I've also been working on my own commenting and formatting habits, so here is a needlessly well commented proof of the above. Cheers! \$\endgroup\$ – Taylor Scott Nov 16 '19 at 23:47
5
\$\begingroup\$

PowerShell v6, 102 96 bytes

param($x,$y,$a,$b)$j,$k=' '..'~'|random -C 2
-join((,$j*$x+++'
')*$y|%{"$_$k"[$i++-eq$b*$x+$a]})

Try it online!

This answer, thanks to mazzy, uses the character range feature added in v6 to save several bytes over the more flexible answer below.

PowerShell, 119..105 102 bytes

-16 bytes thanks to mazzy
-1 byte thanks to AdmBorkBork

param($x,$y,$a,$b)$j,$k=32..126|random -C 2
-join((,$j*$x+++'
')*$y|%{[char]($_,$k)[$i++-eq$b*$x+$a]})

Try it online!

Gets two ints in the range of [32,126]. We first make a 1D array out of the first value, appending a new line after every $xchars. Doing this means we also have to increment $x so that our index math isn't affected. We then iterate through the array, and either yield a char-ified first value or the needle. Finally, we join all the yielded values and output it.

Answer is 0-indexed by the way.

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

Python 2, 134 133 120 112 111 bytes

lambda w,h,x,y:zip(*[iter(chr(r[x+y*w==i]+32)for i in range(w*h))]*w)
from random import*
r=sample(range(95),2)

Try it online!

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

Jelly, 11 bytes

QŒṬƤSḂịØṖẊ¤

A monadic Link accepting a list of lists, [[height, width], [row, column]] (1-indexed), which yields a list of lists of characters.

Try it online! (The footer calls the link and joins with newlines.)

How?

QŒṬƤSḂịØṖẊ¤ - Link: [[h, w], [r, c]]
Q           - de-duplicate (i.e. [[h, w]] if [r, c] == [h, w] else [[h, w], [r, c]])
   Ƥ        - for prefixes (of that list):
 ŒṬ         -   get a 2D array with ones at the coordinates specified
    S       - sum (vectorises) (giving us an h*w matrix with zeros almost everywhere,
                                except a 1 at our needle and, if [h, w] != [r,c], a 2 at
                                the bottom-right)
     Ḃ      - modulo two (replacing the 2 with a zero if it exists)
          ¤ - nilad followed by link(s) as a nilad:
       ØṖ   -   list of printable characters
         Ẋ  -   shuffled
      ị     - (left) index into (right) (vectorises)
\$\endgroup\$
4
\$\begingroup\$

Dyalog APL, 24 23 21 bytes

⎕UCS(32+2?95)[⎕∘≡¨⍳⎕]

Try it online! 0-indexed.

-1 thanks to ngn, -2 thanks to Adám suggesting to use a different I/O format.

\$\endgroup\$
  • \$\begingroup\$ (⎕UCS 32+2?95) -> ⎕UCS(32+2?95) \$\endgroup\$ – ngn Oct 16 '19 at 15:26
  • \$\begingroup\$ ⎕UCS(32+2?95)[⎕∘≡¨⍳⎕] \$\endgroup\$ – Adám Oct 17 '19 at 11:48
4
\$\begingroup\$

Python 2, 133 bytes

from random import*
r=range
def f(h,w,x,y):
 p=sample(r(32,127),2)
 for i in r(h):
	print ''.join(chr(p[i==y and j==x])for j in r(w))

Try it online!

-12 thanks to Value Ink for suggesting using a loop comprehension. -2 thanks to Unrelated String for suggesting python 2 instead of python 3 to get rid of parenthesis in the print function!

\$\endgroup\$
  • 4
    \$\begingroup\$ Welcome to PPCG! My first thought was to wrap the innermost loop into a loop comprehension that is then joined together and printed, to eliminate both the end='' part as well as the additional print() call after the loop. This cut the size down to 135 bytes. Try it online! \$\endgroup\$ – Value Ink Oct 17 '19 at 0:50
  • \$\begingroup\$ You can also shave two more off by using Python 2 instead of 3, but it's minor. \$\endgroup\$ – Unrelated String Oct 17 '19 at 6:47
  • \$\begingroup\$ print(end=chr(p[i==y and j==x])) saves three bytes \$\endgroup\$ – Black Owl Kai Oct 18 '19 at 6:38
3
\$\begingroup\$

Python 2, 110 bytes

from random import*
w,h,x,y=input()
m,n=sample(map(chr,range(32,127)),2)
l=eval(`[[m]*w]*h`)
l[x][y]=n
print l

Try it online!

I copied TFeld's solution and managed to golf a char using list assignment. The eval() trick is used to make a mutable matrix to avoid the list mutation applying to every row.

111 bytes

lambda w,h,x,y:[[chr(r[x^i<1>y^j]+32)for i in R(w)]for j in R(h)]
from random import*
R=range
r=sample(R(95),2)

Try it online!

A smaller change that only tied. Calling the function multiple times always give the same random choices, which I hope is OK.

109 bytes

lambda w,h,x,y:[m*w]*y+[m*x+n+m*(w+~x)]+[m*w]*(h+~y)
from random import*
m,n=sample(map(chr,range(32,127)),2)

Try it online!

A shorter function making the list of lines via multiplication. Also generates the characters just once.

\$\endgroup\$
  • \$\begingroup\$ Nice! I didn't know about that eval trick. \$\endgroup\$ – quintopia Oct 31 '19 at 1:19
2
\$\begingroup\$

Perl 5, 86 bytes

($,,$b)=keys%{{map{chr,1}33..126}};$_=($,x$F[0].$/)x$F[1];s;(.*
){$F[3]}.{$F[2]}\K.;$b

Try it online!

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

Julia 1.0, 71 bytes

f(w,h,x,y)=(z=unique(rand(' ':'~',9));g=fill(z[1],(h,w));g[y,x]=z[2];g)

x,y are one indexed. Returns a 2d array of characters, I spent the extra bytes to make sure the default printing has the right orientation (' for transpose no longer works because they stick to a strict mathematical meaning). Getting two distinct randoms is surprisingly verbose, this has about a 1e-18 chance of failing to do so, one more byte could make it 1e-196.

Try it online!

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

J, 21 bytes

u:@(32+2?95){~#.=i.@[

Try it online!

Inspired by dzaima's APL answer.

Thanks to Galen and Adam for the randomize fix.

\$\endgroup\$
  • \$\begingroup\$ Fix by Adam \$\endgroup\$ – Galen Ivanov Oct 16 '19 at 16:15
  • \$\begingroup\$ You need two tuples as input \$\endgroup\$ – Galen Ivanov Oct 16 '19 at 16:18
  • \$\begingroup\$ Yeah I just noticed that, will fix. Thanks for the other fix btw. \$\endgroup\$ – Jonah Oct 16 '19 at 16:19
2
\$\begingroup\$

Octave with Statistics Package, 45 bytes

@(x)randsample(' ':'~',2)(sparse(x{:},0:1)+1)

The input is a cell array of 2 numeric vectors of length 2: {[h y] [w x]}, with x,y 1-based.

Try it online!

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

Ruby, 62 bytes

->w,h,x,y{a,b=[*?\s..?~].sample 2;r=[a*w]*h*$/;r[y*-~w+x]=b;r}

Try it online!

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

Pyth, 56 50 48 41 bytes

JEKE=TE=Yrd\~=Zh.SYVJVQ ?qHK?qNTpeYpZpZ)d

I'm somewhat struggling to golf Pyth, but posting this to force myself to learn.

Edit 1: Golfed it down a bit, and made it an actual solution -6 bytes

Edit 2: Looked at it after posting it and realized a few bytes save by ignoring space. -2 bytes

Edit 3: Today I learned about character ranges, which shortens things significantly. -7 bytes

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

Excel + CSV, 104 bytes

,,,,=94*RAND()+32,=REPLACE(REPT(REPT(CHAR(E1),A1)&"
",B1),D1*A1+D1+C1+1,1,CHAR(MOD(E1+62*RAND(),95)+32))

Save as CSV, add input as A1 - D1. Output will be in F1.

Using @Engineer Toast's solutoin for generating 2 unique characters.

Needle position is 0-indexed, which is curious, as Excel itself if 1-indexed. Changing to 1-indexed input adds 3 bytes ((D2-1)*(A2+1)+C2 instead of D1*A1+D1+C1+1).

\$\endgroup\$
  • 1
    \$\begingroup\$ @Arnauld, it does not. Thanks for poingin out. Have updated. \$\endgroup\$ – Wernisch Oct 29 '19 at 10:34
  • \$\begingroup\$ Just wanted to let you know that the indicated solution for the needle character is not quite correct. You should switch to CHAR(MOD(E1+93*RAND()+1,95)+32) to insure that your solution covers all possible combinations of needle and haystack \$\endgroup\$ – Taylor Scott Nov 22 '19 at 20:21
1
\$\begingroup\$

SOGL, 18 bytes

 ~Δψ] ~Δψ⁴⁴=}A*∙až

Try it here! 1-indexed.

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

Add++, 65 bytes

D,g,?!,
L,c95Rdb[€BXd¦=BFV#@G+b[95€Ω%31€+€CA€RbU‽g$€=$€Ω:A$pbUp$T

Try it online!

Takes input as [y x] and [w h]. x and y are 1-indexed. Outputs a list of lines.

Added 17 bytes to make sure the needle is distinct.

How it works

We start by generating two ranges from \$1\$ to \$95\$ inclusive, before choosing a random value from each. If the two values are equal, we add one to the one of them. We then add \$31\$ to each, yielding two characters ord points in the ASCII range. Finally, we convert them to characters.

Next, we generate a list of all co-ordinates in the grid, and compare them with [y x]. If the co-ordinates match, we yield \$1\$, otherwise \$0\$. Next, we index each of these \$1\$s and \$0\$s into the two characters, creating a grid of \$0\$ characters with 1 \$1\$ character in it at [y x]. Finally, we retrieve the width and split the grid into that many rows.

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

PHP, 113 109 bytes

for([,$w,$h,$x,$y]=$argv,$a=range(' ','~'),shuffle($a);$i++<$h;print"
")for(;$$i++<$w;)echo$a[$i-$y||$$i-$x];

Try it online!

Pass inputs as command arguments ($argv) in order of w, h, x and y. The x and y are one-indexed.

for(
  [,$w,$h,$x,$y]=$argv, // put inputs from $argv array into 4 short named variables
  $a=range(' ','~'),    // create $a array containing printable ASCII characters
  shuffle($a);          // shuffle the array
  $i++<$h;              // loop $h times (rows)
  print"\n"             // print a newline after every row
)
  for(;$$i++<$w;)       // loop $w times (columns)
    echo                // print
      $a[               //   a character from $a (1st char for needle and 2nd for heystack)
        $i-$y ||        //   when row and y don't match
        $$i-$x          //   or when col and x don't match (will be false only for needle)
      ];
\$\endgroup\$
1
\$\begingroup\$

C# (Visual C# Interactive Compiler), 145 bytes

(a,b,c,d)=>{int l=0;for(var j=Enumerable.Range(32,95).OrderBy(k=>Guid.NewGuid()).ToList();l<a*b;)Write((char)j[l==c*a+d?1:0]+(++l%a<1?"\n":""));}

Try it online!

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

Icon, 119 bytes

procedure f(w,h,x,y)
until m:=char(32+?95)&n:=char(32+?95)&m~==n
t:=[];1to h&put(t,repl(m,w))&\z
t[y,x]:=n
return t
end

Try it online!

xand yare 1-indexed

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

Python 3, 137 bytes

lambda w,h,x,y,c=chr:"\n".join([c(a)*w,c(a)*x+c(n)+c(a)*(w-x-1)][r==y]for r in range(h));a,n=__import__("random").sample(range(32,127),2)

Try it online!

Uses zero-based indexing for the needle position.

\$\endgroup\$
  • \$\begingroup\$ from random import* is shorter than __import__("random"). 136 bytes. \$\endgroup\$ – Value Ink Oct 17 '19 at 0:54
1
\$\begingroup\$

Perl 6, 57 bytes

{(' '..'~').pick(2)[0 xx$^a*$^b-1,1;*].pick(*).rotor($a)}

Try it online!

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

Charcoal, 17 bytes

UONN‽γJNN‽Φγ¬⁼ιKK

Try it online! Link is to verbose version of code. Explanation:

UONN‽γ

Draw a rectangle of the given width and height using a random printable ASCII character.

JNN

Jump to the 0-indexed position of the needle.

‽Φγ¬⁼ιKK

Print a random printable ASCII character, but filtering out the character under the cursor.

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

Red, 156 bytes

func[w h x y][c: :collect p: take/part random c[repeat i 95[keep to sp 32 + i]]2
c[repeat i h[keep/only c[repeat j w[keep pick p i * w + j
=(y * w + x)]]]]]

Try it online!

x and y are 1-indexed. Returns a list of strings.

Readable:

f: func [w h x y] [
    c: take/part random collect [
        repeat i 95 [
            keep to sp 32 + i
        ]
    ] 2
    collect[
        repeat i h [
            keep/only collect [
                repeat j w [
                    keep pick c i * w + j = (y * w + x)
                ]
            ]
        ]
    ]
]
\$\endgroup\$
1
\$\begingroup\$

Python 2, 144 132 131 bytes

from random import*
i,j,k,l=input()
n,h=sample(range(32,127),2)
for x in range(j):a=[chr(n)]*i;a[k]=chr((n,h)[x==l]);print`a`[2::5]

Try it online!

Corrected the problem with the guaranteed uniqueness of the characters and saved 12 bytes along the way.

\$\endgroup\$
  • 1
    \$\begingroup\$ I liked the idea of this solution well enough that I shaved off 3 more bytes for you: tio.run/… \$\endgroup\$ – quintopia Oct 30 '19 at 9:16
  • \$\begingroup\$ Nice and also different enough for you to post as your own if you wish :) \$\endgroup\$ – ElPedro Oct 30 '19 at 12:28
  • \$\begingroup\$ Eh, it's not that different. It is a direct modification of yours edited directly on TIO. Posting it separately would have been actual effort. \$\endgroup\$ – quintopia Oct 30 '19 at 19:02
1
\$\begingroup\$

Forth (gforth), 140 bytes

include random.fs
: x 95 random 32 + ;
: f x -rot 0 do cr dup 0 do 2over i j d= >r over r> if begin x 2dup - until nip then emit loop loop ;

Try it online!

0-indexed

Code Explanation

include random.fs        \ import the random library

\ Generate a random number in range 32 to 126 inclusive
: x                      \ start a new word definition
  95 random              \ generate a random number between 0 and 94
  32 +                   \ add 32
;                        \ end word definition

: f                      \ start a new word definition
  x -rot                 \ generate a random number for the haystack, then move it
  0 do                   \ loop from 0 to h-1 (inclusive)
    cr                   \ output a newline
    dup 0 do             \ loop from 0 to w-1 (inclusive)
      2over i j d=       \ check if this is the needle square
      >r over r>         \ hide result, grab a copy of the haystack char, then grab result back
      if                 \ if it is a needle
        begin            \ begin indefinite loop
          x 2dup -       \ generate a new random number and compare to haystack char
        until            \ only end loop when values differ
        nip              \ drop haystack char
      then               \ end if block
      emit               \ output ascii char for value on top of stack
    loop                 \ end row loop
  loop                   \ end column loop
;                        \ end word definition
\$\endgroup\$
1
\$\begingroup\$

C (clang), 87 bytes

f(w,h,x,y){x+=y*w;h*=++w;for(y=time(0)%9023;h--;)putchar(h%w?(x--?y+1:y%96)%95+32:10);}

Try it online!

Stealing from @Arnauld answer

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

K (oK), 27 23 bytes

-4 bytes thanks to ngn!

{`c$(32+-2?95)x#&/y=!x}

Try it online!

0-indexed x and y

Similar to Dzaima's APL and Jonah's J solutions.

\$\endgroup\$
  • 1
    \$\begingroup\$ (x/y)=x#!*/x -> x#&/y=!x \$\endgroup\$ – ngn Oct 19 '19 at 17:17
  • \$\begingroup\$ @ngn That's much better than my naive solution. Thanks! \$\endgroup\$ – Galen Ivanov Oct 19 '19 at 18:34
  • \$\begingroup\$ @ngn Clever use of the odometer for 2d matching! \$\endgroup\$ – Galen Ivanov Oct 19 '19 at 18:47
1
\$\begingroup\$

05AB1E, 15 bytes

žQΩIPמQΩIPǝ¹нô

Coordinates are 1-indexed. Outputs as a list of lines.

Try it online (» in the footer joins the list of strings by newlines to pretty-print, feel free to remove it to see the actual output).

Explanation:

žQ              # Push all printable ASCII characters
  Ω             # Pop and push a random character
   IP           # Push the first input (rectangle-size), and take its product
     ×          # Repeat the random character that many times as string
      žQΩ       # Push a random character again
         IP     # Push the second input (1-based coordinate), and take its product as well
           ǝ    # Insert the random character at this (0-based) index into the string
            ¹н  # Push the first input again, and only leave its first value (width)
              ô # Split the string into parts of that size
                # (after which the resulting list of strings it output implicitly as result)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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