text:
A bit of a digital XOR
Here are the first 100 numbers of a sequence:
1,2,33,4,55,66,777,8,99,11,111,12,133,141,1515,1,11,18,191,22,222,222,2232,24,252,266,2772,282,2922,3030,31313,3,33,33,335,36,377,383,3939,44,441,444,4443,444,4455,4464,44747,48,499,505,5151,522,5333,5445,55555,565,5757,5855,59559,6060,61611,62626,636363,6,66,66,676,66,666,770,7717,72,737,744,7557,767,7777,7878,79797,88,888,882,8838,888,8888,8886,88878,888,8898,9900,99119,9929,99399,99494,995959,96,979,988,9999,100

How does this sequence work?
n:            1 2  3  4   5   6   7   8    9    10   11   12   13   14   15   16    17
binary:       1 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111 10000 10001
n extended:   1 22 33 444 555 666 777 8888 9999 1010 1111 1212 1313 1414 1515 16161 17171
1-bit digits: 1 2  33 4   5 5 66  777 8    9  9 1 1  1 11 12   13 3 141  1515 1     1   1
result:       1 2  33 4   55  66  777 8    99   11   111  12   133  141  1515 1     11

As you can see, the steps to get the output are as follows:

Convert integer \$n\$ to a binary-string.
Extend integer \$n\$ to the same length as this binary-string. (I.e. \$n=17\$ is 10001 in binary, which has a length of 5. So we extend the 17 to this same length of 5 by cycling it: 17171.)
Only keep the digits in the extended integer \$n\$ at the positions of the 1s in the binary-string.
Join them together to form an integer†.

Challenge:
One of these options:

Given an integer \$n\$, output the \$n^{\text{th}}\$ number in the sequence.
Given an integer \$n\$, output the first \$n\$ numbers of this sequence.
Output the sequence indefinitely without taking an input (or by taking an empty unused input).

Challenge rules:

†Step 4 isn't mandatory to some extent. You're also allowed to output a list of digits, but you aren't allowed to keep the falsey-delimiter. I.e. \$n=13\$ resulting in [1,3,3] or "1,3,3" instead of 133 is fine, but "13 3", [1,3,false,3], [1,3,-1,3], etc. is not allowed.
Although I don't think it makes much sense, with option 1 you are allowed to take a 0-based index \$m\$ as input and output the \$(m+1)^{\text{th}}\$ value.
If you output (a part of) the sequence (options 2 or 3), you can use a list/array/stream; print to STDOUT with any non-digit delimiter (space, comma, newline, etc.); etc. Your call. If you're unsure about a certain output-format, feel free to ask in the comments.
Please state which of the three options you've used in your answer.
The input (with options 1 and 2) is guaranteed to be positive.
You'll have to support at least the first \$[1, 10000]\$ numbers. \$n=\text{...},9998,9999,10000]\$ result in \$\text{...},9899989,99999999,10010]\$ (the largest output in terms of length within this range is \$n=8191 → 8191819181918\$).

General rules:

This is code-golf, so shortest answer in bytes wins.
Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
Default Loopholes are forbidden.
If possible, please add a link with a test for your code (i.e. TIO).
Also, adding an explanation for your answer is highly recommended.

PS: For the 05AB1E code-golfers among us, 4 bytes is possible.

I was hoping that the 4-byte 05AB1E answer would look like the word base.

@a'_' Hehe, unfortunately not. It kinda spells 'pibi' or 'psbi' I guess. ;p

I don't know 05AB1E, but Jelly has a 4-byte solution as well. No idea if I could make it shorter, though.

@RGS Yeah, I saw your 4-byter in Jelly. Already +1-ed it. :) The 05AB1E approach I had prepared was different though. Dorian just posted it as an answer.

The terminology people use is surprising sometimes.  I'm used to thinking about integers as already being in binary, and the special thing is working with their decimal digits which goes without any mention here.  Unless we're allowed to work in our choice of base, like hex, or perhaps more convenient base256 i.e. chunks of 8 bits = 1 byte or base 2^32?  Maybe a challenge where AVX512 machine code's large instructions could actually be non-terrible, using hardware left-packing of 32-bit integers according to a bitmask.

Wolfram Language (Mathematica), 72 bytes
Pick[Flatten[(i=IntegerDigits)/@Table[#,s=Length[p=#~i~2]]][[;;s]],p,1]&

Try it online!
Here is the plot of the first 30.000 such numbers

And here is the Logarithmic plot

Python 3, 80 \$\cdots\$ 52 53 bytes
Saved a 2 bytes thanks to Jitse!!!
Saved 7 6 bytes thanks to Surculose Sputum!!!
Added a byte to fix bugs kindly point out by Jitse and Surculose Sputum.
lambda n:[c for c,d in zip(str(n)*n,f'{n:b}')if'0'<d]

Try it online!
Returns the \$n^{\text{th}}\$ number in the sequence as a list of digits.

@Arnauld Should be correct now.

59 bytes

@Jitse Very sweet - thanks! :-)

You can return a list of digits instead, which saves the cost of joining.

@SurculoseSputum Thanks, wasn't sure about that.  Great minds think alike, yeah! :D

Jelly, 4 bytes
BTịD

Try it online, code that computes the \$n\$th term of the sequence, or check the first 100 terms!
How it works:
B     convert number to binary, i.e. 5 -> [1, 0, 1]
 T    keep the indices of the Truthy elements, i.e. [1, 0, 1] -> [1, 3]
  ị   and then index safely into...
   D  the decimal digits of the input number

By "index safely" I mean that indices out of range are automatically converted into the correct range!

I might start considering porting this answer. Good job!

Byte for byte what I tested with when assessing the sandboxed post :)

@JonathanAllan I hope that means I found the optimal solution and not that you think I copied your answer or something like that D:

These golfing languages never cease to amaze me

I think you did find the optimal solution. I didn't post it so copying it would have been impressive!

@JonathanAllan ah I see. I said that because I was downvoted and I was afraid it was you, thinking I had stolen your answer. But if it wasn't you, it wasn't you !

Nope. I do find short, well explained answers in golfing languages do occasionally get an inexplicable downvote.

So, it's better to switch to a practical language...

J, 13 10 bytes
#:##@#:$":

Try it online!

05AB1E, 4 bytes
×IbÏ

Try it online!
Yeah, I found the mysterious 4-byte 05AB1E answer :D
×   expand the input digits (input 123 -> 123123123123123... )
Ib  get the binary value of input (123 -> 1111011)
Ï   keep only the digits where the corresponding binary digit is 1

Ah nice. I actually had Þ instead of ×, with a list of digits as output. But I actually like your approach more, since the output is a single joined string. :)

Actually, I tried to find the Þ function, but I didn't know what to search in the info.txt :D

APL (dzaima/APL), 7 bytes
⊤⌿≢∘⊤⍴⍕

Try it online!
How it works
⊤⌿≢∘⊤⍴⍕  ⍝ Input: n
  ≢∘⊤    ⍝ Length of base-2 digits
     ⍴⍕  ⍝ Repeat the digits of n (as a string) to the length of above
⊤⌿       ⍝ Take the digits where the corresponding base-2 digit is 1

APL (Dyalog Unicode), 16 bytes
⍕(∊⊢⊆⍴⍨∘≢)2∘⊥⍣¯1

Try it online!
How it works
⍕(∊⊢⊆⍴⍨∘≢)2∘⊥⍣¯1  ⍝ Input: n
          2∘⊥⍣¯1  ⍝ Binary digits of n
⍕                 ⍝ Stringify n
 (       )        ⍝ Inner function with the two args above
       ∘≢         ⍝ Length of binary digits
     ⍴⍨           ⍝ Cycle the string digits to the length
  ∊⊢⊆             ⍝ Filter the digits by the binary digits

Incredibly done! Beats my Dyalog answer by eons, and I really spent a lot time on it. Also, I must admit I didn’t realize dzaima’s dialect could make it so much shorter! Which properties/operators in particular allowed you to take such a different (and superior) approach in dzaima’s APL extension?

@AviF.S. Actually it is the same approach. It's just that monadic ⊤ in the extension means exactly 2∘⊥⍣¯1, and ⌿ is a pure function "replicate" rather than a mixed function/operator. ⊤ is shared between various extensions, but pure function ⌿ is unique to dzaima's (which is usually the sole reason to choose the particular extension).

@AviF.S. See the discussion here.

JavaScript (ES6), 55 bytes
n=>n.toString(2).replace(/./g,(d,i)=>+d?(n+=[n])[i]:'')

Try it online!
Commented
n =>               // n = input
  n.toString(2)    // convert n to a binary string
  .replace(        // replace:
    /./g,          //   for each
    (d, i) =>      //   digit d at position i:
      +d ?         //     if d is '1':
        (n += [n]) //       coerce n to a string (if not already done)
                   //       and double its size to make sure we have enough digits
        [i]        //       extract the i-th digit
      :            //     else:
        ''         //       discard this entry
  )                // end of replace()

Python 2, 52 bytes
lambda n:[c for c,i in zip(`n`*n,bin(n)[2:])if'0'<i]

Try it online!
Input: An integer \$n\$
Output: The \$n^{th}\$ numbers in the sequence, in the form of a list of digits.
How:

bin(n) is the binary string of n, e.g bin(2) is "0b10". Thus bin(n)[2:] is the binary string of n without the 0b.
`n`*n creates the n-extended string by repreating the decimal string of n n times. This is longer than needed, but that's ok because extra characters will be truncated later.
c,i in zip(`n`*n,bin(n)[2:]) takes each pair of corresponding characters c,i from the binary string and the n-extended string.
if'0'<i checks if i is the character "1", if so the corresponding character c is kept in the result list.

C (gcc), 101 \$\cdots\$ 96 91 bytes
Save a 6 bytes thanks to ceilingcat!!!
b;i;f(n){char s[n];for(b=1;i=n/b;b*=2);for(;b/=2;++i)b&n&&putchar(s[i%sprintf(s,"%d",n)]);}

Try it online!
Outputs the \$n^{\text{th}}\$ number in the sequence.

APL (Dyalog Unicode), 25 24 bytes
Code
{b←2∘⊥⍣¯1⋄(b⍵)/(⍴b⍵)⍴⍕⍵}
Try it online!

Explanation
{                                        ⍝ Start function definition
  b ← 2∘⊥⍣¯1                             ⍝ Let b ← binary conversion function
              ⋄                           ⍝ Start new clause
                (b⍵)                      ⍝ Binary representation of ⍵ (input)
                     /                    ⍝ Mask boolean list over following string
                       (⍴b⍵)              ⍝ Length of boolean representation of ⍵
                             ⍴            ⍝ Reshape
                                ⍕⍵        ⍝ Stringify ⍵
                                    }     ⍝ End function definition

Binary Conversion
This is all much longer than one would expect from APL and is due to the lack of a concise binary conversion function. Unfortunately, the above is the best we can do. Below is the breakdown:

'Power' (⍣) does an operation n times. So f⍣¯1 calculates the inverse of f, if it can.
'Decode' (⊥) converts from an arbitrary base back to decimal; 2 ⊥ 1 1 0 1 returns 13.
'Jot' (∘) can compose two functions as in (f∘g) 3 or curry as in(1∘+) 3.

Together, 2∘⊥⍣¯1 denotes the inverse of the function that converts from binary to decimal. (Two left-curried with the encoding function, 2∘⊥, converts binary to decimal.)

Welcome to PPCG and nice first answer! You can try converting the function into a train to save some bytes

Hi, welcome to CGCC! Nice first answer. I don't know APL, but why is the entire code in the input-section instead of code section? Usually we'd have a full program or function, and the input is than taken through STDIN, System-arguments, or function arguments/parameters.

@user41805 The / function is often problematic in trains.

@Adám It can be circumvented with (/⍨⍨)

@user41805 Thanks! I know it looks likes it's begging to be trainified but I was unable to make it any shorter. If you can golf it further, please do comment; I'll keep looking as well as I'm not completely happy with it.

@KevinCruijssen Ah, you're right that it's atypical, I just prefer it REPL-style. I personally find it clunky otherwise because you have to name it; you can't keep it anonymous. That means it'll look like it requires more code than it does. However, I've updated the link and if you want to calculate the 42nd element, just input f 42.

How thrilling to have the legendary Adám comment! I absolutely did run into much frustration with the / function.

You can often (e.g. in this case) use ∊⊂ instead of /

@Adám Anything of the form {∊⍺⊂⍵} returns itself, it seems. On a similar note, {⊃¨⍺⊂⍵} works as a replacement, though! Is that what you mean?

No, typo. I meant ∊⊆

Check out my answer to see how you might golf such a function.

Ruby, 68 bytes
->n{n.to_s(2).gsub(/./).with_index{|b,i|b>?0?(n.to_s*n)[i]:""}.to_i}

Try it online!
Returns the nth number in the sequence.

I'm no expert golfer, so it's undoubtedly possible there's a better Ruby solution, but I'm (not altogether unpleasantly) surprised to see a challenge where Python and JavaScript both outperform Ruby. I guess python's list comprehensions are a perfect fit for this challenge, and JavaScript passing the index as a parameter to the replace method is very convenient.

with_index is really long -- you can save 5 bytes by working around it and then another byte by folding the test into the string multiplication

APL+WIN, 25 bytes
Prompts for integer n and outputs nth term
((b⍴2)⊤n)/(b←1+⌊2⍟n)⍴⍕n←⎕

Try it online! Coutesy of Dyalog Classic

Red, 131 bytes
func[n][i: 0 remove-each _ t: take/part append/dup t: to""n n |:
length? s: find to""enbase/base to#{}n 2"1"|[s/(i: i + 1) =#"0"]t]

Try it online!

PHP, 75 86 81 73 bytes
for(;$i<strlen($d=decbin($a=$argn));$i++)if($d[$i])echo$a[$i%strlen($a)];

Try it online!
Gives the nth number.
Original version didn't handle 0's in input correctly.

05AB1E, 4 bytes
∍IbÏ

Try it online!
How?
∍IbÏ - Full program expecting a single input      e.g. 13    stack:
∍    - extend a to length b (stack empty so a=b=input)       [1313131313131]
 I   - push the input                                        [1313131313131, 13]
  b  - convert to binary                                     [1313131313131, 1101]
   Ï - a where b is 1                                        [133]
     - implicit output                                       133

I'm not used to you posting 05AB1E answers. :) Btw, not sure if you had noticed it, but it's rather similar as this existing 05AB1E answer. Of course it's fine since you came up with it independently, but figured I'd let you know in case you missed it.

Yeah, I saw not long after I posted (I originally had s rather than I too, but realised I was more natural) I didn't notice x when making it either. (I found this during sandboxing BTW)

Well, your ∍ is probably slightly better for memory usage than x anyway, since 100 100x would be 10,000 characters long, whereas 100 100∍ would be 100 characters long. :)

Ah, reading "expand" and "123123..." I assumed it was a lazy infinite generator :)

That would be Þ ;) Although it implicitly converts it to a list of characters/digits. My prepared 4-byter was actually ÞIbÏ, but I like the approach with x or ∍ actually more, since the output is than a single string/number instead of a list of characters/digits.

Perl 5 -n, 75 bytes
map{$i=0;@b=split//,sprintf"%b",$_;say@s=grep{$b[$i++]}split//,$_ x@b}1..$_

Try it online!
Prints the first n numbers in the sequence
Perl 5 -nl, 60 bytes
@b=split//,sprintf"%b",$_;say@s=grep{$b[$i++]}split//,$_ x@b

Try it online!
Shorter version that just prints the nth number

You can cut the latter entry down to 55 bytes

Rust, 131 129 bytes
|n|format!("{:b}",n).chars().zip(format!("{}",n).chars().cycle()).flat_map(|(b,c)|if'0'<b{Some(c)}else{None}).collect::<String>()

Try it online!
Try it online!
Works according to option 1 and returns the \$n^{\text{th}}\$ number of the sequence as a string.
-2 thanks to Kevin Cruijssen!
Explanation
|n|                  // Closure taking a parameter n
format!("{:b}",n)    // Binary string of n
.chars()             // Iterate over the chars
.zip(                // Zip iterator with
  format!("{}",n)    //   Decimal string of n
  .chars().cycle()   //   Cycle over the chars
)
.flat_map(           // Map with the following iterator-returning
                     // function and flatten the result
  |(b,c)|            //   Closure taking the char pairs (b,c)
  if'0'<b{Some(c)    //   If '1' then return an iterator yielding c
  else{None}         //   Else return an empty iterator
)
.collect::<String>() // Evaluate into a string

Nice answer! The if b=='1' can apparently be if'0'<b for -2 bytes. :)

@KevinCruijssen thanks for the tip!

C (gcc), 79 bytes
V;M;r(n){M<=V?r(n/10?:(M*=2,V)),M/=2,M&V&&putchar(n%10+48):0;}f(n){M=1;r(V=n);}

Try it online!
Generates the nth number

Bash + GNU utilities, 87 bytes
x=$1$1$1$1
for((b=`dc<<<2o$1p`;b;)){ [ $[b] = $b ]&&printf ${x:0:1};x=${x:1};b=${b:1};}

Try the test suite online!
Input \$n\$ is passed as an argument, and the \$n^\text{th}\$ number in the sequence is output on stdout.
How it works:
x is set to 4 copies of the input in a row, which is more than enough digits to match the binary equivalent of the input.  (A number in base 2 can never be longer than 4 times its representation in base 10, since \$\log_2(10)<4.\$)
b is initialized to the binary representation of the input.
The for loop repeats the following as long as b still has at least one 1 in it:

If b doesn't start with a 0, then the first character in x is printed.
The first character is chopped off of x and b.

The golfiest trick is probably the way I check to see if b starts with a 1: the expression $[b] means: b evaluated as an arithmetic expression. This will omit any initial 0s (except that it will keep a final 0 if all the characters in b are 0).  So [ $[b] = b ] is true iff b either starts with a 1 or is equal to "0".  But b can't equal "0" since the loop termination condition would have been true in that case, and the loop would have ended already.

Ruby, 58 bytes
->n{a=n.digits 2;([n]*n*m='').chars{|x|m<<x*(a.pop||0)};m}

Try it online!

Java (JDK), 108 bytes
n->{var s=""+n;for(int b=n.highestOneBit(n),i=0;b>0;b/=2,i++)if((b&n)>0)System.out.print((s+=s).charAt(i));}

Try it online!
Credits

-7 bytes thanks to Kevin Cruijssen

@KevinCruijssen Nice idea to repeat that way!

I agree. Not my idea btw, but Arnauld's. When he posted his answer I had to verify whether there was some integer with a binary pattern 10...0...01 for which this might fail, but apparently not. 9 results in exactly enough digits with -> 99 -> 9999, and all integer above that concatenated four times are larger (in terms of length) than their binary-string.

Husk, 5 bytes
fḋ¹¢s

Try it online! This function works according to option 1, outputting the term as a string.
Explanation
fḋ¹¢s  (Let X denote the argument.)
f      Select the elements of
    s    the string representing X,
   ¢    cycled infinitely, corresponding to truthy values of
 ḋ¹     the binary digits of X.

Japt, 8 bytes
Came up with a few approaches but couldn't do better than 8 bytes.
With output as a digit array:
¤¬ðÍ£sgX

Try it
With output as a string:
¤ËÍçEgUs

Try it
¤¬ðÍ£sgX     :Implicit input of integer U
¤            :To binary string
 ¬           :Split
  ð          :Truthy indices when
   Í         :  Converted to integer
    £        :Map each X
     s       :  Convert U to string
      gX     :  Get digit at index X

¤ËÍçEgUì     :Implicit input of integer U
¤            :To binary string
 Ë           :Map each D at index E
  Í          :  Convert D to integer
   ç         :  That many times repeat
    Eg       :  Index E into
      Uì     :  Digit array of U

Vyxal s, 17 bytes
₌SbL:‟*Ẏf?bZ't;vh

Try it Online!
A mess.

AWK, 89 bytes
{for(f=b=1;$1>=b;e=e$1)c[d++]=and($1,b)/(b*=2);for(;d--;f++)c[d]?g=g substr(e,f,1):0}$0=g

Try it online!
Not that short, but AWK doesn't have a print format to generate binary strings from integers, so it has to iterate to get that info...
At a high level, one loop uses bitwise and operations with a single bit moved one position to the left each time to built an array of "binary" settings.  It also builds up a string composed of multiple copies of the N number while it's looping.  AWK doesn't have a nice string*number operator either.
Then the second loop works backwards through that array and for each entry which is 1, it appends the appropriate character to a "results" accumulator.
The final step just prints the accumulated string.
# Loop 1, build the "binary" array and string of duplicated "N" characters
for(f=b=1;$1>=b;e=e$1)c[d++]=and($1,b)/(b*=2);
   (f=b=1;                                     # Loop init, "f" is used in loop #2
          $1>=b;                               # Exit test, goes until bit check > N
                e=e$1)                         # End of loop, build "N dup string
                      c[d++]=and($1,b)/(b*=2); # Body, does a couple of things...
                                               # d++ : increment bit position
                                               # and($1,b) : extract bit
                                               # /(b*=2) : normalize, then shift bit
                                               # c[d++]= : add to "binary" array

# Loop 2, accumulate chars associated with set bits
for(;d--;f++)c[d]?g=g substr(e,f,1):0
     d--;                             # Exit test, when all bits checked stop
         f++)                         # End of loop, increment char pos in "N" dup str
             c[d]?                 :  # Ternary, code runs if bit is set
                  g=g substr(e,f,1)   # Append current char to accumulator
                                    0 # No-op "else" from ternary

# Print the result
$0=g   # Typical AWK golf trick, assign "$0" to what you want to print w/o code block

Charcoal, 11 bytes
⭆↨Ｉθ²⎇ι§θκω

Try it online! Link is to verbose version of code. Explanation:
   θ        Input as a string
  Ｉ         Cast to integer
 ↨  ²       Convert to base `2`
⭆           Map over digits
      ι     Current digit
     ⎇      If non-zero
        θ   Input as a string
       §    Cyclically indexed by
         κ  Current index
          ω Else empty string

05AB1E, 6 bytes
The Ï< ruins the consecutive word bāsè... (If you don't get it, the hex code 05AB1E converted to base64 would result in base.)
bāsÏ<è

Try it online!
Explanation
b      To base 2
 ā     Length-range to 1
  s    Prepend
   Ï   Keep all that's truthy
    <  -1 due to 0-based indexing ... that's terrible!
     è Modular Indexing

Great, +1 in that case (and I like how it -almosts- spells 'base'). PS: As mentioned at the bottom of my question, 4 bytes is possible in 05AB1E. ;)


text:
Return a word with a prescribed sum of letters
Identify each letter of the English alphabet with the number denoting its position in the alphabet, that is,
a = 1, b = 2, c = 3, ..., z = 26
(no distinction between lower and upper case letters is made). Every other character is identified with 0.
The "sum" of a word is the sum of its characters, for example: the sum of e-mail is 40 = 5 + 0 + 13 + 1 + 9 + 12, since e = 5, - = 0, m = 13, a = 1, i = 9, l = 12.
The Challenge
Write a program or a function that takes as input an integer n in the range 10-100 and returns a word of the English language whose sum is equal to n
This is codegolf, standard loopholes are forbidden.
ADDENDUM:

For a list of English words, see: https://github.com/dwyl/english-words
Reading a remote list of words is forbidden.

Welcome to code golf! This appears to almost be a good challenge, you just have one significant problem: you haven't defined the English language. I would personally recommend saying the submissions are allowed to take a lexicon of English words as a free argument. For the future, please consider using our sandbox to work through such problems before posting.

@FryAmTheEggman I don't understand what your suggestion of "taking a lexicon of English words as a free argument" means.

Essentially, you need to somehow define what is a valid English word. @FryAmTheEggman suggested adding a list of possible English words as an input.

I've been trying to find a good example of another challenge that does this, the best I have found so far is this one, though I am certain there are others.

I see. But what is a valid English word is something that is decided by the entirely community of English speakers. Therefore, I think that a better solution would be that each answers post the list of "n - word" pairs of its solution, and people upvote or downvote if they think the words are valid or not.

Hmm, this can be a very cool Kolmogorov-complexity problem then. The requirement can be: with no input, output the English words for n from 1 to 100 or something.

I'm afraid that just isn't how this site works. Solutions must be verifiable objectively. And besides, it isn't unreasonable to require that the program adapt to what the user decides is valid English.

@Nik Challenges on this site are required to be objective, with posters being able to validate and score their solutions as they post. We've found that asking voters to vote based on a certain judgment is ineffective and does not make for good quality control.

If we cannot assume the knowledge of English, we can probably assume xnor has just said "I approve of this question. Have you considered also allowing Spanish?".

As an alternative to making the dictionary be an input, I think a good way to go is to specify your own dictionary by linking to a downloadable file (that code is not allowed to access) in the question. Then it becomes a compression-style challenge about finding a good set of words to use for each length.

@FryAmTheEggman and xnor: Would adding a link to any English dictionary make the challenge objectively verifiable?

I think so, but I think it's also important for the word list to be something that can be downloaded and not just queried online.

The word list looks good. Could you please also link to the file directly? (Edit: Saw you already answered my question about capitals.)

Would it be reasonable to drop the 'word' idea/requirement and just say that any ascii alphabetic string input should return the sum?

@ouflak No, that's the funny part. Otherwise, "aaa...a" (n times a) would do it.

Due to some confusion, I think you should clearly edit in that only those words in the file count as English words. Thank you for making the suggested changes, so far.

I looked at the words.txt file at the github link you gave (you should specify that that's the file you meant, if it is).  That word list looks good -- it appears to include most grammatical forms (plurals, participles, etc.).  I'd happy if you replaced "returns a word in the English language" with "a word in https://github.com/dwyl/english-words/words.txt" (but of course your code can't download that file!).  This is a good challenge!

I should add that I don't think we should be able to pass the entire word list as an argument for free.  That would make it much less interesting.  (If you want to include the word list in your code, you should have to count all the bytes in it!)

I think the file you really want us to use is words_alpha.txt rather than words.txt, right? (cc @MitchellSpector)

@Arnauld  You could be right (I didn't compare them), but my other comments stand.  (And this confirms that OP should specify the specific file used as a reference for what's an English word.)

The most important question is whether your program can read from a file for free, or if you have to count the bytes in any external file in your byte count.  Some people seem to be assuming that you can use an external file for free, but that seems to me to go against both the spirit of the challenge and general codegolf scoring rules.

@MitchellSpector From my understanding you aren't allowed to read a file at all. You need to store the words you want to output (compressed) inside your program. This challenge is mostly about choosing the shortest 90 words to compress, then it is about actually returning them based on the input.

@KevinCruijssen That's what I thought also, but some of the answers seem to have assumed otherwise, so I thought it was worth spelling out.

I think you should just tell us which is the official word list to use for this challenge, direct link. So we all can use the same accepted words. Whether that list is a good or bad list of the English language is beyond the point here.

Here's a program that takes the smallest words 10-100 from the wordlist. Runs in about a second on words.txt: https://tio.run/##ZVHRboMgFH3nK@66pEJal/ZVrD@yNQ1BakkUDGKXpfXbHeBW6MbL5R7PuZx75H2fN5zP86tUvB1rAaXUgzWCdRWKmEOkalKEc/vVixTpWF8hJFUrlQCpLHxqU5@4HpXFXKvBwmDrolhGwdpVgm4I3PFkc5toaM7aYDZaDRwKCCT4OQY2B8AccsAZy1zZEwJryLEcWNtfGOakqvY7sswxwo5GgaFo8q4sdEwqfNWy/n02teNN04i6XUqn2aacCoaOte3JrzVQ9DBLoRHW63Egc6m2YRyhsHi/PTZYYvBmQixwSDNaNH@4T5Hx0ThJ4uI9KI9RJM/4xbHeWqEae8EE7nd46qtg7dHHcMPq/ya752IyU9zZryDdx/2Oulr6i79tNnHgEoYeLZSl55SwKmDla/qMPHok@1CZ@0/z/A0

Please don't be discouraged by the few downvotes or the comment flood. Despite the initial confusion about the rules, I think that's a pretty cool first challenge. The task is now quite clear but it would be better to link to the exact file we're supposed to use rather than the GitHub repository.

Python 3.8 (pre-release), 262 235 bytes
lambda x:f'JKLmGoPlheAhVegytMtosOdtthfvtWypvttgYsRWspytps    e  eegli ra eehnkPooeoroyyauiuruotoituooup    b   aggd  p ai    mnrwiwpnwsnyotrosturwutr{"":8}d{"":14}gnlz   nht ntkpstmsltty'[(k:=x-10)//46*23+k%23::46].strip()+k//23%2*'er'

Try it online!
Uses words from the list that appear with and without a trailing er, cutting the number of required words almost in half.

JavaScript (ES6),  217  205 bytes
An idea similar to the one used by ovs.
Most words are used twice: once with the -ty suffix (which is worth \$45\$ points) and once without it.
n=>"JK"[n-10]||["Hwy",,"Yor",,"Yot"][n-56]||"KaMMaOPQCanSTAtMiAmiCatDuBawBetGilBolPieBitBooCooEmpToFooBunCotDotKitBoxBusButCutJotJaunGusGutYesUmpJutSixMusUnsNut".match(/.[a-z]*/g)[(n-12)%45]+(n>55?'ty':'')

Try it online!

JavaScript (Node.js),  325 ... 240  235 bytes
Words of \$3\$ to \$5\$ letters ending in either "d" or "y", with the penultimate letter deduced from the other ones.
n=>(w="EAGCABCABACBCCHFABAAAAdBADFaFGAAAKBCASCDBFEYLGNHHArOPSPPTOYRSDoCoDoCuFoEyYaLoYoNoSpSiPoOoRoToAttCurIzAtyButCurDizSuDruExpYesMurFurYumMusMizBuz".match(/.[a-z]*/g)[n-10])+(B=Buffer)([B(w+(c=n>27?'y':'d')).map(c=>n+=96-c)&&n+64])+c

Try it online!

05AB1E, 187 51 48 bytes
žĆ•o‹§d∍(Ì•3в¾7:65Å1«.¥žy+èãJε„'ÿ.V}ʒAsSk>OQ}Réθ

Try it online. (Pretty slow unfortunately, so no test suite, but here is a list of all the words used.)
Explanation:
  •o‹§d∍(Ì•           # Push compressed integer 13897672729830113
    3в                # Convert it to base-3 as list: [2,1,1,1,1,1,1,1,1,1,1,2,0,1,1,2,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,2]
      ¾7:             # Replace the 0 with a 7
         65Å1         # Push a list of 65 1s
             «        # And append it to the list
              .¥      # Undelta the list (with leading 0): [0,2,3,4,5,6,7,8,9,10,11,12,14,21,22,...]
                žy+   # Add 128 to each: [128,130,131,...]
žĆ                 è  # Index each into the 05AB1E codepage builtin
ã                     # Get the cartesian product with itself, to create all possible pairs
 J                    # Join each pair together
  ε     }             # Map over each pair:
   „'ÿ               '#  Push string "'ÿ", where the `ÿ` is automatically filled with the current pair we're mapping over
      .V              #  And eval it as 05AB1E code, pushing the dictionary word
ʒ       }             # Filter the list of words by:
 A                    #  Push the alphabet
  s                   #  Swap to take the current word we're filtering over
   S                  #  Convert it to a list of characters
    k                 #  Get the index of each letter inside the alphabet
     >                #  Increase it by 1 to make the 0-based indices 1-based
      O               #  Sum them all together
       Q              #  And check if it's equal to the (implicit) input-integer
R                     # Then reverse the list of remaining words (work-around for input n=11,
                      # which otherwise would result in "fda", which is not in OP's list)
 é                    # Then (stable) sort all words based on length, from shortest to longest
  θ                   # And only leave the last one
                      # (after which it is output implicitly as result)

Unfortunately, not all words that can be found in the 05AB1E word list can be found in the provided list as well.
See this 05AB1E tip of mine (sections How to use the dictionary?, How to compress large integers?, and How to compress integer lists?), to understand how the dictionary words and compressed integer list works.

Original 187 bytes answer:
“„é…ªƒ…°»ØÎ‰éãŠêˆÜŠ°í©ÓŽÄÍÝ‚†–ìŠÑÞã™Ä‡ÉˆÁ³²áäÁÑÆ©…¥Ê†…íÆ±Ñœ›Ç²èœÊ‚ì€€Šµ€„±½†íª¯ÅÝ‚îäÔÈÃÞºì¤ƒ‚ž¨€º¢êˆ¨ïëïÆÐ¼ˆÌ²Ï……ƒÔ…ÙÒ„±ÞŒÂä†ÔÚ´´½é‚¤»œË´¥º™Žâ¤Ñ¸‚É„¾ÈÕˆî†Û‚äŠÁ‹‚Œæ‹Ì†ÏƒÓ‡È…Ï‰Éƒà‚ë„¶™£“#sè

Try it online or verify all test cases.
I've chosen random words which are both in the English dictionary provided, as well as in 05AB1E word list.
Explanation:
“...“     # Dictionary string containing all words, space-separated
     #    # Split it on spaces
      s   # Swap to get the (implicit) input
       è  # And used it to index into the list (0-based and with wrap-around,
          # so 91-100 wrap around to the first few words)
          # (after which the result is output implicitly)

Here is just the dictionary string part of the program.
See this 05AB1E tip of mine (section How to use the dictionary?), to understand how the dictionary string works.

Perl 5, 361 bytes
say''.(memGunzip(decode_base64('H4sIAINkcl4CAx2PC3LDIBBDL/Qu5Q+JneJAgbVZTl/RGWA0WkloQ2BdDs6Niy+JPRIi50llqZyRRTcUQsWJX1Znc943wXnpDFLBLlIjdqLza9RGckaiF4pTneYyVvpD76w2CGKOp/FNDx+7eYs77sk5P24KdbLmaVSytNmcYp3Uhb1Tpa/S7pPY0nAF32x2T9BVTv6P6ek+pilyuWrlohYvG4M8jcdE1YsG1oZa5kftpuaaE7dmCpBvs6Lk/Rz66LFh7CrjLG7qGsOkc2pa9GVFOFq3mVHV/Po3aefhfyb5uBZsAQAA'))=~/\w+/g)[-10+pop]

Try it online!
Ungolfed program.pl:
#!/usr/bin/perl
use v5.10;
use MIME::Base64 'decode_base64';
use Compress::Zlib 'memGunzip';

# base64-encoded gzip'ed string of 91 words:
my $data=<<'';
H4sIAINkcl4CAx2PC3LDIBBDL/Qu5Q+JneJAgbVZTl/RGWA0WkloQ2BdDs6Niy+JPRIi50
llqZyRRTcUQsWJX1Znc943wXnpDFLBLlIjdqLza9RGckaiF4pTneYyVvpD76w2CGKOp/FN
Dx+7eYs77sk5P24KdbLmaVSytNmcYp3Uhb1Tpa/S7pPY0nAF32x2T9BVTv6P6ek+pilyuW
rlohYvG4M8jcdE1YsG1oZa5kftpuaaE7dmCpBvs6Lk/Rz66LFh7CrjLG7qGsOkc2pa9GVF
OFq3mVHV/Po3aefhfyb5uBZsAQAA

say ''.(memGunzip(decode_base64($data))=~/\w+/g)[-10+pop]

Run:
for n in {10..100};do echo -n "n=$n "; perl program.pl $n; done
.
.
.
n=95 potsy
n=96 furzy
n=97 luxus
n=98 musty
n=99 mizzy
n=100 buzzy

Improvement: I could have search for words in words.txt that gave shorter gzip'ed $data. Probably shortest AND most similar word from one n to the next.

You can shave off some bytes: Try it online!

C (gcc), 574 bytes
char*s[]={"ee","afd","ic","m","n","o","dl","el","ii","s","as","il","3rd","er","es","y","ln","by","cy","gv","ey","fy","fz","or","um","ot","lx","yl","ym","yn","yo","zo","xr","yr","ys","ty","bys","xw","xx","buz","ety","hwt","now","yew","guz","hvy","hwy","kyu","yor","yum","yot","you","puy","yow","yox","yoy","suz","swy","doxy","cozy","xxv","cuvy","xxx","eyry","yawy","xyz","yoky","youp","prys","fuzz","yoyo","huzz","yows","yowt","typw","burys","muzz","yutu","xyst","curvy","dizzy","wuzu","druxy","ayuyu","yesty","potsy","furzy","yummy","yours","yourt","buzzy"};f(n){n=s[n-10];}

Wordlist generated using my program run as program < words.txt.
Try it online!

I think you can ditch the char at the beginning.

source: Stack Exchange

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

sort: votes


text:
Name your novel disease
Introduction
The current coronavirus disease is officially named COVID-19, from the 3 words corona virus disease, and the year 2019. (Technically it's coronavirus, making 2 words, but whatever...)
Given this example, we can apply this naming convention to name other potential diseases.
Challenge
You will be given 3 words and a year.

Take the first letters of the first 2 words, up to and including the first vowel, and append them together.
Then, append the first letter of the 3rd word.
Finally, append the character -, followed by the last 2 digits of the year.

Thus, corona,virus,disease,2019 -> co + vi + d + - + 19 -> covid-19.
Challenge rules

It is guaranteed that each of the three words have at least one vowel. For the purposes of this challenge, vowels are defined as the letters a, e, i, o, u.
You may assume that words consist only of lowercase letters a-z, or only uppercase letters A-Z if you prefer. Your output may be in either case.
It's guaranteed that the date is exactly four digits.
Input may be specified in any format, as long as there is a delimiter between the words. For example, ['corona', 'virus', 'disease', '2019'], corona,virus,disease,2019, [['corona', 'virus'], 'disease', 2019] and corona virus disease 2019 are all valid inputs.

This is code-golf, so shortest answer wins.
Example test cases
corona,virus,disease,2019 -> covid-19
computer,addiction,syndrome,1970 -> coas-70
code,golf,fun,2020 -> cogof-20
a,ba,ca,1234 -> abac-34
tree,string,create,9000 -> trestric-00
love,time,cholera,1985 -> lotic-85

Can I take input in the format ['corona','virus'], 'disease', 2019?

Welcome to code golf, thank you for submitting a clear and well specified first challenge. Please consider editing your test cases to be easier to copy and paste without modification (I recommend removing the bullets and putting them in one code block). For future challenges please consider using our sandbox. Good luck :)

When you say we may ignore all capitalization, does that mean we can expect input to be lowercase? Or that we have to handle different types of capitalization (but may output whichever capitalization)?

@EmbodimentofIgnorance sure!

@xnor You can expect input to be lowercase, or uppercase, depending on your wish; similarly, you can output in lowercase or uppercase.

OK, can we expect that the three words consist only of letters a-z (or A-Z if we choose)?

@xnor that's fine!

Golfers might find it useful to look at answers to Spoonerise words, which also involves extracting consonants before (though not including) the first vowel of two words.

I don't know how to feel about a challenge inspired by a dangerous disease that's killing thousands of people... :-/

Are we allowed to take each word as a list of characters? And consequently, can we give the output as a list of characters?

"In the year 9000 humans will be able to create complete trees with strings." -- Test case 5. I'm looking forward to that!

@Lyxal sure, if that's convenient.

Suggested test case: "love","time","cholera", 1985 -> "lotic85" since the novel Love in the Time of Cholera was published in 1985. How's that for a novel disease!

Are the first words expected to always contain vowels? If not, what is the expected output for rhythm,rhythm,rhythm,1111?

Python 3, 83 81 bytes
lambda a,b,c,d:g(*a)+g(*b)+c[0]+"-"+d[2:]
g=lambda c,*s:c[:c in"aeiou"]or c+g(*s)

Try it online!
-2 bytes thanks to @JonathanAllan!
Explanation:
g is a recursive function that takes in a splatted string and return the string, truncated after the first vowel.

lambda c,*s gather the splatted string into the first character c and the rest s.
c[:c in"aeiou"] or c+g(*s) evaluates to:

if c is a vowel, then c[:c in"aeiou"] evaluates to c[:1] which is c. Since c is Truthy, it is returned.
if c is not a vowel, then c[:c in"aeiou"] evaluates to c[:0] aka the empty string. The empty string is Falsy, so c+g(*s) (the recursive case) is returned.

Old solution, kept here for sentimental reason
Python 3, 89 bytes
lambda a,b,c,d:g(a)+g(b)+c[0]+"-"+d[2:]
g=lambda s:s[:[x in"aeiou"for x in s].index(1)+1]

Try it online!

Really clever list comprehension!

g=lambda c,*s:c[:c in"aeiou"]or c+g(*s) saves 2

Wow this is really nice

@JonathanAllan Very clever! Thanks!

Java 8, 82 74 71 67 61 bytes
s->s.replaceAll((s="(.*?[aeiou]).*,")+s+"(.).*,..","$1$2$3-")

-8 bytes thanks to @ValueInk.
-6 bytes thanks to @Nevay.
Input as a single comma-separated string like in the challenge description.
Try it online.
Explanation:
s->                // Method with String as both parameter and return-type
  s.replaceAll(    //  Regex-replace the match with the replacement (see below)
                   //   As match:
    (s="(.*?[aeiou]).*,")+s
                  //     Repeat this String twice (re-using the input-variable)
    +"(.).*,..",  //     and append this String
    "$1$2$3-")    //    And as replacement: use this String

Regex explanation:
(.*?[aeiou]).*,(.*?[aeiou]).*,(.).*,..  # MATCH:
 .*                                     #  0 or more characters
   ?                                    #  which are optional to lower their priority
    [aeiou]                             #  followed by a vowel
(          )                            #  Stored in capture group 1
            .*                          #  Followed by some optional characters
              ,                         #  and a comma
               (.*?[aeiou]).*,          #  Same again, with capture group 2
                               .        #  Then a single character
                              ( )       #  Stored in capture group 3
                                 .*     #  Followed by some optional characters
                                   ,    #  and a comma again
                                    ..  #  Followed by 2 characters

$1$2$3-                                 # REPLACEMENT:
$1$2$3                                  #  The contents of groups 1, 2, and 3
      -                                 #  Appended with a literal "-"

Note how the two trailing digits of the input-String aren't touched, and will still be there after the replacement.

Do non-greedy quantifiers like .*? not work in Java?

@ValueInk They do, so thanks for -8. :)

The last capture group can be removed, 61 bytes: s->s.replaceAll((s="(.*?[aeiou]).*,")+s+"(.).*,..","$1$2$3-")

@Nevay Smart thanks! Haven't seen you here in a while. :)

Retina 0.8.2, 26 bytes
\B.*¶\d.
-
([aeiou]).*¶
$1

Try it online! Link includes test suite. Takes lowercase words and year on separate lines, but test suite splits each test case on commas automatically for the convenience of the user. Explanation:
\B.*¶\d.
-

Truncate the last word after the first character, remove the first two digits of the year, and join the two together with a -.
([aeiou]).*¶
$1

Truncate each of the first two words after the first vowel, and join everything together.

Japt v2.0a0 -P, 15 bytes
®¯ÒZb\vÃpVÎ'-W¤

Saved a byte thanks to @Shaggy (s2 -> ¤)
Try it
®¯ÒZb\vÃpVÎ'-W¤           Input: ["corona" "virus"] "disease" "2019"
®      Ã                  Map ["corona" "virus"] to
   Zb\v                     Index of first vowel in word
  Ò                         Add one
 ¯                          Slice 0..index+1
                          ["co" "vi"]
        p                 Append the following:
         VÎ               A) First letter of third word
           '-             B) "-"
             W¤           C) Last two digits of year
                          ["co" "vi" "d" "-" "19"]
-P                        Implicit join -> "covid-19"

Don't forget the shortcut for s2.

Jelly,  18  17 bytes
ḣe€ØcM$ḢƊ€⁴Ḣ”-3⁵ṫ

A full program accepting arguments ['word1', 'word2'] 'word3' 'year' which prints the result.
Try it online!
How?
ḣe€ØcM$ḢƊ€⁴Ḣ”-3⁵ṫ - Main Link: [word1, word2]
         €        - for each (w in [word1, word2]):
        Ɗ         -   last three links as a monad:
      $           -     last two links as a monad:
  €               -       for each (character, c of w):
 e                -         (c) exists in?:
   Øc             -           vowels = "AEIOUaeiou"
     M            -       maximal indices (i.e (sorted) indices of vowels in w)
ḣ                 -     head to index (vectorises across the list of indices):
       Ḣ          -     head (the first such head-to-index result)
          ⁴       - program's 2nd argument, word3
                  - ...N.B. a nilad here forces Jelly to smash the previous list
                  -         together and print to STDOUT.
           Ḣ      - head - i.e. the first character of the third word
            ”-    - literal '-' character
                  - ...N.B. again a nilad here forces a print of the previous
                  -         result, the first character of the third word.
              3   - literal three
               ⁵  - program's 3rd argument, year
                ṫ - tail from index (i.e. "2019" -> "19")
                  - implicit print (of these two characters)

Outputs covid19 instead of covid-19.

Ah missed that requirement somehow - will fix...

Fixed, and thanks for notifying :)

Bash + Core utilities, 58 55 bytes
sed -E 's/([aeiou]).*/\1/;3s/\B.*/-/;4s/..//'|tr -d \\n

Try it online!
3 bytes shorter through the use of \B, thanks to user41805.
Accepts newline-delimited input on stdin.
Output on stdout.

Nice thinking on separating by newlines!

You can give sed the -z flag and remove newlines with sed to save a byte. And using \B in your second sed substitution can help save a bit

@user41805 Thanks -- I put in the \B improvement.  I don't see right away how to use -z in a way that's compatible with the rest of the code; I had looked at that originally and it didn't seem to do what I needed.

Ah my bad, I missed your usage of addresses, so it seems -z doesn't provide a shorter alternative

Python 3, 86 bytes
lambda t,c,y:''.join(re.sub('([aeiou]).*',r'\1',s)for s in t)+c[0]+'-'+y[2:]
import re

Try it online!
Inputs the first two words in a tuple followed by the third word and then year as a string.

This doesn't explicitly check for the vowels; it just appends the first 2 characters of the first 2 words, so it fails on tree,string,create,9000.

@rkong Fixed it.

beat you to 86 bytes whoops

@OliverNi Just golfed that and then saw you did the same, dropping your helper lambda! :D

haha :DD its like pretty much exactly the same

QuadS, 33 bytesSBCS
Takes lowercase multi-line input.
∊('-',⍨⊃)¨@3⊢⍵
^.*?[aeiou]|\d.$
&

Try it online!
& Search for and return
^.*?[aeiou]|\d.$ initial letters ending with a vowel, or a trailing digit with another character
⊢⍵ on that
(…)¨@3 at the third match:
 ⊃ pick the first character
 '-',⍨ prepend a dash
∊ ϵnlist (flatten)

Perl 5 -p, 48 bytes
$p='(.*?[aeiou]).*? 'x2;s/$p(.).*(..)/$1$2$3-$4/

Try it online!
Basically, a straight forward regex to pick out the relevant parts and put them back together.

Save three bytes: $p='(.*?[aeiou]).*? 'x2;s/$p(.).* ../$1$2$3-/

Zsh, 41 bytes
<<<${(Mj::)@[1,2]#*[aeiou]}${3[1]}-${4:2}

Try it online!
Normally ${param#pattern} is prefix removal, adding the (M) flag keeps the prefix instead.
<<<${(Mj::)@[1,2]#*[aeiou]}${3[1]}-${4:2}
   ${      @[1,2]         }                 # first two args
   ${(M   )      #*[aeiou]}                 # match shortest prefix ending with a vowel
   ${( j::)               }                 # join the resulting words on empty string
                           ${3[1]}          # third param, first char
                                   ${4:2}   # fourth param, starting at third char

If the first two words can be given as a single space seperated argument (as in corona virus disease 2019), then one byte can be saved for 40 bytes:
<<<${(Mj::)${=1}#*[aeiou]}${2[1]}-${3:2}

Try it online!

JavaScript (ES6),  65  63 bytes
Takes input as 4 distinct strings.
(a,b,[c],[,,d,e])=>a.match(r=/.*?[aeiou]/)+b.match(r)+c+'-'+d+e

Try it online!

JavaScript (ES6), 71 bytes
Takes input as ["word1", "word2", "word3", "year"].
a=>'012-3'.replace(/\d/g,i=>a[i].match([,,/./,/..$/][i]||/.*?[aeiou]/))

Try it online!

y.slice(-2) -> y[2]+y[3] for -2 bytes

@EmbodimentofIgnorance Thanks. I've just noticed that the year is guaranteed to be made of 4 digits and was already editing to another 63.

Python 3, 86 bytes
lambda a,c,d:''.join(re.sub("([aeiou]).*",r"\1",x)for x in a)+c[0]+"-"+d[2:]
import re

Accepts input like ["corona", "virus"], "disease", "2019"
Try it online!

Icon, 95 bytes
procedure f(a,b,c,d)
return a[1:1+upto(t:='aoeiu',a)]||b[1:1+upto(t,b)]||c[1]||"-"||d[3:0]
end

Try it online!

perl -anE, 65 bytes
s/[aeiou]\K\w+// for@F[0,1];$F[2]=~s/.\K.*//;$F[3]=~s/../-/;say@F

Ruby, 48 bytes
->a,b,c,d{a[r=/.*?[aeiou]/]+b[r]+c[0]+?-+d[2,2]}

Try it online!

APL (Dyalog Unicode), 44  40 bytes
Original (and more fun): {t←{⍵↑⍨⊃⍸⍵∊'aeiou'} ⋄ ,/⍎¨'tt12',¨'  ↑↓',¨⍵}
Improved: {d←2∘↓⋄t←{⍵↑⍨⊃⍸⍵∊'aeiou'}⋄,/⍎¨'tt⊃d',¨⍵}
Try it online!1
Takes input of form: '''word''' '''word''' '''word''' '''dd-dd'''
This one is just a lot of fun and rather unconventional. Not necessarily the shortest, but that's the price of fun! Have a feeling t function can be further golfed but haven't managed to. The rest I'll leave as is because it's primarily neat; concision is secondary for once. Plus, who could possibly stomach messing with 42 bytes!
I'll add the full explanation tomorrow, however in short it's all just an abuse of the fact that we were trusted to determine the input format. Thus, one can pass it to the function as data and prepend (with a couple zips) the necessary manipulations, before evaluating the pieces of the list. This requires taking strings of strings as input; In Dyalog APL, quotes are escaped by doubling them, so printing '''Hello world''' yields 'Hello world'.
Before each element is evaluated and concatenated: {'tt12',¨'  ↑↓',¨⍵} yields t 'corona' ,  t 'virus' ,  1↑'disease' ,  2↓'20-19'. The two strings in the function are zipped together with the input to yield a piece of code containing the manipulations we desire for each piece. To clarify, t is the function which takes a string and returns the first elements until a vowel is spotted. The function t is defined in the right half of the code.

1Due to the dangerous 'execute' (⍎) operator, I've only gotten it to run online in TIO under dzaima's dialect, which is the TIO page linked above. However, as long it's downloaded, it'll work in any old flavor of Dyalog, so I'm insisting on marking it as such in the title!

You can use monadic ∊ instead of ,/. Btw, ⍎ isn't an issue on TIO (only on TryAPL), so it works fine.

I'm not sure including - in the input is quite in the spirit of the challenge.

Erlang (escript), 124 bytes
f(A,B,C,D)->g(A)++g(B)++[hd(C)]++"-"++string:slice(D,2).
g([H|T])->case"aeiou"==("aeiou"--[H])of true->[H]++[g(T)];_->H end.

Try it online!
Explanation
f(A,B,C,D)->g(A)++g(B)                                            % Slice things up to vowels for A and B
                      ++[hd(C)]                          % Add the head of C
                                        ++"-"++string:slice(D,2). % Add a - and tail of D

g([H|T])-> % Recursive function for the vowel slicing
case"aeiou"==("aeiou"--[H])of true-> % If head isn't vowel:
[H]++[g(T)];                         % Return head + slicing (tail)
_->H end.                            % Else: return head
```

Perl 6, 44 bytes
{S:g/<[aeiou]><(.*?\s//}o{S/\S<(\S*\s\d./-/}

Try it online!
Combination of two substitution regexes, the first to replace the third word and year with the letter dash date, and the second to remove anything between a vowel and a space (removing the space as well).

Charcoal, 26 bytes
⭆Ｅ²Ｓ…ι⌊ΦＥaeiou⊕⌕ιλλ§Ｓ⁰-✂Ｓ²

Try it online! Link is to verbose version of code. Takes lowercase words either space or newline-separated. Explanation:
⭆Ｅ²Ｓ

For the first two words...
…ι⌊ΦＥaeiou⊕⌕ιλλ

... find the positions of the vowels, and take the minimum of those that exist, and truncate the word after that point.
§Ｓ⁰

Print the first letter of the third word.
-

Print a -.
✂Ｓ²

Input the year as a string and print the last two digits.

Red, 94 92 bytes
func[a b c d][g: func[t][head clear find/tail t
charset"aoeiu"]rejoin[g a g b c/1"-"at d 3]]

Try it online!

JavaScript (Node.js), 64 bytes
(a,[b],c)=>a.map(x=>/.*?[aeiou]/.exec(x)).join``+b+'-'+c[2]+c[3]

Try it online!

05AB1E, 55 bytes
1(UI#v´yXiн?}Tи`žMvykˆ}¯ʒ2+≠}WD.ïiŠŠs>£?}X>U}"-"?UR2£R?

Try it online!
I'm sure this can be optimized in so many different ways, but I'll throw it in here anyway.

"I'm sure this can be optimized in so many different ways" You're indeed correct. I'm not sure where to begin with giving optimization-tips tbh, so let me instead start by welcoming you to CGCC! :D Anyway, I made a start with some optimizations, including explanation why, here in this pastebin. If you have any questions, feel free to ask.

Thanks! Using the global array I'm saving the first index of each vowel, then filtering out -1s and taking the minimum

Ah ok. Hmm, in that case the ʒ2+≠} can be ®K as well, to just remove all -1. :) PS: There is also a +2 (and -2) builtin, which is Ì.

R, 106 bytes
function(a,b,c,y,s=substr,f=function(x)s(x,1,regexpr("[aeiou]",x)))paste0(f(a),f(b),s(c,1,1),"-",s(y,3,4))

Try it online!
Say hello to R's atrocious handling of strings. I wouldn't be surprised if this could be golfed significantly.

05AB1E, 22 bytes
εžMySkd0šÅ¡н}Iн'-I¦¦)S

Inputs as ["corona","virus"], disease, and 2019.
Output as a list of characters.
Try it online or verify all test cases. (Feel free to remove the Join in the footer to see the actual output-list.)
Explanation:
ε                      # Map over the first (implicit) input-list of strings:
 žM                    #  Push the vowel constant "aeiou"
   y                   #  Push the current word we're mapping over
    S                  #  Convert it to a list of characters
                       #   i.e. "virus" → ["v","i","r","u","s"]
     k                 #  Get the index of each character in the string (-1 if not found)
                       #   → [-1,2,-1,4,-1]
      d                #  Check for each index if it's non-negative (>= 0)
                       #   → [0,1,0,1,0]
       0š              #  Prepend a 0 to this list
                       #   → [0,0,1,0,1,0]
         Å¡            #  Split the string we're mapping over on the truthy indices
                       #   → ["vi","ru","s"]
           н           #  And only leave the first part
                       #   → "vi"
            }I         # After the map: push the second input-string
              н        # Pop and push just its first letter
                       #  i.e. "disease" → "d"
               '-     '# Push a literal "-"
                 I     # Push the third input-integer
                  ¦¦   # Remove its first two digits
                       #  i.e. 2019 → 19
                    )  # Wrap all values on the stack into a list
                       #  → [[["c","o"],["v","i"]],"d","-","19"]
                     S # And convert it to a flattened list of characters
                       #  → ["c","o","v","i","d","-","1","9"]
                       # (after which it is output implicitly as result)

ssed -R, 70 bytes
Expects input through stdin in lowercase separated by spaces, e.g., corona virus disease 2019.
s_(.+?(?![aeiou])).*? (.+?(?![aeiou])).*? (.).*? \d\d(\d\d)_\1\2\3-\4_

ssed, known as "super sed", has PCRE which gives us non-greedy matchers.
(.+?(?![aeiou])).*?<space>
                ^^^^^^^^^^: Eats the rest of the word before the space
    ^^^^^^^^^^^: Before a character that is a vowel
 ^^^: Match fewest number of characters

The rest is simple enough once you understand the above. If anyone is interested I can go into more depth but I think this is enough.
The try-it-online thing doesn't have ssed installed in Bash. To try it locally you can install ssed through Homebrew by brew install ssed if you're on a mac. If anyone knows a way to get a working try-it-online I'll add it.

C (gcc), 96 bytes
#define z write(1,*a++,strcspn(*a,"aeiou")+1)
f(a,y)char**a;{z;z;printf("%c-%.2d\n",**a,y%100);}

-13 bytes and all concerns resolved thanks to ceilingcat!
Try it online!

dirt, 38
([^,]*[aeiou]{[^,]*,})*.{[^,]*,..}'-..

Accepts a comma-separated list of strings and outputs the disease name.
e.g. dirt disease.dirt -i "corona,virus,disease,2019" prints covid-19.
Explanation
(
 [^,]*      # match and output any number of non-comma characters
 [aeiou]    # match and output a vowel
 {          # with no output:
  [^,]*     # - match any number of non-comma characters
  ,         # - match a comma
 }
)*          # run the above any number of times.
.           # match and output 1 character.
{           # with no output:
 [^,]*      # - match any number of non-comma characters
 ,          # - match a comma
 ..         # - match 2 characters
}
'-          # output a hyphen
..          # match and output 2 characters

The non-competing rule for newer languages doesn't apply any more, so this submission is all good to go!

Vyxal Ṫ, 15 bytes
ƛA1ḟ›Ẏ;∑?h\-?2ȯ

Try it Online!
Explanation
ƛA1ḟ›Ẏ;∑?h\-?2ȯ  # Implicit input
ƛ     ;          # Apply to both of the first two words:
 A1ḟ             #  Index of the first vowel
    ›            #  Incremented to make 1-indexed
     Ẏ           #  That many characters from the start
       ∑         # Join into a string
        ?h       # First character of the last word
          \-     # Push a "-"
            ?2ȯ  # Last two characters of the year
                 # Implicit output of joined stack

Python 3, 128 124 122 119 bytes
a,b,c,d=input().split()
def g(a):
 for i in a:
  if i in'aeiou':return a[:a.find(i)+1]
print(g(a)+g(b)+c[0]+'-'+d[2:])

Try it online!
Pretty new, probably overcomplicated.
edit 1: saved four bytes by moving a part from print() to function
edit 2: saved two more bytes thanks to @surculose-sputum
edit 3: another three bytes thanks to @surculose-sputum

109 bytes by: (1) use Python2, so input() is evaluated implicitly and print doesn't require parentheses. (2) replace a.index(i) by a.find(i). (3) remove redundant whitespaces.

@SurculoseSputum, thanks! don't plan to switch to python 2, but will gladly use the other tips!

Perl 5, + -pF 41 bytes
($_)=$.<3?/^.*?[aeiou]/g:$.<4?@F:s/../-/r

Try it online!

FEU, 57 bytes
s/([^aeiou]+.).+,([^aeiou]+.).+,(.).+,\d+(\d\d)/\1\2\3-\4

Try it online!

Octave, 112 bytes
v='aeiou',a=@arrayfun
p=@(x)x(1:find(a(@(y)any(a(@(z)z==y,v)),x),1))
@(i)[p(i{1}) p(i{2}) i{3}(1) '-' i{4}(3:4)]

Try it online!

Thunno 2 j, 14 bytes
2ɲ'-$h$ıDṃ1Ȯ⁺ɱ

Try it online!
Explanation
2ɲ'-$h$ıDṃ1Ȯ⁺ɱ  '# Implicit input
2ɲ               # Last two characters of the year
  '-            '# Push a "-"
    $h           # First character of the last word
      $ı         # Apply to both of the first two words:
         ṃ1Ȯ     #  Index of the first vowel
            ⁺    #  Incremented to make 1-indexed
        D    ɱ   #  That many characters from the start
                 # Implicit output of joined stack

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


text:
KoTH: Highest HP is Eliminated!
In this challenge, bots must survive as long as possible. In each turn, the bot with the most HP is eliminated.
This challenge is inspired by the Smallest unique number KoTH.
Results
After 100,000 rounds:
Jack: 63390
The Follower: 4942
The Algorithm: 2452
The Randomiser: 140
Toe Tipping: 0
EZ: 0
The Average: 0
LowProfile2: 0
Lower Profile: 0
The Bandwagon: 0
Fair Share: 0
Low Profile: 0

Game Details

In each game, all bots start with 100 HP
In each turn:

All bots select an amount of HP to lose (minimum 1, inclusive)
Each bot loses the amount of HP they returned
All bots with 0 HP or less are eliminated
The bot with the highest HP is eliminated
If there is a tie for highest HP, all bots that tied are eliminated

The last bot alive wins 1 point
If all remaining bots are eliminated in the same turn, no points are awarded
After a number of games (default is 1000), the winner is the bot with the most points

Bot Format
Each bot should be a JavaScript function, which is run once per turn. This function will be provided three arguments:

The bot's HP
The HP of all other bots as of the last turn, or 0 if dead

Formatted as an array, will be randomly shuffled for each game

An object which can be used for storage between turns

The return value of this function should be a number (minimum 1, inclusive), representing the amount of HP to take. If the return value is not a number or is less than 1, it defaults to 1.
Example Bot
Example Bot tries to keep its HP 2 below the previous turn's average.
function(hp, others, storage) {
    var alive = others.filter(bot => bot > 0);
    var avg = alive.reduce((a, b) => a + b, 0) / alive.length;
    return hp - (avg - 2);
}

Controller
//Bots go in this object:

const bots = {
    "Example Bot": function(hp, others, storage) {
        var alive = others.filter(bot => bot > 0);
        var avg = alive.reduce((a, b) => a + b, 0) / alive.length;
        return hp - (avg - 2);
    }
};

//games: Number of games to run
//log: An array of bot names to log info about, or empty array for game overviews

function runGames(games = 1000, log = null) {
    let p = performance.now();
    let botData = [];
    for (let bot in bots)
        botData.push({
            name: bot,
            run: bots[bot],
            uid: 0,
            hp: 0,
            points: 0,
            storage: {},
        });
    for (let g = 0; g < games; g++) {
        let uids = new Array(botData.length).fill(0).map((a, b) => b);
        let turn = 0;
        if (log)
            console.log("[0] Starting game " + (g + 1));
        for (let j, i = uids.length - 1; i > 0; i--) {
            j = Math.floor(Math.random() * (i + 1));
            [uids[i], uids[j]] = [uids[j], uids[i]];
        }
        for (let i = 0; i < botData.length; i++) {
            botData[i].uid = uids[i];
            botData[i].hp = 100;
            botData[i].storage = {};
        }
        do {
            let hps = [];
            let max, alive;
            turn++;
            for (let hp, b, i = 0; i < botData.length; i++) {
                b = botData[i];
                if (!b.hp)
                    continue;
                try {
                    hp = Number(b.run(
                        b.hp,
                        botData.map(a => [a.uid, a.hp]).sort((a, b) => a[0] - b[0]).filter(a => a[0] != b.uid).map(a => a[1]),
                        b.storage
                    ));
                    if (log && log.includes(b.name))
                        console.log("[" + turn + "] " + b.name + " (" + b.hp + "): " + hp);
                } catch(e) {
                    hp = 100;
                    if (log && log.includes(b.name))
                        console.warn(b.name + " (" + JSON.stringify(b.storage) + "):\n" + (e.stack || e.message));
                }
                hps[i] = Number.isNaN(hp) ? 1 : Math.max(1, hp);
            }
            for (let i = 0; i < botData.length; i++) {
                if (hps[i]) {
                    botData[i].hp = Math.max(0, botData[i].hp - hps[i]);
                    if (!botData[i].hp && log)
                        console.log("[" + turn + "] Eliminated: " + botData[i].name + " (0)");
                }
            }
            alive = botData.filter(a => a.hp);
            if (alive.length == 1)
                alive[0].points += 1;
            if (alive.length <= 1)
                break;
            max = Math.max(...botData.map(a => a.hp));
            for (let i = 0; i < botData.length; i++) {
                if (botData[i].hp == max) {
                    if (log)
                        console.log("[" + turn + "] Eliminated: " + botData[i].name + " (" + botData[i].hp + ")");
                    botData[i].hp = 0;
                }
            }
            alive = botData.filter(a => a.hp);
            if (alive.length == 1)
                alive[0].points += 1;
            if (alive.length <= 1)
                break;
        } while (1);
    }
    console.log(games + " game(s) completed (" + ((performance.now() - p) / 1000).toFixed(3) + "s):\n" + botData.map(a => [a.name, a.points]).sort((a, b) => b[1] - a[1]).map(a => a[0] + ": " + a[1]).join("\n"));
}

Rules

Accessing the controller or other bots is not allowed
There's no time limit, but keep within reason
Any bots that error are eliminated
Clarification: Fractional HP is allowed
Deadline: Wednesday, March 25, 12:00 UTC (8:00 EDT) Closed to submissions!

I think I found a bug in the controller; if there are two bots remaining, and one of them drops its health to zero, no points are awarded (what should happen is the bot that didn't drop to zero earns a point)

@pppery Intentional, although it might make more sense if it did work that way...should I change it?

I agree with @pppery because the current runner seems to give "no winner" too often.

@Bubbler Makes sense. I'll update the controller and post tomorrow.

@pppery Fixed controller. Thanks for letting me know about the issue!

On account of the new cheating answer that exploits a controller bug you should probably say that submitting NaN answers is not allowed.

Are we allowed to keep state between games? If not, why are the enemies randomly shuffled? I have an idea for a strategy that will track trends over multiple games, and would like to know if it is allowed.

@MegaTom I should have added that to the challenge spec, but didn't. Do you think it's too late to allow it?

@ValueInk I just fixed the bug, seems like the easiest option. I had intended NaN values to fail the Math.max and return 1, but apparently it doesn't work that way

@RedwolfPrograms a way you could add it without breaking any existing competitors is to add a forth parameter that will be long_term_ storage. This will not break programs that do not use it because JavaScript functions ignore extra parameters. Whether you should is more up to you.
There are also ways I could get around the issue by using this, but I wanted your opinion first.

@MegaTom I don't think I'll add long term storage. Although it might benefit the challenge, with only 2 days left it seems a bit late to enable new game-changing strategies. Maybe I'll post a similar challenge in a few weeks.

Be careful that your "similar challenge" doesn't end up as a duplicate.

@pppery Yeah. I think I've decided not to do another one.

How is it that matches don't ALWAYS end up the same?  When I run this locally with all submitted bots, every match results the same.

@Umbrella Most likely, randomness-based bots never win, so rounds always end up the same

~~Strongest link UHC :P~~

@FireCubez Unrelated, I assure you :p

Ayy, you got the reference

Why is immediately setting your hp to 1 not a winning strategy?

@RayWu You would die on the next turn. Unless everybody else happens to tie at a higher number you'd lose.

@RedwolfPrograms So everyone would die? I don't understand? EDIT: nvm, forgot the minimum 1

@RayWu You have to lose at least 1 HP per turn. If your HP is 0 or less, you die. That means that you'd be forced to die on the next turn. Only one bot is eliminated per turn for having the most HP, and the winner is the last bot alive, so dying almost immediately isn't viable.

Jack
Assumes that half of the bots are stupid. So they will kill theirselves or will end up being killed simultaneously with another bot. We just need to make sure to have enough HP to survive it for enough rounds knowing that.
function(hp, others, storage) {
    var nrOfBots = others.filter(bot => bot > 0).length;
    var hpToTake = 1;
    if (hp == 100) {
        hpToTake = hp - (Math.round(nrOfBots / 2) + 0.0001);
    }
    return hpToTake;
}

First place: Wins 63.39% of games

Low Profile
function(hp, others, storage) {
    var alive = others.filter(bot => bot > 0);
    return hp - alive.length
}

Sets its health to be always equal to the number of bots. Any bot that undercuts this one risks eventually hitting zero health.

I'm honestly not sure if it's even possible for this bot to lose -- but I would love to be proven wrong.

It may lose if the other bots cut their HP faster than this but tightly enough, so that it becomes the highest HP at some point (e.g. two of the other bots use low profile - 1).

@Bubbler Since you appear to have deleted your answers while I was typing (note: I didn't say that they were invalid), I believe your trick doesn't work because one of the two answers is inevitably not a serious contender.

The Follower
function(hp, others, storage) {
    if (!storage.prev){
        storage.prev = others.slice();
        return hp * (Math.random() * 0.1 + 0.8);
    }
    let [decSum, decCnt] = others.reduce(([s,n],v2,i) => {
        if (v2 <= 0) return [s, n];
        return [s * (storage.prev[i]-v2), n + 1];
    }, [1,0]);
    storage.prev = others.slice();
    let avg = decSum ** (1 / decCnt);
    while (avg > hp) avg /= 2;
    return hp - avg;
}

Uses the geometric mean of the decrements chosen by alive opponents (in the previous turn) to decide its next move. There is no such information at the first turn, so it cuts a very large part of its own HP to be safe.

Second place: Wins 4.942% of games

The Bandwagon
function(hp, others, storage) {
    if (hp > 4)
        return 48;
    return Math.max(...others) - 1.5;
}

It's a bit slow to catch onto the trend, and it's not very low profile about it.
It bases its strategy on the assumption that, after 2 turns, it's the endgame. It assumes all the others are going to return 1, and ensures it doesn't die by returning 1.5.

Wait, fractional HP is a thing?

@pppery Yes, I guess I'll make that more clear in the challenge spec

LowProfile2
function(hp, others, storage) {
        var epsilon = 1;
        while (hp + 1 - (epsilon / 2) != hp + 1) {
            epsilon = epsilon / 2;
        }
        var alive = others.filter(bot => bot > 0);
        return hp - alive.length + 1 - epsilon
}

Thanks to the discovery of fractional HP, I realized my old integer-based LowProfile submission could be beaten by one using it. I therefore present LowProfile2, which dynamically calculates the very limits of how close to death one can be!

I'm unsure whether this should have been an edit or a separate answer -- one could make an argument for both.

Toe Tipping
function(hp, others, storage) {
    var highestAlive = Math.max(...others);
    var returnVal = highestAlive / 2 - 0.1;
    return Math.min(returnVal, hp-1);
}

Looks for the highest bot alive, and returns 0.1 below halve that bot's HP.

Average
function(hp, others, storage) { return Math.floor(hp/3); }

Loses a third of its HP every turn, dying in 13 turns if it doesn't end up as highest. (returning zero gets silently interpreted as returning 1 by the controller)

Lower Profile
function(hp, others, storage) {
    var alive = others.filter(bot => bot > 0);
    return hp - alive.length + 1
}

Tries to get lower than, but close to, Low Profile. But looks like it can't win by itself. :(
With an ally having + 2 instead of + 1 (I call it Lowest Profile), snipes Low Profile and this bot wins. Try it online!

What happened to lowest profile?

@RedwolfPrograms Lowest Profile was not a serious contender, for one thing.

It appears that Follower can act as LowestProfile and collude to keep my LowProfile (or, more accurately, LowProfile2, which beats LowProfile under all circumstances) bot from winning.

@pppery Fun thing is that Follower got the second place, while LowerProfile won zero times in the end...

The Randomiser
function(hp, others, storage) {
    var highestAlive = Math.max(...others);
    var returnVal = highestAlive * Math.random();
    return hp > returnVal ? returnVal
                          : hp * Math.random();
}

Returns a random number \$0\dots hp\$ of the highest bot alive (if we have enough \$hp\$ else a random number \$0\dots hp\$ of our \$hp\$).

Fourth place: Wins 0.14% of games

@RedwolfPrograms Wow, that was pretty random! T_T

Fair Share
function (hp, others, storage) {
    return hp / (1 + others.filter(bot => bot > 0).length) | 0;
}

The more bots are left, the more of its hp it has to ditch in order to try to keep ahead.

Your bot seems to lose less HP when there are more bots...fixing it would probably require choosing some constant to multiply by the number of living bots.

The Algorithm
function(hp, others, storage) {
    var rate = (storage.rate || (storage.rate = Math.random() * 0.25 + 0.3));
    var alive = others.filter(bot => bot > 0);
    var avg = alive.reduce((a, b) => a + b, 0) / alive.length;
    return hp > avg * rate ? hp - avg * rate : 1;
}

Picks a random value for each game, and will attempt to set its HP to that value multiplied by the current average.

Third place: Wins 2.452% of games


text:
Day of the week of an ambiguous date
Goal
Write a program or function that returns the day of the week for a date, eg.
01/06/2020  ->  Mon

However, it's unknown if the date is in the format mm/dd/yyyy or dd/mm/yyyy.  If you can be certain of the day of the week, return it.  If there is uncertainty, return an error.
02/07/2020  ->  Err  (Thu? Fri?)

Input
A date in the format #/#/####.

The numbers can optionally have leading zeros.
The year should be read verbatim, assume that 19 = 19 AD, not 19 = 2019 AD.
The separators can be any non-digit character.
Assume the input date is valid in at least one format (ie. not 13/13/2020).
At a minimum, support dates from 2000 through 2030 (which are likely covered by any modern OS and language with a date library.)

Requirements

If the first and second numbers:

are the same (03/03/2020), the date is unambiguous.
either is greater than 12 (13/09/2020, 09/13/2020), the date is unambiguous.
are different and both 12 or less (09/11/2020), the date is ambiguous.

Output

If the date is unambiguous, return the day of the week.
If the date is ambiguous:

If both versions of the date have the same day of the week, return the day of the week.
If both versions of the date have a different day of the week, return an error.

A day of the week should be returned as a string of the day's three-letter abbreviation ("Mon"), case-insensitive.
An error should be returned as any other three-character string, not all whitespace, eg. "Err", "NaN", "???".

Test Cases
02/07/2020  ->  Err
01/06/2020  ->  Mon
05/05/2020  ->  Tue
24/06/2020  ->  Wed
05/09/2030  ->  Thu
03/13/2020  ->  Fri
29/02/2020  ->  Sat
03/12/2000  ->  Sun

Scoring
The code with the least byte count in a week wins the tick.

Can we take the three parts of the date as three separate arguments?

Great question, unfortunately I'll have to downvote due to the cumbersome IO format. Please consider allowing more flexible input (e.g. 3 numbers) and output (e.g a number/initial of the weekday).

Suggested test case 3/2/2019. Since 3rd of feburary and 2nd of march are both a monday, does this count as ambiguous or unambiguous for the purposes of this challenge?

@DarrenH the date is ambiguous, but Mon should still be outputted, according to output specification.

@DarrenH I think you meant 3/2/2020.  Those dates in 2019 fell on different days, but they're both Mondays in 2020.  So Err should be the output for 3/2/2019, but Mon should be the output for 3/2/2020.

@MitchellSpector yes I did mean 2020, years are flying by I forgot we are in another one already, comes with old age

@SurculoseSputum Isn't the Input limitation the point of this challenge?  (i.e. if your form has  Free Text Entry for dates, rather than separate input boxes for Year, Month and Day)

Bash + GNU utilities, 97 96 93 85 80 76 73 58 56 51 bytes
(${d=date +%a -d$3-}$1-$2;$d$2-$1)|uniq|sed N\;cErr

Try it online!
5 bytes off thanks to user41805, who pointed out that I could use sed's c command instead of the final s command.
2 bytes off thanks to Nahuel Fouilleul. (Nahuel also helped by shaving 4 bytes off in an earlier version that has since been revamped.)
When I noticed that the separators can be any non-digit character, I changed the code to use spaces as the separator.
This is called with a command like
checkdate 01 06 2020
The output is on stdout.  (There's spurious output on stderr.)

small improvement d=date/+%a/-d IFS=/

@NahuelFouilleul Very nice -- thank you!

56 bytes

@NahuelFouilleul Thank you again.  I didn't know that bash construct -- the man entry I have shows the ${var:=...} construct but not ${var=...}, unless I'm just missing it.

seems undocumented the difference between two is when the parameter is set to null example

@NahuelFouilleul Thanks!

sed's c command is shorter than s/.*/

@user41805 Good point -- I've updated the code.  Thank you.

05AB1E, 88 82 79 76 79 73 72 bytes
#ÂÀ‚Dε`UÐ3‹12*+>₂*T÷s3‹Xα¬Ésт%D4÷O.•A±₁γβCüIÊä6’C•3ôsè}DËiнës€¨13‹WiтëθÏ

-3 bytes thanks to @Arnauld (initially -6, but +3 bytes again, since Jan./Feb. 2000 would still result in the previous century in the formula).
-7 bytes thanks to @Grimmy.
Input is space-separated; and outputs in lowercase with 100 as error.
Try it online or verify all test cases.
Explanation:
Since 05AB1E has no Date builtins, we'll have to calculate the Day of the Week manually.
The general formula to do this is:
$${\displaystyle h=\left(q+\left\lfloor{\frac{13(m+1)}{5}}\right\rfloor+K+\left\lfloor{\frac{K}{4}}\right\rfloor+\left\lfloor{\frac{J}{4}}\right\rfloor-2J\right){\bmod{7}}}$$
Where for the months March through December:

\$q\$ is the \$day\$ of the month ([1, 31])
\$m\$ is the 1-indexed \$month\$ ([3, 12])
\$K\$ is the year of the century (\$year \bmod 100\$)
\$J\$ is the 0-indexed century (\$\left\lfloor {\frac {year}{100}}\right\rfloor\$)

And for the months January and February:

\$q\$ is the \$day\$ of the month ([1, 31])
\$m\$ is the 1-indexed \$month + 12\$ ([13, 14])
\$K\$ is the year of the century for the previous year (\$(year - 1) \bmod 100\$)
\$J\$ is the 0-indexed century for the previous year (\$\left\lfloor {\frac {year-1}{100}}\right\rfloor\$)

Resulting in in the day of the week \$h\$, where 0 = Saturday, 1 = Sunday, ..., 6 = Friday.
Source: Zeller's congruence
Since the input is guaranteed to be in the year-range \$[2000, 2030]\$, we can modify \$+ \left\lfloor{\frac{J}{4}}\right\rfloor - 2J\$ to a hard-coded \$-35\$ to save some bytes. EXCEPT, when it's Jan./Feb. 2000, in which case it's the previous century. For those, we use ¬És, to add 1 to our hard-coded replacement of \$J\$.
In addition, we won't need the \${\bmod {7}}\$, since we only use it to index into the string list, and 05AB1E uses modular indexing anyway.
We can save 2 more bytes, by just removing the \$-35\$ all together, since it's a multiple of 7 anyway.
And one more byte, by changing the \$\left\lfloor{\frac{13(m+1)}{5}}\right\rfloor\$ to \$\left\lfloor{\frac{26(m+1)}{10}}\right\rfloor\$, since 05AB1E has a single-byte builtin for 26 and 10 (which are ₂ and T respectively).
Code explanation:
#            # Split the (implicit) input-string by spaces
 Â           # Bifurcate it (short for Duplicate & Reverse copy)
  À          # Rotate the reversed copy once towards the left
   ‚         # Pair the top two values together
             # (we now have a pair [[day,month,year],[month,day,year]])
    D        # Duplicate it
     ε       # Map over both values in this pair:

Now comes Zeller's congruence into play:
`            #  Push the day, month, and year separated to the stack
 U           #  Pop and save the year in variable `X`
  Ð          #  Triplicate the month
   3‹        #  Check if the month is below 3 (Jan. / Feb.),
             #  resulting in 1 or 0 for truthy/falsey respectively
     12*     #  Multiply this by 12 (either 0 or 12)
        +    #  And add it to the month
             #  This first part was to make Jan. / Feb. 13 and 14

>            #  Month + 1
 ₂*          #  Multiplied by 26
   T÷        #  Integer-divided by 10
s3‹          #  Check if the month is below 3 again (resulting in 1 / 0)
   Xα        #  Take the absolute difference with the year
     ¬       #  Push the first digit (without popping the mYear itself)
      É      #  Check if its odd (1 if 1; 0 if 2)
     s       #  Swap to take the mYear again
      т%     #  mYear modulo-100
D4÷          #  mYear modulo-100, integer-divided by 4
O            #  Take the sum of all values on the stack

And then we'll continue:
.•A±₁γβCüIÊä6’C•
             #  Push compressed string "satsunmontuewedthufri"
  3ô         #  Split it into parts of size 3: ["sat","sun","mon","tue","wed","thu","fri"]
    s        #  Swap to get the earlier calculated number
     è       #  And index it into this list (0-based and with wrap-around)
}D           # After the map: duplicate the resulting two days
Ëi           # If they are both the same:
  н          #  Leave just one of them
ë            # Else (they are different):
 s           #  Swap, to take the initially duplicated pair of
             #  [[day,month,year],[month,day,year]]
  €¨         #  Remove the year from each
    13‹      #  Check for the remaining values if they are smaller than 13
       W     #  Push the flattened minimum (without popping)
        i    #  If it's truthy (so day and month are both below 13):
         т   #   Push 100 (as error value)
        ë    #  Else:
         θ   #   Pop and leave just the last one (either [0,1] or [1,0])
          Ï  #   And only keep the day at the truthy index
             # (after which the top of the stack is output implicitly)

See this 05AB1E tip of mine (section How to compress strings not part of the dictionary?) to understand why .•A±₁γβCüIÊä6’C• is "satsunmontuewedthufri".

"Look mah" would look less "mah" as "Looks meh" :D I would edit it in, but I'm not sure if the "mah" is the "Dutch version" of "meh" :)

You can probably get rid of $J$ since we're only asked to support dates from 2000 through 2030.

@Arnauld Thanks, -6 bytes by hard-coding $+\left\lfloor {\frac {J}{4}}\right\rfloor -2J$ to $-35$. :)

My bad, my previous comment was wrong, I deleted it. #Ð2£TSǝ => #ÂÀ for -4. Rotate the list of days back to what it was so you can delete the -36 (-35 is a noop mod 7).

@Grimmy Thanks! Can't believe I hadn't thought about removing -35 for being a multiple of 7.. -6 bytes right there. :)

13*5÷ => ₂*T÷ for -1.

@Grimmy Ah, nice one. Thanks! :)

Perl 6, 124 121 bytes
{<Err Mon Tue Wed Thu Fri Sat Sun>[2>set($/=|grep ?*,map {try Date.new(|$_).day-of-week},m:g/\d+/[[2,1,0],[2,0,1]])&&$0]}

Try it online!

Red, 186 169 167 bytes
-2 bytes thanks to Kevin Cruijssen
func[d][a: to-date t: load form split d"/"m: min a b:
to-date reduce[t/2 t/1 t/3]either any[a/10 = b/10 t/1 > 12
t/2 > 12][pick[:Mon:Tue:Wed:Thu:Fri:Sat:Sun]m/10][.1]]

Try it online!
Takes the input as string, because Red doesn't accept invalid dates in dd/mm/yyyy format. That's strange, because the coerce function to-date that takes a block of 3 values [dd mm yyyy] accepts any integer, including 0 and negative numbers and creates a "correct" date based on them.

You can save a byte by changing 'Err to 123 (or any other 3-digit number).

@Kevin Cruijssen Thanks, I always forget that.

Another -1 thanks to @Arnauld, by using .1 instead of 911, which will automatically become 0.1.

@KevinCruijssen Of course! That's nice.

JavaScript (ES6),  136 132  131 bytes
Returns "Err" for an error.
s=>'SunMonTueWedThuFriSatErr'.match(/.../g)[[i,j]=([d,m,y]=s.split`/`).map(M=>new Date(y,M-1,M^m^d).getDay()),d<13?m>12|i==j?i:7:j]

Try it online!
Commented
s =>                           // s = input string
  'SunMonTueWedThuFriSatErr'   // lookup string
  .match(/.../g)[              // split it and pick the relevant entry:
    [i, j] =                   //   (i, j) = day-of-week indices
      ([d, m, y] = s.split`/`) //   split s into (d, m, y)
      .map(M =>                //   for each value M in there (ignoring y):
        new Date(              //     create a date:
          y,                   //       using y as the year
          M - 1,               //       using M - 1 as the 0-indexed month
          M ^ m ^ d            //       using the other value as the day
        )                      //     end of Date()
        .getDay()              //     get the day-of-week index (Sun:0, ..., Sat:6)
      ),                       //   end of map()
    d < 13 ?                   //   if d is a valid month:
      m > 12 | i == j ? i      //     non-ambiguous if m is an invalid month or i = j
                      : 7      //     ambiguous otherwise (-> "Err")
    :                          //   else:
      j                        //     use j
  ]                            // end of lookup

Perl 5 -MPOSIX -naF/, 125 bytes
sub d{substr ctime(mktime 6,0,0,$_[0],$_[1]-1,$_[2]-1900),0,3}@G=@F[1,0,2];say$F[0]>12?d@F:$F[1]>12?d@G:d(@F)eq d(@G)?d@F:Err

Try it online!
Not completely happy with this one, but haven't thought up a better way (yet).

Save two bytes by replacing d(@F)eq d(@G) with d@F,eq d@G,

Python, 180 164 158 bytes
Saved 3 bytes thanks  to Kevin Cruijssen and Arnauld!!!
Saved 3 bytes thanks to Surculose Sputum!!!
lambda a,b,c:(x:=d(a,b,c))==(y:=d(b,a,c))and x or(x and y and.1)or y or x
from datetime import*
def d(a,b,y):
 try:return date(y,a,b).strftime("%a")
 except:0

Try it online!
Assumes we can input the date as three separate arguments and returns 0.1 if ambiguous.
Date as string
Python, 197 191 bytes
Ditto the above saves and thanks! :D
lambda s:(x:=d(s))==(y:=d(s,1))and x or(x and y and.1)or y or x
from datetime import*
def d(s,q=0):
 a,b,c=map(int,s.split('/'))
 if q:a,b=b,a
 try:return date(c,a,b).strftime("%a")
 except:0

Try it online!

Why pre-release? Python 3.8 is released.

@Tyilo Just because TIO calls it that. Hand edited to Python.

You can save 2 bytes by changing "Err" to -99 (or any other negative 2-digit number).

@KevinCruijssen .1 (rendered as 0.1) would be even shorter.

except:0 saves 3 bytes

@KevinCruijssen Nice one - thanks! :-)

@Arnauld You're the master - thanks! :-)

@SurculoseSputum Clever - thanks! :-)

PHP, 115 bytes
foreach(['/','-']as$s){if($x=strtotime(strtr($argn,'/',$s)))$o=date('D',$x);if($p&&$o!=$p)die('err');$p=$o;}echo$p;

Try it online!
Uses the peculiarity that the builtin strtotime parses dates as either European or American format according to whether the delimiter is either slash or dash.
Takes input as a/b/Y and returns err for an error condition.

Python 3.8 (pre-release), 125 bytes
Improvement over @Noodle9's answer

lambda a,b,y:[.1,w:=g(y,a,b)][w==g(y,b,a)]
g=lambda y,m,d:m<13and date(y,m,d).strftime("%a")or g(y,d,m)
from datetime import*

Try it online!
Input: 3 integers representing date, month, and year.
Output: A 3-character abbreviation of a weekday, or 0.1 if the weekday is ambiguous.
How:

date(y,m,d).strftime("%a") returns the abbreviated weekday of the date d/m/y.
g(y,m,d) returns the weekday if the date is valid, otherwise returns the weekday of the date where month and day are swapped. Thus if g(y,a,b) and g(y,b,a) are the same, then the weekday is not ambiguous. Otherwise, the weekday is ambiguous.
[.1,w:=g(y,a,b)][w==g(y,b,a)] evaluates to g(y,a,b) if the weekday is not ambiguous, or 0.1 if the weekday is ambiguous.

Perl 5 -MTime::Local=timegm_modern -pF'/', 116 113 108 bytes
sub f{$_[1]--;eval{timegm_modern 0,0,9,@_}}$_=($a=f@g=@F)*($b=f@F[1,0,2])&$a-$b?Err:substr gmtime($a|$b),0,3

Try it online!
Tries converting both formats into an epoch time.  The eval traps the error that would occur for an invalid date. Multiplies the two epoch times together to make sure that one is 0, and checks that they are not the same with substraction.  Uses their bitwise or to convert back to an actual date, then picks off the day of the week from that.

This has no effect on bytecount now that flags don't count towards that, but why not -pF/ and forgo the quotes?

It could have been.  I'm just so in the mindset of quoting certain things, I did it out of habit.

Excel, 85 Bytes
=IF(OR(DAY(A1)>12,MOD(A1-DATE(YEAR(A1),DAY(A1),MONTH(A1)),7)=0),TEXT(A1,"ddd"),"???")

Input the date into cell A1
Since Excel will automatically evaluate the date into a valid form for us, we can first check if the Day is >12, since this would immediately make the date unambiguous.
We then work out if difference between the "dd/mm/yyyy" and "mm/dd/yyyy" versions is a multiple of 7, using MOD, since this would mean both Weekdays are the same
If either of these conditions are True, then the Weekday is unambiguous.

Ruby -apl, 102 bytes
Takes input as a line of input from STDIN with space as the separator. Outputs false if the dates are ambiguous and the days of week don't match.
In order to make sure we get a correct date the first time, we sort the first two arguments to ensure the smaller of the two (which is guaranteed to be less than 13) is placed in the month field. We then reverse the arguments when comparing the days of week using wday (if it would be a valid date, done by checking b>12 first), and if they match (or the date was unambiguous) we use strftime("%a") to output the day of the week in a human-readable format.
-p takes each line of input and outputs the contents of $_ at the end of a program run.
-a is the autosplit flag, which will split the input on spaces and save into $F.
-l makes the input ignore newlines (they are included by default for Ruby's input function).
*x,y=$F.map &:to_i
d=Time.gm y,*x.sort!
a,b=x
$_=(b>12||d.wday==Time.gm(y,b,a).wday)&&d.strftime("%a")

Try it online!


text:
Tips for golfing in Pure Data
Pure data is a graphical programming language designed for audio processing.  This makes it unsuitable for most general programming but especially unsuitable for code-golf.
It would then be nice to have a tips question so that people can get a first foot up in this language.
What tips are there for golfing in Pure Data?  Answers should apply specifically to Pure Data.

Use a text editor
The editor that comes with Pure Data is really useful for making programs that work or helping you to understand existing programs.  However if you want to golf, the files it creates are full of extra stuff that can be removed with an text editor (e.g. vim).
This post will serve as a list of a bunch of small byte saving tricks accessible only through or more easily though a traditional editor.

Use defaults on canvas:  Your file needs a canvas line.  #N canvas; is enough to get things to run without error. The missing arguments default to zero.
Newlines are optional:  The graphical editor puts newlines between statements.  Presumably to make these files somewhat readable.  However these are not strictly required and can be removed with an editor.
Rearrange your objects for better object indices:  Since connections identify objects by their order in the source, placing objects with a lot of connections earlier in the file can shorten your source.  Make sure that you update all the references once you reorder.
Put everything in the top left:  Since object location is purely a graphical aid, you can place them wherever. Single digit locations are the shortest so changing the location to 0 0 or something similar will save you.  This turns your code into an unreadable blob so it is probably best to do this once everything already works.

Avoid using triggers to sequence messages
One of the common uses of trigger objects is to make the order of execution clear when a single object is sending messages to multiple places. In those cases, since code readability is not a concern for us, you can depend on Pure Data's default behavior which is to send the messages across connections in the order that the connections were created (or if you are using a text editor, the connection that appears first in the file).


text:
Tips for Golfing in Symja
Symja is a "computer algebra language & Java symbolic math library for Android NCalc calculator". It's a fun little language, so I'm wondering if y'all have any tips for golfing in Symja.
As per usual, "remove comments", etc, isn't really an answer. It turns out that there is no comment system in Symja, so "remove comments" isn't an answer. :P

remove comments

@QuoraExpert I would, but there are no comments to remove in the first place! :P

I should use this language more, that way I don't have to make up any excuses for never commenting my code :D

LOL! NICE EDIT!!

This language is basically just Mathematica but uses round brackets instead of square ones, so Tips for golfing in Mathematica would be helpful.

Don't Use Print...Use the Formatted Output
Here's an example fizzbuzz:
For(i=1,i<101,i++,s="";If(Mod(i,5)==0,s=s<>"Fizz");If(Mod(i,3)==0,s=s<>"Buzz");If(Mod(i,5)*Mod(i,3)!=0,s=s<>ToString(i));Print(s))

Now, this is alright, but it can be improved:
For(i=1,i<101,i++,If(Mod(i,5)==0,s=s<>"Fizz");If(Mod(i,3)==0,s=s<>"Buzz");If(Mod(i,5)*Mod(i,3)!=0,s=s<>ToString(i));s=s<>"\n");s

Sure, it's only two bytes shorter, but hey, it's two bytes shorter.
Just put all the output into a string and tack a ;<variable_name> onto the end and you'll have a shorter program (usually).