text:
Average Two Letters
Introduction
Every letter in the English alphabet can be represented as an ASCII code. For example, a is 97, and S is 83. As we all know, the formula for averaging two numbers \$x\$ and \$y\$ is  \$\frac{x+y}{2}\$.  I'm pretty sure you can see where this is going.  Your challenge is to average two letters.
Challenge
Your program must take two letters as input, and output the average of the ASCII values in it. If the average is a decimal, you should truncate it.

Input will always be two ASCII letters. You can assume they will always be valid, but the case may vary. Basically, both letters will be in the range 97-122 or 65-90. The second letter will always have a greater ASCII value than the first. If your language has no method of input, you may take input from command line arguments or from a variable.
You must output the ASCII character signified by the average of the two numbers. As stated above, it should always be truncated to 0 decimal places. If your language has no method of output, you may store it in a variable. Exit codes and return values are considered valid output methods.

Example I/O

Input:  A, C
Output: B
Input:  a, z
Output: m
Input:  d, j
Output: g
Input:  B, e
Output: S
Input:  Z, a
Output: ]

Rules
This is code-golf, so shortest answer in bytes wins!

Please specify whether, for example, B e is a valid input.

Why is the output of the last example U? The value of B is 66 and the value of e is 101, which averages to 83.5, truncated to 83, which corresponds to S

If that example is correct, it will invalidate all of the existing answers.

Sorry. I read an ASCII table wrong and got 69 for B, not 66.

Could I enter for a non-ASCII compliant system?

C# (Visual C# Interactive Compiler), 20 bytes
a=>b=>(char)(a+b>>1)

Try it online!

x86-16 machine code, IBM PC DOS, 13 12 10 bytes
Binary (xxd):
00000000: a182 0002 c4d0 e8cd 29c3            ..........

Listing:
A1 0082     MOV  AX, [0082H]    ; load two chars into AH and AL from command line
02 C4       ADD  AL, AH         ; AL = AL + AH
D0 E8       SHR  AL, 1          ; AL = AL / 2
CD 29       INT  29H            ; write to console
C3          RET                 ; return to DOS

Standalone PC DOS executable.  Input is via command line, output to console.
Example:

Only 5 bytes if written as a function :-)

@CodyGray only 4 bytes as a snippet or a MACRO.  Not sure where the "line" is though... :)

Functions are always permitted, as are full programs, per house code golfing rules. Not sure about macros, though; interesting suggestion. Although avoiding that 1-byte RET is probably not going to be enough to make a difference most of the time...

Jelly, 4 bytes
OSHỌ

Try it online!
Explanation
OSHỌ  Main Link: takes (a, b)
O     (ord(a), ord(b))
 S    sum; ord(a) + ord(b)
  H   halve; (ord(a) + ord(b)) / 2
   Ọ  chr

Rajneesh A.K.A. OSHỌ

Poetic, 163 bytes
software inside a computer
a robot+a man+a keypad+a plan=a PC
still,P.C.this,P.C.that?i await a day i crush a PC
resist P.C,Google,or an Apple
i do Linux,i suppose

Try it online!
Poetic is an esolang I made in 2018 for a class project. It's basically brainfuck with word-lengths instead of symbols.
(I actually use PC myself. )

Love the idea of this language.

Ruby, 22 bytes
->a,b{""<<(a+b).sum/2}

Try it online!

Huh. TIL the functionality of str << int.

J, 17 bytes
(+/<.@%#)&.(3&u:)

Try it online!

(+/<.@%#)  truncated average...
&. "Under", which applies a transform, then the verb it modifies -- truncated avg in this case -- then the inverse transform....
3&u: convert to ascii byte integer.

That is, it converts each letter to its ascii number, gets the truncated average of those, and applies the inverse of "convert to ascii number", which takes an ascii number and returns a letter.

R, 56 37 bytes
intToUtf8(mean(utf8ToInt(scan(,""))))

Try it online!
Description

intToUtf8() converts the average into its ASCII character.

mean() takes the average which is automatically truncated.

utf8ToInt() converts the inputs into two ASCII numbers.

scan() allows inputs.

Welcome to CGCC! A few tips: 1. You can use an anonymous function, so don't need the f=; 2. You don't need print; 3. In this case, it is actually shorter to take input with scan that to define a function; 4. floor is not needed: if you feed a non-integer numeric to intToUtf8, R truncates it automatically before converting to character. Also, TIO must have been experiencing issues when you tried it; the base package is included. All in all, your solution can be shortened to 37 bytes.

@RobinRyder Thanks for the reduction!

Shakespeare Programming Language, 144 bytes
Try it online!
(Whitespace added for readability)
/.Ajax,.Puck,.Act I:.Scene I:.[Enter Ajax and Puck]
Ajax:Open mind.
Puck:Open mind.
You is the quotient betweenthe sum ofyou I a big cat.
Speak thy.

Simple enough, just finds the average. ASCII characters and numbers are identical in SPL, so this language was ideal for the task.

Keg -ir -oc, 5 2 bytes (SBCS)
Works in all 3 test cases.
+½

Try it online!
Explanation
-ir will *not* try to evaluate the input
+   Add them
 ½  Halve the value
-oc Output all as a character, if possible

Implicit print. The output is print nice by default.
```

Loading issue. I just tried the first test case and it didn't error.(I got to clone the most recent Keg interpreter.)

Using -ir and -oc will allow this two byter: +½

What a great solution. I think we cannot go shorter.

K (oK), 8 bytes
Solution:
`c$.5*+/

Try it online!
Explanation:
Sum, multiply by 0.5 and convert to ASCII.
`c$.5*+/ / the solution
      +/ / sum (add-over)
   .5*   / multiply by 0.5
`c$      / convert to ASCII

Bash, 56 bytes
printf \\x$(printf %x $[`printf "(%d+%d)/2" \'$1 \'$2`])

Try it online!

The outer pair of quotes is needed only because the \x, so better escape just that single character; 2) The deprecated $[..] is shorter for arithmetic evaluation; 3) The old \``..`is shorter for subcommand, except when needs escaping; 4) The inner pairs of quotes are needed only because of'`, so better escape just those characters. Try it online!

@manatwork: Do you want to post this as an answer? Or should I edit my post?

Feel free to edit your post. Is mostly your work. I didn't had the patience this time to juggle with the printfs.

You have an error in the version posted here: the closing " should be on the left side of the nearby space to avoid touching the next argument's first character, the \. (The TIO code is correct though.)

@manatwork: Thanks for pointing me to this.

Excel, 28 bytes
=CHAR((CODE(A1)+CODE(B1))/2)

Julia 1.0, 26 bytes
a\b=Char(sum(Int[a,b])÷2)

TIO was timing out for me, so only tested at REPL.
Try it online!

"You must output the ASCII character signified by the average of the two numbers". Shouldn't your output be a single ASCII character?

Thanks for catching that, fixed.

dzaima/APL, 11 bytes
(+/÷≢)⍢⎕UCS

Try it online! dzaima/APLs ⎕UCS - convert to/from char currently ignores the fractional part of the given number, so no floor is necessary.

Befunge-98 (PyFunge), 7 bytes
~~+2/,@

Try it online!

Python 2, 31 bytes
lambda*A:chr(sum(map(ord,A))/2)

Try it online!

Lua, 42 41 bytes
a=...print(a.char(a:byte()+a:byte(2)>>1))

Try it online!
Removed 1 byte using ouflak's method of taking input as a single command line argument.
Takes input as a single command line argument of two characters. Uses the convenient operator precedence of >>.
Note that this is actually a full standalone Lua 5.3 program, because command line arguments are accessible as a top-level vararg.

You beat me: print(string.char((io.read():byte()+io.read():byte())/2)).

Thanks to your tip on my answer, I think I just figured out how to save 1 byte on yours.

jq, 23 characters
[explode|add/2]|implode

Sample run:
bash-5.0$ jq -Rr '[explode|add/2]|implode' <<< 'AC'
B

Try it online!

Preproc, 1187 bytes
#define A
#define B,
#define C,,
#define D,C
#define E,D
#define F,E
#define G,F
#define H,G
#define I,H
#define J,I
#define K,J
#define L,K
#define M,L
#define N,M
#define O,N
#define P,O
#define Q,P
#define R,Q
#define S,R
#define T,S
#define U,T
#define V,U
#define W,V
#define X,W
#define Y,X
#define Z,Y
#define a Z H
#define b,a
#define c,b
#define d,c
#define e,d
#define f,e
#define g,f
#define h,g
#define i,h
#define j,i
#define k,j
#define l,k
#define m,l
#define n,m
#define o,n
#define p,o
#define q,p
#define r,q
#define s,r
#define t,s
#define u,t
#define v,u
#define w,v
#define x,w
#define y,x
#define z,y
#define _(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,_,cb,cc,cd,ce,cf,cg,ch,ci,cj,ck,cl,cm,cn,co,cp,cq,cr,cs,ct,cu,cv,cw,cx,cy,cz,da,db,dc,dd,de,df,dg,dh,di,dj,dk,dl,dm,dn,do,dp,dq,dr,ds,dt,du,dv,dw,dx,dy,dz,ea,eb,ec,ed,ee,ef,eg,eh,ei,ej,$,...)#$
#define $($a,$b)_($a $b z,y,y,x,x,w,w,v,v,u,u,t,t,s,s,r,r,q,q,p,p,o,o,n,n,m,m,l,l,k,k,j,j,i,i,h,h,g,g,f,f,e,e,d,d,c,c,b,b,a,a,`,`,_,_,^,^,],],\\,\\,[,[,Z,Z,Y,Y,X,X,W,W,V,V,U,U,T,T,S,S,R,R,Q,Q,P,P,O,O,N,N,M,M,L,L,K,K,J,J,I,I,H,H,G,G,F,F,E,E,D,D,C,C,B,B,A,A)

Try it online!
Defines a macro $ which can be called (as shown in the footer of the TIO link above)
This challenge is barely possible in preproc (pure macro) -- if the input can be non-alphanumeric characters too, it would not be possible.
I don't see any simple way to shorten this code -- it might be possible to make the part to take the (n)th element shorter, but that would come at the cost of making the initial macro definitions significantly longer.

Zsh, 33 31 characters
a=({$1..$2} 0)
echo ${a[$#a/2]}

This one does no character code conversion.
Sample run:
manatwork ~ % set -- A C

manatwork ~ % a=({$1..$2} 0);echo ${a[$#a/2]}
B

Try it online!

Very clever use of brace expansion! I managed 27 bytes in a more boring way :)

K4, 9 8 bytes
Solution:
10h$_avg

Examples:
q)k)10h$_avg"AC"
"B"
q)k)10h$_avg"az"
"m"
q)k)10h$_avg"dj"
"g"

Explanation:
Unfortunately the space is needed. Turns out the space isn't necessary!
10h$_avg / the solution
     avg / calculate mean
    _    / floor
10h$     / cast to char

Bonus:

10h$-256+avg for a 12 byte Q version (more/less hacky than 10h$(_)avg for 10)

MarioLANG, 63 bytes
,
)
,
>[!(>[!
"=#="=#
  - ( >
) ( + -
!+< ) [
#=" !-<)
    #=".

Try it online!
Super golfable, I'm sure - not really able to think in MarioLANG yet. Calculates \$\lfloor\frac{x+y}{2}\rfloor\$.

Forth (gforth), 15 bytes
: f + 2/ emit ;

Try it online!
Code Explanation
: f      \ start a new word definition
  +      \ add top two stack arguments
  2/     \ divide top stack value by 2
  emit   \ output char of resulting ascii value
;        \ end word definition

The input requires char, e.g. char a char c f would output b.

More usable version: : g char char + 2/ cr emit ;, run like g e B, (outputs S), etc.  Note that it doesn't seem to matter which order the arguments are in, so g B e also outputs S.

@agc In gforth ' will also work, so 'a 'b f would also output b and looks much more similar to other languages

Python 2, 33 32 bytes
-1B from Embodiment of Ignorance using bit ops.
Exactly as specified. For a Python 3 answer change the / into //.

lambda a,b:chr(ord(a)+ord(b)>>1)

Try it online!

This could be just /2 in Python 2.

I mean, this way.

I see, I thought the complete function body can be turned into /2.

You can save 2 bytes with lambda*s:chr(sum(map(ord,s))/2)

Nice golfing, but now it is an almost exact duplicate of this answer. (The names of the parameters are changed.)

lambda a,b:chr(ord(a)+ord(b)>>1) saves a byte

For a Python 3 answer change the / into //.  part is outdated

Lua, 63 60 bytes
s=io.read()print(s.char(math.floor((s:byte()+s:byte(2))/2)))

Takes the two letters with no delimeters, i.e. AB, j$, |1, etc....
Try it online!
Saved 3 bytes thanks to PhillipRoman

There are shorter Lua solutions. They look also interesting, @outflak.

@ouflak I'd like to clarify that my solution is a full standalone Lua 5.3 program, because command line arguments are always accessible as a top-level vararg

@PhilipRoman, So what TIO is doing is virtually running a command line Lua 'shell' and passing in the arguments appropriately? Interesting....

@PhilipRoman, I assumed naturally that that's what you were doing. I was pondering how TIO did it. Somehow they have to emulate "lua myscript.lua a z".

@ouflak Ah, sorry, I misunderstood you. Yeah, the fact that TIO shows the time taken just like the linux "time" command, seems to indicate that there is indeed a real shell involved.

Hexagony, 14 13 bytes
|*;:2@+/',{,|

Try it online!

Linear control flow: ,{,'+{*2':;@
I decide to plug it in the Hexagony brute forcer program, and it can't find a 12-byte program. At least for that specific linear code.
Other possible linear control flows:
,{,'+'2=':;@
,{,'+'2{=:;@
,},"+{*2':;@
,},"+'2=':;@
,},"+'2{=:;@
,{,'+{+2':;@

(none of them results in a 12-byte solution (there are only some non-halting 12-byte solutions); nevertheless, the brute force program has room for improvement.)

That's one horrific control flow D:

Perl 5, 31 30 bytes
$x+=ord for@ARGV;print chr$x>>1

Try it online!
Shortened to 30 bytes thanks to comment by Dadsdy

Welcome to Code Golf, and nice answer!

Can't you replace the >>1 with /2?

Whitespace, 45 bytes
[S S S N
_Push_0][S N
S _Duplicate_0][T   N
T   S _Read_char_from_STDIN][T  T   T   _Retrieve][S N
S _Duplicate][S N
S _Duplicate][T N
T   S _Read_char_from_STDIN][T  T   T   _Retrieve][T    S S S _Add][S S S T S N
_Push_2][T  S T S _Integer_divide][T    N
S S _Print_as_character]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.
Try it online (with raw spaces, tabs and new-lines only).
Explanation:
Character inputs in Whitespace are always stored as unicode integers, so we don't have to do an explicit conversion manually. The program has the following pseudo-code:
int a = STDIN as character
int b = STDIN as character
int c = (a+b) integer-divided by 2
Print c as character to STDOUT

I also use the first input as a heap-address for the second input, since it's guaranteed to be non-negative. This saves a byte by using SNS (duplicate) twice instead of SSSN + SNS (push 0 and duplicate).

brainfuck, 46 bytes
,>,[-<+>]++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>>>.

Try it online!
,>,                             Takes input into cells 0 and 1
[-<+>]                          Sums the two values, storing the result in cell 0
++<                             Sets cell 1 to 2, and returns to cell 0
[->-[>+>>]>[+[-<+>]>+>>]<<<<<]  Divides cell 0 by cell 1
>>>.                            Moves to and outputs cell 3, where the quotient is stored

,<,[>+<-]>[-[->+>]<[<<]>]>. is only 27 bytes, and it does the division by 2 by basically decrementing the sum, decrementing the sum again only if the result is still greater than 0, and incrementing another tape value, all until the sum is 0.

(e)Lisp, 50 bytes
(insert (/ (+ (aref (read) 0) (aref (read) 0)) 2))

CJam, 10 bytes
rcirci+2/c

Try it online!

T-SQL, 64 bytes
declare @ char='Z',@2 char='a'print char((ascii(@)+ascii(@2))/2)

assuming @ and @2 the input.
37 bytes if only put:
print char((ascii('B')+ascii('C'))/2)

T-SQL, 32 bytes
SELECT CHAR(AVG(ASCII(c)))FROM i

Input is taken via a pre-existing table \$i\$ with CHAR(1) column \$c\$, per our IO standards.
The two input characters are entered as separate rows. (Note that because SQL is set-based, this will calculate the average of an arbitrary number of inputs.)

C (gcc), 22 bytes
Saved 0 bytes, but got a giggle, thanks to @ceilingcat!
(*c)()=L"\xd137048d쏸";

Try it online!

Can you write \xd1 as a char?

@l4m2 Seg fault when I tried (*c)()=L"Ñ37048d쏸";

That's because tio use utf8

(*c)()="??7???"; is 1 byte shorter than c(a,b){b=a+b>>1;}

PHP 7.3, 52 51 bytes
-1 byte thanks to manatwork
$x=function($a,$b){echo chr((ord($a)+ord($b))/2);};

Try it online!

I guess you intended to write “51 bytes” there. Assuming you count the TIO version which is 1 byte shorter than the one posted here.

And you got something wrong: either (x+y)/2 or x+y>>1. I mean, if you use parenthesis, then division is shorter. The shift-right is used to avoid the need to use parenthesis.

Red, 18 bytes
func[a][average a]

Try it online!
Takes the input as a list of two letters.
If this is not acceptable:
Red, 20 bytes
func[a b][a + b / 2]

Try it online!

So Red's default behavior is to do the conversion to numbers and then back to letter for the output?

@Jonah The type of the result is implied by the first argument. #"A" + 1 is #"B"; 1 + #"A" is 66

@Jonah From the documentation: "The full range of mathematical functions can be used with char! values. A Math Error is raised if the result of the arithmetic falls outside of the range 00 - 10FFFF (hexadecimal)."

MATL, 3 bytes
Ymc

Try it online!
Explanation
Ym   % Implicit input: string of two letters. Implicitly convert to ASCII, and take mean
c    % Implicitly round down, and convert to char
     % Implicit display

It's fun to stay at the...

Runic Enchantments, 7 bytes
ii+2,k@

Try it online!
Input is space sepatrated. Use invalid inputs at your own peril.

PowerShell, 32 bytes
$args|%{$s+=+$_}
[char]($s-shr1)

Try it online!

Pari/GP, 57 bytes
fun(x,y)=Strchr(floor((Vecsmall(x)[1]+Vecsmall(y)[1])/2))

Try it online!
Description

Vecsmall(x)[1] gives the ASCII number of x.
Vecsmall(y)[1] gives the ASCII number of y.
/2 gives the average.
floor() truncates the average.
Strchr() converts the average to its ASCII character.

Ceylon (named function) 74 68 65 64 60
Contrary to e.g. Java, in Ceylon you can't directly add characters (The compiler complains with Left operand must be of summable type: Character is not a subtype of Summable). Instead, we first need to convert it to an integer, and afterwards back to character. This gives 74 bytes:
Character c(Character x,Character y)=>((x.integer+y.integer)/2).character;

We can write this shorter by using the .hash attribute instead of the .integer attribute, which for characters turns out to have the same implementation (returning the Unicode value of a character). This is 68 bytes:
Character d(Character x,Character y)=>((x.hash+y.hash)/2).character;

A more ceylonic way of doing this is to use the fact that Character is a Enumerable type, and implements the .neighbour and .offset methods. The average has an offset from the smaller which is half as large as the offset of the larger to the smaller. This even turns out slightly smaller, with 65 bytes.
Character a(Character x,Character y)=>x.neighbour(y.offset(x)/2);

Unfortunately most of this is the declaration of the types. We can reduce this slightly by having the method take a sequence (tuple/pair) of two characters instead of both individually – this removes one parameter, but adds [...] several times, coming to 64 bytes:
Character b(Character[2]c)=>c[0].neighbour(c[1].offset(c[0])/2);

An alternative way of making the type declaration shorter is an alias declaration. This only is worthwile from 3 usages of Character, which we have here, reaching 60 bytes:
alias C=>Character;C e(C x,C y)=>x.neighbour(y.offset(x)/2);

(The .hash version with alias comes to 63 bytes.)
Try all the examples online

PHP (7.4), 34 bytes
fn($a,$b)=>chr(ord($a)+ord($b)>>1)

Try it online!

Wren, 67 bytes
There should be a Wren answer for every Lua answer.
Fn.new{|a|String.fromCodePoint((a.bytes.reduce{|a,i|a+i}/2).floor)}

Try it online!

Javascript, 59 53 Bytes
i=>String.fromCharCode(Buffer.from(i).reduce((t,v)=>t+v)/2)
i=>String.fromCharCode((b=Buffer.from(i))[0]+b[1]>>1)
> f('ae')
'c'
> f('ab')
'a'
> f('ac')
'b'
> f('ad')
'b'
> f('ae')
'c'
> f('aZ')
']'
> f('Be')
'S'

Bonus (Sorry if off topic, I'm not sure if this is allowed and couldn't find anything with a quick check. Please advise if this is actually a viable answer or not), here is the first answer written as NodeJS REPL input (making use of tabs to complete partial names):
i=>St  .f  h   (Bu .f  (i).reduce((t,v)=>t+v)/2) (43 bytes)
Note tabs might be malformed by page formatting.
Note pasting anything after the tab will suppress completion on some terminals.

Could this be shortened using toString(36) and parseInt?

Suggest Buffer(i) instead of Buffer.from(i) for 5 bytes. I think this is the shortest possible solution in Javascript (which is definitely not the right tool for this job, sadly).

shortC, 12 8 bytes
APG+G>>1

Try it online!
Please advise on golfing skeeels.

Welcome to the site!

There is auto-completion of brackets and semicolons. Also note that >>1 does the same thing as /2 and saves a bracket.

It says Adam P. Goucher

1+, 25 23 bytes
,,+11##1+"\"/^"+1+<1+#;

Try it online!

Husk, 3 bytes
c½Σ

Try it online!
Input as a two character string.

Zsh, 27 bytes
Not as original as @manatwork's solution, but shorter. Try it online!
<<<${(#)$(((##$1+##$2)/2))}

Alternative for 30 bytes: printf \\$[[##8](##$1+##$2)/2]

Julia 1.0, 24 21 14 bytes
a\b=a+(b-a)÷2

Try it online!

Vyxal, 3 bytes
CṁC

Try it Online!
Explanation
CṁC
     (implicit input)
C    Convert to character code list
 ṁ   Get average
  C  Convert back to letter

Piet (ASCII-Piet), 12 bytes
jN LnN FjCjJ

ASCII-Piet is a compact encoding for the image-based esolang Piet that encodes each pixel (or codel) of Piet code as a single ASCII character. This ASCII-Piet code translates into the following program:

Or enlarged to codel size 25:

Edit: fixed the enlarged version, and golfed two bytes off by rotating the program.
Simply takes two characters from input (Piet can only represent chars on the stack by codepoints), sums them, divides by two, and outputs the result char.

ABAP
    SELECTION-SCREEN BEGIN OF BLOCK b0.
    PARAMETERS: p_first  TYPE c LOWER CASE OBLIGATORY,
                p_second TYPE c LOWER CASE OBLIGATORY.
    SELECTION-SCREEN END OF BLOCK b0.

    START-OF-SELECTION.

    WRITE / cl_abap_conv_in_ce=>uccpi( uccp =
         (
            ( cl_abap_conv_out_ce=>uccpi( char = p_first )
              + cl_abap_conv_out_ce=>uccpi( char = p_second ) ) / 2 )
          ).

Welcome to Code Golf! Is all of that whitespace necessary, or could some be removed to save bytes?

><> (Fish), 5 bytes
+2,o;

Try it

Thunno 2 B, 2 bytes
mC

Attempt This Online!
mC  # implicit input, B flag converts string to byte array
m   # mean
 C  # convert to letter

Vyxal 2.4.1 K, 2 bytes
ṁC

Try it Online!

Trilangle, 8 bytes
ii2+d@'o

Try it in the online interpreter!
Takes the two letters on stdin with no separator. Very straightforward, putchar((getchar() + getchar()) / 2).

Java (JDK), 20 21 bytes

-1 byte after seeing in other languages that [...]>>1 is a shorter way to do ([...])/2 because it has less operator priority!

A 2-parameters problem is the only moment where the double lambda can shine!
a->b->(char)(a+b>>1)

Try it online!

C, 17 bytes
f(a,b){a=a+b>>1;}

At first I thought
f(a,b){a=(a+b)/2;}

was the best but then I remembered Cs operation precedent and realized it would be shorter to shift right by 1.

Triangular, 10 9 bytes
t+~2.`>_@

Try it online!
Ungolfed:
   t
  + ~
 2 . `
> _ @

----------------------

t~`           - Read 2 characters from input; change direction to SE after
+2>_          - Add the two top values of the stack, then divide by 2
@             - Print as a character

Previous Version (10 bytes):
~.~..+@_2<

05AB1E, 4 bytes
ÇÅAç

Try it online! or verify all test cases
Explanation
Ç    | Get ASCII values of both inputs
 ÅA  | Take the mean
   ç | Convert to ASCII char

Perl 5 -p, 22 bytes
$_=chr+(ord(<>)+ord)/2

Try it online!

C (gcc), 17 bytes
f(a,b){a=a+b>>1;}

Try it online!

Charcoal, 7 bytes
℅⊘ΣＥＳ℅ι

Try it online! Link is to verbose version of code. Takes input as a string of two letters. Explanation:
    Ｓ   Input string
   Ｅ    Map over characters
      ι Current character
     ℅  Take the ordinal
  Σ     Take the sum
 ⊘      Halved
℅       Convert to character
        Implicitly print

Ruby, 27 bytes
->x,y{(x.ord+y.ord>>1).chr}

Try it online!

Python 3, 34 bytes
lambda a,b:chr((ord(a)+ord(b))//2)

Try it online!

Labyrinth, 8 bytes
,,+_2/.@

Try it online!
How?
, read a character from STDIN and push its ordinal
, read a character from STDIN and push its ordinal
+ pop y, pop x, push x+y
_ push a zero
2 pop x, push 10*x+2
/ pop y, pop x, push x/y (integer division, rounded towards negative infinity)
. pop x, print byte at (x%256)
@ exit program

Japt, 8 6 bytes
xc z d

Try it

Why not just xc z d?

@EmbodimentofIgnorance, because beer! Also, lack of practice. But mainly beer!

Pyth, 6 5 bytes
C.OmC

Try it online!
As a bonus, works with more than two letters
Edit: -1 thanks to @randomdude999, wasnt aware that the lambda function implicitly adds the lambda variable
How it Works
C.OmC
   mC - Map (char to int) to the implicit input
 .O    - Take the average
C      - Int to char

Oh wow, I made a solution that was identical to this yesterday but didn't post it, nice one

You don't need the trailing d.

@randomdude999 good catch

Haskell, 32 bytes
toEnum.(`div`2).sum.map fromEnum

Try it online!

JavaScript - 62 60 bytes
I'm certain there's a better way than this:
(a,b,c=x=>x.charCodeAt())=>String.fromCharCode(c(a)+c(b)>>1)

Would love some feedback!
Example:
f=(a,b,c=x=>x.charCodeAt())=>String.fromCharCode(c(a)+c(b)>>1)
f('a','c') // 'b'

Another way to divide by 2 is to delete the last binary digit by doing a right-shift one place. This would be >>1. This is of course longer than /2, but the advantage is that it has lower precedence in terms of order-of-operations, so you can remove a pair of brackets. This results in a net gain of one character. So (...)/2 -> ...>>1

I count 64 bytes. You don’t need the 0 argument. As far as I know only the function is needed, without the name; so you could use (a,b,c=x=>x.charCodeAt())=>String.fromCharCode((c(a)+c(b))/2), which would be 61 bytes. 60 with @Max’s suggestion.

Thanks you guys, very clever. I thought about the bitshift but didn't realize it is low in op precedence!

Write c as a helper and take two inputs as a=>b=>

You can reduce it to 58 bytes by currying the function, defining the c function inline and doing the division by 2 within it: a=>b=>String.fromCharCode((c=x=>x.charCodeAt()/2)(a)+c(b))

Gol><>, 6 bytes
ii+2,H

Try it online!
Explanation
ii     Push 2 input chars as int to stack
  +    Add them
   2,  Float divide by 2
     H Output as char and halt (Seems to truncate)

Stax, 4 bytes
:V@]

Run and debug it

GolfScript, 10 bytes
{+}*2/]''+

Explanation
{+}*       # Fold the input string with sums
    2/     # Divide this number by 2
      ]''+ # Put stack into array & convert to string

# Implicit print

Try it online!

@, 6 bytes
Has some trailing garbage, but can't be avoided because all functions have return values.
ō/+čč2

Explanation
  +čč  Sum two inputs' charcodes
 /   2 Halve the number
ō      Output as a character

Ahead, 7 bytes
ii+2/o@

Try it online!

Burlesque, 9 bytes
)**avavL[

Try it online!
If I'm allowed to report the ceiling, can save 2 chars )**foL[ fo is defined as avpd which calculates the average and then ceilings it.
)** # Map ord(a)
av  # Calculate average
av  # Floor the resulting double
L[  # Int to Char

Haskell, 48 bytes
f=fromEnum;g a b=toEnum(div((f a)+(f b))2)::Char

Try it online

Erlang (escript), 26 bytes
Sums the input, divide by 2, and then convert to character.
f(X)->[lists:sum(X)div 2].

Try it online!

MAWP, 5 bytes
|M2P;

Input must be given without any separator.
Try it!

F***... MAWP have a division built-in...

@HighlyRadioactive well, there are four arithmetic operations: M, A, W, P

@Dion I'm getting used to the lack of subtraction and division. Isn't this answer nice, by the way?

05AB1E, 4 bytes
ÇO;ç

Try it online!
ÇO;ç  # full program
  ;   # divide...
 O    # sum of...
Ç     # charcodes of...
      # implicit input...
  ;   # by 2
   ç  # convert to charcodes, rounding down
      # implicit output

Raku, 18 characters
{($^a..^$^b)[*/2]}

Sample run:
> {($^a..^$^b)[*/2]}('A', 'C')
B

Try it online!

Python 53 46 bytes
thanks to @manatwork recommended not to store inputs in variables.
print(chr(int((ord(input())+ord(input()))/2)))

You only use a and b once, so better avoid storing them in variables by inputting them on separate lines. Try it online!

@manatwork yes, tanks!

Java, 45 chars
char c(char a,char b){return(char)((a+b)/2);}

Try it online!

Pyth, 5 bytes
C.OCM

Try it online!

Factor, 8 bytes
[ + 2/ ]

Try it online!
Or if we're allowed to take input in a list, then
Factor, 4 bytes
mean

C++ - 34 Bytes
int f(int a,int b){return(a+b)/2;}

Ungolfed
int f(int a, int b)
{
    return (a + b) / 2;
}

Explanation
A function that returns the average of two integers, in this case it can be used with ASCII characters.

you can remove the type names and use just f(a,b){return(a+b)/2;} since itll default to int

@sugarfi Thanks for your comment but `implicit int in declarations' is not defined for C++, although it is defined for C (at least for C89).  I even tried it on GCC to make sure, and it doesn't compile if I remove the type names;  but thanks anyway.

Knight, 14 bytes
O A/+A P A P 2

Try it online!

Scala, 32 bytes
Golfed version. Try it online!
z=>(z.map(_.toInt).sum/2).toChar

C (gcc), 49 bytes
int a,b;scanf("%c,%c",&a,&b);printf("%c",a+b>>1);

Try it online!
Got the idea of bit-shift operators from this answer

Swift, 134 bytes
var s=readLine(),a=readLine();print(Character(UnicodeScalar((s?.compactMap{$0.asciiValue}[0])!+(a?.compactMap{$0.asciiValue}[0])!/2)))

Ruby, 45 bytes
a,b=gets.split;puts"#{((a.ord+b.ord)/2).chr}"

Attempt This Online!

32 bytes taking input separated by newlines

J-uby, 22 bytes
:*&:ord|+:+|~:/&2|:chr

Attempt This Online!
Explanation
:* & :ord | +:+ | ~:/ & 2 | :chr

:* & :ord |                       # Map with .ord, then
            +:+ |                 # sum, then
                  ~:/ & 2 |       # integer divide by two, then
                            :chr  # convert to character

Uiua, 18 bytes
⍜∩utf(⌊÷2+)

Try It
Explanation
⍜∩utf(⌊÷2+)
⍜∩utf # convert both chars to ints,
      # apply the operation in parentheses, and undo the char to int conversion
     (⌊÷2+) # calculate a floored avg
         + # sum both elements
       ÷2 # divide by two
      ⌊ # floor the result

authors: ə̷̶̸͇̘̜́̍͗̂̄︣͟


text:
Horizontally mirror a brainflak program
Your task is to write a program or function which takes a pure brainflak program as input (assume it contains only balanced ()[]{}<>), and output a visually mirrored copy of it.
If you reversed a brainflak program as a string, say ({}()) (add one to an input), you would get ))(}{(, which is not valid.
Instead, you should mirror it, by reversing the direction of the parentheses/brackets/braces/angle-brackets, like what you would see if the program was placed in front of a mirror: ((){}).
Test cases (??? means anything is okay):
()               -> ()
({}[{}])         -> ([{}]{})
()[]             -> []()
<(){}[]>         -> <[]{}()>
([{<()[]{}<>>}]) ->([{<<>{}[]()>}])
(a)              -> ???
{>               -> ???
))(}{(           -> ???
()↵[]            -> ???

This is a code golf challenge, shortest answer per language wins.

I'd recommend removing the invalid test cases as they add nothing to the challenge, and instead add some edge cases, or something maybe a little longer

@cairdcoinheringaahing What edge cases would you recommend?

Maybe something like ([{<()[]{}<>>}]) or similarly convoluted?

@cairdcoinheringaahing I'll add it, but I'm keeping the invalid test cases to remove any possible confusion

I think I know exactly what prompted this challenge heh :P

A nice brain-flak term to describe the inputs: a pure brain-flak program contains only (){}[]<> and is perfectly balanced.

@DJMcMayhem Updated, thanks for the suggestion.

This feels like a dupe to me. Maybe a subset of a challenge that asked us to reverse a string, replacing characters that can be "mirrored".

@Shaggy I searched, but couldn't find anything

@RedwolfPrograms, Yeah, I can't find it either. Either I'm not searching right (entirely possible; I'm a few pints deep!) or it's still in the Sandbox.

I am disappointed (but still hopeful) that there is no answer in brainflak.

@JoKing Oh wait, wrong challenge. I also recently posted a different question about reversing code.

@StianYttervik Oh wait, wrong challenge. I also recently posted a different question about reversing code. Nvm my last comment.

Charcoal, 3 bytes
Ｓ‖Ｔ

Try it online! Link is to verbose version of code. Explanation: Ｓ reads the input and implicitly echos it, while ‖ is the mirroring operator, which normally just reverses the input, but the Ｔ modifies it to mirror the characters at the same time.

+1 right primitive for the job

JavaScript (Node.js),  51 47  44 bytes
Saved 3 bytes thanks to @xnor
s=>Buffer(s).map(c=>c^68%c/3%8).reverse()+''

Try it online!
How?
For each pair of characters, we can switch from the 1st to the 2nd character (and vice versa) by XOR'ing the ASCII code with \$1\$, \$2\$ or \$6\$.
 char 1 | code | XOR | code | char 2
--------+------+-----+------+--------
   '('  |   40 |  1  |   41 |  ')'
   '<'  |   60 |  2  |   62 |  '>'
   '['  |   91 |  6  |   93 |  ']'
   '{'  |  123 |  6  |  125 |  '}'

Given an ASCII code \$c\$, we can turn it into the correct XOR value by using the following function:
$$f(c)=\left\lfloor((68 \bmod c)/3)\bmod 8\right\rfloor$$
   c  | 68 mod c |   / 3  | mod 8 | floor
------+----------+--------+-------+-------
   40 |    28    |  9.333 | 1.333 |   1
   41 |    27    |    9   |   1   |   1
------+----------+--------+-------+-------
   60 |     8    |  2.667 | 2.667 |   2
   62 |     6    |    2   |   2   |   2
------+----------+--------+-------+-------
   91 |    68    | 22.667 | 6.667 |   6
   93 |    68    | 22.667 | 6.667 |   6
  123 |    68    | 22.667 | 6.667 |   6
  125 |    68    | 22.667 | 6.667 |   6

Why Buffer(s) instead of s.split\``?

@RedwolfPrograms [...s] would be shorter than using split. But this answer is working on ASCII codes, not on characters.

Oh, I get it now. (I've also never though of using the ... operator on strings, that's handy to know)

I brute forced some expressions for the XOR value table and got 68%c/3%8, which seems to work for 3 bytes shorter: TIO

Python 3, 47 bytes
lambda x:x[::-1].translate('>]<[)('*20+'}_{'*2)

Try it online!
Python has a convenient string method translate that accepts a translation string s, and maps each character c to s[ord(c)]. So, we just need to make a translation string with the right characters at the positions of ASCII values [40, 41, 60, 62, 91, 93, 123, 125] of ()<>[]{}.
The ideal would be to make the table like '????????'*16, putting the correct character for each ASCII value modulo 8. Unfortunately, the values [40, 41, 60, 62, 91, 93, 123, 125] are not distinct modulo 8, and the first modulus making them distinct is 18, which would mean something like '??????????????????'*6.
However, conveniently, the lowest 6 ASCII values [40, 41, 60, 62, 91, 93] are distinct modulo 6. That lets us handle them with '>]<[)('*20, translating ASCII values 0 through 119. For the remaining two, 123 and 125, we use '}_{'*2 to hit the next 6 ASCII values 120 to 125. Python 3 lets us stop there, unlike Python 2, which requires the translation string to be length 256 exactly.

Jelly,  13  12 bytes
Saved 1 byte thanks to @JonathanAllan
O&80%15‘^OỌṚ

Try it online!
How?
The idea here is to XOR the ASCII codes to turn each character into its mirrored counterpart, like I did in my JS answer. But we use a formula that is bit golfier in Jelly:
$$f(c)=((c\text{ & }80)\bmod 15)+1$$
where \$\text{&}\$ is a bitwise AND.
 char | code | and 80 | mod 15 |  + 1 | XOR code | new char
------+------+--------+--------+------+----------+----------
  '(' |   40 |    0   |    0   |   1  |    41    |   ')'
  ')' |   41 |    0   |    0   |   1  |    40    |   '('
------+------+--------+--------+------+----------+----------
  '<' |   60 |   16   |    1   |   2  |    62    |   '>'
  '>' |   62 |   16   |    1   |   2  |    60    |   '<'
------+------+--------+--------+------+----------+----------
  '[' |   91 |   80   |    5   |   6  |    93    |   ']'
  ']' |   93 |   80   |    5   |   6  |    91    |   '['
  '{' |  123 |   80   |    5   |   6  |   125    |   '}'
  '}' |  125 |   80   |    5   |   6  |   123    |   '{'

Commented
O&80%15‘^OỌṚ - a monadic link taking a string, e.g. "(<>[])"
O            - convert the input to ASCII codes --> [40, 60, 62, 91, 93, 41]
 &80         - bitwise AND with 80              --> [ 0, 16, 16, 80, 80,  0]
    %15      - modulo 15                        --> [ 0,  1,  1,  5,  5,  0]
       ‘     - increment                        --> [ 1,  2,  2,  6,  6,  1]
         O   - input to ASCII codes again       --> [40, 60, 62, 91, 93, 41]
        ^    - bitwise XOR                      --> [41, 62, 60, 93, 91, 40]
          Ọ  - convert back to characters       --> ")><][("
           Ṛ - reverse                          --> "([]<>)"

I've used up all of my votes for today, imaginary +1

You can save one if you avoid the register use by taking advantage of chaining rules and repeating O like so: O&80%15‘^OỌU (side note: personally I go for Ṛ when U's depth action is not required, so would do O&80%15‘^OỌṚ)

Canvas, 1 byte
↔

Try it here!
Surprised that this is the first 1-byte answer.

05AB1E, 4 bytes
º2äθ

Try it online! or verify all test cases
Explanation
º    | Mirror (i.e. "({}[{}])" -> "({}[{}])([{}]{})"
 2ä  | Split into two pieces
   θ | Take the last piece

J, 24 bytes
|.rplc(;"0|.)@'([{<>}])'

Try it online!
Test cases by Jonah.

J, 32 25 bytes
'([{<)]}>'|.@([{~8|4+i.)]

Try it online!
Quick explanation:

Find the index of each input char within the string '([{<)]}>'.
Add 4 to it to get its mirror
Take that mod 8 to handle wrapping around to the beginning
Use the result to index back into '([{<)]}>'
And reverse that result

24 bytes using rplc

@GalenIvanov, v nice! i think it's different enough in both concept and implementation that you should feel free to post separately.

Ok, thanks! I'll post it separately.

Retina 0.8.2, 20 bytes
O^$`.

T`([{<>}])`Ro

Try it online! Link includes test cases. Explanation:
O`.

Sort individual characters...
$

... by substitution value (constant empty string, therefore keeps original order)...
^

... with reversed sort order (i.e. reversing the string).
T`([{<>}])

Substitute each character of ([{<>}])...
`Ro

... with the matching character from the reverse of that string, thus mirroring those characters.

Note that in Retina 1 you can save 4 bytes by using V\`` to reverse the string instead of ``O.``.

Japt, 12 bytes
Blatant port of Arnauld's JS solution so go upvote him.
ÔcÈ^68%X/3%8

Try it

Brain-Flak, 302 bytes
{(({}(<()>))<({}[(((()()()()()){}){}){}])>{[()](<()>)}{}<({}[()])>{()(<()>)}{}<({}[(((()()())){}{}){}()])>{[()()](<()>)}{}<({}[()()])>{()()(<()>)}{}<({}[(((()()()){}()){}){}()])>{[()()](<()>)}{}<({}[()()])>{()()(<()>)}{}<({}[(((()()()()()){})){}{}])>{[()()](<()>)}{}<({}[()()])>{()()(<()>)}{}<>)<>{}}<>

Try it online!
This is (currently) very poorly golfed, but I thought there ought to be at least one Brain-Flak answer to this question.

Python 3, 61 bytes
lambda x,s="([<{}>])":"".join(s[7-s.find(c)]for c in x[::-1])

Try it online!

Icon, 67 bytes
procedure f(s)
r:="reverse"
return map(r(s),d:="([{<>}])",r(d))
end

Try it online!

Cool idea for finding the mirroring.  Is Icon a language worth looking into?

@Jonah Thank you! Yes, I think so, but keep in mind it's an old language. Icon is one of the first languages to have generators. A cool concept is the "goal directed evaluation" - if some expression fails, Icon automatically backtracks and generates another value(s) if there's a generator involved.

Jelly, 13 bytes
This approach has many 13-byte solutions, although I can golf Arnauld's 13 byter to 12 bytes.
QṢiⱮịQṢṭ2/FƲṚ

Try it online!
How?
QṢiⱮịQṢṭ2/FƲṚ - Link: list of characters, P
Q             - de-duplicate (P)
 Ṣ            - sort (call this X)
   Ɱ          - map across (p in) P with:
  i           -   first index of (p) in (X)
           Ʋ  - last four links as a monad - i.e. f(P):
     Q        -   de-duplicate (P)
      Ṣ       -   sort
        2/    -   2-wise reduce with:
       ṭ      -     tack
          F   -   flatten (i.e. pair-wise reversal of sorted unique values)
    ị         - (left) index into (right)
            Ṛ - reverse

Red, 56 bytes
func[s][foreach c reverse s[prin select"[][()({}{<><"c]]

Try it online!

Jelly, 15 bytes
“[({})]”©iⱮUịUɼ

Try it online!
A monadic link that reverses the input and input brackets of all their types.

Perl 5 -p, 32 bytes
$_=reverse y/(){}[]<>/)(}{][></r

Try it online!

C (gcc), 85 84 64 60 bytes
60 bytes thanks to Neil
p;f(char*s){for(p=strlen(s);p--;)putchar(s[p]^68%s[p]/3%8);}

Try it online!

60 bytes

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Longest pristine(ish) codepoint run
Your challenge is to create the longest run of characters with incrementing Unicode codepoints in a pristine program as you can. To keep things simple, I'll abridge the definition for this challenge to be "any program which produces no errors but will error if any one character is removed".
Let's define a codepoint run as any contiguous substring of N characters, where 1 <= N <= program length, where the Unicode/UTF-8 codepoints increment by 1 for each character.
For example: abc, <=>, {|, and ƐƑƒƓƔ are all codepoint runs.
Your program (must be a standalone program) doesn't have to be purely a codepoint run. Instead, its score will be the length in characters of the longest codepoint run in its source code. A program dabc's score would be 3.
Note that your program does not need to actually output anything, as long as it does not error.

Compiler warnings do not count as errors
Your program does not need to (but still can) error if more than 1 contiguous character is removed
Your program may take input only if the contents of the input do not affect whether or not the program errors
Any code which is not part of the longest codepoint run is ignored in the scoring
Highest score, as in code golf, is per-language

Yeah, I realized it was trickier than I first thought and deleted my comment. I suspect for most languages, the goal will be to achieve putting in the longest possible Unicode sequence into a string or comment in a pristine way, with a pristine check that it's the right length or that the code itself has the right length.

@xnor It's impossible AFAIK to put a comment in a pristine program, and strings would be hard still

What does the program have to do? Nothing/not error? A specific task?

@cairdcoinheringaahing Anything, as long as it follows the specification

To the 4 people who have voted to close, what's the reason? I have nothing to go on here...

I consider any challenge in which it is possible to get an arbitrarily good score in many different languages to be per se too broad.

@pppery I made a mistake in the specification, but I wouldn't consider it "too broad." The challenge is defined clearly, it's just not that good. You're a little trigger happy with closing posts for unusual reasons I've noticed...

Python 3, run of 1,114,111
#coding:utf
assert len(open(__file__).read(1061))==1061
"""

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂăĄąĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıĲĳĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňŉŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃǄǅǆǇǈǉǊǋǌǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰǱǲǳǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɂɃɄɅɆɇɈɉɊɋɌɍɎɏɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼʽʾʿˀˁ˂˃˄˅ˆˇˈˉˊˋˌˍˎˏːˑ˒˓˔˕˖˗˘˙˚˛˜˝˞˟ˠˡˢˣˤ˥˦˧˨˩˪˫ˬ˭ˮ˯˰˱˲˳˴˵˶˷˸˹˺˻˼˽˾˿̴̵̶̷̸̡̢̧̨̛̖̗̘̙̜̝̞̟̠̣̤̥̦̩̪̫̬̭̮̯̰̱̲̳̹̺̻̼͇͈͉͍͎͓͔͕͖͙͚̀́̂̃̄̅̆̇̈̉̊̋̌̍̎̏̐̑̒̓̔̽̾̿̀́͂̓̈́͆͊͋͌͐͑͒͗͛ͣͤͥͦͧͨͩͪͫͬͭͮͯ̕̚͘͜͟͢͝͞͠͡ͅͰͱͲͳʹ͵Ͷͷ͸͹ͺͻͼͽ;Ϳ΀΁΂΃΄΅Ά·ΈΉΊ΋Ό΍ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώϏϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧ"""

Try it online!
The triple-quoted contains the entire Unicode range except for the null byte \0 which terminates a program. (Thanks to Chas Brown for suggesting triple-quoting, which allowed 13 more characters.) The TIO link uses a shortened version; assume that the number 1061 is replaced with the code length.
The program opens itself and checks that it has the appropriate length, which guards against any deletion. No one-character deletion can disable this logic in the code. Lowering either the number of characters read or the number checked for equality will make the assertion fail.
I'm not totally sure if all Unicode characters except '\0' are valid in Python code, and I haven't been able to test it. Maybe this is system dependent. Please let me know if this fails at some point.
We can also do this without reading the file:
s="""

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂăĄąĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıĲĳĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňŉŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃǄǅǆǇǈǉǊǋǌǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰǱǲǳǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɂɃɄɅɆɇɈɉɊɋɌɍɎɏɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼʽʾʿˀˁ˂˃˄˅ˆˇˈˉˊˋˌˍˎˏːˑ˒˓˔˕˖˗˘˙˚˛˜˝˞˟ˠˡˢˣˤ˥˦˧˨˩˪˫ˬ˭ˮ˯˰˱˲˳˴˵˶˷˸˹˺˻˼˽˾˿̴̵̶̷̸̡̢̧̨̛̖̗̘̙̜̝̞̟̠̣̤̥̦̩̪̫̬̭̮̯̰̱̲̳̹̺̻̼͇͈͉͍͎͓͔͕͖͙͚̀́̂̃̄̅̆̇̈̉̊̋̌̍̎̏̐̑̒̓̔̽̾̿̀́͂̓̈́͆͊͋͌͐͑͒͗͛ͣͤͥͦͧͨͩͪͫͬͭͮͯ̕̚͘͜͟͢͝͞͠͡ͅͰͱͲͳʹ͵Ͷͷ͸͹ͺͻͼͽ;Ϳ΀΁΂΃΄΅Ά·ΈΉΊ΋Ό΍ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώϏϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧ"""
assert len(s)==999

Try it online!
There isn't a way to delete a character from the assertion line while keeping it syntactically valid and preserving the length number.

Instead of a comment, can you use a triple-quoted string? Then you could include code point 14...

Not sure if reading your own source code should be allowed, but I guess it's too late

@ChasBrown I had tried that, but it complains about an invalid escape sequence with the backslash, and using a raw string doesn't fix it. Edit: Never mind, I messed up escaping in the test, I think your idea works.

... and this is why the creator should have required real pristine code.

@RedwolfPrograms I'm pretty sure one could do the same without source code reading just as s=[the string];assert len(s)==[its length].

I think you don't want the #coding:utf in python3 which defaults to utf-8 encoding (on my Mac, and also at TIO anyway).

@ChasBrown You're right, looks like it only gives the "Non-UTF-8 code" error for the source-reading version.

C# (Visual C# Interactive Compiler), Score: 1114076
var s=@"Insert all characters from character 36 then on";if(s.Length!=1114076)throw new Exception();

Try it online!

x86 machine code, score: 1,114,112
E9 81 F7 42 00 00 01 02 ... F4 8E BF BF C3

In assembly:
main:
    jmp $+4388742 # i.e. to the end
    .byte 0,1,...,0xF4,0x8F,0xBF,0xBF
end:
    ret

The code that is executed is just a relative jump followed by a return. All the unicode codepoints are in between.
If the jump itself or any of the first three bytes of its offset are deleted, then the unicode codepoints are executed as code until it crashes. If any byte after that is removed, then it jumps past the end of the program and eventually crashes.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Draw a fuzzy grid
Print the ASCII version of a random grid.
################################################################################
#    #   #  #    #   #   #     #     #   #  #    #   #     #   #   #   #  #   #
#    #   #  #    #   #   #     #     #   #  #    #   #     #   #   #   #  #   #
#    #   #############   #     #     #   #  #    #   #     #   #   #   #  #   #
##########   #   #   #####################  #    #   #     #   #####   ########
#    #   #   #   #   #   #   #   #       #######################   #####   #  ##
#    #   #   #   #   #   #   #   #       #  #   #     #   #    #   #   #   #  #
#    #   #   #   #   #   #####   #       #  #   #     #   #    #   #   #########
##########################   #######################################   #    #  #
#    #    #   #   #  #   #   #    #      #   #   #   #   #     #   #####    #  #
#    #    #   #   #  #   #   #    #      #   #   #   #   #     #   #   #    ####
###############   #  #   #####    #      #   #   #   #   #     #   #   #    #  #
#    #   #    ########   #   ###################################   #   ######  #
#    #   #    #   #  #####   #     #    #  #    #   #   #      #########    #  #
######   #    #   #  #   #   #     #    #  #    #   #   #      #   #   #    #  #

The picture should illustrate the constraints:

# is solid,  is empty.
Print 80 columns, at least 80 rows.
On the first and last columns and first and last rows there is some freedom, but at least the printout must be extendible to a legal grid.
Boxes contain empty areas between 1x1 and 7x7.
Constraints: Boxes are rectangular, no lonely corners (1), no empty boxes (2), no broken lines(3) or gaps (4), when in doubt refer to the image above.
A grid is considered "random", if the first 80 rows contain: 1.) 60 unique rows and 60 unique columns. 2.) At least one box with inner area of size (2, 2), (3, 2), (4, 2), (5, 2), (2, 3), (3, 3), (4, 3), (5, 3), (2, 4), (3, 4), (4, 4), (5, 4), (2, 5), (3, 5), (4, 5), (5, 5) each. You can verify the randomness and some constraints with this julia script.
The program should nondeterministically produce a minimum number of 1000   grids fulfilling the constraints with different first 80 rows, where rotations, circular shifts and reflections counted as same and the majority of produced grids should be "random" as specified above.

    #####4########################
    #                #   #    #
    #    #       #   #   #    3
    #    #       #########   #
    #########1   #   #   #########
    #    #   #   #   ##2##   #   #
    #    #   #   #   #####   #   #
    #    #   #   #   #   #   #####

Code golf!

You need to specify exactly what you mean by random. "Do not systematically produce homogeneous rows of boxes..." also needs to be made objective.

@xnor I created a rule specifying "randomness".

You say "at least 80 rows" but - specifically - "80 columns". Is that indended? Also, your program gives a warning for more than 80 rows.

The program expects you to submit the first 80 rows of your output, the remainder can be anything, as long as it is a valid labyrinth.

I added a requirement discouraging to encode a hand drawn valid grid as 80*80 bit number ;-)

@dzaima Yeah, it has to be non-deterministic... made a change. This is super tricky to specify.

@Veskah, yes, I'll fix that.

Hey OP - I've found it really difficult and stressful for handling the cascade of queries and objections on new code challenges. Just so you know, you're not alone.

@AJFaraday No worries, maybe maybe the next time I use the sandbox... ;-)

Julia, 254 bytes
Not very golfed, just to keep it going;
l=length
function f(M,r,s)
l(r)<7&&return l(s)>6&&g(M,r,s)
h,j=rand([f,g],2)
a,c=extrema(r)
b=rand(a+1:c-1)
M[b,s].=2
h(M,b+1:c,s)
j(M,a:b-1,s)
end
g(M,r,s)=f(M',s,r)
n=80
M=fill(1,n,n)
f(M,1:n,1:n)
for i∈1:n
print.(getindex.(" #",M[i,:]))
println()
end

Verification, try it yourself


text:
Symbol Search Deleter [rephrased]
Your challenge is to parse nonsensical text and output a "congruous phrase" - which I shall define here to be text with any contiguous characters in between, and including, a given set of like symbols removed.
The given set of like symbols (ignore all brackets and commas here, they're only for notation) are: {(< >), (^ ^), (' '), (: :), (% %)}

[NOTE: This question has been heavily refined after several critical errors were identified.]
EXAMPLE 1:

Thi'inquit Caecilius's qu % est provocationem %h^ ad howe et^s [ben] heavilede ^citi:ssim:e^< rn^> ^quolibe doetiguis^dited %inger 'ingenia'%! S__o:esse: rr %^umd^%y...

OUTPUT 1:

This qu hs [ben] heavilede  dited  ! S__o rr y

.
Be wary of the nested like symbol parts - e.g ^citi:ssim:e^ and < rn^> from above, where the pair : : are sandwiched between another pair ^ ^, and a half-pair ^ in between < >. Both of these non-congruous phrases must be removed.
EXAMPLE 2:

W%cd'fuf'dc%at<>ch^'o'^out!

OUTPUT 2:

Watchout!

.
EXAMPLE 3: Special Case (partial nested like symbols)

aaa^bbb%ccc'ddd^eee%ddd'fff

OUTPUT3: The first occurence of the given like symbol is the dominant; in this case ^

aaaeee%ddd'fff

The code must apply to the general case, so any text of your choosing, of length >= 30 characters, may be used as test cases.
The shortest code, in bytes, that completes this challenge successfully, is the winning code.

Scoring on character count is a bad idea. It leads to code that's gibberish packed into multibyte characters that's decompressed and run within the program.

@JoKing I'm terribly sorry, this gibberish has been corrected; different timezone here, so I wasn't quite myself..

@xnor Thanks for pointing that out; it has been corrected to shortest bytes

Are you meant to take those symbols as input, or are they hardcoded?

@JoKing They're hardcoded

You say the code must apply to the general case, so what do you expect for partially overlapping like symbol pairs like aaa^bbb<ccc^ddd>eee, or like symbol triples like aaa:bbb:ccc:ddd, or more complicated cases?

You need more test cases, clarifying "Be wary of the nested like symbol parts - e.g ^citi:ssim:e^ and < rn^>"

@AndersKaseorg Nice observation; in such special cases, the first like symbol to appear is the dominant one; see EXAMPLE 3 edit

@HiddenBabel Yes, I have added 2 more e.gs, involving separate special cases

I'm voting to reopen this, but I don't think it is that interesting of a question

Could this be moved to the sandbox (where it probably should have started)?

C# .NET, 162 bytes
using System;class A{static void Main(string[] s){Console.Write(System.Text.RegularExpressions.Regex.Replace(s[0],String.Format("([{0}]{{1}}).*?\\1",s[1]),""));}}

Try it online!
Er, the OP's test case is faulty. Either you remove all text between any two symbols, or you remove all text only between like symbols. OP does both in his test case... So I'm doing only between like symbols.
Takes as input the string to search and the character set to use. OP is incorrect about the output, though. It reads,
, Howarm y congruum dor ingqussld...

Yes, I had meant like symbols, as you managed to somehow figure out from my gibberish; I have updated the question, and the difficulty has slightly increased due to nested like symbols.


text:
Proportion of strings with ascending letters
Challenge

Construct n strings, each with three distinct letters, chosen randomly with equal probability.
Print the proportion k/n where k is the number of strings such that all three characters are in ascending order. Print also those k strings.

Input

The only input is n (and thus it must be a positive integer).

Outputs

The proportion k/n must be truncated to two decimal places.
The strings that are in ascending order of letters.

Requirements

The letters must come from the English alphabet.
You cannot print the value of k.

Examples

Input: 6, Output: 0.16 agh
Input: 1, Output: 1.00 suv
Input: 9, Output: 0.22 hls jqr

How to Win

Fewest number of bytes wins.

Just curious: Why do you keep changing the examples? They are examples, not test cases! The output will obviously vary from run to run for any such program.
The probability of making a word with 3 distinct letters which are in ascending order is exactly 1/6, and given n, the number k is a random variable that is binomially distributed with parameters (n, 1/6). The expected value for k is exactly n/6, and so the quotient k/n is just approximating 1/6.

The problem remains that the generation of the strings is an unobservable requirement. Since there are only 6 possible orderings of three distinct characters, and only one of those is in strict ascending order, the same result would be obtained by throwing a die n times and showing the proportion of 6’s.

@TheSimpliFire that makes them unobservable. For example, I think https://tio.run/##K/qfZvs/rTQvuSQzP0@jQjMtJz@/SMPQwECrKCkzLz9Xw1CnQsdQ30xTv0JTHyj8P03DTPM/AA would give the correct answers but doesn’t generate any strings.

@TheSimpliFire it’s still an unobservable requirement since you’re relying on reading the code. Specifying precise means of doing something tends not to be looked on well here: other than the standard loopholes, it is generally better to indicate (using our I/O defaults) your inputs and outputs and leave the implementation up to the answerer. One option here would be to specify an output that includes the n strings and the proportion that are in ascending order, while leaving the precise characters and the output mechanism (STDOUT, list, array, object, etc. ) to the implementation.

See https://codegolf.meta.stackexchange.com/a/10002/42248

@NickKennedy Is this compromise okay?

Outputing both a list of ascending word, and the quotient k/n seems a bit overkill. Maybe it makes sense to only output the ascending words? The quotient k/n can easily be computed from the list of ascending words. But perhaps one shouldn't change the challenge once its posted..

What is the point of "must be truncated to two decimal places?

Does the string have to be three characters long? Or is it okay if it is more than three characters, but has three distinct characters?

@EmbodimentofIgnorance Exactly three distinct characters.

What happens if our language of choice can't round decimals?

Jelly, 31 bytes
13 bytes to cater for the truncation requirement!
ØaẊ⁸Ð¡Ḋḣ€3ṢƑƇðL÷+⁵×ȷ2ḞṾs2j”.Ḋṭ⁸

A monadic link which, given an integer, yields a list.
Try it online! (footer joins the list with spaces)

If (1) we remove the truncation requirement and (2) "The letters must come from the English alphabet" implies that we may choose any subset of three or more such letters then this 16 works:
“ḃ»Ẋ⁸Ð¡⁼ƇḢ$ðL÷;⁸

Try this one (only uses A, B, and C)

If we may also avoid the unobservable creation of all the strings as part of of our code. then this 15 works:
6ẋX€ỊƇ“ḃ»ẋðL÷;⁸

Try this one (only uses A, B, and C, and does not create any unordered strings)

Although it seems an unnecessary requirement, the current spec calls for truncation at 2 decimal places.

Thanks, I didn't notice that, what an odd requirement. Updated.

sorry to be a pain, but the official spec is to truncate rather than round. I don’t think Jelly has a built in, so (unless I’m missing something) it’s either convert to string and head, or it’s multiply by 100, floor, divide by 100.

LOL what a mess

Neither of those suggestions work if 1 must prodce 1.00 either.

Fixed by adding ten, multiplying by 100, un-evaluating, splitting into chunks of length two, joining with a '.', and dequeuing (whew).

Japt, 25 bytes
;ÆBö3Ãf_¶ñ
u»UÊ/N)h2)ú0,4

Try it

20?

@Shaggy I never knew that you could divide an array like that, and I forgot about N. Nice!

Hooray for JS's implicit casting!

Wait, N.h() won't work here due to the stupid & unnecessary requirement that the result be truncated to 2 decimal places.

@Shaggy Fixed. It's really convenient that N.h() returns a string

It doesnt look like it fits the requirement that all three letters be distinct, unless Im missing something

Python 3, 131 bytes
It seems like having to print the string complicates the program...

from random import*
n=int(input())
o=[]
a=['a','b','c']
x=0
for i in range(n):
 o+=[sample(a,3)]
 x+=a==o[-1]
print('%.2f'%(x/n),o)

Try it online!

90 bytes BD

Please see the (hopefully final) edit.

Along with fixing to fit the new spec with respect to printing the strings it also needs to truncate rather than round (1->1.00, 0.166667->0.16, 0->0.00).

Pyth, 26 bytes
FNQKO.PG3IqKSK=ZhZK;.RcZQ2

Try it online!
Does what OP wants, +4 bytes due to truncation requirement.
How it works
FNQKO.PG3IqKSK=ZhZK;.RcZQ2
FNQ                        - For N in Input
   K                       - K is equal to
    O.P 3                  - A random permutation length 3 of...
       G                   - The lowercase alphabet
         IqKSK             - If K is sorted
              =ZhZ         - Increment Z (which is autoinitialized to 0)
                  K        - Implicitly print K
                   ;  cZQ  - End loop, float division of Z by the input
                    .R   2 - Round to 2 decimal points

Pyth, 24 bytes
FNQI!O6=ZhZSO.PG3;.RcZQ2

Try it online!
Cheat answer but since it only saves two bytes im not gonna bother. Also +4 due to truncation

How does the second one cheat? The two seem to behave the same

It doesnt generate strings and check if theyre sorted; it only generates sorted strings with a 1/6 chance (which is the probability that a random string of length 3 will be sorted)

J, 44 bytes
((4j2":%~),@,~[:u:97+26/:~@?~]#3:)1#.0=?@$&6

Try it online!
Note: This one does not actually construct the strings (the one below does) but its output has an identical probability distribution.  I agree with Nick Kennedy on this point.

J, 48 bytes
(];~4j2":(%~#))[:<@u:"1[:(97+(-:/:~)"1#])26?~#&3

Try it online!
Note: Because the required output does not have a homogeneous data type, J requires us to box it.

Strings in your first submission dont seem to be in ascending order

@frank ty.  fixed now.

authors: ə̷̶̸͇̘̜́̍͗̂̄︣͟


text:
20 cards with no Set
Background
Set is a card game. The deck consists of 81 unique cards that vary in four features: number of shapes (one, two, or three), shape (diamond, squiggle, oval), shading (solid, striped, or open), and color (red, green, or purple).
For convenience, let's write a card as a 4-tuple of numbers from 1 to 3, e.g.

1111 = one red solid diamond
1122 = one red striped squiggle
1223 = one green striped oval
2312 = two purple solid squiggle

Given several cards (usually 12), the objective of the game is to find a "set" of three cards such that

They all have the same number or have three different numbers.
They all have the same shape or have three different shapes.
They all have the same shading or have three different shadings.
They all have the same color or have three different colors.

i.e. the cards are either all the same or all different in each of the four features.
Here are some examples of sets:
1111, 1112, 1113
1111, 2222, 3333
2312, 3321, 1333

Here are some examples of non-sets:
1111, 1122, 1123
2131, 3221, 1213

A cap set is a collection of cards that doesn't contain any Set. It was proven in 1971 that the maximum number of cards without a Set is 20. Interestingly, finding the largest cap set for the generalized game of Set is still an open problem in mathematics.
The Wikipedia page shows an example of 20-cap set, and here is the 20 cards in the number notation:
1111, 1113, 1131, 1133,
1312, 1332, 1321, 1323,
3311, 3313, 3331, 3333,
3112, 3132, 3121, 3123,
1222, 2122, 2322, 3222

There are 682344 20-cap sets in total, but under affine transformations on 4-dimensional finite space, they all reduce to essentially one cap set.
Task
Output any of the 20-cap sets in the game of Set.
Input and output
Your program/function is not allowed to take input.
The output is a collection (list, set, ...) of 20 cards which is a cap set. Each card should be represented as a 4-tuple (or equivalent ordered collection) whose elements are one of three distinct values (not necessarily 1, 2, 3). Flexible output applies in the following ways:

Nested or flattened list
Ordering of cards doesn't matter
You may choose to output the same set or different set across runs
For string/text output, it's fine as long as we can clearly identify the structure (20 chunks of four items) of the output

Verification script example in Python using the example shown above.
Scoring and winning criterion
Standard code-golf rules apply. The shortest valid code in bytes wins.

@Arnauld Neither. You can choose to output the same set or different set across runs.

For anyone that wants to make use of it, we can specify a cap set as all (a,b,c,d) from {0,1,2}^4 with a*a+b*b+c*d=0 (mod 3) except for (0,0,0,0).

So I understand, would this count as a boring brute force solution?  And so then the game becomes either "find a formula like xor's for generating one of these" or, perhaps, search the entire space of all of them for one that can be compactly represented with some packing function?  If the latter, would a kolmogorov-complexity tag be in order?

I'm with Jonah. The task does not require computing, just compressing.

@Jonah Yes, that is a valid solution, though it's arguably a boring one. And yes, it's a compression challenge. No, I don't think it's [tag:kolmogorov-complexity], since you can choose from 682344 * 20! / (some constant) possible outputs. Also, I can think of at least three approaches to this problem: 1) compress a cleverly chosen cap set 2) enumerate all 20-card sets and pick one that is a cap set 3) use math formula.

Fair enough, @Bubbler.  Thanks for explaining.

Haskell, 62 bytes
tail[t|t@[a,b,c,d]<-mapM(:[1,2])[0,0,0,0],mod(a*a+b*b+c*d)3<1]

Try it online!
Defines a cap-set as all  \$(a,b,c,d)\$ from \$\{0,1,2\}^4\$ where $$a^2+b^2+cd=0\bmod3,$$ except not \$(0,0,0,0)\$.
I found this formula by looking at Wikipedia's example and coming up with progressively simpler formulas linking the allowed inner coordinates \$(a,b)\$ to the outer coordinates \$(c,d)\$.

Haskell, 46 bytes
[t|t<-mapM(:"12")"0000",sum[1|'0'<-t!!0:t]==2]

Try it online!
This uses a modified condition giving a different but equivalent cap set:
$$a^2+b^2+c^2 - d^2=0\bmod3,$$ still without \$(0,0,0,0)\$.
This is equivalent to \$a^2+b^2+c^2 + d^2 + d^2 =0\bmod3,\$, so we can duplicate an element and check that the give-element list of squares adds to zero modulo 3. Since squares modulo 3 are 0 or 1, this is further equivalent to this condition:

There are exactly \$2\$ zeroes among \$[a,b,c,d,d]\$.

This automatically excludes the all-zero point. Of course, duplicating $d$ was arbitrary -- choosing another element gives a different but equivalent cap-set.

+1 for ruining 1/3 of the fun.

@Bubbler Did you know about this polynomial? I'm curious why it works and, from what you say in the challenge, gives a unique solution up to symmetries. flawr and I are discussing it in Primes and Squares.

Nah. I tried to read the proof in the linked paper, but to no avail. And for the "unique solution up to symmetries", I just ripped off that part from the Wikipedia page.

05AB1E, 16 13 11 9 bytes
2Ý4ãʒĆ0¢<

Port of the found formula of @xnor, as mentioned in his comment as well as his Haskell answer, so make sure to upvote him!
-2 bytes by using @xnor's updated formula (thanks for letting me know).
-2 bytes thanks to @xnor again by simply counting whether there are exactly 2 zeroes in \$[a,b,c,d,a]\$.
Also outputs a list of lists with values in the range \$[0,3]\$.
Try it online.
Explanation:
Will leave quartets \$[a,b,c,d]\$ for which there are exactly 2 zeroes in the list \$[a,b,c,d,a]\$.
2Ý         # Push the list [0,1,2]
  4ã       # Create all possible quartets using the values in this list
           # by taking the cartesian power of 4
    ʒ      # Filter the remaining quartets by:
     Ć     #  Enclose the quartet; appending its own head: [a,b,c,d] → [a,b,c,d,a]
      0¢   #  Count the amount of 0s in this list
        <  #  And decrease it by one
           #  (Since only 1 is truthy in 05AB1E, the filter with count(0)-1 will only
           #   leave quartets where the [a,b,c,d,a].count(0) is exactly 2)
           # (after which the filtered list is output implicitly as result)

This beats the simple compression-based approach, though not by much. A shame that handling leading zeroes costs so much.

@Grimmy Still a nice approach. Also, can something be saved by using the digits 1234 instead of 0123, so you won't have to deal with the leading 0s? I guess the extra bytes are then still there, but at other places instead?

Good idea, but it ends up worse by two bytes, unfortunately.

@Grimmy Yeah, I was afraid that might be the case. Thanks for confirming, though. :)

I realized the formula a^2 + b^2 + c^2 - d^2 = 0 mod 3 also works. Maybe this would be shorter for your implementation via negating or duplicating top of element the stack before summing.

@xnor Thanks for letting me know. Using $a^2+b^2+c^2+d^2+a^2 = 0 \pmod 3$ with the enclose builtin actually saved 2 bytes. :)

Another formulation is that the list [a,b,c,d,a] has exactly two zeroes. Since you have a built-in to make that list, might that be yet shorter?

@xnor Ah, that indeed saves another byte, since only 1 is truthy in 05AB1E and we can use enclose.count(0)-1 == 1 (truthy). Thanks again. EDIT: Actually saves 2, since we also no longer need to remove the [0,0,0,0] first..

JavaScript (ES6),  73  67 bytes
_=>[...'11138272726454626454'].map(i=>3333-(t-=i).toString(3),t=80)

Try it online!
Outputs the following set, as an array of integers:
1112, 1113, 1121, 1131, 1223, 1232, 1323, 1332, 2123, 2132,
2222, 2233, 2322, 2333, 3123, 3132, 3222, 3233, 3322, 3333

Test it online!

Perl 6, 46 36 bytes
{grep *[0,^*].Bag{0}==2,[X] ^3 xx 4}

Try it online!
Uses xnor's updated formula.
Explanation:
{                                  }  # Anonymous code block
 grep                                 # Filter from
                       ,[X]             # The cross product of
                            ^3 xx 4     # 0,1,2 four times
      *[0,^*]                         # Duplicating the first element
             .Bag{0}                  # Where the number of zeroes
                    ==2               # Is equal to 2

APL (Dyalog Unicode), 21 19 bytes
-2 bytes thanks to Bubbler
((3=1⊥5⍴×)¨⊆⊢),⍳4/3

Try it online!
This uses xnor's formula, finding all  cards from the permutation that when the first attribute is duplicated, has exactly 2 zeroes (this code being 0-indexed). The output is slightly weird, since some cards are grouped together, but you can still make out the individual cards.
Explanation
              ,⍳4/3     ⍝ Generate all length 4 permutations of 0,1,2
 (       )¨             ⍝ For each permutation, e.g 0,1,2,1
        ×               ⍝ Get the sign,         e.g 0,1,1,1
      5⍴                ⍝ Reshape to size 5     e.g 0,1,1,1,0
    1⊥                  ⍝ Base 1 (or sum)       e.g 3
  3=                    ⍝ Is equal to 3         e.g 1
           ⊆⊢           ⍝ And partition the ones that return true

You can golf the {...}¨ part like this. Nice use of ⊆ there btw.

Ruby, 78..52 49 bytes
"U ".bytes{|r|p ($.+=r).to_s 4}

Try it online!
How
The sequence can be DPCM-encoded.
If we consider a card as a single base-4 integer (1111 through 3333), we can take any sequence, sort it, and use a single ASCII character to encode the difference between successive elements. The first character represents the first value of the sequence. All values are relatively small, and the decoding is still simple enough to be golfed.
Thanks Value Ink for -3 bytes ("to print the unprintable")
In theory, with a different encoding, every value can be encoded as a single byte, and this would bring the byte count down to 43, but with UTF-8 it's impossible (or at least, I can't figure it out).

Can't you just encode the string as unprintables to cut out the -34? 49 bytes

Yes. In that case I could encode the values directly instead of the differences. 3333 base 4 is 255.

Yes that is probably a good idea.

Jelly,  13  11 bytes
-2 using more of xnor's ideas
3ṗ4ṁ5ỊS⁼ʋƇ2

A niladic Link which yields a list of lists of integers.
Try it online!
How?
Cards being [a, b, c, d] where \$a,b,c,d \in [1,3]\$ this method picks cards for which there are exactly two 1s in [a, b, c, d, a].
3ṗ4ṁ5ỊS⁼ʋƇ2 - Link: no arguments
3           - literal three
  4         - literal four
 ṗ          - (implicit range(x)) Cartesian power -> [[1,1,1,1],[1,1,1,2],...,[3,3,3,3]]
          2 - set the right argument to two
         Ƈ  - filter keep if:
        ʋ   -   last four links as a dyad:
   ṁ5       -     mould like 5 ([a,b,c,d] -> [a,b,c,d,a])
     Ị      -     insignificant? (abs(x)<=1) (vectorises)
      S     -     sum
       ⁼    -     equals (2)?

Previous
3ṗ4Ṗ2œ?ḋƊ3ḍƊƇ

A niladic Link which yields a list of lists of integers.
Try it online!
How?
A method which works in a similar vein as xnor's.
With cards being [a, b, c, d] where \$a,b,c,d \in [1,3]\$ this method picks cards for which \$3 \mid (a^2+b^2+2cd)\$ (except [3,3,3,3])
3ṗ4Ṗ2œ?ḋƊ3ḍƊƇ - Link: no arguments
3             - literal three
  4           - literal four
 ṗ            - (implicit range(x)) Cartesian power -> [[1,1,1,1],[1,1,1,2],...,[3,3,3,3]]
   Ṗ          - pop off the rightmost (remove [3,3,3,3])
            Ƈ - filter keep those for which:
           Ɗ  -   last three links as a monad:- i.e. f([a,b,c,d])
        Ɗ     -     last three links as a monad - i.e. g([a,b,c,d]):
    2         -       literal two                 2
     œ?       -       nth permutation             [a,b,d,c]
       ḋ      -       dot product                 a*a+b*b+c*d+d*c
         3    -     literal three               3
          ḍ   -     divides?                    (a*a+b*b+c*d+d*c)%3 == 0?

I realized the formula a^2 + b^2 + c^2 - d^2 = 0 mod 3 also works, in case this is shorter for you to write that the dot product with permutation. You can also write this with duplicating a square rather than negating it: a^2 + b^2 + c^2 + d^2 + d^2 = 0 mod 3.

Using the fact that squares are 0 or 1 mod 3 that saves at least a byte... think 11 is probably possible; hard on mobile!

Yep 11 was possible - thanks!

Charcoal, 24 bytes
ＵＢ0Ｅ²⁰⮌⍘Σ…”)″&:igＫ⁶Mψ”ι³

Try it online! Link is to verbose version of code. Outputs the given set, but with digits decremented and sorted in order of reverse of string. Explanation:
ＵＢ0

Pad all lines to the same length using 0.
Ｅ²⁰

Loop i from 0 to 19 and implicitly print each result on its own line.
⮌⍘Σ…”)″&:igＫ⁶Mψ”ι³

Convert the digital sum of the ith prefix of the compressed string 8343834422244383438 to base 3 and print it backwards.

Python 2, 85 bytes
print eval('[[a,b,c,d]'+'for %s in 0,1,2'*4%tuple('abcd')+'if(a*a+b*b+c*d)%3<1]')[1:]

A full program which performs xnor's algorithm.
Try it online!

That's a nifty way to write the multiple for loops.

Python 2, 62 bytes
for c in"P}nF-Z>a9*)V=.Q":n=ord(c);print n/50,n%3,n%4,n%5

Try it online!
Using ideas from Bubbler and Jo King, we can cut a few bytes from the below. The decompression method n/50,n%3,n%4,n%5 turns an ASCII value into a 4-tuple. While not every set can be obtained this way using n from 0 to 127, there's enough wiggle room in the choice of cap-set to find one within the obtainable subset. We also avoid problematic characters that need escaping such as \0 or \n, though unprintables can't be avoided.

Python 2, 65 bytes
for c in'RSTW_ahjq"(,15;=CGLP':print[ord(c)/B%3for B in 27,9,3,1]

Try it online!
String compression looks like the way to go for Python. We compress each of the 20 elements as a value from 0 to 80, which we represent as a character. Since we only need the values to be correct modulo 81, we can keep the string within the printable ASCII range. Python 3 could save a few bytes using a bytestring.
An alternative compression method would be 81 bits marking which of the 81 cards are present. Even though the 81 bits needed for this are less than the \$20 \log_2(81)\approx 127\$ bits for the method used, the latter wins out easily for how concisely the string can be written and decoded.
For comparison, here's a solution using the formula I found.
79 bytes
n=81
while n:
 t=a,b,c,d=n/27,n/9%3,n/3%3,n%3;n-=1
 if(a*a+b*b+c*d)%3<1:print t

Try it online!

I found a string that works with for B in 1,3,7,9, so 64 bytes. Btw, the "wins out easily" link seems to be broken.

In Python 3, you can skip the ord part with a bytestring for 57 bytes

Brachylog, 32 bytes
Just an inefficient Brachylog answer passing by, both in speed and bytes. But it works in the generalized case and will give every possible set if you let it run several years!
l₂₀{l₄ℕᵐ<ᵛ³}ᵐ{cᵐ≠&}¬{⊇l₃\{=|≠}ᵐ}&≜

Try it online! … or don't; this will just give you a 5 cap set, the maximum for TIO's time limit. The version uses up/down arrows for ease of use. First number is size of cap set, second is number of properties per card, and third is variations of each property. The 6 cap set I found locally: [[0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [0, 1, 1, 1], [1, 0, 0, 0]].
How it works
l₂₀{l₄ℕᵐ<ᵛ³}ᵐcᵐ≠&¬{⊇l₃\{=|≠}ᵐ}&≜ (the implicit input we are looking for)
l₂₀                              is a list of 20 cards,
   {       }ᵐ                    where each card
    l₄                             has 4 elements,
      ℕᵐ                           numbers >= 0 – to be precise
        <ᵛ³                        that are also lower than 3
                                   (so [0,0,0,0] up to [2,2,2,2])
             cᵐ                  if each card is concatenated to a string,
               ≠                   they would be different. (sadly ≠
                                   doesn't work on lists.)
                 &¬{          }  the following doesn't hold for the input:
                    ⊇l₃            take any list of 3 cards,
                       \           transpose it
                                   ([[0,1,2],[3,2,1],[0,0,0],[2,2,2]])
                        {   }ᵐ   each of the row's elements are …
                         =|≠       either equal or different to each other
                              &≜ actually get some numbers for the list

Python 3, 108 104 100 bytes
Saved 4 bytes thanks to @JonathanAllan!
Saved 4 bytes thanks to @xnor!
Blatant rip of @xnor's algorithm:
lambda:[(a,b,c,d)for a,b,c,d in product(*[(0,1,2)]*4)if(a*a+b*b+c*d)%3<1][1:]
from itertools import*

Try it online!

Some single byte saves: (1) use (the generally bad)from itertools import* avoiding the t.; (2) use (0,1,2) rather than range(3); (3) unpack i immediately, allowing i[0]**2+i[1]**2+i[2]*i[3] to become a*a+b*b+c*d; (4) test for ...%3<1 rather than ...%3==0. Try it online!

@JonathanAllan Thanks, really interesting how you can squeeze those bytes out of, what looks like to me, a stone! :)

You can also save a few bytes using product(*[(0,1,2)]*4). But almost always, you're better off not using itertools and finding way to do it manually that saves bytes over the lengthy import.

@xnor Thanks! That makes a lot of  sense.

Scala, 68 bytes
BigInt("3aglhdjjb0zmp3uvkpxvwio58",36).toString(3).grouped(4).toList

Try it online!
Just storing the 20-cap set as a 80-digit base-3 number (using 0, 1, 2 for notation - since it's stated in the question that it's not necessary to use exactly 1, 2, 3), constructing it from base-36 to save space, and splitting the string to 4-character slices, finally getting a list of 20 cards (represented as strings like "1111", "0222" etc.). A couple more bytes probably can be golfed, using a smaller number.


text:
Expand a recursive pattern
Given a description of the base state of a recursive ASCII pattern, output an expanded state somewhere along the recursion steps.
More specifically: Let the following be an example:
##..
##..
..__
..__

Where # is filled, . is empty, and _ is recursive.
This describes a pattern wherein the top left quarter is filled, the top right and bottom left are empty, and the bottom right repeats the current pattern.
More rigorously, the pattern is a grid containing some number of #, ., and _. The grid will always be rectangular, and there will be at least one _ and all _ will be in a rectangular sub-grid such that the overall grid's (width, height) is an integer multiple of the sub-grid's (width, height).
Your task is, given such a pattern and a number of steps, build up an expanded form of this pattern. That is, each step, expand the grid by n times (where n is the ratio between the recursive sub-grid and the overall grid), and fill the _ sub-grid with the pattern. At the end, fill the base-state _ all with # or . - you choose which, but it must all be the same, and it must be consistently one or the other no matter the input.
To be VERY rigorous, f(g, n) where f is this challenge, g is the pattern grid, and n is the number of steps, then f(g, 0) == g (with the _ replaced by # OR .), and f(g, n) is the grid scaled up by r ** n times (where r is the ratio of the pattern to the recursive sub-grid), with _ replaced by f(g, n - 1).
Let's do an example:
#.
._

3

At 0 steps, the grid is this:
#.
._

At 1 step, the grid is this:
##..
##..
..#.
..._

At 2 steps, the grid is this:
####....
####....
####....
####....
....##..
....##..
......#.
......._

At 3 steps, the grid is this:
########........
########........
########........
########........
########........
########........
########........
########........
........####....
........####....
........####....
........####....
............##..
............##..
..............#.
..............._

Then, your output can either replace the _ with . or #, but again, all _ must become the same in the final output, and you must always fill it with . or # no matter the input.
Examples
The _ are shown in this output - you are to replace them with # or ., by choice. They are simply shown as _ just to reduce confusion as to where the _ were and where pre-filled # and . are meant to be.
#.#.
.__#
#__.
.#.#

2

becomes
####....####....
####....####....
####....####....
####....####....
....##..##..####
....##..##..####
......#.#.######
.......__#######
#######__.......
######.#.#......
####..##..##....
####..##..##....
....####....####
....####....####
....####....####
....####....####

(Just gonna put this out there - this is NOT what I thought it would look like AT ALL)
A non-square non-double example:
##.
##.
##.
##.
.#_
.#_

2

becomes
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
.........###############...
.........###############...
.........###############...
.........###############...
.........###############...
.........###############...
.........###############...
.........###############...
.........###############...
.........###############...
.........###############...
.........###############...
.........#########...#####.
.........#########...#####.
.........#########...#####.
.........#########...#####.
.........#########...###.#_
.........#########...###.#_

Last example.
#__#
.##.

3

becomes
###############__###############
##############.##.##############
############..####..############
############..####..############
########....########....########
########....########....########
########....########....########
########....########....########
........################........
........################........
........################........
........################........
........################........
........################........
........################........
........################........

Rules and Specifications
Input requires a grid and an integer. This grid can be taken in any reasonable, convenient format, and you can replace the characters with any three consistent, distinct values. These can be integers too, for example.
Output requires a grid. This grid can be given in any reasonable, convenient format, and you can replace the characters with any two consistent, distinct values. These do not have to be the same as the ones corresponding to the inputs (why???).
Standard loopholes apply.
This is a code-golf challenge, so the shortest program in bytes for each language wins. No answer will be accepted.
Happy golfing!

@AdmBorkBork That's just to avoid confusion if I put # and then an answer has . and it looks different. It's going to be potentially confusing any way I put it :/ Unless you have a better suggestion :P I am not certain

@AdmBorkBork Fair enough. I'll do that instead. Thanks.

@LuisMendo Whoops - yes. Thanks for catching that.

@ChasBrown At stage 0, it's 2x2, and each time, it scales by x2, so wouldn't stage 1 be 4x4 (like shown) and stage 2 be 8x8 (like shown)?

Ah I see: and all _ will be in a rectangular sub-grid such that... I thought we were replacing each _ with a copy, not some sub-range.

These can be integers too So can we input and output matrices of numbers (not of characters)?

The _ are shown in this output - you are to replace them with # or ., by choice. and Output requires a grid. This grid can be given in any reasonable, convenient format, and you can replace the characters with any three consistent, distinct values. . Those two clauses contradict each other. In the first one, you say all _ must be replaced with either # or . in the output leaving only two distinct characters, but in the second you say that there should be three distinct characters

@EmbodimentofIgnorance Oh. Forgot about that, thanks.

@LuisMendo Yes.

Are you sure it's a good idea to request multiple passes in one run? That seems to be difficult to achieve without simply wrapping everything in a loop (effectively directly increasing the gap between concise and verbose languages).

@someone Hm. That's fair enough; I'll definitely keep that in mind going into future challenges but for this one it's too late to change it now, but thanks for the reminder anyway.

MATL, 33 30 27 26 bytes
ii:"l1G1=aYm/t&Y"1Gy1=(]Zc

Input is a numerical matrix with 0 for empty, 9 for filled and 1 for recursive.
Replaces recursive by filled at the end.
Output is a character matrix with   (space) for empty and # for filled.
Try it online! Or verify all test cases.
Explanation
i      % Take first input: matrix, M. This will be grown recursively
i      % Take second input: number, n
:      % Range [1 2 ... n]
"      % For each
  l    %   Push 1
  1G   %   Push first input, M
  1=   %   Compare with 1
  a    %   Any. This gives a vector with 1 for columns that contain
       %   at least a 1 in input M, and 0 otherwise
  Ym   %   Mean. This gives the proportion of columns with 1
  /    %   Divide 1 by that. This gives the ratio r referred to in the challenge
  t    %   Duplicate
  &Y"  %   Repeat elements. This enlarges the current matrix by r along each dimension
  1G   %   Push input M again
  y    %   Puesh a copy of the current enlarged matrix
  1=   %   Compare with 1. Gives a logical mask
  (    %   Write M into the positions indicated by that mask
]      % End
Zc     % Convert nonzeros to character '#' and zeros to space. Implicitly display

Jelly, 32 28 bytes
³,Z¬ÆmṀ$€İḞ¤xZ¥ƒYṣ0ż³F¤FỴµ¡!

Try it online!
A full program that takes two arguments, a matrix of integers (0-2) and the number of steps and returns a matrix of integers (1-2). 0 is used for the recursive bit.
Thanks to @JonathanAllan for saving two bytes!
Explanation (outdated)
                           µ¡ | Repeat the following the number of times indicates by the right argument
             ¤                | - Following as a nilad:
³                             |   - Original left argument (matrix of integers)
 ,Z                           |   - Paired with itself transposed
           Ɗ€                 |   - For each of the pair, do the following as a monad:
   ¬                          |     - Not
    ẸƇ                        |     - Keep only those with any True values
      F                       |     - Flatten
          Ɗ                   |     - Following as a monad:
       L                      |       - Length
        :                     |       - Divided by (integer)
         S                    |       - Sum
                ¥ƒ            | - Reduce using the argument to this iteration as the initial argument and the following as a dyad:
              x               |   - Repeat that many times
               Z              |   - Transpose
                  Y           | Join with newlines
                   ṣ0         | - Split at zeros
                     ż  ¤     | - Zip with the following as a nilad:
                      ³       | - Original left argument
                       F      | - Flattened
                         F    | - Flatten
                          Ỵ   | - Split at newlines
                             !| Factorial (0 becomes 1)

Save a byte with o1 -> !, since $0!=1!$ and $2!=2$ :) ...and another as ⁹ is implicit there.

Python 2, 250 249 280 266 250 248 bytes
def f(p,n):
 s=p;Q=L(p[0])
 for z in R(n):u,y=[(Q/r.count('_'),y)for y,r in enumerate(s)if'_'in r][0];s=[''.join(s[j/u][i/u]for i in R(u*L(s[0]))).replace('_'*Q,p[(j-y*u)%L(p)])for j in R(u*L(s))]
 return[c.replace('_','#')for c in s]
R=range;L=len

Try it online!
Input and output are both lists of strings.

Japt, 35 bytes

Ê/Uèø0
NÌÆ=c@VÇXmpV r0@NÎ¬gT°
®r0Q

Try it

You may use

 instead of indented text to preserve the leading newline.


text:
In Flanders Fields
Today is November 11th, which for many regions is Remembrance Day.
If you don't know anything about the history or context of Remembrance Day, you can read about it in the wiki page, but it's not relevant for this challenge.
In Flanders Fields is a poem that is pretty well-known relating to this day. It opens like so:
In Flanders fields the poppies blow
Between the crosses, row on row

Challenge
You will be given a grid with crosses (represented below as +) on it. Your task is to grow poppies between all crosses. That is, fill the space between any two crosses that are on the same row or column with poppies (represented below as *).
Example
....+....
...+.+...
.........
....+....
..+...+..
.........
..+...+..

This becomes:
....+....
...+*+...
....*....
....+....
..+***+..
..*...*..
..+***+..

Rigorously defined, on a non-cylindrical grid, each grid space is + if it was +, and becomes * if it has a + in the same column above and below it, or in the same row to its left and right.
Test Cases
.....+...    .....+...
+......+.    +******+.
....+.+.. -> *...+*+..
+.+...+..    +*+***+..
...++.+..    ...++*+..

.+.....    .+.....
....+..    .*..+..
...+..+    .*.+**+
.+++...    .+++*.*
....... -> .****.*
.+++.+.    .+++*+*
.++.++.    .++*++*
.......    .*....*
.+....+    .+****+

.......    .......
...+...    ...+...
.....++    .....++
++.....    ++...**
+....+. -> +****+*
.....+.    .....+*
.......    ......*
.......    ......*
..+...+    ..+***+

.+.+..    .+*+..
.....+    .*.*.+
+.....    +*.*.*
.+....    .+.*.*
...+.+ -> ...+*+
......    ......
......    ......
....+.    ....+.

Rules and Specifications
Input requires a grid of two distinct values. You can take this in any convenient format, and you can choose to use any reasonable convenient values, like 0 and 1, for example.
Output requires a grid of three distinct values. Again, you can deliver this in any reasonable, convenient format.
Standard loopholes apply.
This is a code-golf challenge, so the shortest solution in each language wins. No answer will be accepted.
(Sorry for posting another challenge, especially another ascii-art one, so soon, but I really wanted to do something for 11/11 and I thought of it after my pattern expansion one)

Python 2, 131 125 bytes
f=lambda A,p=1:map(''.join,zip(*[re.sub('\+.+\+',lambda x:re.sub('\.','*',x.group()),s)for s in p and f(A,0)or A]))
import re

Try it online!
Input is a list of strings; as is output.

Ended up with similar approach, maybe it will help you 122 bytes

121 bytes with your recursive approach

Jelly, 12 bytes
ẒT.ịr/Ṭ»)Z$⁺

A monadic Link accepting a list of lists where:

crosses, +, are 2
spaces, ., are 0

which yields a list of lists as above with poppies, *, as 1.
Try it online! Or see one which translates IO.
How?
ẒT.ịr/Ṭ»)Z$⁺ - Link: list of lists
          $  - last two links as a monad  - i.e. f(Rows):
        )    -   for each Row in Rows:
Ẓ            -     is prime? (vectorises) (isCross() that work's once poppies are planted)
 T           -     truthy indices e.g. [0,0,1,0,0,1,1,0] -> [3,6,7]
  .          -     literal one half
   ị         -     index into (the truthy indices)  -- non-integer indices reference the
             -         items on either side of that location & indexing is 1-based and
             -         modular, so [last,first]  e.g. [3,6,7]->[7,3] or [8] -> [8,8]
     /       -     reduce by:
    r        -       inclusive range  e.g. [7,3]->[7,6,5,4,3] or [8,8]->[8]
      Ṭ      -     un-truth  e.g. [7,6,5,4,3]->[0,0,1,1,1,1,1] or [8]->[0,0,0,0,0,0,0,1]
       »     -     maximum (with Row) (vectorises) (keep crosses, plant poppies)
         Z   -   transpose
           ⁺ - repeat the last link (plant the remaining column poppies and transpose back)

PowerShell, 96 bytes
param($a)$a=&($g={($a=$a-replace'(?<=\+.*)\.(?=.*\+)','*')[0]|% t*y|%{-join$a.chars($i++)}});&$g

Try it online!

Japt -h, 16 bytes
2Æ=Õ®Ëd0E©nFÊÉ}S

No regex!
Try it
2Æ=Õ®Ëd0E©nFÊÉ}S     U = input
2Æ                   2 times do:
  =                    Set U to
   Õ                     U transposed
    ®                    Map each row:
     Ë        }S           Split each row on spaces (crosses),
                           and pass each chunk through the following function,
                           then rejoin on spaces
                           For each chunk:
      d0                     Replace all 0's (empty spaces)
        E©nFÊÉ               And replace with 1 if this chunk wasn't the first or last chunk
-h                   Take final result of second iteration

J, 44 bytes
'.*+'{~[:(+:+-.*](+.|:)&(>./\.*>./\)|:)=&'+'

Try it online!
No regex used:

Takes the product of the max scan of the prefixes and the max scan of the suffixes to turn the in-between cells to 1.
Does this for both the input and its transpose (to get both directions)
"Or"s these two matrices.
Multiplies by one minus the input, to get rid of endpoints (ie, original crosses)
Add double the original matrix to that.
After all this, in-between points in both directions are 1, original points are 2, rest are 0.
We use that to index into '.*+.

Jelly, 18 14 bytes
UÄUaÄa2
ZÇZoÇ_

Try it online!
-4 bytes because I figured out what I did wrong with my cumulative sums
Input and output is as two-dimensional lists with . mapped to 0, + mapped to 1, and * mapped to 2. (The footer on TIO converts automatically for convenience.)
           Helper link:
     a2    Fill in 2s wherever
    Ä      there's at least one truthy value to the left
UÄUa       and at least one truthy value to the right.
           This fills in poppies between (and on) all crosses horizontally.

   oÇ      Overlay the horizontal poppies
ZÇZ        on the vertical poppies,
     _     and subtract the crosses out to recover them.

JavaScript (Node.js), 85 bytes
a=>(g=m=>m[0].map((_,i)=>m.map(l=>l.join``.replace(/(?<=x.*)-(?=.*x)/g,8)[i])))(g(a))

Try it online!
Input / Output as character matrix. Use x for +, - for ., 8 for *.
First, convert dots . between two crosses + in a row into star *.
l.join``.replace(/(?<=\+.*)\.(?=.*\+)/g,'*')

Then. rotate the matrix
a=>m=>m[0].map((_,i)=>m.map(l=>l[i]))

Repeat twice, and get the result.

You could save a few by using different, non-RegEx characters in the input instead.

... and another 2 using a digit instead of '*'.

@Shaggy you are right...

Ruby, 101 bytes
->s{g=->x{x.map(&:chars).transpose.map(&:join).map{|l|l[w=/\+.+\+/]&&l[w]=l[w].tr(?.,?*);l}};g[g[s]]}

Try it online!
Not really satisfied with it, but it's a starting point.

Japt v2.0a0 -h, 22 21 19 13 bytes
Uses <space> for +, * for . & 1 for *.
2Æ=Õr/ .+ /È×

Try it (Header & footer convert I/O to characters used in spec)
2Æ=Õr/ .+ /È×     :Implicit input of string U
2Æ                :Map the range [0,2)
  =               :Reassign to U
   Õ              :Transpose U
    r/ .+ /       :Global RegEx replacement
           È      :Pass each match through a function
            ×     :  Replace all * with 1
                  :Implicit output of last element in array

Retina 0.8.2, 80 bytes
+`#( *)#
#$.1$**#
+ms`^(((.))*#.*^(?<-2>.)*(?(2)$)) (.*^(?<-3>.)*(?(3)$)#)
$1*$4

Try it online! Includes header/footer that translates input/output between . and + to something more regex-friendly for the actual code. Explanation:
+`#( *)#
#$.1$**#

Repeatedly horizontally fill all s between #s. (Since this requires an unbroken run of s, this has to repeat until completion before the second stage runs.)
+ms`

Repeat as many times as necessary, allow ^ to match after a newline, and allow . to match newlines.
^(((.))*#.*

Look for a # and capture its indent twice.
^(?<-2>.)*(?(2)$)) (.*

Look for a  at the same indent.
^(?<-3>.)*(?(3)$)#)

Look for another # at the same indent.
$1*$4

Replace the  with a *.

Red, 160 154 bytes
func[b][loop 2[t: collect[until[parse keep rejoin
collect[forall b[keep take b/1]][any[thru"+"change
copy p to"+"(replace/all p".""*")]]empty? b/1]]b: t]]

Try it online!

Perl 5 (-p), 80 bytes
/
/;$l="."x"@-";1while s/(\+\S*)\.(\S*\+)|(\+$l(.$l)*)\.($l(.$l)*\+)/$1$3*$2$5/s

Try it online!

Python 3.8, 354 bytes
e,r=enumerate,range
def f(s):
	s=s.split('\n')
	t=[(x,y) for y,i in e(s) for x,c in e(i) if c=='+']
	#t is the '+'es coordinates
	m=sum((l for x,y in t for u,v in t
		if (x==u)!=(y==v)and x<=u and y<=v and
		(l:=[[(y,j)for j in r(x+1,u)],[(i,x)for i in r(y+1,v)]][x==u]) and
		#l is coordinates of cells between two '+'es
		all(s[i][j]=='.' for i,j in l)),[])
	return '\n'.join(''.join([c,'*'][(y,x) in m]for x,c in e(i))for y,i in e(s))

Try it online! (without comments or unnecessary white-space)

Japt -R, 19 bytes
yV=_gZa0 oZb0)_p
yV

Try it
U = U.y // for each columns
(V = function(Z) { return
  Z.g // modify
(Z.a(0).o(Z.b(0)), // indexes from first cross to Last cross
function(Z) { return Z.p() // power of 2: -1 => 1
 })  });
V = U.y(V); // repeat transposing

Outputs a matrix of values:
-1 -> ground,  1 -> poppies,  0 -> cross
Footer maps to [' ','○','+']

With the help of @Shaggy and @Embodiment of Ignorance