21
\$\begingroup\$

Challenge

The goal of this challenge is to generate and output a \$16 \times 32\$ (height \$\times\$ width) grid where all cells contain a decoy character, except for a random single cell that contains the target character. The input will be a pair of ASCII (32-126) characters: [target,decoy], where target is the character to find, and decoy is the character that fills the rest of the grid. The selection of the target cell must be uniformly random from among the \$512\$ cells, ensuring that each cell has an equal chance (\$\frac{1}{512}\$) of being chosen for modification.

Examples

The preferable output format should closely resemble these examples below as this enhances the challenge of locating the target character. However, creative solutions are welcome and minor deviations in format (e.g., additional leading/trailing whitespace, alternative ways of representing the grid) are acceptable.

Input

[0,O]

Output

OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOO0OOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO

Input

[v,w]

Output

wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wvwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww

[target,decoy] suggestions

[0,O] [1,l] [1,I] [2,Z] [5,S] [8,B] [v,u] [m,n]
[b,d] [p,q] [C,G] [E,F] [V,U] [V,Y] [s,z] [6,9]
[D,O] [&,8] [C,O] [$,S] [R,P] [8,3] [4,A] [c,o]
\$\endgroup\$
5
  • \$\begingroup\$ Can we reverse the input i.e. decoy followed by target? \$\endgroup\$
    – Graham
    Commented Feb 28 at 19:24
  • \$\begingroup\$ Sure. Both [target,decoy] or [decoy,target] are fine. \$\endgroup\$
    – vengy
    Commented Feb 28 at 19:25
  • \$\begingroup\$ I've VTCed because you need to specify the acceptable output formats. \$\endgroup\$
    – Shaggy
    Commented Feb 29 at 22:49
  • \$\begingroup\$ Like Shaggy said, there seems too much wiggle room. For example in C, is char grid[16][32] an acceptable output format, like f(t,d,char g[][32])? Some would argue that a 2D grid layout is implicit in a 2D array, unlike in a string where newlines are needed. Especially in languages like Python where common implementations have pretty-printing of 2D arrays. \$\endgroup\$ Commented Mar 3 at 0:41
  • \$\begingroup\$ One of your test-cases has a non-ASCII character: "¢". The challenge part says "The input will be a pair of ASCII characters". Perhaps that's intended as a bonus for answers that support unicode or an 8-bit character set? \$\endgroup\$ Commented Mar 3 at 0:43

38 Answers 38

1
2
2
\$\begingroup\$

Swift 5.9, 138 130 105 bytes

let h={let s=([$0+""]+{[_].init}()($1,511)).shuffled()
(0...15).map{print(s[$0*32..<$0*32+32].joined())}}

The first argument to h(_:_:) is the "decoy", and the second is the "target".

Try It Online doesn't support a modern enough version of Swift, and Attempt This Online doesn't support Swift at all as of yet. So, here's a link to something entirely different (JDoodle) that'll still get the job done.

Whitespace restored:

let h = {
  let s = ([$0 + ""] + { [_].init }()($1, 511)).shuffled()
  (0...15).map {
    print(s[($0 * 32)..<($0 * 32 + 32)].joined())
  }
}

I'll run through this step-by-step.

let h = { /* ... */ }

Function signatures in Swift are long. So I decided to assign a closure to a variable instead. I was able to infer the types of both arguments and the return value (which is just () anyway, this saved one byte).

let s = ([$0 + ""] + { [_].init }()($1, 511)).shuffled()

There's a lot to swallow here, so I'll go inside out.

  • [_].init is inferred as [String].init; this saves two bytes over Array.init.

  • We toss the initializer in a closure and immediately call it, giving us the same initializer, but with one important difference: all argument labels are removed. This is especially handy for the bulky .init(repeating:count:) initializer.

  • We then call this new label-less initializer with two arguments:

    • the value to repeat (the "target" value, referred to as $1 thanks to implicit parameters)
    • the number of times to repeat it (512 - 1)
  • We prepend (or append, it doesn't matter) an array literal containing one value -- the "decoy". This gives us a 512-element array, containing 511 "targets" and 1 "decoy".

    Notice the trick here with $0 + "" -- appending an empty string gives the type checker a hint that the type of $0 is String, which, combined with other inferences, allows us to drop type signatures entirely.

  • Finally, we call the shuffled() method on this mess, giving us an identical array, except that the "decoy" is now somewhere else. (I'm trusting that Swift's SystemRandomNumberGenerator is good enough for this challenge.)

(0...15).map { /* ... */ }

We create a ClosedRange from 0 to 15 and iterate over it. map is four bytes shorter than forEach, and it behaves identically, with the exception that it'll generate a warning if you don't use the return value (which doesn't exist here anyway).

print(s[($0 * 32)..<($0 * 32 + 32)].joined())

What this basically does is iterate over s in 32-element chunks. For some reason, Swift still doesn't have some sort of chunk(into:) method in the standard library, and implementing one would be overkill for this challenge, so I'm just doing a bit of math instead.

We join the chunks into strings and print them. By default, Swift's print(_:separator:terminator:) function prints a trailing newline, which is exactly what we want here.

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

Assembly (nasm, x64, Linux), 158 bytes

660fc7f56681e5ff0141b810000000b92000000049b90000000000000000
b0586639dd7402b02e41880149ffc166ffc3e2ec66b8010066bf010048be
000000000000000066ba21000f0549ffc875c0

Try it online!

Source

rdrand bp
and bp,511
mov r8,16
p:mov rcx,32
mov r9,a
r:mov al,t
cmp bp,bx
je c
mov al,d
c:mov[r9],al
inc r9
inc bx
loop r
mov ax,1
mov di,1
mov rsi,a
mov dx,33
syscall
dec r8
jnz p
section .data
a times 33 db 10
\$\endgroup\$
2
\$\begingroup\$

VBA Excel, 43 54 bytes

[b1:ag16]=[a1]:cells(int(rnd*16+1),int(rnd*32+2))=[a2]
  • Input the values target and decoy into the cells A1:A2
  • Run the code in immediate window

enter image description here

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Just curious, does your random method (pick a random row, then a random cell within that row) agree with each cell having a \$\frac{1}{512}\$ chance of being chosen? Probability was never a strong point. Thanks. \$\endgroup\$
    – vengy
    Commented Mar 23 at 18:10
  • 1
    \$\begingroup\$ Looks like it's okay: P(specific cell) = P(row) \$\times\$ P(cell in row) \$ = \frac{1}{16} \times \frac{1}{32} = \frac{1}{512}\$ \$\endgroup\$
    – vengy
    Commented Mar 23 at 18:21
  • 5
    \$\begingroup\$ @vengy It is a very good point. I have just run 100000 cycles and I have found out that the columns B and Q and rows 1 and 16 are populated about 4 times less frequently when I use the formula cells(rnd*31+1,rnd*15+2). I will optimize the code. Thanks for paying attention. \$\endgroup\$ Commented Mar 23 at 18:36
1
\$\begingroup\$

Lua, 110 bytes

Header

-- Get inputs
t,d=io.read(),io.read()

-- Randomise seed
math.randomseed(os.time())

Main code

g={}for i=1,512 do g[i]=d end g[math.random(1,512)]=t for j=1,#g do io.write(j%32==0 and g[j].."\n"or g[j])end

Input is on separate lines, first the target, then the decoy.

Try it online!


Explanation

In the header, we get the inputs t (target) and d (decoy). We set the seed of math.random so that math.random can be randomised every run.

In the main code, we create a grid and populate it with decoys:

g = {}
for i=1,512 do
    do g[i]=d
end

After that, we set a random cell to the target, t.

g[math.random(1,512)] = t

And then we print the grid. At the end of a row, we add a new line.

for j=1,#g do
   io.write(j%32 == 0 and g[j] .. "\n" or g[j])
end
\$\endgroup\$
1
\$\begingroup\$

GolfScript, 22 bytes

~511*+{;9.?rand}$32/n*

Try it online!

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

J, 26 25 bytes

{{x(<(?16),?32)}16 32$y}}

Left argument is the target, right argument is the decoy.

this probably could be optimized, I'm new to J and array programming in general.

This uses a J direct definition because otherwise the random numbers would only be generated once on assignment and never again.

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Could you add a Try it online! example? Thanks. \$\endgroup\$
    – vengy
    Commented Mar 8 at 22:05
  • \$\begingroup\$ @vengy done (altho the code there is a bit different since it looks like the TIO interpreter doesn't support {{ and }}) \$\endgroup\$ Commented Mar 8 at 22:41
1
\$\begingroup\$

Qbasic, 106 bytes

SUB F(a$,b$):FOR i=1TO 16:FOR j=1TO 32:?a$;:NEXT:PRINT:NEXT:LOCATE INT(RND*16+1),INT(RND*32+1):?b$:END SUB

F "O", "0"

Output:

enter image description here

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

YASEPL, 61 bytes

=u=t'=d'=r¢0,512=i$`1!)d!i}7,r,3!)t`3!~$i%32+[2>""`2!i+}2,513

takes in 2 inputs. first one is the target, second one is the decoy.

\$\endgroup\$
1
2

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.