27
\$\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 at 15:02
  • 4
    \$\begingroup\$ Obligatory xkcd about the choice of the characters. Applies to a few early answers... :p \$\endgroup\$ – Arnauld Oct 16 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 at 16:17
  • 1
    \$\begingroup\$ @UnrelatedString Yes and yes? Those are standard I/O rules. \$\endgroup\$ – AdmBorkBork Oct 17 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 at 13:34

33 Answers 33

1
\$\begingroup\$

Japt -R,34 30 29 24 bytes

;E=öx)ÎpU*V hW*U+XEg1)òU

Try it

5 Bytes saved thanks to @Shaggy.

Inputs are U,V => size , W,X => needle coords 0 indexed

 ;E=   // set of printable characters 
     öx) // random permutation 
 Î // => g0  pU*V    repeats U*V times first element of set
           hW*U+XEg1) // overwrite at W,X with 2nd element 
                      òU // split
\$\endgroup\$
  • \$\begingroup\$ @Shaggy my first try, the best I can do, any suggestions are implicitly welcome! \$\endgroup\$ – AZTECCO Oct 20 at 20:49
  • 1
    \$\begingroup\$ A few quick savings for you here. \$\endgroup\$ – Shaggy Oct 22 at 9:11
  • \$\begingroup\$ Thanks @Shaggy! The good thing is that I 've understood your improvements, though I'm still far from a good usage of this language, maybe due to my poor experience in JS \$\endgroup\$ – AZTECCO Oct 22 at 13:34
  • \$\begingroup\$ you don't really need a JS background to learn Japt. \$\endgroup\$ – Shaggy Oct 22 at 17:56
0
\$\begingroup\$

Zsh, 108 bytes

Needle location is 1-indexed

repeat $2 : $[h=r++?h:RANDOM%95]&&(repeat $1 s+=${(#)$((n=r-$4||++c-$3?h:(n=RANDOM%94)+(n>=h),32+n))};<<<$s)

Try it online!

repeat $2
  # set hay when row is 0 (shorter than setting it before due to the cost of "(( ))")
  # ": $[  ]" always exits true. "((  ))" would exit false if hay == 0
  : $[hay = row++ ? hay : RANDOM % 95] && (
    # inner loop in (subshell), $str and $col will be empty every time
    repeat $1
      # ${(#)$((x))} expands to the Unicode character at codepoint $x
      str+=${(#)$((offset =
        row - $4 || ++col - $3
        ? hay
        : (offset = RANDOM % 94) + (offset >= hay),
        32 + offset
      ))}
      <<< $str
  )

Proof of correctness by exhaustion, for all combinations of RANDOM%95 and RANDOM%94.

\$\endgroup\$
0
\$\begingroup\$

C (clang), 130 117 116 109 106 bytes

c[2];f(w,h,x,y){x+=y*w;for(h*=++w;y++<h|*c==c[1];)c[y%2]=time(0)%94+33;for(;h--;)printf(h%w?c+!x--:"\n");}

Try it online!

Saved 13 thanks to @ceilingcat Didn't thought using just only time() was enough And also didn't thought printf accepted a int pointer as a format string!

Needle is 0 indexed

c[2]; // needle and hay stored in array 
f(w,h,x,y){
 x+=y*w; // sets counter for needle (x no more needed)
 for(
     h*=++w; // while incrementing w for newline sets counter for haystack 
     y++<h  // more than 2 iterations to fill array
     |*c==c[1]; // until they're different 
     )
     c[y%2]=time(0)%94+33; // assign value to array (I've excluded spaces )
 for( ;h--; ) printf(h%w?c+!x--:"\n")
 // output: on h%w =0 => newline 
 //              if  x != 0 => hay
 //              when x=0 => needle 
 //              and continue to finish haystack 
\$\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.