In Bloons Tower Defense 6, the strength of different bloons can be measured by their Red Bloon Equivalent (RBE), or the number of single pops it takes to completely defeat the bloon.
The RBE for the bloon types are as follows (sourced from the wiki)
| Bloon | RBE |
|---|---|
| red | 1 |
| blue | 2 |
| green | 3 |
| yellow | 4 |
| pink | 5 |
| black | 11 |
| white | 11 |
| purple | 11 |
| lead | 23 |
| zebra | 23 |
| rainbow | 47 |
| ceramic | 104 |
| moab | 616 |
| bfb | 3164 |
| zomg | 16656 |
| ddt | 816 |
| bad | 55760 |
The Challenge
Given a run-length encoded list of bloon types, calculate the total RBE. More specifically, find the RBE of each bloon type according to the table, multiply by the given count, and sum them all.
Notes
- Input can be taken in any reasonable format (comma-separated string, list of tuples, etc.)
- You must output a single integer
- Assume that input will never be invalid
- Bloon types must be given exactly as shown in the table above, in lowercase
- This is code-golf, so the lowest score in bytes wins!
Test Cases
Input: 1 red
Output: 1
Input: 7 green
Output: 21
Input: 5 bfb, 11 moab
Output: 22596
Input: 1 red, 2 yellow, 3 white, 4 zebra, 5 moab, 6 ddt
Output: 8110
Input: 1 moab, 1 bfb, 1 zomg, 1 ddt, 1 bad, 1 red, 1 blue, 1 green, 1 yellow, 1 pink, 1 black, 1 white, 1 purple, 1 lead, 1 zebra, 1 rainbow, 1 ceramic
Output: 77257
12 Answers 12
JavaScript (ES6), 111 bytes
Expects a list of [count, bloon] pairs.
a=>a.reduce((t,[k,s])=>t+k*[23,3,104,616,3164,1,16656,4,47,23,816,55760,5,11,2][parseInt(s,36)*53%437%44%15],0)
How?
The hash function was found by brute force:
parseInt(s, 36) * 53 % 437 % 44 % 15
It's a bit long but almost perfect:
- all slots from 0 to 14 are used
- black, white and purple (all scoring 11) gracefully collide on the same slot
- however, two distinct slots are used for lead and zebra (both scoring 23)
Below is a summary table sorted by final lookup index:
string | parseInt() | * 53 | mod 437 | mod 44 | mod 15 | value
-----------+-------------+---------------+---------+--------+--------+-------
"lead" | 998293 | 52909529 | 191 | 15 | 0 | 23
"green" | 28152239 | 1492068667 | 339 | 31 | 1 | 3
"ceramic" | 27013759860 | 1431729272580 | 134 | 2 | 2 | 104
"moab" | 1057907 | 56069071 | 223 | 3 | 3 | 616
"bfb" | 14807 | 784771 | 356 | 4 | 4 | 3164
"red" | 35509 | 1881977 | 255 | 35 | 5 | 1
"zomg" | 1664872 | 88238216 | 50 | 6 | 6 | 16656
"yellow" | 2080372496 | 110259742288 | 37 | 37 | 7 | 4
"rainbow" | 59409106160 | 3148682626480 | 243 | 23 | 8 | 47
"zebra" | 59454982 | 3151114046 | 127 | 39 | 9 | 23
"ddt" | 17345 | 919285 | 274 | 10 | 10 | 816
"bad" | 14629 | 775337 | 99 | 11 | 11 | 55760
"pink" | 1190576 | 63100528 | 350 | 42 | 12 | 5
"black" | 19468964 | 1031855092 | 204 | 28 | 13 | 11
"white" | 54565250 | 2891958250 | 189 | 13 | 13 | 11
"purple" | 1563335762 | 82856795386 | 336 | 28 | 13 | 11
"blue" | 541526 | 28700878 | 29 | 29 | 14 | 2
Python 3.9, 104 + 17 = 121 bytes
lambda l:sum([47,11,3164,616,16656,4,1,5,23,104,11,23,3,2,11,816,55760][hash(a*9828)%17]*b for a,b in l)
You also need to set an environment variable (I included it in the byte count).
PYTHONHASHSEED=65
Input is a list of tuples of the form (name, amount)
-
\$\begingroup\$ I bet you could do better by compressing that crazy bit array somehow \$\endgroup\$Lucas Mumbo– Lucas Mumbo2023年04月15日 00:49:42 +00:00Commented Apr 15, 2023 at 0:49
Jelly, 47 bytes
ḋɓ"μCḅṃ’,14ḥⱮị(%xBŻ€ṁ@"£t¢Bƈ/¦£¤Bh\礿€ƥṣ1⁄2‘¤ḅØ5
A dyadic Link that accepts the frequencies on the left and the respective bloons on the right and yields the total RBE.
How?
ḋɓ"...’,14ḥⱮị(%xBŻ€ṁ@"...‘¤ḅØ5 - Link: frequencies, bloons
Ɱ - map across the bloons applying:
ḥ - hash...
"...’ - ...with salt: 160553470
,14 - ...and values: [1,2,...,14]
¤ - nilad followed by link(s) as a nilad
(%x - 10371
B - convert to binary -> [1,0,1,0,0,0,1,0,0,0,0,0,1,1]
Ż€ - zero range each -> [[0,1],[0],[0,1],[0],[0],[0],[0,1],[0],[0],[0],[0],[0],[0,1],[0,1]]
"...‘ - code-page indices = [2,116,1,66,156,47,5,2,3,66,104,4,23,3,11,12,164,223,10]
ṁ@ - mould -> [[2,116],[1],[66,156],[47],[5],[2],[3,66],[104],[4],[23],[3],[11],[12,164],[223,10]]
ị - (hashed bloons) index into (that)
Ø5 - 250
ḅ - convert from base (250) -> bloon RBEs
ɓ - dyadic chain:
ḋ - (frequencies) dot-product (bloon RBEs)
Excel, 203 bytes
=LET(
a,TEXTSPLIT(A1," ",","),
SUM(LOOKUP(TAKE(a,,-1),
{"b","bf","bla","blu","c","d","g","l","m","p","pu","r","re","w","y","z","zo"},
{55760,3164,11,2,104,816,3,23,616,5,11,47,1,11,4,23,16656})*TAKE(a,,1))
)
Input is comma-separated string, e.g. 1 red, 2 yellow, 3 white, 4 zebra, 5 moab, 6 ddt, in cell A1.
C (gcc), 200 bytes
Takes an array of strings and its length as input.
f(s,n,c,t)char**s;{int L[]={47,23,55760,4,0,0,0,0,0,816,2,0,0,0,0,0,3,0,0,5,3164,0,0,0,616,16656,1,0,11,23,0,104};for(t=0;n--;t+=c*L[((**s*2[*s++]*7711)>>15)&31])for(c=atoi(*s);*(*s)++-32;);return t;}
-
\$\begingroup\$ 173 bytes \$\endgroup\$ceilingcat– ceilingcat2023年04月15日 09:45:01 +00:00Commented Apr 15, 2023 at 9:45
Swift 2.2, 128 bytes
{0ドル.reduce(0){0ドル+1ドル.1*[0,16656,3164,0,5,616,3,0,0,11,1,816,0,23,0,0,23,0,55760,11,104,2,4,0,0,47][(1ドル.0.hashValue>>8&63^6)%26]}}
Takes a dictionary, e.g. ["red": 3, "blue": 7].
It turns out that after some bit twiddling, each bloon type has a unique* hashValue mod 26. So far I haven't found a way to get the modulus any lower. Since Swift 3, hash values differ between runs of the same program, so this strategy is no longer viable.
*"white" and "black" map to the same value, but they also have the same RBE, so it works out.
Retina, 146 bytes
.+ed
*
.+ue
*2*
.+en
*3*
.+y
*4*
.+nk
*5*
.+[khp]
*11*
.+e[ab]
*23*
.+n
*47*
.+c
*104*
.+ab
*616*
.+f
*3164*
.+g
*16656*
.+dt
*816*
.+ad
*55760*
_
Try it online! Takes input on separate lines but link is to test suite splits on , for convenience. Explanation: Each stage matches a colour of balloon to multiply its quantity appropriately. The shortest possible unique remaining substring is used at each point, with preference being given to the rightmost such substrings as this will be deleted and therefore can be ignored when matching subsequent substrings. In this way for instance .+nk matches and deletes the whole of pink allowing .+[khp] to only match black, white and purple. The final _ then calculates the total RBE which is converted back to decimal.
05AB1E, 81 bytes
ø`.•4в#‡fÕçòÖ1<÷E¤E%ÝÙ/J"Å;>Íslζ2θ...•3ôs3δ£k•Ì\δвιλùEmæâåÇÛZ•4в•Cƒ2œÝù•3äÁ«.\>sè*O
I suck at finding magic numbers, so this will have to do for now.. Replacing .•4в#‡fÕçòÖ1<÷E¤E%ÝÙ/J"Å;>Íslζ2θ...•3ô3δ£k with C, optional Ø, and some modulos will probably save some bytes.
Try it online or verify all test cases.
Explanation:
ø # Zip/transpose the (implicit) input-list
` # Pop and push the list of Bloons and list of counts separated to the stack
.•4в#‡fÕçòÖ1<÷E¤E%ÝÙ/J"Å;>Íslζ2θ...•
# Push compressed string "redblugreyelpinblawhipurleazebraicermoaddtbfbzombad"
3ô # Split it into parts of size 3
s # Swap so the input-list of Bloons is at the top
δ # Map over each Bloon:
3 £ # Leave just its first 3 characters
k # Get the index of each in the list of strings
•Ì\δвιλùEmæâåÇÛZ• # Push compressed integer 1001001001006000000012000024057512200
4в # Convert it to base-1000 as list:
# [1,1,1,1,6,0,0,12,0,24,57,512,200]
•Cƒ2œÝù• # Push compressed integer 13492391042348
3ä # Split it into 3 equal-sized parts: [13492,39104,2348]
Á # Rotate it once: [2348,13492,39104]
« # Merge the two lists together
.\ # Undelta it with leading 0: [0,1,2,3,4,10,10,10,22,22,46,103,615,815,3163,16655,55759]
> # Increase each by 1
sè # Index the earlier indices into this list
* # Multiply each value by its count
O # Sum this list together
# (after which the result is output implicitly)
See this 05AB1E tip of mine (sections How to compress strings not part of the dictionary?, How to compress large integers?, and How to compress integer lists?) to understand why .•4в#‡fÕçòÖ1<÷E¤E%ÝÙ/J"Å;>Íslζ2θ...• is "redblugreyelpinblawhipurleazebraicermoaddtbfbzombad"; •Ì\δвιλùEmæâåÇÛZ• is 1001001001006000000012000024057512200; •Ì\δвιλùEmæâåÇÛZ•4в is [1,1,1,1,6,0,0,12,0,24,57,512,200]; and •Cƒ2œÝù• is 13492391042348.
Charcoal, 86 bytes
IΣE⪪S, ΠIE⪪ι ⎇μ§⪪")¶⊟S|4ηJ?α8⊕rüQG§%⊗βjNo8c/ojo"9⌕⪪"&⌈⊟2...x⦃P⦄h¿◨T-α〜6?T÷` ́Cgψ↥b·CQq"3...λ3λ
Try it online! Link is to verbose version of code. Explanation:
S Input string
⪪ , Split on literal string `, `
E Map over substrings
ι Current substring
⪪ Split on literal string ` `
E Map over words
⎇μ If second word then
"..." Compressed lookup table
⪪ 3 Split into substrings of length `3`
⌕ Find index of
λ Second word
... Truncated to length
3 Literal integer `3`
§ Index into
"..." Compressed lookup table
⪪ 9 Split on literal string `9`
λ Otherwise first word
I Cast to integer
Π Take the product
Σ Take the sum
I Cast to string
Implicitly print
77 bytes using the newer version of Charcoal on ATO by taking the input as a dictionary:
×ばつιI§⪪")¶⊟S|4ηJ?α8⊕rüQG§%⊗βjNo8c/ojo"9⌕⪪"&⌈⊟2...x⦃P⦄h¿◨T-α〜6?T÷\` ́Cgψ↥b·CQq"3...κ3
Attempt This Online! Link is to verbose version of code.
Pyth, 61 bytes
sm*@[616C\/5 816J2K11ZKy8328hZ23KZZ3y52Z3164yJ55760)%Ced8027h
Takes input as a list of lists. The lookup portion could probably be compressed some more but who knows.
Explanation
sm*@[...)%Ced8027hdQ # implicitly add dQ
# implicitly assign Q = eval(input())
s # sum of
m Q # map lambda d over Q
* hd # multiply the first element of d by
ed # the last element of d
C # converted to int using base 256 and code points
% 8027 # modulo 8027
@[...) # modularly indexed into the lookup table
C#, 123 bytes
x=>x.Sum(y=>new[]{616,1,4,0,5,47,3164,104,16656,816,3,23,0,11,55760,2}[y.Key.Aggregate(0,(a,n)=>3*a+n)*75%1847%16]*y.Value)
Pretty similar to the existing JavaScript answer. I brute-forced another hash function:
y.Key.Aggregate(0,(a,n)=>3*a+n)*75%1847%16
C# has no built-in way to parse base 36 numbers (which the JavaScript answer uses), so I had to use Aggregate to get a unique int for each string which worked here (GetHashCode returns different values between program executions for strings so can't be used).
string | aggregate |*75%1847%16
--------------------------------
red | 1429 | 1
blue | 4070 | 15
green | 12743 | 10
yellow | 41924 | 2
pink | 4406 | 4
purple | 41204 | 13
black | 12131 | 13
white | 13841 | 13
zebra | 13930 | 11
lead | 4216 | 11
rainbow | 119486 | 5
ceramic | 109962 | 7
moab | 4331 | 0
bfb | 1286 | 6
zomg | 4723 | 8
ddt | 1316 | 9
bad | 1273 | 14
[red, red, red]rather than3 red\$\endgroup\$