text:
Pseudo-deterministic number generator
Task
Write a function/full program that will be able to produce two different sequences of integers in [0, ..., 9]. You will take an input seed to decide whether to output your specific sequence or the common one. For that matter, you must choose one non-negative integer, let us call it k. When the input seed is equal to k, you will be dealing with your specific sequence s; when the input seed is anything else, you will be dealing with your common sequence c.
Both sequences should be such that the relative frequencies with which each digit appears tend to \$10\%\$. Be prepared to prove this if needed. Said another way, the running fraction of that digit's appearances needs to have a defined limit that equals \$0.1\$. Formally, this means that for every \$d \in \{0,...,9\}\$,
$$\lim_{n\rightarrow \infty}\dfrac{\left|\{i : i \in \{1\dots n\}, s_i=d\}\right|}{n} = 0.1$$
Adapted from What an Odd Function
There should be one extra restriction your sequences should satisfy: when zipped together* to form a sequence a of terms in [0, ..., 99], the relative frequency of each number should converge to 0.01 via a limit like the formula above.
*That is, the \$n\$th term of the sequence a is the two-digit number built this way: the digit in the tens place is the \$n\$th term of the sequence c and the digit in the units place is the \$n\$th term of the sequence s.
Input
A non-negative integer representing the "seed", which you use to decide whether to output the common sequence or the specific one.
Output
Your output may be one of the following:

an infinite stream with the sequence (and you take no additional input);
output the nth term of the sequence (by taking an additional input n that is 0- or 1-indexed);
output the first n terms of the sequence (by taking an additional positive input n).

Example pseudo-algorithm
Assuming I have defined seed as an integer, and for these choices I made for s and c:
input_seed ← input()
n ← input()
if input_seed = seed: print (n mod 10) # this is my sequence s
else: print ((integer div of n by 10) mod 10) # this is my sequence c

Both sequences output numbers in [0, ..., 9] and the frequency with which each digit appears tends to 0.1 as n → infinity. Similarly, zipping c and s together gives n mod 100 so it is also true that as n → infinity we have that the relative frequency with which each number in [0, ..., 99] shows up goes to 0.01.

so to clarify, when given any number I should print a specific sequence c which appears random, which would be the same sequence for all input apart from a specific N that I choose?

Can my sequence be 0,1,2,3,4,5,6,7,8,9 repeated infinitely?

@SurculoseSputum here should be one extra restriction your sequences should satisfy: when zipped together* to form a sequence a of numbers in [0, ..., 99], the relative frequency of each number should converge to 0.01.

@CommandMaster If the other sequence is 10 0s, 10 1s, 10 2s, it'll work.

@Adám Regarding the "s.t.", I think it means "such that"/"so that". Although I was indeed wondering the same thing at first. Not a very commonly used abbreviation.. Apart from that I also have the same question as you: what is meant with 'infinite sequence' here (and what is the purpose if we only have [0,9] to output anyway)?

I suspect OP intended some pseudo-randomness here.

Ah, I didn't see that random tag. Deleted my answer until the meaning of random is clarified.

@RGS Indeed, I've already deleted those two, but my third one about randomness hasn't been addressed.

@RGS Deleted my comment. In that case, could you please add an example of a valid $seed$, $s$, $c$, and perhaps $c_{seed+1}$, $c_{seed+2}$ (doesn't have to be optimal, just an example), since I don't understand it tbh..

Do I understand this correctly, that we have to write a PRNG with two possible functionally distinct seeds?

I'm confused, does "given an integer seed, always creates the same sequence" mean that different seeds are allowed to give different sequences, as long as each specific seed always gives the same thing? Or that they all give the same sequence regardless of the seed?

@xnor the first paragraph has been rewritten and I have included an example submission to help clarify things.

@KevinCruijssen check the example pseudo-alg I provided.

@Adám the use of "random" was misleading; it should be clear now what I mean.

Thanks, that clear it up. I still find it pretty convoluted though, not so much because of the explanation, but because the premise is pretty weird. It seems to me that really we're given a Boolean that tells us which of the two sequences to produce. And I can't imagine answers doing anything but converting to this bool as the first step. Like, the two-independently-uniform-sequences is a cool idea but it's too bad that the reader has to first process all the stuff in the first paragraph before they get to that.

@xnor that was pretty much what I wanted the challenge to be, "depending on an input seed, produce one of two independently uniform sequences" but I assumed that would be too unclear.

I think your example algorithm needs to do a mod-10 in the second case so that its results are from 0 to 9.

Are the probabilities/frequencies of 10%/0.01 roughly or exact? Since you use the phrases "the relative frequencies with which each digit appears tend to 10%" and "the relative frequency of each number should converge to 0.01.", it seems to apply roughly. Reason I'm asking is the discussion in the 05AB1E answer, where the probability for the infinite sequence is indeed ~10%/0.01, but the count of 0 will always be at least 1 (and at most 10) behind on the count of the other digits, regardless of the sample size. The counts of the digits can never be the same, but it's still ~10%.

^To clarify why: the 05AB1E answer will always output $n$ instead of $\left\lfloor{\frac{n}{10}}\right\rfloor$ for $n<10$, regardless of the $seed$, which is where this irregularity comes from of the 0 always being $[1,10]$ behind in terms of counts.

@KevinCruijssen The value 0.1 should be the exact value for the limit of $\frac{\text{number of times d appeared before term n}}{n}$ as n tends to infinity, for d in [0, ..., 9] for either sequence c or s. Similarly with 0.01 for the zipped sequence. The 05AB1E answer has the count of 0s lagging behind, but as n → infinity the limit above still gives the correct answer :)

@RGS Thanks for clarifying. I'll keep my comments in case anyone else thinks the same as I did.

Python 2, 23 22 bytes
Thanks @xnor for figuring out a really cool way to convert the seed to -1 or -2, which saved 1 byte.

lambda s,n:`n+9`[2/~s]

Try it online!
Input: The seed s (non-negative) and an index n (positive).
Output: The element at the nth index (the sequence is one-indexed)
If the seed is positive, the sequence is 0123456789 repeated infinitely.
If the seed is 0, the sequence is: 1111111111 2222222222 ... 9999999999 0000000000 (where each digit repeats 10 times) repeated infinitely.
How

`n+9` creates a string from a number that has at least 2 digits.
2/~s evaluates to -2 if s is 0, or -1 if s is positive
Thus `n+9`[2/~s] takes the last digit (unit digit) of \$n+9\$ if s is positive, or the second to last digit (ten digit) if s is 0.

2/~s also works and is shorter.

I admit I didn't actually figure this out. :-P I just brute-forced all short expressions. There was also -2>>s for a tie. Switching the two cases didn't give anything.

05AB1E,  4  3 bytes
ΘÍè

Try it online!
Takes the seed then n and outputs the nth term, outputs different sequence for seed of 1

Explanation
Θ                  - truthified (so 1 if input is 1, else 0)
 Í                 - subtract 2 (so -1 if input is 1, else -2)
  è                - take this index of the nth term

Since 05AB1E uses modular indexing it won't go out of bounds, and a[-1] is the last element of a. Likewise a[-2] is the penultimate.

Alternatively to output an infinite sequence.
05AB1E, 6 bytes
∞εIΘÍè

Try it online!

For the first 10 values this is indeed true, but let's say you take the first 200, then there are just 11 0s, but 21 of every other digit: see here. I think you have to add a leading 0 for inputs n below 10 first before reverting (i.e. with т+RIΘè or 0ìRIΘè).

No I disagree.. You've just picked a specific value still in a small range which will do this.. Try it online!

It's always going to be at most 10 behind @KevinCruijssen so as it tends to infinity it will tend to 0.1 probabilty...Try it online!

Although a valid point with it being just 1 behind for the 209 sample size, I was under the impression that the probabilities of 10% and 0.01 were exact for specific sample sizes, not roughly.. No matter the sample size, the count of all ten digits can never be the same in your answer, since the 0 is always at least 1 (and at most 10) behind on the others. But OP does indeed use the terms "tend" and "should converge", which seems to apply roughly 10%/0.01, so maybe it indeed doesn't matter.. :S I'll ask OP to verify.

This looks valid to me. The challenge asks about the limit frequency of each digit or pair. Changing any finite number of entries can't affect this.

Ok, in that case I stand corrected. I'll keep my comments for now in case anyone else thinks the same as I did. (And OP just clarified that it's indeed valid.)

C (gcc), 24 bytes
f(s,n){s=(s?n/10:n)%10;}

Try it online!
Input: seed (\$s\$) and \$n\$.
Output: \$n^{\text{th}}\$ term zero-indexed.
For \$s=0\$ the sequence is: \$0,1,2,\dots,9,\dots\$
For \$s>0\$ the sequence is: \$\underbrace{0,0,\dots,0}_{10},\underbrace{1,1,\dots,1}_{10},\underbrace{ 2,2,\dots,2}_{10},\dots,\underbrace{9,9,\dots ,9}_{10},\dots\$

Wolfram Language (Mathematica), 38 bytes
Takes Input [n,seed] and outputs nth term
Specific seed is 0
If[#2>0,#~Mod~10,Floor[#~Mod~100/10]]&

Try it online!

Charcoal, 9 5 bytes
§Ｓ⊕¬Ｎ

Try it online! Link is to verbose version of code. Takes input as n, s and outputs the (1-indexed) third digit of n if s is zero otherwise the second digit of n (so somewhat similar to @ExpiredData's answer, although this was unintentional). The two sequences separately always output an exact 10% frequency after a power of 10 terms, while the combined sequence outputs an exact 1% frequency between the (0-indexed) 10th term and a higher power of 10 terms. Explanation:
    Ｎ   Input `s`
   ¬    Logical Not
  ⊕     Incremented
 Ｓ      Input `n` as a string
§       Cyclically indexed
        Implicitly print

Version that outputs the first n terms for each of the first s seeds:
ＥＩθ⭆Ｉη§Ｉλ⊕¬ι

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

JavaScript (ES7), 19 bytes
Takes input as (seed)(n) and returns the \$n\$-th term. The special seed is \$0\$.
s=>n=>n/10**!s%10|0

Try it online!

Does this work for 16? Takes n as a string

@ExpiredData I think so. You may want to post it as a separate answer. (Note that you don't need the leading +.)

Ok thanks @Arnauld :)

Bash, 25 23 bytes
Saved 2 bytes thanks to Mitchell Spector!!!
echo $[$2/($1?10:1)%10]

Try it online!
Input: seed (\$s\$) and \$n\$.
Output: \$n^{\text{th}}\$ term zero-indexed.
For \$s=0\$ the sequence is: \$0,1,2,\dots,9,\dots\$
For \$s>0\$ the sequence is: \$\underbrace{0,0,\dots,0}_{10},\underbrace{1,1,\dots,1}_{10},\underbrace{ 2,2,\dots,2}_{10},\dots,\underbrace{9,9,\dots ,9}_{10},\dots\$

You can save 2 bytes by using $[...] instead of $((...)).

@MitchellSpector Nice one -  thanks! :-)

JavaScript (Node.js), 15 bytes
s=>n=>n[!s+1]|0

Try it online!
If seed is 0 it will take the 3rd digit of the number, else it will take the 2nd digit of the number

Retina 0.8.2, 16 bytes
^(0,.+).
$1
!`.$

Try it online! Link includes test cases. Takes input as s,n and outputs the second last digit of n if it has one and s is zero otherwise the last digit of n. The individual sequences are 10% of each digit but the combined sequence only approaches 1% after the 10th term. (I have a 16 byte answer in Retina 1 for which the combined sequence contains 1% of each pair.) Explanation:
^(0,.+).
$1

If s is 0 then delete the last digit of n unless that is its only digit.
!`.$

Output the last digit of n.

dc, 15 13 bytes
Saved 2 bytes thanks to Mitchell Spector!!!
[A/]sa?0=aA%p

Try it online!
Input: \$n\$ and seed (\$s\$).
Output: \$n^{\text{th}}\$ term zero-indexed.
For \$s>0\$ the sequence is: \$0,1,2,\dots,9,\dots\$
For \$s=0\$ the sequence is: \$\underbrace{0,0,\dots,0}_{10},\underbrace{1,1,\dots,1}_{10},\underbrace{ 2,2,\dots,2}_{10},\dots,\underbrace{9,9,\dots ,9}_{10},\dots\$

You can use i or o instead of 10, saving 2 bytes.

@MitchellSpector Didn't like i or o but it worked with A - thanks! :-)

Sorry, I meant I or O (with capital letters), but A is even better.

MATLAB, 45 bytes
v=input('');rng(fix(~v(1)));randi(10,v(2),1)-1

randi(N,n,1) generates an n-length sequence of uniform random integers in the range 1,...,N. Taking two digits of the resulting sequence of realizations at a time, the required distribution follows naturally, which can be checked using the example code below.
N = 50000 ;
[h,x] = hist(10*(randi(10,N,1)-1) + (randi(10,N,1)-1), 100) ;
h = h/sum(h) ;
stem(x,h) ;
axis([0 10 0 0.1]) ;

rng(fix(~s)) sets the random number generator seed to one if s=0 otherwise to zero.
Inputs
Read from the console in the format (incl brackets) "[s n]".
Comments

This method can be extended to generate limitless number of sequences which satisfy the required properties.
Now compatible with several versions of MATLAB

Does this do a different sequence for every possible seed?

@AdHocGarfHunter thank you! My mistake cost me one byte.

I don't know MATLAB, but I think you need to take s as an input somehow rather than expecting it to be stored in the variable s.

@xnor Thanks! It's done.

R, 22 19 17 bytes
Following earlier resolutions, this R code is producing two different sequences with the correct limiting frequencies whether \$s=0\$ (penultimate digits) or \$s\ne 0\$ (last digits):
1:n%/%10^(!s)%%10

Try it online!
As for checking whether or not the merged sequences work as well, one can run, e.g.,
summary(as.factor((10*(1:n%/%10%%10)+(1:n%%10))))

Husk, 5 bytes
!←±⁰d

Try it online! Gives a single term, given seed and n as arguments. k is equal to 0.

perl -apple, 18 bytes
$F[0]&&chop;$_%=10

Try it online!
Prints the last digit of n for the special sequence (c = 0), otherwise, the penultimate digit of n. It doesn't quite work for single digit n's, but since we only have to tend towards equal distribution, it doesn't matter what it prints.

W, 2 bytes
(Port of the Charcoal answer.) How in the world can a 3-byter ever compress in the compressor‽
H≡

Uncompressed:
!)[

Explanation
!   % Logical negate the first input.
 )  % Increment the negated input.
  [ % Cyclic index the second input by that result.


text:
KoTH: Wizard Battle
In this challenge, all bots are wizards. At the beginning of each round, they create a wand which has a certain chance of successfully stunning another wizard. They then fight, by choosing one bot to attack in each turn. The last bot remaining wins.
Results
500 games, 1000 rounds each
Revenge!: 132101.68886125216
JustEnough: 125373.84608578209
Copycat: 118350.98257686458
Climber: 100280
UpperMiddleClassHunter: 99618.4944296837
Golden: 92541.83731532418
Bully: 84120
TallPoppyLoper: 81359.05734216684
A Wizard Arrives Precisely When He Means To: 81218.40354787472
The Wild Card: 77687.08356861532
My First Bot: 74766.78481191777
Roulette Wheel: 67559.90399160102
Don't Kill Me: 58361.64359801064
Marginally Lower Threat: 40538.27420692073
Simple Threat Neutralizer: 13957
ThereCanOnlyBeOneStrongest: 13000
The Terminator: 3701
SimpleSimon: 3295
Peace Lover: 0
Pacifist: 0

Game details

A game consists of a number of rounds
At the beginning of each round, all bots choose the success chance of their wand (0 to 1, inclusive, defaults to 0 if invalid)
A round will last until one bot remains, or all remaining bots have a 0% chance of winning

In each turn, every bot must choose a bot to attack
If an attack succeeds (based on the wand's success chance), the bot who is attacked is eliminated for the rest of the round

The last bot alive wins 1/sqrt(chance) points (up to a maximum of 20), where chance is the wand's success chance
If all remaining bots are eliminated in the same turn, no points are awarded
The bot with the most points after a certain number of games wins

Bot format
Each bot should consist of two JavaScript functions, the first of which is run once per turn. This function will be provided three arguments:

Itself as an object (see below for format)
An array containing all other non-eliminated bots

Each bot is formatted as an object
Each bot contains a uid property, which is an integer ID randomly chosen for each game
Each bot contains a wand property, which contains their wand's success chance
Each bot contains a attacked property, which contains the UID of the last bot they attempted to attack (or null if first turn)

A storage object

Can be used for storage between turns or rounds (resets for each game)

The return value of this function should be the UID of the bot to attack.
A second function will choose its wand's success chance before the first turn of each round, and will be provided one argument, its storage object.
Example bot
Example bot will attack a random (valid) bot that another bot attacked last turn, even itself. Always chooses a 75% wand success chance.
//Turn

function (self, others, storage) {
    var attacked = others.map(bot => bot.attacked).filter(uid => others.find(bot => bot.uid == uid));
    return attacked[Math.random() * attacked.length | 0] || others[0].uid;
}

//Wand

function (storage) {
    return 0.75;
}

Controller
//Bots go in this object:

var bots = {
    "Example bot": [
        function (self, others, storage) {
            var attacked = others.map(bot => bot.attacked).filter(uid => others.find(bot => bot.uid == uid));
            return attacked[Math.random() * attacked.length | 0] || others[0].uid;
        },
        function (storage) {
            return 0.75;
        }
    ]
};

//games: Number of games to run
//rounds: Number of rounds per game
//turns: Max turns per game
//log: 0 (no logging), 1 (errors only), 2 (detailed logging)

function runGames(games = 100, rounds = 100, turns = 1000, log = 0) {
    let p = performance.now();
    let botData = [];
    for (let bot in bots)
        botData.push({
            name: bot,
            turn: bots[bot][0],
            round: bots[bot][1],
            uid: 0,
            alive: !0,
            wand: 0,
            attacked: 0,
            points: 0,
            storage: {}
        });
    for (let g = 0; g < games; g++) {
        let uids = new Array(botData.length).fill(0).map((a, b) => b);
        let round = 0;
        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].storage = {};
        }
        for (let r = 0; r < rounds; r++) {
            let turn = 0;
            if (log >= 2)
                console.log("[0] Starting round " + (g + 1) + "-" + (r + 1));
            for (let b, i = 0; i < botData.length; i++) {
                b = botData[i];
                try {
                    b.wand = Math.max(0, Math.min(1, Number(b.round(
                        b.storage
                    ))));
                } catch(e) {
                    b.wand = 0;
                    if (log)
                        console.warn("[" + turn + "] " + b.name + "[1]:\n" + (e.stack || e.message));
                }
                if (Number.isNaN(b.wand))
                    b.wand = 0;
                if (log >= 2)
                    console.log("[" + turn + "] " + b.name + " (" + b.uid + "): " + (b.wand * 100) + "%");
                b.alive = !0;
                b.attacked = null;
            }
            do {
                let attacks = [];
                let max, alive = [];
                turn++;
                for (let b, i = 0; i < botData.length; i++) {
                    b = botData[i];
                    if (!b.alive)
                        continue;
                    try {
                        attacks[i] = b.turn(
                            {
                                uid: b.uid,
                                wand: b.wand,
                                attacked: b.attacked
                            },
                            botData.filter(a => a.alive && a.uid != b.uid).map(a => ({
                                uid: a.uid,
                                wand: a.wand,
                                attacked: a.attacked
                            })).sort((a, b) => a.uid - b.uid),
                            b.storage
                        );
                    } catch(e) {
                        attacks[i] = !1;
                        if (log)
                            console.warn("[" + turn + "] " + b.name + "[0]:\n" + (e.stack || e.message));
                    }
                }
                for (let b, i = 0; i < botData.length; i++) {
                    b = botData[i];
                    if (!b.alive)
                        continue;
                    if (!botData.find(a => a.alive && a.uid === attacks[i])) {
                        b.alive = !1;
                        if (log >= 2)
                            console.log("[" + turn + "] " + b.name + " (" + b.uid + "): Invalid bot (" + attacks[i] + ")");
                        attacks[i] = undefined;
                    }
                    b.attacked = attacks[i];
                }
                for (let b, i = 0; i < botData.length; i++) {
                    b = botData[i];
                    if (attacks[i] === undefined)
                        continue;
                    if (Math.random() < b.wand) {
                        if (log >= 2)
                            console.log("[" + turn + "] " + b.name + " (" + b.uid + "): Attacked " + botData.find(a => a.uid == attacks[i]).name + " (" + attacks[i] + ")");
                        botData.find(a => a.uid == attacks[i]).alive = !1;
                    } else if (log >= 2) {
                        console.log("[" + turn + "] " + b.name + " (" + b.uid + "): Failed to attack " + botData.find(a => a.uid == attacks[i]).name + " (" + attacks[i] + ")");
                    }
                }
                alive = botData.filter(a => a.alive);
                if (alive.length == 1)
                    alive[0].points += Math.min(20, 1 / Math.sqrt(alive[0].wand));
                if (alive.length <= 1) {
                    if (log >= 2)
                        console.log("[" + turn + "] Winner of round " + (g + 1) + "-" + (r + 1) + ": " + (alive.length ? alive[0].name : "No winner"));
                    break;
                }
            } while (turn < turns);
        }
    }
    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 or choose an invalid bot to attack are eliminated
Deadline: Challenge finished Friday, April 3, 12:00 UTC (8:00 EDT)

Clarification: Wand success chance is only chosen at the beginning of each round, not once per turn.

It looks like the deadline (March 27, 12:00 UTC) is 5½ hours before the challenge was posted (March 27, 17:28 UTC), making it impossible to compete

Too much luck involved.  The only way to win is to have your wand's random chance wipe out the terminator (any wand with chance = 1) before it gets you.

@Xcali The challenge only really works with a larger number of bots, the advantage of having a lower attack chance is being targeted less and potentially earning a lot more points if you win

I don’t really understand why you’d give yourself a chance of less than 100%

@AJFaraday To increase the points you get from winning, and make yourself less of a target (as bots will likely attack the biggest threat)

Are storage objects shared between the two functions?

Why is my bot not included in the array of all non-eliminated bots?

So... what happens when a player with 0 wand wins? Infinity? NaN? What's the score???

@Alion Oops! I (falsely) assumed a bot with a 0% success chance could never win, my mistake. Will fix. The score will max at 20 to prevent extremely low success rates from being too OP.

@RedwolfPrograms I appreciate the bug fix, but at least mention this arbitrary limit that you've just imposed in the spec, please. It'd be nice if you also put some answers to my other questions there while you're at it...

@Alion Oh, thanks for reminding me. I didn't have much time, meant to fix the spec later. I'll go ahead and clarify a few things.

@RedwolfPrograms Do you think we should be able to not attack during a turn (e.g by returning null)? I feel like this can be a valid strategy, which is not supported by the current controller.

The attacked attribute always seems to be null, am I missing something here?

It's quite interesting how the ranking shuffle whenever a new bot is introduced :P

@SurculoseSputum No, it's on purpose that bots always have to attack. That way a bot can't just idle about and wait for the others to kill each other.

@AJFaraday No, the attacked value is initialized to null at the beginning of each round, and is a UID for every round after that

Wow, this question really blew up! More than 10 answers in one night (also, just reached 3k rep!).

@RedwolfPrograms I have a bot that changes its wand strength per turn, however reading the spec again, it explicitly states wand strength is one at the beginning of the round. Is this something that is desirable? i would have thought you could change your wand strength per turn as we do when we choose who to target.

@Moogie No, it's per round. That's on purpose.

@RedwolfPrograms Is the deadline tomorrow (April 2) or Friday?

@mathjunkie Friday. I guess I somehow messed up the math and made March have 32 days...

Revenge!
A bot that always takes revenge on the bot that attacked it the most thus far, with just a 0.5% wand success rate:
'Revenge!': [
  function(self, others, storage){
    // Initialize attackLog the first round:
    if(storage.attackLog == null)
      storage.attackLog = {};

    // Update the attackLog:
    others.forEach(other => {
      if(storage.attackLog[other.uid] == null)
        storage.attackLog[other.uid] = 0;
      if(other.attacked == self.uid)
        storage.attackLog[other.uid]++;
    });

    // Filter from the remaining bots the one that attacked you the most thus far:
    var attackedMostBy = null;
    var maxAttackedBy = 0;
    others.forEach(other => {
      if(storage.attackLog[other.uid] > maxAttackedBy){
        attackedMostBy = other;
        maxAttackedBy = storage.attackLog[other.uid];
      }
    });

    // If the bots that are left never attacked you: just attack one at random:
    return attackedMostBy == null ? others[Math.random()*others.length|0].uid
    // Else: take revenge on the bot that attacked you the most thus far:
                                  : attackedMostBy.uid;
  },
  function(storage){
    // 0.25% is the lowest wand success rate that is still within the max of 20 boundary,
    // so we'll use twice that wand success rate of 0.5% for a score of roughly 14.1 each
    return 0.005;
  }
]

Try it with all current bots. It seems to be doing quite well, since it's usually in second place.

First place, nice bot!

good work! It has been a consistent top place bot.

@RedwolfPrograms Oh, really? Nice! :) In my TIO tests it was always second place after Golden, although new bots might have affected the scores. Also, how many rounds did you do, out of curiosity?

@KevinCruijssen 500 games, 1000 rounds each (the additional number of rounds might have affected it as well)

Golden
Uses the golden ratio, which, if my calculations are correct, is a Nash equilibrium solution to the two-player game. Attacks the most deadly if there is still more than one opponent.
"Golden": [
    function(self, others, storage) {
        var targ;
        for (var i in others) {
            if (targ == null || others[targ].wand < others[i].wand)
                targ = i
        }
        return others[targ].uid;
    },
    function(storage) {
        return 0.381966;
    }
]

Try it online!

Bully
"Bully": [
    function attack(self, others, storage) {
        minWand = Math.min(...others.map(bot => bot.wand));
        targets = others.filter(bot => bot.wand === minWand);
        return targets[Math.random() * targets.length | 0].uid;
    },

    function wandChance(storage) {
        return 0.0025;
    }
]

Only targets the "weakest" bots, aka bots with the lowest wand success chance.
Test all current bots!

Climber
Always target the bot who, by our calculation, looks to have the highest score. Keeps a 1% wand for the 10 point payout if he wins.
"Climber": [
    function(me, them, storage) {
        storage.current = them.slice(0);
        fromEntries = function(arr){
            var obj = {};
            for(var pair of arr) obj[pair[0]] = pair[1];
            return obj
        }
        if(!storage.scores)
            storage.scores = fromEntries(them.map(x => [x.uid, 0]));

        var targ;
        for (var i in them) {
            if (targ == null || storage.scores[targ] < storage.scores[them[i].uid])
                targ = them[i].uid;
        }
        return targ;
    },
    function(storage) {
        if(storage.scores){
            for(var bot of storage.current)
                // divide the score by the number of bots that could have won
                storage.scores[bot.uid] +=
                           Math.max(Math.pow(bot.wand, -1/2), 20) /
                             (storage.current.length + 1);
        }
        return 0.01;
    }
]

Upper Middle Class Hunter
"UpperMiddleClassHunter": [
    function(self, others, storage) {
        var myOthers = others;
        myOthers.sort((a, b) => a.wand - b.wand);
    return myOthers[myOthers.length * 0.8 | 0].uid;
    },
    function(storage) {
        return 0.333;
    }
],

It hunts the upper middle class bots knowing that the supreme bots will kill each other and be targets from other bots and so it doesn't need to target them. Nor will it hunt the lower bots as they also are targeted by others. Instead hunt the bots that are not the strongest but could be a threat.
It attacks with a 1/3 chance of winning, seeking a balance to kill of the threatening bots, but still gain a reasonable score if winning a round.
Its simplicity hides its effectiveness... in my tests it is either winner or runner up after 500 games.

Peace Lover
Not a troll entry! ...probably.
function attack(me, alive) {
    const them = alive.filter(bot => bot.uid !== me.uid);
    const attackers = them.filter(bot => bot.attacked === me.uid);

    function getMaxWand(bots) {
        return Math.max(...bots.map(bot => bot.wand));
    }
    function hasWand(wand) {
        return bot => bot.wand === wand;
    }

    function getTargets(bots) {
        return bots.filter(hasWand(getMaxWand(bots)));
    }
    const primaryTargets = getTargets(attackers);
    const secondaryTargets = getTargets(them);

    function getRandomValue(array) {
        return array[Math.random() * array.length | 0];
    }

    return (getRandomValue(primaryTargets) || getRandomValue(secondaryTargets)).uid;
}
function chooseChance() {
    return 0;
}

Points its useless wand according to an improved version of the heuristic of this other entry of mine.
Note: This entry didn't work properly because of a bug in the controller, but along with the bug fix came a limit of a measly 20 instead of the Infinity that can be inferred from the spec imposed on the score per win...

If the maximum score you can get is 20 anyway, you might as well set the wand's success chance to 0.05

@mathjunkie First, I just want to keep this entry fully peaceful. It's beneficial vs entries that don't like players with high wand. Second, it would have to be 0.0025. I expected more from a math junkie :P

JustEnough
Targets the strongest of the lowest third of opponents using a wand that is slightly stronger.
Otherwise, targets the first opponent with almost full power unless less than three opponents exist, then use almost no power.
"JustEnough": [
    function(self, others, storage) {

        var targ;
        storage.wand = 0.002;

        var multiplier = 1.01;
        if (others.length > 2){
           multiplier = 1.25;
           storage.wand = 0.99;
        }

        for (var i in others) {
            if ( others[i].wand < 0.3)
            {
                if (targ == null || others[i].wand > others[targ].wand) {
                   targ = i;
                   storage.wand = others[targ].wand * multiplier ;
                   if (storage.wand > .99) storage.wand = 0.99;
                }
            }
        }

        if (targ == null)
        {
           targ = 0;
        }

        return others[targ].uid;
    },
    function(storage) {
        return storage.wand;
    }
]

Bot derived from MegaTom's entry: Golden

My First Bot
This is my first attempt at entering a KotH competition and I don't know what I'm doing.
It literally just hits everyone in turn for a damage value which seemed to be returning good results.
    'My First Bot': [
      function(self, others,storage) {
        if(typeof storage.n == 'undefined'){
          storage.n = 0;
        }
        if(others[storage.n]){
          return others[storage.n].uid;
        } else {
          storage.n = 0;
          return others[0].uid;
        }
      },
      function(storage) {
        return 0.009;
      }
    ]

A Wizard Arrives Precisely When He Means To
'A Wizard Arrives Precisely When He Means To': [
  function(self, others, storage){
    // Store the amount of bots left:
    storage.numBots = others.length;

    // Get the bots within the highest 10% wand success rate:
    var strongOnes = [];
    for(var wandTreshold = 0.9; strongOnes.length == 0; wandTreshold -= 0.1)
      var strongOnes = others.filter(o => o.wand >= wandTreshold);
    // And pick a random one of those strong bots to attack:
    return strongOnes[Math.random()*strongOnes.length|0].uid;
  },
  function(storage){
    // Increase the round number (or initialize at 1 the first round):
    storage.round = storage.round == null ? 1 : storage.round+1;

    // If just one or two bots are left: increase wand success rate to 100%
    return storage.numBots <= 2 ? 1
    // If there are more than two bots are left: use wand success rate dependent on the round
                                : Math.max(1 / storage.round - 0.01, 0.001);
  }
]

This bot does a couple of things:

It lowers its own wand success rate \$SR\$ based on the round number \$r\$, using the formula: \$SR_r\text{ (in %)}=\frac{1}{round}\times100-1\$, which will progress like this: \$SR_r=[99, 49, 32\frac{1}{3}, 24, 19, 15\frac{2}{3}, 13\frac{2}{7}, 11\frac{1}{2}, 10\frac{1}{9},9, ...]\$, unless this is below 0.1%, in which case it'll use that instead. Also, it will use a 100% wand success rate, if there are just two or three bots (including itself) left in play.
It will attack a random bot within the top 10% ranged wand success rate (i.e. \$[90\%, 100\%]\$ until all those are eliminated, then \$[80\%, 90\%)\$ until all those are eliminated, etc. So let's say the bots left have a wand success rate of [83%, 75%, 50%, 1%, 25%, 82.5%, 50%, 50%, 72.5%, 85%] it will pick a random both in the range \$[80\%, 90\%)\$, thus one of the bots [83%, 82.5%, 85%].

From the current bots, this bot usually ends up somewhere in the middle, so not too great, but also not last: Try it with all current bots.

The Terminator
Turn
function (self, others, storage) {
    var attacked = others.map(bot => bot.attacked).filter(uid => others.find(bot => bot.uid == uid));
    return attacked[Math.random() * attacked.length | 0] || others[0].uid;
}

Wand
function (storage) {
    return 1.00;
}

Listen, and understand! That The Terminator is out there! It can't be bargained with. It can't be reasoned with. It doesn't feel pity, or remorse, or fear. And it absolutely will not stop... ever, until you are dead!

Simple Threat Neutralizer
Just to get this challenge going a bit, perhaps...
function attack(me, them) {
    them = them.filter(bot => bot.uid !== me.uid);
    const maxWand = Math.max(...them.map(bot => bot.wand));
    const attackers = them.filter(bot => bot.attacked === me.uid);
    return (attackers.filter(bot => bot.wand === maxWand)[0] || them.filter(bot => bot.wand === maxWand)[0]).uid;
}
function chooseChance() {
    return 1;
}

Chooses bots with a simple danger heuristic - first bots that have attacked it in the previous turn, then all the rest. Sort by most powerful wand and target the first in the array.

Note: No need to filter yourself out of the them array, that's done by the controller by default.

@RedwolfPrograms Keeping it in in case the controller starts following the spec in this regard...

Tall Poppy Loper
Has a major case of Tall Poppy Syndrome and will elminate that bot.
It also has an irrational fear of others' potential so will elminate bots that threaten its supremancy.
"TallPoppyLoper": [
    function(self, others, storage) {

        if (storage.history == null )
        {
            storage.history = {};
            storage.selfuid = self.uid;
            storage.roundNo = 0;

            for (var i in others) {
                var historyBot = {};
                historyBot.alive = true;
                historyBot.killCount = 0;
                storage.history[others[i].uid] = historyBot;
            }
        }
        else if (self.attacked === null)
        {
            storage.roundNo = storage.roundNo + 1;
        }

        for (var i in others) {
            storage.history[others[i].uid].alive = true;
        }

        var targ;
        for (var i in others) {

            if (others[i].attacked != self.uid && others[i].attacked !=null && !storage.history[others[i].attacked].alive) {
                storage.history[others[i].uid].killCount = storage.history[others[i].uid].killCount + 1;
            }

            if (targ == null || storage.history[others[targ].uid].killCount < storage.history[others[i].uid].killCount)
            {
                targ = i
            }
        }

        for (var i in others) {
            storage.history[others[i].uid].alive = false;
        }

        return others[targ].uid;
    },
    function(storage) {
        return 0.95;
    }
]

Bot derived from MegaTom's entry: Golden

This bot can throws error around this part: storage.history[others[i].attacked].alive, since storage.history[...] is undefined.

yeah, just tried it out... in the process of fixing it up

Now fixed... i think

Roulette Wheel
Every action taken is uniformly random.
"Roulette Wheel": [
  function (self, others, storage) {
    return others[Math.random() * others.length | 0].uid //Random target out of all opponents
  },
  function (storage) {
    return 0.0025 + Math.random() * 0.9975 //Random strength in range [1/400, 1]
  }
]

The Wild Card
Chooses a wand success chance at random from the set {0.1, 0.2, ..., 0.9}, favouring values closer to 0.5. Each turn, it makes a decision to either attack a bot who previously attacked it or attack at random.
'The Wild Card': [
  function(self, others, storage){
    // Keep a list of the bots who we hold grudges against
    if (!storage.enemies) storage.enemies = [];

    // Update our list of enemies
    others.forEach(o =>{
        if (o.attacked === self.uid && !storage.enemies.includes(o.uid)){
           storage.enemies.push(o.uid);
        }
    });

    // Filter out bots that have been eliminated
    storage.enemies = storage.enemies.filter(x => others.map(o => o.uid).includes(x));

    if (Math.random() > storage.wand || storage.enemies.length === 0){
        // Our wand couldn't beat a random number
        return others[Math.random() * others.length | 0].uid
    }

    // Our wand was stronger than a random number - attack one of our "enemies"
    return storage.enemies[Math.random() * storage.enemies.length | 0];
  },
  function(storage){
    // Reset the enemies list at the start of each round
    storage.enemies = [];

    // Randomly assign a wand success rate (favours values closer to 0.5)
    var u = Math.random();
    var randNum = 0.9
    if (u < 0.3) randNum = 0.5
    else if (u < 0.5) randNum = 0.4
    else if (u < 0.7) randNum = 0.6
    else if (u < 0.8) randNum = 0.3
    else if (u < 0.9) randNum = 0.7
    else if (u < 0.925) randNum = 0.2
    else if (u < 0.95) randNum = 0.8
    else if (u < 0.975) randNum = 0.1

    // Store our wand success rate to use when choosing a target
    storage.wand = randNum;

    return randNum;
  }
],

Try it against current bots

Don't Kill Me
Survives by staying the second most dangerous wizard throughout the game, so there's always a bigger fish to fry. Scores pretty high.
"Don't Kill Me": [
    function attack(self, others, storage) {
        storage.left = others.length
        maxWand = Math.max(...others.map(bot => bot.wand))
        storage.safeWand = Math.max(...others.filter(bot => bot.wand != maxWand).map(bot => bot.wand))
        return others.filter(bot => bot.wand === maxWand)[0].uid
    },

    function wandChance(storage) {
        return storage.safeWand ? ((storage.left > 1) ? storage.safeWand : 0.01) : 0.1
    }
]

Try it Online!

Copycat
Attempts to make it to the late stages of a round, then copy the average wand strength of the remaining bots when there are 1 or 2 other bots left.
Targets bots with wand strength between 0.1 and 1 (exclusive).
"Copycat": [
    function(self, others, storage) {
        // Copy the strategy of the bots that make it to the end
        if (others.length == 2){
            storage.strength = (others[0].wand + others[1].wand) / 2;
        } else if (others.length == 1) {
            storage.strength = others[0].wand;
        }

        // Filter out the highest and lowest strength bots
        var filteredOthers = others.filter(a => a.wand < 1 && a.wand > 0.1);

        if (filteredOthers.length > 0)
            return filteredOthers[Math.random() * filteredOthers.length | 0].uid;
        return others[Math.max(0, others.length - 2)].uid;
    },
    function(storage) {
        // Prevent overfitting: discard the copied strategy with 1/10 probability
        if (!storage.strength || Math.random() <= 0.1){
            storage.strength = 0.025;
        }

        return storage.strength;
    }
],

Try it against the other bots

There Can Only Be One Strongest
Simply chooses the strongest remaining bot and attacks at full power!
"ThereCanOnlyBeOneStrongest": [
    function(self, others) {
        var targ;
        for (var i in others) {
            if (targ == null || others[targ].wand < others[i].wand)
                targ = i
        }
        return others[targ].uid;
    },
    function(storage) {
        return 1;
    }
]

Bot derived from MegaTom's entry: Golden

Simple Simon
Simply chooses the first bot in the collection of other opponents and attacks at full power
"SimpleSimon": [
    function(self, others) {
        return others[0].uid;
    },
    function(storage) {
        return 1;
    }
]

Bot derived from MegaTom's entry: Golden

Pacifist
Thinks wizard battles are not cool and will not target anyone.
"Pacifist": [
    function(self, others) {
        return others[0].uid;
    },
    function(storage) {
        return 0;
    }
]

Bot derived from MegaTom's entry: Golden

null return value is currently invalid. Maybe returning self.uid would be better? Although this makes the bots less pacifist and more like suicidal :)

-1 "In each turn, every bot must choose a bot to attack"

ok now targetting the "first" bot

Marginally Lower Threat
"Marginally Lower Threat": [
  function (self, others, storage) {
    let maxwand = others.reduce((a,b) => Math.max(a,b.wand), 0)
    let maxbots = others.filter(b => b.wand == maxwand)
    return maxbots[Math.random() * maxbots.length | 0].uid
  },
  function (storage) {
    return 0.999
  }
]

If bots are going to target the strongest remaining, then why not be just a little less than the strongest? Targets a random strongest bot each turn.

source: Stack Exchange

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

sort: votes


text:
God is real . . . unless declared integer
This challenge is inspired by Fortran's idiosyncratic implicit typing rules. Your task will be to determine the data type of the object GOD according to the implicit typing rules explained below.
Background
Fortran 77 has six data types: CHARACTER, COMPLEX, DOUBLE PRECISION, INTEGER, LOGICAL, and REAL. Any object not explicitly declared to have one of these types is implicitly assigned a type by the compiler, as determined by the first letter of the object's name. The default implicit types are:
----------------------------
First letter | Implicit type
-------------+--------------
    A-H      |     REAL
    I-N      |   INTEGER
    O-Z      |     REAL
----------------------------

For example, the object called NUMBER (first letter N) has implied type INTEGER whereas the object called DUMBER (first letter D) has implied type REAL. These rules lead to the old joke that GOD is REAL . . . unless declared INTEGER.
The default implicit types can be overridden using IMPLICIT statements. For example,
IMPLICIT DOUBLE PRECISION (D,X-Z), INTEGER (N-P)

means that all objects whose names start with D, X, Y, or Z now have implied type DOUBLE PRECISION and those starting with N, O, or P have implied type INTEGER. Objects whose names start with any other letter retain their default implied types (in this example, REAL for A–C, E–H, and Q–W and INTEGER for I–M).
For the purposes of this challenge, we will adopt a more concise syntax: the IMPLICIT keyword (redundant here) will be dropped and we will use the single-character identifiers C, D, I, L, R, and X to represent the six data types (X represents COMPLEX). Thus, the example IMPLICIT statement given above becomes
D(D,X-Z), I(N-P)

i.e. a series of identifier–range pairs.
The challenge
Assume that the object GOD exists in a Fortran 77 program and does not have an explicitly declared type. Write a program or function that returns the implied type of GOD, given a compact IMPLICIT statement as input. This is code-golf: the shortest submission (in bytes) in each language wins.
Input

Input is either empty or otherwise consists of 1 to 26 identifier–range pairs.
Input may be taken in any reasonable format (e.g. one long string, list of identifier–range pairs). If you divide the input into identifier–range pairs, each pair may either be taken as is, e.g. 'D(D,X-Z)', or split, e.g. ['D', '(D,X-Z)'].
In ranges, letters appear in alphabetical order and are separated either by commas (for single letters) or dashes (indicating a span of letters). One-letter spans, e.g. G-G, are valid. The outer parentheses must be included, but may be replaced with other paired delimiters (e.g. [] or {}) if desired.
IMPLICIT statements are guaranteed not to overlap. That is, no letter has its implied type specified more than once.
Alphabetic characters must be uppercase.

Output
The uppercase identifier, C, D, I, L, R, or X, that represents the implied type of the object GOD. If the input is empty, your code must return R (the default type of GOD).
Test cases
Input -> Output
'' -> R
I(M-Z) -> R
I(A-Z) -> I
I(G) -> I
I(G-G) -> I
L(A,B,D-H,M-X,Z) -> L
D(D,X-Z), I(N-P) -> R
L(B,D,F,H,J,L,N,P,R,T,V,X,Z), C(A,C,E,G,I,K,M,O,Q,S,U,W,Y) -> C
D(S-Z), D(J-Q), D(A-H) -> D
I(I-K,M,R-T), R(N-P,U-Z), D(D-F,H), X(C,G), C(A,B,Q), L(L) -> X
I(F), X(N), R(P-P), I(C-C), C(A-A), I(J-J), R(V), D(H-H), X(O), L(B-B), C(R), L(Q-Q), I(D), L(X), R(S-S), C(Y), L(T-T), L(Z), X(U), D(K-K), R(G), X(W-W), D(I), C(L-L), R(E), I(M) -> R

Note: In the first test case, single quotes denote string boundaries.
Bonus imaginary internet points!
Awarded to answers that only use characters from the standard Fortran 77 character set: the 26 uppercase letters A-Z, the 10 digits 0-9, the space  , and the 12 characters +-*/=().,’:$

Can we use different encoding for Fortran's types? E.g 1, 2, 3, 4, 5, 6 instead of C, D, I, L, R, X.

@SurculoseSputum you're right that the identifiers are arbitrary but I'd probably prefer not to allow changing them. Mainly because I'd then be obliged to accept things like (65-90) for ranges too.

@JonathanAllan in hindsight, allowing whitespace input creates an unnecessary edge case. Edited.

Great challenge! About the 'any reasonable format" for input, are the ranges specified as strings of a form like "(D,X-Z)" or is that bit flexible too? For instance, can we take this part without parentheses?

Can the input have square braces instead of the round ones you use in this example: ['D', '(D,X-Z)']? So would ['D', '[D,X-Z]'] be valid input?.

This is heresy. GOD objects are widely thought to be an anti-pattern by most programming linguistic theologists.

@Noodle9 yes, any sensible paired delimiters are acceptable.

@xnor I'd say the parentheses (or other delimiters; see previous comment) are required in fairness to those taking input as a single string.

Do we have to use the abbreviated input syntax?

@mcocdawc what do you have in mind? The real Fortran syntax?

yes indeed (now I have to fill up characters...)

@mcocdawc if you think you can make a competitive answer, I say go for it!

Can we take the input as pairs, but without the parenthesis (i.e. like this: [["I","I-K,M,R-T"], ["R","N-P,U-Z"], ...])?

@KevinCruijssen I'd prefer not to allow that in fairness to those taking input as a single string.

@Dingus Sounds reasonable. And np, I've just noticed my 05AB1E solution is the same amount of bytes with or without parenthesis anyway. :)

Lisp can get that Bonus Imaginary Internet points without much effort (Lisp allows you to program in capital letters); unfortunately I'm too lazy to learn it. (Surprisingly Common Lisp is also case-insensitive!)

FORTRAN IV (Compiled with gfortran -ffixed-form), 309 291 290 280 398 393 392 334 237 231 bytes + Bonus imaginary Internet points

This should now be a proper FORTRAN IV program, with no anachronisms!

	REALS(200)
	DATAG,R,H,A/1HG,1HR,1H-,1H(/
	READ 9,S
    9	FORMAT(200A1)
	DO1 I=1,200
	C=S(I)
	IF(C.NE.A)GOTO2
	T=S(I-1)
	GOTO1
    2	IF(C.LT.G.AND.S(I+1).EQ.H.AND.S(I+2).GE.G.OR.C.EQ.G)GOTO8
    1	CONTINUE
	T=R
    8	PRINT 9,T
	END

Try it online!
Here's the same code embedded in a loop that runs through the entire test suite.  I don't think this can be done with TIO's header and footer.

18 bytes off thanks to @JonathanAllan, who pointed out that one IF statement wasn't needed.
1 more byte off by eliminating a stray space between CHARACTER and S at the top.
And 10 more bytes by rearranging the spaghetti code a bit.
Added 118 bytes to put it in proper FORTRAN IV fixed-column punch-card formatting. (This is for historical accuracy -- it isn't necessary for proper functioning under gfortran.)
Shaved off 5 more bytes: Cleaned up the GOTOs a bit, and changed the treatment of characters so it's actually correct for FORTRAN IV.
1 more byte off from removing an unneeded space in the DATA statement.
58 bytes off by streamlining the flow of control through the various IF statements.
97 more bytes off by: (1) eliminating variable P; and (2) replacing the spaces required at the beginning of a line with a tab character, which I found is allowed, according to an old FORTRAN IV manual. (I was thinking of punch card machines, which, as I recall, didn't have a horizontal tab, but I forgot about teletype machines, which did have a tab key.)
Thanks to @Dingus for 6 more bytes (from removing the B in the DATA statement which was no longer needed after P was eliminated).

I've limited myself to FORTRAN IV constructs here.  This should now be a correct FORTRAN IV program, without such things as the CHARACTER data type and quote-delimited strings, which were only introduced later.
Characters in FORTRAN IV needed to be entered as Hollerith constants, and they could be stored in variables of type REAL (and probably other types sometimes too, but there was no CHARACTER type originally).  (As I recall, a real could hold 5 ASCII characters from what we now call a string.  I think they were padded with spaces if there were fewer than 5 characters in a grouping.  The single characters I use are each stored as a real, padded with extra space characters in the real.)
Input is on stdin, on one line, just like the OP's test cases.
Output is on stdout.

FORTRAN IV was my introduction to computer programming -- it was the first programming language I ever learned.  When I was a boy, I read through my dad's textbooks when he took a class in it at NYU, which was required by his musicology graduate program.  Computer programming (as well as FORTRAN itself) has changed quite a bit since then :) .

Does it work for the empty input? The loop version suggests so, but the normal version suggests it fails - maybe a TIO thing?

Also can't you have input with no spaces and remove the space-goto-1?

@JonathanAllan  It does work on a blank line, as the loop version shows.  For the standalone answer, TIO requires a newline for that one blank line to be processed as valid input.  (If not, the program gets an end-of-fille error.)  I've had that input issue on TIO with some programs in other languages as well.

@JonathanAllan You're right about not needing the test for space -- thanks, I'll get rid of it.

Seems so - if I move the blank line to the end the loop version requires an extra line too

@JonathanAllan  Yes -- that's what I've seen with other languages as well. I don't think it's really an extra line that's needed; I think the final blank line just needs to be terminated with a newline. (This actually makes some sense for FORTRAN IV -- its input is line-oriented from back in the old days with punch cards.)

Wow! I'd imagined solutions using the character intrinsics in newer Fortrans, but your spaghetti code takes the cake. Enjoy those well-earned bonus imaginary internet points!

@Dingus Thank you!

I think you can save another 6 bytes by eliminating B from the DATA statement.

@Dingus Thanks, you're right  -- I've made that change.  When I eliminated the variable P, that also removed the only reference to B, so the B in the DATA statement was no longer needed.

I was really hoping to see a FORTRAN entry, so very glad to see this answer.  If I could assign extra up-votes for it being FORTRAN IV, I would.  The first program I ever ran was in FORTRAN IV on a timeshare terminal at a college.

If you're doing it in FORTRAN, can you just ask the compiler what type it assigned to it?

@Acccumulation (1 of 5) It's been a long time since I had thought about any of this, and I was never an expert in it, so take this with a grain of salt. My understanding is that FORTRAN IV just has Hollerith constants, written in the form 4Htext, with the number of characters, followed by H, followed by the actual characters. But there's no character or string type. (Continued)

@Acccumulation (2 of 5) So if you use a Hollerith constant like that one, you're simply stuffing the bits of the ASCII codes in "text", padded with blanks, into whatever variable you put it in (sort of like type-casting a char * as an int * or a float * in C, except that there is nothing corresponding to the char * type in the first place). (Continued)

@Acccumulation (3 of 5) I think there are only two things that you are guaranteed to be able to do with a Hollerith constant: initialize a variable to that value (that is, stuff the appropriate bits in the right places) using a DATA statement, and use it in a FORMAT statement (which isn't relevant to what you asked).  I think some compilers have supported using Hollerith constants in assignment statements or IF statements, but that wasn't guaranteed. (Continued)

@Acccumulation (4 of 5) You can also read character data into a variable with a READ statement; to do this you use an accompanying FORMAT statement with an A specification; this puts the ASCII codes of the character(s) read into a variable (or an array), stuffing and padding with blanks as above.  Writing character data is similar.  You can see examples of this in my answer. (Continued)

@Acccumulation (5 of 5) Once you have characters stuffed into variables (of some numeric type), you can compare them with the logical operators .EQ., .NE., .LT., etc.  But this is just doing a numeric comparison that "happens to work", because you're comparing ASCII codes numerically.

@Acccumulation In part 5 of the comment series above, I wrote "logical operators", but I meant "relational operators",

@WayneConrad  I didn't realize until I wrote this answer that FORTRAN IV would bring out nostalgia!

In Fortran IV all spaces after column 6 can be removed.  Meaning READ9,S,  DO1I=1,200 and PRINT9,T will work.  So you can drop another 3 characters.

Python 3, 61 bytes
lambda i:[a for a,b in i if re.match(b,'G')]or['R']
import re

Try it online!
Input a list of lists of the form ["<type char>", "[<var letters/ranges separated by commas>]"] (eg [['D','[D,X-Z]'],['X','[E,A-J]']]).
Output a list of of one string of type char.

Jelly,  21  20 bytes
ṪḊṣ”,Om2r/71eƲƇµƇȯ”R

A full program accepting a list of pairs as defined in the specification (each being [type_character, ranges_string]) which prints the appropriate type character.
Try it online! Or see the test-suite.
How?
ṪḊṣ”,Om2r/71eƲƇµƇȯ”R - Main Link: list of pairs, [[type_char, range_str],...]
               µƇ    - filter keep those for which:
Ṫ                    -   tail & yield (removes the range_str which we now process
                         ...leaving [type_char] as what the filter might keep)
 Ḋ                   -   dequeue - remove the leading '('
  ṣ”,                -   split at commas (e.g. 'A,F-H,K-K)' -> ['A', 'F-H', 'K-K)']
     O               -   to ordinal (vectorises)            -> [[65], [70,45,72], [75,45,75]]
              Ƈ      -   filter keep those for which:
             Ʋ       -     last four links as a monad:
      m2             -       modulo-2 slice                 ->  [65]  [70,72]  [75,75]
          /          -       reduce by:
         r           -         inclusive range              ->  [65]  [70,71,72] [75]
           71        -       71
             e       -       exists in?                     ->  0     1          0
                     -   }-->                               -> [[70,45,72]]
                                                               (non-empty is truthy)
                     - }--> [[type_char]] or []
                  ȯ”R - logical or with 'R' (i.e. 'R' if empty)
                      - implicit, smashing print

sed -E, 50 45 44 bytes
1 byte off thanks to @user41805.
s/^/R(G/;s/(.)*\([^)]*(G|[A-F]-[H-Z]).*/\1/;

Try it online!
This takes input on stdin formatted on one line just as in the OP's test cases, and output is on stdout.

From my regex tip, .*(.) can become (.)*

@user41805 Thanks -- I missed that optimization.

JavaScript (ES6), 39 bytes
Takes input as an array of ['type','[patterns]'].
a=>(a.find(a=>'G'.match(a[1]))||'R')[0]

Try it online!
Commented
a => (              // a[] = input array of [type, pattern]
  a.find(a =>       // find in a[]:
    'G'.match(a[1]) //   an entry whose pattern is matching 'G'
  )                 // end of find()
  || 'R'            // find() returns undefined if nothing is found,
                    // in which case we use the string 'R' instead
)[0]                // extract either the type of the entry that was found
                    // or the first (and only) character of 'R'

Perl 5 -MList::Util=pairgrep -ap, 53 30 bytes
$_=(pairgrep{G=~/$b/}@F)[0]||R

Try it online!
Input:
A single line, with literal square brackets:
type [letter|range...] ...

Ruby, 37 bytes
->x{(x.find{|_,r|/#{r}/=~?G}||?R)[0]}

Try it online!
Takes input as pairs with brackets, and interprets the second element of each pair as a regexp.

Retina 0.8.2, 37 36 bytes
$
R(G
1!`.(?=\([^)]*(G|[A-F]-[H-Z]))

Try it online! Link includes test cases. Edit: Saved 1 byte thanks to @MitchellSpector. Explanation:
$
R(G

Default to Real.
.(?=\([^)]*(G|[A-F]-[H-Z]))

Match a letter that's followed by a ( and then any non-( characters including a G or a range that includes a G.
1`

Only output the first match, in case the default is a duplicate.
!`

Print the match rather than the count of matches.

I think you can save 1 byte by changing R(G) to R(G  Try it online! -- 36 bytes

Ruby -pl, 47 bytes
Takes space-separated arguments from STDIN.
t=?R
gsub(/(\w)(\S+)/){t=$1if"G".tr!$2,''}
$_=t

Try it online!

Java 10, 63 bytes
m->{var r="R";for(var p:m)r="G".matches(p[1])?p[0]:r;return r;}

Input as an array of String-pairs in the format ["type", "[declaration]"].
Try it online.
Explanation:
m->{                     // Method with String-matrix as input and String return-type
  var r="R";             //  Result-String, starting at "R" as default
  for(var p:m)           //  Loop over each pair `p`
    r=                   //   Set the result to:
      "G".matches(p[1])? //    If "G" regex-matches the second part of the pair
       p[0]              //     Set the result to the first part of the pair
      :                  //    Else:
       r;                //     Leave the result unchanged
  return r;}             //  After the loop: return the result-String

PowerShell, 38 bytes
+ to @Noodle9
$r=$args|?{'G'-match$_[1]}
"R$r"[!!$r]

Expects input via splatting.
Try it online!

Perl 5 with -apF'(?=\[)', 25 bytes
Accepts input as:
A
[A-F,H-M]
B
[N-Z]

$\||=$_ x"G
"=~<>}{$\||=R

Try it online!
Verify all test cases.
Note: the empty test case is missing from the verify all link because my test suite is bad and I should feel bad, but it works when tested in isolation.

Pip, 18 bytes
@@Y'G~``.@>_FIg|'R

Takes each identifier–range pair as a separate command-line argument, in the format D[D,X-Z]. Try it online!
Explanation
              g     The list of cmdline args
            FI      Filter on this function:
         @>_         Everything after the first character
      ``.            Convert to Pattern (regex) by concatenating with an empty Pattern
   'G~               Match against the string "G"
                    We now have either a list containing the pair that matched, or empty list
               |'R  Logical OR with "R": if no pair matched, use "R" instead
  Y                 Yank (to get the operator precedence to cooperate)
 @                  Take first element: the pair that matched, or "R"
@                   First element of that: the identifier from the pair, or "R"
                    Autoprint

Core Maude, 271 bytes
mod G is pr LIST{String}+ LEXICAL . op g : String ~> Qid . var A B C D
:[Qid]. var X Y :[String]. ceq g(X Y)= A if A '`( B C D '`) := tokenize(Y)/\
C == 'G or substr(string(C),0,1)< "H" and substr(string(C),2,1)> "F" . eq g(X
S:String)= g(X)[owise]. eq g(nil)= 'R . endm

The result is obtained by reducing the g function with a Maude list of strings of the form "A(B,C-D)". The result will be a quoted identifier of the letter for the type of GOD, e.g., 'R.
Example Session
             \||||||||||||||||||/
           --- Welcome to Maude ---
             /||||||||||||||||||\
         Maude 3.1 built: Oct 12 2020 20:12:31
         Copyright 1997-2020 SRI International
           Thu Oct 21 00:28:50 2021
Maude> mod G is pr LIST{String}+ LEXICAL . op g : String ~> Qid . var A B C D
> :[Qid]. var X Y :[String]. ceq g(X Y)= A if A '`( B C D '`) := tokenize(Y)/\
> C == 'G or substr(string(C),0,1)< "H" and substr(string(C),2,1)> "F" . eq g(X
> S:String)= g(X)[owise]. eq g(nil)= 'R . endm
Maude> red g(nil) .
result Qid: 'R
Maude> red g("I(M-Z)") .
result Qid: 'R
Maude> red g("I(A-Z)") .
result Qid: 'I
Maude> red g("I(G)") .
result Qid: 'I
Maude> red g("I(G-G)") .
result Qid: 'I
Maude> red g("L(A,B,D-H,M-X,Z)") .
result Qid: 'L
Maude> red g("D(D,X-Z)" "I(N-P)") .
result Qid: 'R
Maude> red g("L(B,D,F,H,J,L,N,P,R,T,V,X,Z)" "C(A,C,E,G,I,K,M,O,Q,S,U,W,Y)") .
result Qid: 'C
Maude> red g("D(S-Z)" "D(J-Q)" "D(A-H)") .
result Qid: 'D
Maude> red g("I(I-K,M,R-T)" "R(N-P,U-Z)" "D(D-F,H)" "X(C,G)" "C(A,B,Q)" "L(L)") .
result Qid: 'X
Maude> red g("I(F)" "X(N)" "R(P-P)" "I(C-C)" "C(A-A)" "I(J-J)" "R(V)" "D(H-H)" "X(O)"
>       "L(B-B)" "C(R)" "L(Q-Q)" "I(D)" "L(X)" "R(S-S)" "C(Y)" "L(T-T)" "L(Z)"
>       "X(U)" "D(K-K)" "R(G)" "X(W-W)" "D(I)" "C(L-L)" "R(E)" "I(M)") .
result Qid: 'R

Ungolfed
mod G is
    pr LIST{String} + LEXICAL .

    op g : String ~> Qid .

    var A B C D : [Qid] .
    var X Y : [String] .

    ceq g(X Y) = A
        if A '`( B C D '`) := tokenize(Y)
        /\ C == 'G or substr(string(C), 0, 1) < "H" and substr(string(C), 2, 1) > "F" .
    eq g(X S:String) = g(X) [owise] .
    eq g(nil) = 'R .
endm

Japt -g, 12 bytes
k@'GrXÌÃÎª'R

Try it

05AB1E, 23 21 20 bytes
ʒθ',¡εáÇŸ}˜71å}˜'Rªн

Input as a list of pairs in the format ["type","(declaration)"].
Try it online or verify all test cases.
Explanation:
ʒ           # Filter the (implicit) list of pairs by:
 θ          #  Pop and push the last value of the pair
            #   i.e. ["I","(I-K,M,R-T)"] → "(I-K,M,R-T)"
  ',¡      '#  Split it by ","
            #   → ["(I-K","M","R-T)"]
     ε      #  Map each inner range to:
      á     #   Remove the "(", "-", and ")" by only leaving the letters
            #    → ["IK","M","RT"]
       Ç    #   Convert each letter to its codepoint integer
            #    → [[73,75],[77],[82,84]]
        Ÿ   #   And then convert it to a range
            #    → [[73,74,75],[77],[82,83,84]]
     }˜     #  After the map: flatten the list of lists of integers
            #   → [73,74,75,77,82,83,84]
       71å  #  Check if 71 is in this list (the codepoint for "G")
            #   → 0 (falsey)
}˜          # After the filter: flatten the remaining list of pairs (potentially empty)
            #  i.e. [["X","(C,G)"]] → ["X","(C,G)"]
  'Rª      '# Append an "R" to this list
            #  → ["X","(C,G)","R"]
     н      # Pop and only leave the first item of this list
            #  → "X"
            # (after which it is output implicitly as result)

You forgot to remove the ¦¨ in your source code.

@petStorm Ah, already did, but only in the explanation and byte-count I see.. >.> Somehow forgot to update the actual program and TIOs.. Thanks for noticing.

PowerShell, 38 37 bytes
($args+'RG'|?{'G'-like"[$_ ]"})[0][0]

Try it online!
Takes strings as is, e.g. 'D(D,X-Z)'.

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


text:
Convert Planck unit to SI metric
Objective
Given a dimension of an SI unit, convert the Lorentz-Heaviside version of a Planck unit \$1\$ into SI metric.
What is a Planck unit?
Planck units are a set of units of measurement. It defines five fundamental constants of the universe as dimensionless \$1\$.
What is a dimension?
There are five types of fundamental dimension: L, M, T, Q, and Θ (U+0398; Greek Capital Letter Theta).
L stands for length and corresponds to SI unit m (meter).
M stands for mass and corresponds to SI unit kg (kilogram).
T stands for time and corresponds to SI unit s (second).
Q stands for electric charge and corresponds to SI unit C (Coulomb).
Θ stands for temperature and corresponds to SI unit K (Kelvin).
A dimension is a multiplicative combination of these. For example, SI unit V (volt) is same as kg·m²·C/s⁴ and thus corresponds to dimension L²MQ/T⁴.
Planck to SI
\$1\$ as Planck unit can be converted to SI metric as follows:
$$
1 = 5.72938×10^{−35} \space [\text{m}] = 6.13971×10^{−9} \space [\text{kg}] = 1.91112×10^{−43} \space [\text{s}] = 5.29082×10^{−19} \space [\text{C}] = 3.99674×10^{31} \space [\text{K}]
$$
Input and Output
A dimension is given as the input. Its type and format doesn't matter. In particular, it can be an size-5 array of signed integers, each integer representing the exponent of a fundamental dimension.
The Planck unit \$1\$ is to be converted to the SI unit that corresponds to the inputted dimension, and then outputted. The output type and format doesn't matter.
Examples
Let's say the input format is a tuple of five integers, representing L, M, T, Q, and Θ, respectively.
For example, If the input is \$(2,1,-1,-2,0)\$, it corresponds to SI unit Ohm, and thus:
$$
1 = \frac{(5.72938×10^{−35})^2 × (6.13971×10^{−9})}{(1.91112×10^{−43})×(5.29082×10^{−19})^2} \space [\text{Ω}]
$$
So the output is approximately \$376.730\$.
For another example, if the input is \$(-2,-1,3,0,1)\$, it corresponds to SI unit K/W, and thus:
$$
1 = \frac{(1.91112×10^{−43})^3 × (3.99674×10^{31})}{(5.72938×10^{−35})^2 × (6.13971×10^{−9})} \space [\text{K/W}]
$$
So the output is approximately \$1.38424×10^{−20}\$.
Note that, if the input is \$(0,0,0,0,0)\$, the output must be \$1\$.

How much precision do we need in the constants? I assume that if we use them as is, it's five digits as given. But, if our solution computes them via their logs or inverses, how accurate do we need to get?

@xnor At least 5 digits, as you say. (This is why I hate floating-point numbers.)

Yeah, floats are that worst. Do you mean give digits in the numbers we use, or five digits in the result in produces? for example, if my answer computes $5.72938×10^{−35}$ as 10**-34.241892, where can I cut off the 34.241892? If I cut it off to five decimal places as 34.24189, then the result of 5.72941129637e-35 isn't quite accurate to five places. Sorry to be so finicky here, but this does seem to matter for answers I'm trying.

@xnor Rounding to six significant digits is acceptable.

Regarding (0,0,0,0,0) producing 1:  Literally "1", or a floating point representation of "1", e.g., "1.00000"?

@EricTowers The output format must treat them the same.

05AB1E, 31 29 bytes
•¿NkˆSSÀ¯j5ÄΣDt₁ñµ•8ô6°/₃-*O°

Try it online!
-2 thanks to @Kevin Cruijssen
inspired by @xnor.
explanation:
•¿NkˆSSÀ¯j5ÄΣDt₁ñµ•8ô6°/₃- compressed list [-34.241893, -8.211853000000005, -42.718713, -18.276477999999997, -82.33983, -94.999995]
* multiply by the implicit input (e.g. [-68.48378600000001, -8.211852999999998, 42.718713, 36.552955999999995, 0.0])
O sum (e.g. 2.576029999999996)
° raise 10 to the power of that (e.g. 376.729821659)

Old Solution, 36 35 34 bytes
"7Q/Gy"Ç₃-*O°•7“µ$₁$´*h$Ć²E•6ôImP*

-1 thanks to @Expired Data
Try it online!
explanation:
"7Q/Gy"Ç₃- compressed list [-40,-14,-48,-24,26]
* multiply (vectorize) with the implicit input - [-80, -14, 48, 48, 0]
O sum - 2
° 10^ - 100
•7“µ$₁$´*h$Ć²E• compressed number 572938613971191112529082399674
6ô split into groups of length 6 - [572938,613971,191112,529082,399674]
I push input to the stack, to get [2, 1, -1, -2, 0] [572938,613971,191112,529082,399674] 100
m power (vectorize) - [328257951844, 613971, 5.232533802168362e-6, 3.5723502030270884e-12, 1]
P product - 3.7672911312918473
* multiply - 376.72911312918473, and then implicitly output

•;sê •2ô58- can be "7Q/Gy"Ç₃-  for -1

thanks! how did you find it? I also need to update to TIO link

Well 95 is a 1 byte built in as opposed to 58 which is two and integer lists can be represented as strings and converted from ASCII if they're all in the range you need

You can remove the s before the * in your 31-byte version.

29 bytes by also using ₃- instead of 53- with a different compressed integer.

Thanks, I somehow managed to forget that multiplication is commutative

Python 3, 118 \$\cdots\$ 85 80 bytes
Saved a whopping 29 bytes thanks to Surculose Sputum!!!
Saved 4 bytes thanks to Arnauld!!!
Saved 5 bytes thanks to xnor!!!
lambda a,b,c,d,e:399674e26**e/174539e29**a/162874e3**b/523253e37**c/189007e13**d

Try it online!

116 bytes haha

89 bytes by doing it the vanilla way :)

Not as short as Surculose Sputum's direct solution, but another idea is to convert the problem to addition by working in log-space: Try it online! I don't know though how many digits of precision are needed in the list since the challenge doesn't say. Along similar lines, we could probably save bytes by changing some multiplications to divisions in the direct solution.

@xnor Wow! You've totally blown my mind.  Have to have way more coffee and see if I can figure out what's going there. :D

@SurculoseSputum The beauty (and oft shortness) of simplicity. Sweet - thanks! :-)

@RGS I have to checkout mah.prod! :D

85 bytes

@Arnauld Very clever shifting decimals - thanks! :-)

@xnor Saved 5 bytes by changing 4 multiplications to divisions - thanks! :-)

@xnor Figured out your code. Was reading 1 for your .1 and thought you were using black magic! T_T

Jelly,  35  34 bytes
“~VHð¡ȷ‘I⁵*×“®ƬØʋ¥4ẋİ8nCaḌ’bȷ6¤*⁸P

A monadic Link accepting a list of the five exponents, [L, M, T, Q, Θ], which yields a floating-point number.
Try it online!
How?
“~VHð¡ȷ‘I⁵*×“®ƬØʋ¥4ẋİ8nCaḌ’bȷ6¤*⁸P - Link: list of numbers       [L, M, T, Q, Θ]
“~VHð¡ȷ‘                           - list of code-page indices   [126, 86, 72, 24, 0, 26]
        I                          - differences                 [-40,-14,-48,-24,26]
         ⁵                         - ten                         10
          *                        - exponentiate                [1e-40, 1e-14, 1e-48, 1e-24, 1e26]
                              ¤    - nilad followed by link(s) as a nilad:
            “®ƬØʋ¥4ẋİ8nCaḌ’        -   base 250 number           572938613971191112529082399674
                            ȷ6     -   10^6                      1000000
                           b       -   convert from base         [572938,613971,191112,529082,399674]
           ×                       - multiply (vectorises)       [5.72938e-35,6.13971e-09,1.91112e-43,5.29082e-19,3.99674e31]
                                ⁸  - chain's left argument       [L, M, T, Q, Θ]
                               *   - exponentiate                [5.72938e-35^L,6.13971e-09^M,1.91112e-43^T,5.29082e-19^Q,3.99674e31^Θ]
                                 P - product                     5.72938e-35^L×6.13971e-09^M×1.91112e-43^T×5.29082e-19^Q×3.99674e31^Θ

34 bytes by using STDIN Ɠ instead of first argument ⁸, enabling you to use _³ for -100 instead of the _48.

@KevinCruijssen Nice & thanks; I'm going to do 34 a different way though...

Ah, using differences. Yeah, that's also a way. :)

Fortran (2008), 133 bytes
At least for this challenge there should be a Fortran solution.
Takes input as integer array.
real(real64)function h(I)
use iso_fortran_env
integer I(5)
h=product([572938d-40,613971d-14,191112d-48,529082d-24,399674d26]**I)
end

A slightly longer and less accurate function uses the logarithm (stolen from @xnor):
real(real64)function f(I)
use iso_fortran_env
integer I(5)
f=exp(sum([-7884487d-5,-1890850d-5,-9836347d-5,-42083140d-5,7276562d-5]*I))
end

Would be awesome if you could solve this one with Fortran! :D

Thank you for the tip

You can save a few bytes by getting rid of the decimal points (e.g. 5.72938d-35 ~> 572938d-40).

Thank you very much

Frink, 76 bytes
f[a,b,z,d,e]:=l_P^a m_P^b(4π)^((a-b+z-e)/2)t_P^z(ℏ c epsilon0)^(d/2)T_P^e

Example usage:
f[2,1,-1,-2,0]
376.73031366686987155 m^2 s^-3 kg A^-2 (electric_resistance)
f[-2,-1,3,0,1]
1.3842382138391631282e-20 m^-2 s^3 kg^-1 K (thermal_resistance)

(As a bonus, it outputs a description of the unit of the result!)
Frink has the constants plancklength, planckmass, plancktime, and plancktemperature built in, with abbreviations l_P, m_P, t_P, and T_P respectively. Unfortunately, these are the Gaussian versions of the units, and the challenge specifies that we must use the Lorentz-Heaviside versions. This is a factor of \$\sqrt{4\pi}\$ conversion for each unit, which is consolidated into the (4π)^((a-b+z-e)/2) expression in the solution. (This expression is placed in the middle of the code to save a byte by letting us remove the space between m_P^b and t_P^z.)
Incidentally, 4π is exactly as long as 4pi in UTF-8, so it doesn't actually save any bytes -- it just looks fancier. :P
Finally, Frink inexplicably lacks the built-in unit planckcharge, so we calculate the Lorentz-Heaviside version directly ourselves as (ℏ c epsilon0)^(1/2) (this time, ℏ actually saves a byte over hbar!).

Perl 5 -pa, 84 80 bytes
@Arnauld and I both realized that you can save bytes by removing the decimal points.
$\=1;map$\*=$_**$F[$i++],572938E-40,6.13971E-9,191112E-48,529082E-24,399674E26}{

Try it online!

I was actually just working on that when you posted.

dc, 85 81 78 75 70 bytes
16iFFk1F875AI15^*?^35C8BI18^*?^/9B5431E?^/3C1109I1E^*?^/1A3ADDIA^*?^/p

Try it online!
Or try a test suite that shows the sample cases listed in the challenge.  (This is a bash script that runs the dc program on each test data set in turn.)

Saved 4 bytes by removing the decimal points, thanks to @Arnauld.
Had to add 1 byte also though, because I had inadvertently omitted a digit in one of the constants.
Saved 3 more bytes by changing constants to hexadecimal.
Thanks to @Noodle9 for pointing out that using division instead of multiplication can shorten this. That, plus careful attention to how many significant digits were needed throughout, yielded a savings of 5 additional bytes.

Input on stdin, one number per line, in base 16, in the following order:
Θ
L
M
T
Q

This is the OP's order except the last one there is moved to the first position instead.
(The challenge says, "A dimension is given as the input. Its type and format doesn't matter."  Also, hexadecimal input won't make a difference in practice given the problem domain, because we're not going to have a dimensional exponent outside the range -9 to 9.  And this is allowed anyway by "Yes, I/O in unary, binary, octal, decimal or hexadecimal should be acceptable by default", which got the required support of at least 5 net votes, and at least twice as many upvotes as downvotes -- in this case, 20 upvotes, 8 downvotes, and 12 net votes.)
Output on stdout, in base 10 as usual, with lots of decimal places :) .

If you try this out, note that when you enter negative numbers in dc, they're written with an initial _ character instead of -, since - is reserved for the binary subtraction operator.  And don't forget to put Θ first, and to enter them all in hexadecimal!  (Output is still in decimal.)

JavaScript (ES7),  81  76 bytes
Saved 5 bytes thanks to @Noodle9
Seems like the direct formula is the shortest way... ¯\_(ツ)_/¯
Takes input as 5 distinct arguments.
(a,b,c,d,e)=>399674e26**e/174539e29**a/162874e3**b/523253e37**c/189007e13**d

Try it online!

JavaScript (ES7), 86 bytes
Using reduce() adds  5  10 bytes.
Takes input as an array.
a=>a.reduce((p,c,i)=>p*([572938e8,613971e34,191112,529082e24,399674e74][i]/1e48)**c,1)

Try it online!

76 bytes.

Mathematica, 260 bytes
Using a different method than the OP's.  In particular, Table 2 at https://en.wikipedia.org/wiki/Planck_units#Definition
Many opportunities for cleanup (e.g., shrink name to c, saving 6 bytes), but seems pointless.  Newlines and indenting are inessential and are only present for presentation.  Two spaces are required, at the end of the BoltzmannConstant line and at the end of the ElectricConstant line.
convert=Function[{L,M,T,Q,t},
  N[UnitConvert[
    Quantity["BoltzmannConstant"]^-t
      Sqrt[
        (4Pi)^(L-M+T-t)
        Quantity["SpeedOfLight"]^(-3L+M-5T+Q+5t)
        Quantity["ElectricConstant"]^Q
        Quantity["GravitationalConstant"]^(L-M+T-t)
        Quantity["ReducedPlanckConstant"]^(L+M+T+Q+t)
      ]
  ],6]
]

Checking:
convert[2, 1, -1, -2, 0]
(*  376.730 kg m^2/(s^3A^2)  *)
(*  FullForm: Quantity[376.730, ("Kilograms" ("Meters")^2)/(("Amperes")^2 ("Seconds")^3)]  *)

convert[-2, -1, 3, 0, 1]
(*  1.3842\[Times]10^-20 s^3K/(kg m^2)  *)
(*  FullForm: Quantity[1.3842\[Times]10^-20, ("Kelvins"*"Seconds"^3)/("Kilograms"*"Meters"^2)]  *)

convert[0, 0, 0, 0, 0]
(*  1.00000  *)

Notice that this code uses a curated source of consensus scientific values of the constants, and the output will change as those values change.  Of relevance to the Challenge (and exemplified in the above samples), the gravitational constant is only 6.674 30(15) *10^(-11) m^3 /(kg s^2), so is only known to four significant digits.  This impacts the precision of length, mass, and time (except in combinations where this term cancels) in the Challenge, although the Challenge does not acknowledge this limitation of precision in those constants.

PowerShell, 124 101 bytes
-23 bytes thanks to mazzy
$t=1
$args|%{$t/=[math]::pow((174539e29,162874e3,523253e37,189007e13, 2502039161917e-44)[$i++],$_)}
$t

Try it online.

? Try it online!

It looks great :) what about this slightly longer answer? Try it online!

It looks nice. I don't see any good reason to use 1/const and const in the same expression at the same time, unless it shortens the expression.

Fortran (GFortran), 95 90 bytes
READ*,I,J,K,L,M
PRINT*,399674D26**M/174539D29**I/162874D3**J/523253D37**K/189007D13**L
END

Try it online!
Input on stdin, output on stdout.
Thanks to @Noodle9 for saving 5 bytes by pointing out that using division instead of multiplication can shorten this.

90 bytes.

@Noodle9 -- Thank you!  This same idea shortened my dc solution too.

Java 8, 118 bytes
Math M=null;(a,b,c,d,e)->M.pow(399674e26,e)/M.pow(174539e29,a)/M.pow(162874e3,b)/M.pow(523253e37,c)/M.pow(189007e13,d)

Port of @Noodle9's Python answer, so make sure to upvote him!!
Try it online.

TI-83 Basic, 62 tokens
Using list operations:
prod({5.72938ᴇ−35,6.13971ᴇ−9,1.91112ᴇ−43,5.29082ᴇ−19,3.99674ᴇ31}^Ans

where
prod(                 Multiply all list elements together (1 token)
     { ... }          Constants in list (59 tokens)
            ^         Power using 2 lists as arguments (1 token)
             Ans      Input list stored in answer variable (1 token)

Example:
| {2,1,-1,-2,0}    | Give input
|    {2 1 -1 -2 0} |
| prgmPLANCK       | Run program
|      376.7291131 | Result

Second example unfortunately returns 0, because of insufficient precision on calculator.