| Bytes | Lang | Time | Link |
|---|---|---|---|
| 052 | Python 2 | 241111T014628Z | Lucenapo |
| 041 | JavaScript ES6 | 241107T102914Z | Arnauld |
| 063 | Perl 5 MListUtil=sum pF | 241107T183600Z | Xcali |
| 024 | Charcoal | 241107T165503Z | Neil |
| 012 | 05AB1E | 241107T110048Z | Kevin Cr |
| 100 | Retina 0.8.2 | 241107T101047Z | Neil |
| 022 | Uiua | 241107T093208Z | mousetai |
Python 2, 52 bytes
lambda i:i[88614024>>int(`sorted(i)`[2::5])%74%28&3]
This is Arnauld's answer which I translated into Python.
JavaScript (ES6), 41 bytes
Expects an array of 3 integers and returns an integer.
Mapping: 0, 1, 2, 3, 4 → Fire, Soil, Metal, Water, Wood.
a=>a[88614024>>a.sort().join``%37%14*2&3]
Method
Once the input array is sorted in ascending order, there are only 35 possible cases that can be identified with the concatenation of the values:
000, 001, ..., 333, 334, 344, 444
It turns out that it's quite efficient to use a modulo chain on this identifier, combined with a bitmask encoding the position of the answer in the sorted array.
It's worth noting that we may have several possibilities for the position (e.g. for 000 all positions are correct). This potentially allows us to optimize the collisions in the lookup data. But in practice, taking the first matching position is apparently just as good.
JavaScript (ES6), 39 bytes
We can exploit the loose I/O format to save a few bytes. But I don't really like doing so.
Mapping: 0, 2, 4, 6, 8 → Fire, Soil, Metal, Water, Wood.
a=>a[88614024>>a.sort().join``%74%28&3]
Perl 5 -MList::Util=sum -pF, 63 bytes
s;.;$a[5+sum map{($b=($_-$&)%5)==1||-($b==2)}@F]=$&;ge;$_=pop@a
Input as three digits with no spaces:
4 Fire
3 Soil
2 Metal
1 Water
0 Wood
Output uses the same encoding.
Charcoal, 24 bytes
Fθ⊞υ↨E²№θI﹪⁺κ⊕ι⁵±¹§θ⌕υ⌊υ
Try it online! Link is to verbose version of code. Takes input as a string of digits 1-5 representing Wood, Water, Metal, Soil, Fire. Explanation:
Fθ
Loop over each digit.
⊞υ↨E²№θI﹪⁺κ⊕ι⁵±¹
Count the number of times the incremented and double incremented digit appears (modulo 5) in the input string, and take the difference (but the wrong way around, so that the points are negated).
§θ⌕υ⌊υ
Output the digit with the minimum negated points.
05AB1E, 16 14 12 bytes
Σ-5%2LδQÆO}θ
Mapping: Wood=1; Water=2; Metal=3; Soil=4; Fire=5.
Try it online or verify all possible combinations.
Explanation:
Σ # Sort the (implicit) input-triplet by:
- # Subtract the current value from each value in the (implicit) input
5% # Modulo-5 each (-4,-3,-2,-1,0,1,2,3,4 becomes 1,2,3,4,0,1,2,3,4)
2L # Push pair [1,2]
δ # Apply double-vectorized:
Q # Equals check
# (==1 are +1 point cases; ==2 are -1 point cases)
Æ # Reduce each inner-most pair of checks by subtracting
O # Sum this triplet together
}θ # After the sort-by: pop and keep the last/maximum item
# (which is output implicitly as result)
Retina 0.8.2, 100 bytes
O`.
$
¶$`
T`d`0670`.+$
.
$*_¶
O$^`(_+)(?=¶+\1(_)\b)?((?!(¶+_+)*¶+\1__\b))?
$#2$*1$#3$*
1G`^_{1,5}$
_
Try it online! Takes input as a string of digits 1-5 representing Wood, Water, Metal, Soil, Fire but link is to test suite that converts from and to words for convenience. Explanation:
O`.
Sort the digits.
$
¶$`
Make a copy of the digits.
T`d`0670`.+$
Change 1 and 2 to 6 and 7 and the other copies to 0.
.
$*_¶
Convert to unary.
O$^`(_+)(?=¶+\1(_)\b)?((?!(¶+_+)*¶+\1__\b))?
$#2$*1$#3$*
Sort descending by points plus one ($#3 is 1 if there is no negative action).
1G`^_{1,5}$
Take the first, but take care not to take 6 or 7 by mistake, as they are only used for scoring purposes.
_
Convert to decimal.
Uiua, 22 chars
=⟜/↥×⊃(+1-⊃(↻2|↻1))±/+
Represents the elements as follows:
Fire ← 0_0_0_0_1
Soil ← 0_0_0_1_0
Metal ← 0_0_1_0_0
Water ← 0_1_0_0_0
Wood ← 1_0_0_0_0
Basic explanation:
total = sum(input)
mask = sign(s) # filter non-zero elements
scores = rotate(total, 1) - rotate(total, 2) + 1
masked_scores = scores * mask
max_value = max(masked_scores)
output = max_value == masked_scores