13
\$\begingroup\$

Background

Wuxings(五行) are the five "elements" in Chinese philosophy. They are Fire(火), Water(水), Wood(木), Metal(金), and Soil(土). You can find them on East Asian calendar, where some days (Tuesday through Saturday) are named by the Wuxings.

Some Korean names are given according to Wuxings, so that father's name will have a positive effect to his children. Let's simulate that.

Positive actions

  • Fire fertilizes Soil.
  • Soil incubates Metal.
  • Metal is a container for Water.
  • Water nourishes Wood.
  • Wood fuels Fire.

Negative actions

These are irrelevent to this challenge, but I'm showing them anyway.

  • Fire melts Metal.
  • Metal chops Wood.
  • Wood penetrates Soil.
  • Soil blocks Water.
  • Water extinguishes Fire.

Ideographs

Some ideographs have a Wuxing as its radical. Here, only the CJK Ideographs(U+4E00–U+9FFF), a Unicode block, will be considered as of Unicode 1.0.1.

  • 火(U+706B)–爩(U+7229) have Fire as the radical.

  • 水(U+6C34)–灪(U+706A) have Water as the radical.

  • 木(U+6728)–欟(U+6B1F) have Wood as the radical.

  • 金(U+91D1)–钄(U+9484) have Metal as the radical.

  • 土(U+571F)–壪(U+58EA) have Soil as the radical.

  • All other characters fall in don't care situation.

Notes

  • Some characters, in Unicode's own dictionary, disagree with the categorization above. For example, 泵(U+6CF5) actually doesn't have Water as its radical, but rather "石". For another example, 渠(U+6E20) has ambiguous radical, Water or Wood. Such characters also fall in don't care situation.

  • After Unicode 1.0.1, Unicode added more characters that has a Wuxing as their radical to the block and other blocks. For example, 龦(U+9FA6) also has Fire as its radical. This detail shall be ignored in this challenge, and such characters also fall in don't care situation.

Objective

Given an ideograph having a Wuxing \$W\$ as its radical, output any ideograph whose radical will be positively acted by \$W\$.

Examples

Given 溒(U+6E92), it has Water as its radical, so output any ideograph having Wood as its radical, since Water nourishes Wood. For example, 杜(U+675C).

Given 坽(U+577D), it has Soil as its radical, so output any ideograph having Metal as its radical, since Soil incubates Metal. For example, 鉺(U+927A).

\$\endgroup\$
8
  • 2
    \$\begingroup\$ I was half-tempted to do a similar challenge with Genshin Impact elemental reactions. :-p \$\endgroup\$ – Arnauld Nov 7 '20 at 9:45
  • \$\begingroup\$ Is it acceptable to take / return integers instead of Unicode characters? (This is probably the only way to go in some languages.) \$\endgroup\$ – Arnauld Nov 7 '20 at 9:56
  • 2
    \$\begingroup\$ @pxeger I'm not entitled to answer this question but I was thinking about Unicode codepoints, as it would drastically simplify the challenge otherwise. \$\endgroup\$ – Arnauld Nov 7 '20 at 10:21
  • 1
    \$\begingroup\$ @pxeger Just like Arnauld said. \$\endgroup\$ – Dannyu NDos Nov 7 '20 at 10:25
  • 6
    \$\begingroup\$ Next time I accidentally spill water on the wooden floor in the living room, I'll see it as a positive action. :-p \$\endgroup\$ – Arnauld Nov 7 '20 at 15:30
5
\$\begingroup\$

Jelly, 18 bytes

“Ọ{ƊɠṪƲ‘ɓ:Ḣ<Sịɗ‘×Ḣ

A monadic Link accepting an ordinal which yields an ordinal as below:

Input                           Output
Fire   (28779 火 - 29225 爩)    22444  垬  (Soil)
Soil   (22303 土 - 22762 壪)    37467  鉛  (Metal)
Metal  (37329 金 - 38020 钄)    27874  波  (Water)
Water  (27700 水 - 28778 灪)    26426  机  (Wood)
Wood   (26408 木 - 27423 欟)    28960  焠  (Fire)

Try it online! Or see all valid cases.

How?

Integer dividing by \$181\$:

  1. keeps the ranges distinct
  2. reduces all values to less than \$256\$
  3. has more than one result for each range
  4. has a single result greater than \$181\$

This allows us to place all our magic numbers into a single list of code-page indices, using these for the integer division, the category identification, a lookup of the new category, and a final multiplication:

“Ọ{ƊɠṪƲ‘ɓ:Ḣ<Sịɗ‘×Ḣ - Link: ordinal, n       e.g. n = 27700 (木 - minimal Water)
“Ọ{ƊɠṪƲ‘           - code-page indices (call this M) [181,123,145,159,206,153]
        ɓ          - new dyadic chain - f(n,M):
         :         -   integer divide                [27700//181, 27700//123,...]
          Ḣ        -   head (call this x)            27700//181 = 153
              ɗ    -   last three links as a dyad - f(x, M):
           <       -     (x) less than? (M)          [1, 0, 0, 1, 1, 0]
            S      -     sum                         3
             ị     -     index into (M)              145
               ‘   -   increment                     146
                ×  -   multiply (M)                  [146×181, 146×123, ...]
                 Ḣ -   head                          146×181 = 26426 (机 - a Wood)
\$\endgroup\$
8
\$\begingroup\$

JavaScript (Node.js), 39 bytes

I/O: Unicode codepoints as integers.

n=>Buffer("99944,777I")[n/543%62&15]<<9

Try it online!

How?

Step 1

We first look for some divisor \$d\$ such that the following element sets \$S_k\$ are disjoint:

$$S_k=\left\{\left\lfloor\dfrac{n}{d}\right\rfloor,\:C_{min}(k)\le n\le C_{max}(k)\right\}$$

where \$C_{min}(k)\$ and \$C_{max}(k)\$ are the codepoint bounds of the \$k\$-th element.

Because the Unicode range of Water (U+6C34 to U+706A) is immediately followed by the Unicode range of Fire (U+706B to U+7229), there are not many possible options for \$d\$: it must be a proper divisor of \$28779\$ (0x706B), i.e. \$d\in\{1, 3, 53, 159, 181, 543, 9593\}\$. The best value in there that actually works is \$d=543\$.

Step 2

We then look for some modulo chain that takes \$n\$ as input and turns it into an index corresponding to the counterpart element, using \$n/543\$. Instead of rounding the result towards zero, we force the last operation to a bitwise AND rather than a modulo.

A quick brute-force search leads to:

$$f(n)=((n/543)\bmod 62)\operatorname{and}15$$

Step 3

Finally, we look for some multiplier \$m\$ such that there exists some \$q_k\$ for each \$k\$ that satisfies:

$$C_{min}(k)\le q_k\times m\le C_{max}(k)$$

One possible golf-friendly value is \$m=512\$, leading to the following table:

 element | hexa range      | q  | q*512 | as hexa
---------+-----------------+----+-------+---------
  Soil   | 0x571F - 0x58EA | 44 | 22528 | 0x5800
  Wood   | 0x6728 - 0x6B1F | 52 | 26624 | 0x6800
  Water  | 0x6C34 - 0x706A | 55 | 28160 | 0x6E00
  Fire   | 0x706B - 0x7229 | 57 | 29184 | 0x7200
  Metal  | 0x91D1 - 0x9484 | 73 | 37376 | 0x9200

The values of \$q\$ are encoded as the ASCII codes of ,479I.

\$\endgroup\$
6
\$\begingroup\$

Haskell, 51 bytes

w x="金火林土水"!!sum[1|c<-"朧氳灪釐",x>c]

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Charcoal, 28 25 bytes

℅×⊘φ℅§6-L888   :::6÷℅S⁵⁴³

Try it online! Link is to verbose version of code. Explanation: Takes the ordinal of the input, integer divides by 543, cyclically indexes into the lookup table, takes the ordinal of that character, multiplies by 500, and converts back to Unicode.

I tried to reduce the size of the lookup table but although subtracting 3 and dividing by 654 allowed me to reduce it by 2 bytes it cost 3 bytes to subtract 3, so it didn't help.

\$\endgroup\$
2
\$\begingroup\$

Python 3.8 (pre-release), 99 91 bytes

lambda c:{k:v for v,r in zip("水土木火金","钅爪火欠士")for k in range(ord(r))}[c]

Try it online!

-8 bytes thanks to @ovs

Input as an integer representing a unicode codepoint, output as a length-1 string.


Python 3.8 (pre-release), 40 bytes

lambda n:b"MMMFF<JJJc"[n//543%62&15]*378

Try it online!

Shameless copy of @Arnauld's answer

\$\endgroup\$
2
  • 1
    \$\begingroup\$ 91 bytes \$\endgroup\$ – ovs Nov 7 '20 at 18:38
  • \$\begingroup\$ @ovs goes to show how bad tunnel vision is \$\endgroup\$ – pxeger Nov 7 '20 at 18:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.