# Challenge

Generate two $$\16 \times 16\$$ grids, each initially filled with "@" symbols and spaces. Each cell in the grids should be independently filled with an "@" or a space, with each character having an equal probability ($$\50\%\$$) of being chosen for each cell. This ensures that both grids start off identically, with all possible configurations of each grid having the same probability of occurrence, corresponding to a uniform distribution across all possible grid states.

After generating these identical grids, modify a single, randomly selected cell in the second grid by either adding or removing an "@" symbol. This modification guarantees that the second grid differs from the first grid in exactly one position. The selection of this cell must be uniformly random from among the $$\256\$$ cells, ensuring that each cell has an equal chance ($$\\frac{1}{256}\$$) of being chosen for modification.

Input

None

Output

Both grids side by side, separated by a vertical bar "|", to visually compare them and spot the single difference. e.g. row $$\3\$$, col $$\10\$$.

@ @ @ @   @ @ @@|@ @ @ @   @ @ @@
@@@ @@   @    @| @@@ @@   @    @
@ @@@@@@ @   @ | @ @@@@@@@@   @
@  @  @@ @@ @ |  @  @  @@ @@ @
@@@  @@ @@  @  @|@@@  @@ @@  @  @
@ @   @ @@  @@|  @ @   @ @@  @@
@ @ @@ @  @@ @@@|@ @ @@ @  @@ @@@
@ @       @@    |@ @       @@
@ @@   @@@ @|    @ @@   @@@ @
@@ @    @@ @@  | @@ @    @@ @@
@    @@@@   @ @@|@    @@@@   @ @@
@@ @@ @@  @@@ @@|@@ @@ @@  @@@ @@
@@@ @ @@    @ @| @@@ @ @@    @ @
@ @  @  @ @  |   @ @  @  @ @
@@@@ @@@@@ @  @@|@@@@ @@@@@ @  @@
@  @@@ @@@@ @@@| @  @@@ @@@@ @@@
• Do the characters have to be @, |, and space? Also just to make sure, we don't have to output the position of the difference right? Feb 15 at 19:51
• This task seems so random. Is there some purpose to it? Feb 16 at 13:23
• Just a random idea to create a simple Spot The Difference puzzle. Feb 16 at 13:29
• Are the grids random? Is this challenge missing [random] tag? Feb 16 at 17:06

# Jelly,  25  22 bytes

⁹ḶẊ⁾ @Ẋḷ\⁹¡¥Ɱs⁴Z€j€”|Y

Try it online!

### How?

⁹ḶẊ⁾ @Ẋḷ\⁹¡¥Ɱs⁴Z€j€”|Y - Link: no arguments
⁹                      - 256
Ḷ                     - lowered range {256} -> [0..255]
Ẋ                    - shuffle -> IsEqualIndicators
⁾ @                 - list of characters -> " @"
Ɱ          - map across {i in IsEqualIndicators} with:
¥           -   last two links as a dyad - f(" @", i):
Ẋ                -     shuffle {" @"} -> " @" or "@ "
⁹¡            -   repeat {i} times: (i.e. a no-op when i=0)
\              -     cumulative reduce {ShuffledCharacters} by:
ḷ               -       left argument
(first takes " @" to "  ", or "@ " to "@@"
then further applications have no more effect)
s⁴        - split into chunks of 16
Z€      - transpose each
j€”|  - join each with '|'
Y - join with newlines

Here is a difference spotter which accepts an output and replaces any space on one of the two sides where there is an @ on the other with a +.

# Google Sheets, 170 161 bytes

Formula in $$\A1\$$

=INDEX(LET(g,MAP(A25:P40,LAMBDA(_,IF(COINFLIP(),"@"," "))),r,ROW(1:16),{g,IF(r,"|"),IF((r=RANDBETWEEN(1,16))*(TOROW(r)=RANDBETWEEN(1,16)),IF(g="@"," ","@"),g)}))

• Nice! Save 6 bytes with map(A25:P40,lambda(_ instead of makearray() and another 3 bytes with if(g="@"," ","@") instead of ifs(). Feb 16 at 7:10
• @doubleunary, thanks! I initally had IFS(g="@"," ",g=" ","@") and changed it to IFS(g="@"," ",1,"@") I didn't think of using IF. (:
– z..
Feb 16 at 7:18

# Python 3, 147141139138 124 bytes

-8 bytes thanks to Mukundan314. -14 bytes thanks to Jonathan Allan.

from random import*
g=getrandbits
n=g(4)
r=16
while r:r-=1;s=g(16);print(f'{s:16b}|{s^(r==n)<<g(4):16b}'.translate('@ '*25))

Try it online!

## Explanation (outdated)

That's a lot of use out of Python's random module. First, it iterates over $$\[0, 16)\$$ shuffled with for r in sample(a:=range(16),16). The random ordering means that r will only be zero once, but it can be on any of the 16 iterations. When this is the case, the row that it outputs in that iteration will contain the difference.

It represents cells as bits and therefore, rows as 16-bit integers. Luckily, getrandbits(16) can generate a random 16-bit integer like 16846 or 01000001110011102. (Though randrange(65536) or randint(0,65535) would've worked just as well.)

Now, for the interesting bit manipulation. To toggle a random cell, it takes the bitwise XOR of the row with a 16-bit integer that has only one randomly chosen bit turned on like 00010000000000002. This integer can be made by left shifting 1 bitwise by a random integer in $$\[0, 16)\$$. When r is zero, r<1 is True, which can be used as if it were 1 in numerical operations. choice(a) returns a random choice from $$\[0, 16)\$$. Therefore, s^(r<1)<<choice(a) computes something like:

00000000000000012
<<               12
--------------------
00010000000000002
^ 01000001110011102
--------------------
01010001110011102

However, when r is not zero, left shifting False or 0 bitwise or taking the bitwise XOR of it with something does nothing.

Finally, in order to represent it as a string and turn the bits into @s and spaces, it first uses a format string {s:16b}. This converts the integer into binary and pads it with enough spaces to increase its length to 16, turning 16846 into ' 100000111001110'. It then uses .translate({49:64,48:32}) (a table of the characters' respective ASCII ordinal numbers) to turn it into ' @ @@@ @@@ '.

• Save seven bytes by only using getrandbits for all your random needs - TIO Feb 16 at 13:25
• Make that eight switching to a while loop TIO Feb 16 at 13:37
• ...make that fourteen by using a string, '@ '*25, rather than an ordinal map in your translation - TIO Feb 16 at 13:46
• @JonathanAllan Thanks, thanks, and... wait, str.translate can do that? That function's always been in my blind spot... Thanks! Feb 16 at 14:40

# JavaScript (V8), 107 bytes

A full program.

for(R=Math.random,v=R(n=16)*512|0;n--;print(s))for(k=33,m=R(s="")*2**k;k--;)s+=" @|"[k-16?m>>k%17&1^!v--:2]

Try it online!

# C (gcc), 106 bytes

f(v,n,m,k){for(v=rand(n=16)&511;n--;)for(m=rand(k=33);~k--;)putchar(~k?k-16?32<<(m>>k%17&1^!v--):124:10);}

Try it online!

# J, 41 38 37 bytes

' @|'{~(?@$&2([,.2,.~:)?|.{.&1)@16 16 Try it online! -1 thanks to Mukundan314 • ?|.{.&1 Create a 16x16 grid of zeros with a 1 in the upper left, and randomly rotate it to one of the 256 possible positions • ?@$&2 Create a 16x16 grid of random 0-1s
• [,.2 Zip that grid with 2, to make the dividing wall
• ,.~: Then zip that with "where is the random grid not equal to the random-single-1 grid"
• ' @|'{~ Translate all that to the appropriate ascii chars

# APL+WIN, 54 46 bytes

Index origin = 0

'@ |'[(2|z+m⍴(?i)⌽i↑1),2,z←(m←2⍴16)⍴2|i?i←256]

Try it online!Thanks to Dyalog Classic

# R, 112 111 bytes

s=sample
A=B=s(2,256,T)
B[i]=3-B[i<-s(256,1)]
?=\(v)matrix(c("@"," ")[v],16)
cat(rbind(?A,"|",?B,"
"),sep="")

Attempt This Online!

@s=map{(@z=map{('@',$")[rand 2]}0..15),'|',@z,$/}0..15;$s[34*(0|rand 16)+rand 16]^='';say@s Try it online! # Retina, 49 48 bytes 16*$(16*$( @)¶ (.){2}$?1
.+
$&|$&
@T @@  |@

Try it online! Edit: Saved 1 byte thanks to @Leo. Explanation:

16*$(16*$( @)¶

Insert a 16×16 grid of pairs of spaces and @s.

(.){2}
$?1 Pick a random character from each pair. .+$&|$& Duplicate each row joined with |. @T @@  |@ Flip a random space or @. 16-byte difference spotter written in Retina 0.8.2: +@(.{16})@$1

Try it online! Removes all of the paired @s.

• Wow, I have tried to solve this in Retina and ended up with almost exactly the same solution: Try it online! I didn't realise you could omit the closing bracket in the first regex, but you can save one byte by using  |@ for the last one
– Leo
Feb 15 at 23:50
• @Leo Ooh, |, how very appropriate for this challenge!
– Neil
Feb 16 at 0:35

=index(let(y,row(1:16),x,torow(y),t,(x=randbetween(1,16))*(y=randbetween(1,16)),g,map(t,lambda(_,if(coinflip()," ","@"))),{g,if(y,"|"),if(t,if(""=tocol(if(t,g,),1),"@"," "),g)}))

Put the formula in cell A1.

Ungolfed:

=arrayformula(let(
y, sequence(16),
x, transpose(y),
truthyTable, (x = randbetween(1, 16)) * (y = randbetween(1, 16)),
firstGrid, map(truthyTable, lambda(_, if(coinflip(), "@", " "))),
currentChar, tocol(if(truthyTable, firstGrid, iferror(ø)), 1),
flipChar, if(" " = currentChar, "@", " "),
secondGrid, if(truthyTable, flipChar, firstGrid),
hstack(firstGrid, if(y, "|"), secondGrid)
))

# Racket, 369 Bytes

(define(f x)(if(empty? x)x(cons(take x 16)(f(drop x 16)))))(let*([s list->string][b build-list][m map][g((λ(x)(list(m(λ(x y)(xor x y))x(b 256((λ(y)(λ(x)(= y x)))(random 256))))x))(b 256(λ(x)(=(random 2)0))))][h(λ(x)(m(λ(x)(if x #\@#\ ))x))][i(list(m s(f(h(car g))))(m s(f(h(cadr g)))))])(display(string-join(m(λ(x y)(string-append x"|"y))(car i)(cadr i))"\n")))

Try it online!

This is my first post here so I'm hoping I'm following all the rules. I'm also still learning Racket so I'm sure this isn't optimized and I'm excited to receive any tips, but I wanted to post as far as I've gotten. Below is a rough description of what's going on.

#lang racket
;splits a list of 256 into 16 lists of 16
(define(f x)(if(empty? x)x(cons(take x 16)(f(drop x 16)))))

(let*(
;shorten reused functions
[s list->string]
[b build-list]
[m map]

;generate a pair of boolean lists of lists differing by 1 entry
[g((λ(x)(list(m(λ(x y)(xor x y))x(b 256((λ(y)(λ(x)(= y x)))(random 256))))x))(b 256(λ(x)(=(random 2)0))))]

;convert #t and #f into #\@ and #\
[h(λ(x)(m(λ(x)(if x #\@#\ ))x))]

;create list of strings from list of list of chars

;concat strings
• Welcome to the site! Feb 16 at 17:21

# 05AB1E, 31 bytes

Try it online.

Replaced the incorrect „@ ₁×.r₁£ with ₁F„@ ΩJ} (also -1 byte) to fix the issue mentioned by @Neil: "Strictly speaking, step 1 doesn't generate 256 independent characters; the chances for all @s is $$\(256!)^2\$$ in $$\512!\$$ instead of $$\1\$$ in $$\2^{256}\$$."

Explanation:

Step 1: Generate a random string of 256 "@" and " ", with a 50% chance each:

₁F           # Loop 256 times:
„@         #  Push string "@ "
Ω       #  Pop and push a random character from it
}J     # After the loop: Join all characters on the stack together

Try just step 1 online.

Step 2: Create a copy, and flip the character at a single random position:

Ð             # Triplicate the string
₅Ý           # Push a list in the range [0,255]
Ω          # Pop and push a random integer from it
©         # Store this random index-integer in variable ® (without popping)
è        # Pop one of the strings, and get the character at this index
„@      # Push string "@ " again
Â     # Bifurcate it; short for Duplicate & Reverse copy
‡    # Transliterate "@" to " " and vice-versa
®ǝ  # Pop another string, and insert this flipped character at index ®
‚ # Pair the two strings together

Try just the first two steps online.

Step 3: Format it correctly and output the result:

δ           # Map over both strings in the pair:
16 ô          #  Split it into parts of size 16 each
ø         # Zip/transpose; swapping rows/columns
'|ý     '# Join each inner pair together with "|"-delimiter
»     # Join the list of strings together by newlines
# (which is output implicitly as result)
• Strictly speaking step 1 doesn't generate 256 independent characters; the chances for all @s is 1 in 512! instead of 1 in 2^256.
– Neil
Feb 16 at 13:19
• @Neil Good point. Fixed, and actually golfed by 1 byte in the process. Feb 16 at 22:24
• Sorry, I miscalculated, the all @s is actually (256!)^2 in 512! but that's still not the same as 1 in 2^256.
– Neil
Feb 16 at 22:31

# APL(Dyalog Unicode), 30 bytes SBCS

Assume Index Origin is 0 (⎕IO←0)

' @|'[i,2,~@(⊂?⍴i)⊣i←?16 16⍴2]

Try it on aplgolf

⍝ Rough explaination

' @|'[i,2,~@(⊂?⍴i)⊣i←?16 16⍴2]
i←?16 16⍴2  ⍝ 1. i is a random 16 by 16 bit matrix
~@(⊂?⍴i)⊣i           ⍝ 2. i with one random bit toggled
i,2,~@(⊂?⍴i)⊣i           ⍝ 3. Matrix of i, 2, and the toggled i
' @|'[                       ] ⍝ 4. Indexing into string ' @|'

⍝ Breakdown of step 2

~@(⊂?⍴i)⊣i
⍴i              ⍝ 2-1. The shape of i
?⍴i              ⍝ 2-2. A random index into i
~@(⊂?⍴i)             ⍝ 2-3. A function that toggles at the index
~@(⊂?⍴i)⊣i           ⍝ 2-4. i with one random bit toggled

# ngn/k, 32 bytes

+" @|".[i;2?#i;~:],2,i:16?+!16#2

Try it online

• Nice. Could you add a Try It online! so we can see the output? Thanks. Feb 17 at 15:04
• Looks good! Thanks. Feb 17 at 15:25

# UiuaSBCS, 3635 34 bytes

⊏⍉⊂⊂:↥2⊢.⍜⊡¬⌊×16⊟⚂⚂.⁅⊞⋅⋅⚂.⊚16"@ |"

Try it!

⊏⍉⊂⊂:↥2⊢.⍜⊡¬⌊×16⊟⚂⚂.⁅⊞⋅⋅⚂.⊚16"@ |"
"@ |"  # push string
⁅⊞⋅⋅⚂.⊚16       # 16x16 binary random matrix
.                # duplicate
⍜⊡¬⌊×16⊟⚂⚂                 # invert a random cell
⊂:↥2⊢.                           # append row of 2s
⊂                                 # prepend original matrix
⍉                                  # transpose
⊏                                   # convert to proper ascii symbols

# Swift, 179176 169 bytes

var r=0..<16,a=r.map{_ in r.map{_ in !(.random())}},s={""+($0+[]).map{$0 ?"@":" "}}
zip(a,(a[.random(in:r)][.random(in:r)].toggle(),a).1).map{print(s($0.0)+"|"+s($0.1))}
• @vengy Thanks for the catch! Should be fixed now. Mar 4 at 21:28

# Charcoal, 30 bytes

↶≔¹⁶θＥθ⭆θ‽ @Ｃ⊕θ⁰θＪ‽θ±‽θ§ @⁼ ＫＫ

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

Change the default drawing direction to upwards.

≔¹⁶θ

Save the value 16 in a variable because it gets used to much.

Ｅθ⭆θ‽ @

Output a random 16×16 grid of spaces and @s.

Ｃ⊕θ⁰

Copy it 17 characters to the right.

θ

Draw a line of length 16 in the default drawing direction.

Ｊ‽θ±‽θ

§ @⁼ ＫＫ

Toggle the character at that position.

# APL(Dyalog Unicode), 34 bytes SBCS

Requires Index Origin 0 (⎕IO←0)

' @|'[A,2,A≠(⍴A←?16 16⍴2)⍴1=?⍨256]

Try it on APLgolf!

' @|'[A,2,A≠(⍴A←?16 16⍴2)⍴1=?⍨256]­⁡​‎‎⁪⁡⁪⁠⁪⁢⁡⁢⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁡⁣⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁡⁤⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁢⁡⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁢⁢⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁢⁣⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁢⁤⁪‏‏​⁡⁠⁡‌⁢​‎‎⁪⁡⁪⁠⁪⁢⁡⁡⁪‏‏​⁡⁠⁡‌⁣​‎‎⁪⁡⁪⁠⁪⁤⁣⁪‏⁠‎⁪⁡⁪⁠⁪⁤⁤⁪‏‏​⁡⁠⁡‌⁤​‎‏​⁢⁠⁢‌⁢⁡​‎‎⁪⁡⁪⁠⁪⁢⁤⁡⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁤⁢⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁤⁣⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁤⁤⁪‏⁠‎⁪⁡⁪⁠⁪⁣⁡⁡⁪‏‏​⁡⁠⁡‌⁢⁢​‎‎⁪⁡⁪⁠⁪⁢⁣⁣⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁣⁤⁪‏‏​⁡⁠⁡‌⁢⁣​‎‎⁪⁡⁪⁠⁪⁢⁣⁢⁪‏‏​⁡⁠⁡‌⁢⁤​‎‎⁪⁡⁪⁠⁪⁤⁢⁪‏⁠‎⁪⁡⁪⁠⁪⁤⁣⁪‏‏​⁡⁠⁡‌⁣⁡​‎‎⁪⁡⁪⁠⁪⁣⁣⁪‏⁠‎⁪⁡⁪⁠⁪⁣⁤⁪‏‏​⁡⁠⁡‌⁣⁢​‎‎⁪⁡⁪⁠⁪⁣⁡⁪‏⁠‎⁪⁡⁪⁠⁪⁣⁢⁪‏‏​⁡⁠⁡‌⁣⁣​‎⁪⁪⁠‎⁪⁡⁪⁠⁪⁢⁣⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁤⁪‏‏​⁡⁠⁡‌⁣⁤​‎‎⁪⁡⁪⁠⁪⁡⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁪‏⁠‎⁪⁡⁪⁠⁪⁣⁪‏⁠‎⁪⁡⁪⁠⁪⁤⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁡⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁢⁪‏⁠‎⁪⁡⁪⁠⁪⁣⁡⁢⁪‏‏​⁡⁠⁡‌­
16 16⍴2            # ‎⁡generate 16, 16 matrix of 2s
?                   # ‎⁢replace each with random number less than current value
A←                    # ‎⁣assign to A
‎⁤
?⍨256   # ‎⁢⁡random permutation of [0, 1, ..., 255]
1=        # ‎⁢⁢equals 1 (vectorized)
⍴          # ‎⁢⁣reshape to
⍴A                     # ‎⁢⁤shape of A (16, 16)
A≠                        # ‎⁣⁡not equal/xor against A (vectorized)
2,                          # ‎⁣⁢concatenate column of 2 to start
A,                            # ‎⁣⁣concatenate A to start
' @|'[                           ]  # ‎⁣⁤translate to required characters
💎

Created with the help of Luminespire.

# Windows Batch Scripting, 469262 259 bytes

Thanks to Neil's tips.

@echo off&setlocal EnableDelayedExpansion&set/av=%random%%%256
for /L %%i in (0,1,255)do (set/ar=!random!%%2&set c= &if !r!==0 set c=@
set a=!a!!c!&if %%i==%v% if !c!==@ (set c= )else set c=@
set b=!b!!c!&set/ae=%%i%%16&if !e!==15 echo !a!^|!b!&set a=&set b=)

Notes

EnableDelayedExpansion Delayed Expansion will cause variables within a batch file to be expanded at execution time rather than at parse time.

%random%%%256 generates a random number in the range $$\[0,255]\$$.

Output

• You can use %%i instead of !n!, and the last line can be for /L %%i in (0,16,255)do echo !b:~%%i,16!^|!m:~%%i,16!, and now a is also no longer necessary, and in the first loop you can also inline c. The "s are also mostly unnecessary, the exception being if "!c!"=="@".
– Neil
Feb 16 at 23:46
• You don't actually need c in the first loop, you can just update b directly; this also allows you to remove the ()s around the entire do block. You can also remove the ()s from the command after the elses; they're only required before the else.
– Neil
Feb 17 at 12:02

# Vyxalj, 169 bitsv2, 21.125 bytes

₈ÞB:₈ṁ⁽¬V"ƛ‛ @i;ṅ²÷Zƛ\|j

Try it Online!

Bitstring:

1010111011001011000000101101001010011100010010011000001111001011010101011001000001000110000001100000001001100110111011001000100101001001111010100000110110101011110100100
₈ÞB:₈ṁ⁽¬V"ƛ‛ @i;ṅ²÷Zƛ\|j­⁡​‎‎⁪⁡⁪⁠⁪⁡⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁪‏⁠‎⁪⁡⁪⁠⁪⁣⁪‏‏​⁡⁠⁡‌⁢​‎‎⁪⁡⁪⁠⁪⁤⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁡⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁢⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁣⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁤⁪‏⁠‎⁪⁡⁪⁠⁪⁣⁡⁪‏‏​⁡⁠⁡‌⁣​‎‎⁪⁡⁪⁠⁪⁣⁢⁪‏‏​⁡⁠⁡‌⁤​‎‎⁪⁡⁪⁠⁪⁣⁣⁪‏⁠⁪⁪⁠‎⁪⁡⁪⁠⁪⁤⁤⁪‏‏​⁡⁠⁡‌⁢⁡​‎‎⁪⁡⁪⁠⁪⁣⁤⁪‏⁠‎⁪⁡⁪⁠⁪⁤⁡⁪‏⁠‎⁪⁡⁪⁠⁪⁤⁢⁪‏⁠‎⁪⁡⁪⁠⁪⁤⁣⁪‏⁠⁪⁪‏​⁡⁠⁡‌⁢⁢​‎‎⁪⁡⁪⁠⁪⁢⁡⁡⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁡⁢⁪‏‏​⁡⁠⁡‌⁢⁣​‎‎⁪⁡⁪⁠⁪⁢⁡⁣⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁡⁤⁪‏‏​⁡⁠⁡‌⁢⁤​‎‎⁪⁡⁪⁠⁪⁢⁢⁡⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁢⁢⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁢⁣⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁢⁤⁪‏‏​⁡⁠⁡‌­
₈ÞB                       # ‎⁡256 random bits
:₈ṁ⁽¬V                 # ‎⁢copy and flip a bit at a random index
"                # ‎⁣pair them into a list
ƛ    ;          # ‎⁤map over each
‛ @i           # ‎⁢⁡the corresponding index of the string " @"
ṅ²        # ‎⁢⁢concatenate, turn each string into a square
÷Z      # ‎⁢⁣push each square and zip the two
ƛ\|j  # ‎⁢⁤join by |
💎

Created with the help of Luminespire.

decoder (not at all golfed)

# Assembly (nasm, x64, Linux), 343 bytes

mov byte[l+16],'|'
mov byte[l+33],10
rdrand ax
movzx r12,al
mov bl,0
mov r14,16
p:mov rcx,16
mov r9,l
r:rdrand r8
and r8,1
mov al,[c+r8]
mov[r9],al
cmp r12,rbx
jne o
cmp al,64
je s
jmp o
s:sub al,32
o:mov[r9+17],al
inc r9
inc bl
loop r
mov rax,1
mov rdi,1
mov rsi,l
mov rdx,34
syscall
dec r14
jnz p
c db "@ "
section .bss
l resb 34

Try it online!

Notes

rdrand is an instruction for returning random numbers from an Intel on-chip hardware random number generator.

Set r12 to a random number $$\[0,255]\$$

rdrand ax
movzx r12,al

Set r8 to a random number $$\[0,1]\$$

rdrand r8
and r8,1

# YASEPL, 151 bytes

=v=a$64»=i£1=r¢0,2551!s[3#pipe3=j2!s[7!o¥j,1!)o!g$16*i+j}7,r,9!)a!o}7,a,9!)" "9!~|87!b)a!m¢0,1@6!b)" "6!b~!1©b8!j+}2,17,2!s@4\$|4=s£1>""!i+}2,17