21
\$\begingroup\$

Objective

Given two Chinese ideographs meaning basic colors, output the ideograph that means the color resulting from mixing them.

Basic colors

The basic colors are:

  • 靑(U+9751; blue)
  • 赤(U+8D64; red)
  • 黃(U+9EC3; yellow)
  • 白(U+767D; white)
  • 黑(U+9ED1; black)

Mixed colors

  • Mixing 靑(blue) and 赤(red) yields 靘(U+9758; purple).
  • Mixing 赤(red) and 黃(yellow) yields 熏(U+718F; orange).
  • Mixing 黃(yellow) and 白(white) yields 硅(U+7845; beige).
  • Mixing 白(white) and 黑(black) yields 黻(U+9EFB; grey).
  • Mixing 黑(black) and 靑(blue) yields 黯(U+9EEF; deep blue).
  • Mixing 靑(blue) and 黃(yellow) yields 綠(U+7DA0; green).
  • Mixing 黃(yellow) and 黑(black) yields 騮(U+9A2E; brown).
  • Mixing 黑(black) and 赤(red) yields 紫(U+7D2B; wine red).
  • Mixing 赤(red) and 白(white) yields 紅(U+7D05; pink).
  • Mixing 白(white) and 靑(blue) yields 碧(U+78A7; sky blue).

(This scheme of color terms is historical, and it doesn't reflect the modern usage of Chinese.)

To summarize in Unicode points:

9751, 8D64, 9758
8D64, 9EC3, 718F
9EC3, 767D, 7845
767D, 9ED1, 9EFB
9ED1, 9751, 9EEF
9751, 9EC3, 7DA0
9EC3, 9ED1, 9A2E
9ED1, 8D64, 7D2B
8D64, 767D, 7D05
767D, 9751, 78A7

Rules

I/O format is flexible. In particular, I/O in Unicode points is okay, and outputting trailing whitespace is permitted.

Mixing colors is commutative. It is assumed that the two inputted basic colors are different.

In any case, an input not fitting into your format falls in don't care situation.

Examples

  • Given 靑 and 白, output 碧.
  • Given 赤 and 白, output 紅.
\$\endgroup\$
5

13 Answers 13

19
\$\begingroup\$

Python, 60 bytes

-1 byte thanks to Neil

lambda a,b:' 碧紅騮熏綠硅紫黯黻靘'[abs(a-b)%90%11]

Attempt This Online!

Takes input in Unicode codepoints (integers), and returns a string.

Explanation

Basically, the idea is to "hash" the 2 input values and index into a string of possible outputs. abs(a-b)%90%11 resulted in 10 different indexes for the 10 possible inputs. Generation script

\$\endgroup\$
5
  • \$\begingroup\$ 60 bytes. \$\endgroup\$
    – Neil
    Jul 27, 2023 at 5:58
  • \$\begingroup\$ 59 bytes \$\endgroup\$
    – mousetail
    Jul 27, 2023 at 8:11
  • \$\begingroup\$ @mousetail Needs to be commutative, sorry. \$\endgroup\$
    – Neil
    Jul 27, 2023 at 8:15
  • \$\begingroup\$ 57 bytes, now commutative \$\endgroup\$
    – mousetail
    Jul 27, 2023 at 11:06
  • 4
    \$\begingroup\$ @mousetail Shame that a port of Arnauld's answer is only 55 bytes... \$\endgroup\$
    – Neil
    Jul 27, 2023 at 12:29
17
\$\begingroup\$

Wenyan (文言), 237 bytes

-33 bytes thanks to @tsh.

吾有一術名之曰色欲行是術必先得二數曰「甲」曰「乙」乃行是術曰加甲以乙除其以百六六所餘幾何除其以十一所餘幾何夫『靘黯碧熏硅硅紫紅黻綠』之其乃得矣是謂「色」之術也

Expects two code points.

Based on @Arnauld's Javascript answer, but uses (a+b)%166%11 instead of a*b%25%11, because Wenyan is 1-indexed.

You can try it on this Online IDE. Here is a full test program:

吾有一術名之曰色欲行是術必先得二數曰「甲」曰「乙」乃行是術曰加甲以乙除其以百六六所餘幾何除其以十一所餘幾何夫『靘黯碧熏硅硅紫紅黻綠』之其乃得矣是謂「色」之術也

有數三萬八千七百三十七。名之曰「靑」。
有數三萬六千一百九十六。名之曰「赤」。
有數四萬零六百四十三。名之曰「黃」。
有數三萬零三百三十三。名之曰「白」。
有數四萬零六百五十七。名之曰「黑」。

施「色」於「靑」於「赤」。書之。
施「色」於「赤」於「黃」。書之。
施「色」於「黃」於「白」。書之。
施「色」於「白」於「黑」。書之。
施「色」於「黑」於「靑」。書之。
施「色」於「靑」於「黃」。書之。
施「色」於「黃」於「黑」。書之。
施「色」於「黑」於「赤」。書之。
施「色」於「赤」於「白」。書之。
施「色」於「白」於「靑」。書之。
\$\endgroup\$
1
  • \$\begingroup\$ @tsh It seems that some 「……」 cannot be omitted on the online IDE. \$\endgroup\$
    – alephalpha
    Jul 27, 2023 at 13:08
12
\$\begingroup\$

JavaScript (ES6), 50 bytes

Expects two code points as (a)(b).

a=>b=>"紫騮靘熏X綠黻紅硅黯碧"[a*b%25%11]

Try it online!

How?

Short modulo chains exist for all simple commutative operations (addition, multiplication, XOR and even OR). The benefit of using a multiplication is that no parentheses are required.

It's also interesting to note that we still have enough information when reducing both code points modulo 9:

a=>b=>"XX碧紫紅黯靘黻X綠X硅騮XX熏"[a%9^b%9]

Try it online! (53 bytes)

\$\endgroup\$
0
5
\$\begingroup\$

05AB1E, 33 bytes

α90%•MÚöć'wSlé∞‘cP₃$«¢Γå"α•5ô0šsè

I/O as codepoint integers.

Port of @SuperStormer's Python answer.

Try it online or verify all test cases.

Explanation:

α        # Get the absolute difference of the two (implicit) input codepoint-integers
 90%     # Modulo-90
•MÚöć'wSlé∞‘cP₃$«¢Γå"α•
        '# Push compressed integer 30887320053947029071321603078932043406874069938744
 5ô      # Split it into parts of size 5
   0š    # Prepend a dummy 0
     s   # Swap so the earlier abs(a-b)%90 is at the top of the stack
      è  # 0-based modular index it into this list
         # (after which the result is output implicitly)

See this 05AB1E tip of mine (section How to compress large integers?) to understand why •MÚöć'wSlé∞‘cP₃$«¢Γå"α• is 30887320053947029071321603078932043406874069938744.


Since I was curious: using the actual unicode characters would result in an 18-character program, but it would be 40 bytes in UTF-8 encoding:

α90%" 碧紅騮熏綠硅紫黯黻靘"è

Input as codepoint integers, output as Chinese character.

Try it online.

\$\endgroup\$
4
\$\begingroup\$

Nibbles, 31 30 bytes (60 nibbles)

Edit: -1 byte thanks to xigoi

=%!=$@90:`D 40960 $ 1c179f3cec8cb05803cd69a25df3d95bf5d7758

Attempt This Online!

Port of SuperStormer's Python answer - upvote that.
Input and output as Unicode points.

=%!=$@90:`D 40960 $ 
         `D         # interpret the appended data
            40960   # in base 40960
                    # (so generates 10x 2-byte values);
        :         $ # append the input
=                   # and index into this list using
  !=                # absolute difference
    $@              # of inputs
 %    90            # modulo-90

Nibbles, 44 bytes (88 nibbles)

=%!=$@90.`/3`D256+' '$ c78287c79465c9888ec7666fc79680c78165c7948bc99b8fc99b9bc97d7858

Attempt This Online!

Input and output as Chinese characters.

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

Charcoal, 55 51 bytes

F²⊞υ﹪﹪℅S³¹¦⁵℅I§⪪§⪪”)‴φ<ΦηA∧⌊✂⮌.\`P⁷⸿⁼DT⟦8'R&C”¶⌊υ⁵⌈υ

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

F²⊞υ﹪﹪℅S³¹¦⁵

Input the code points and reduce them modulo 31 and 5 to get them into the range 0-4.

℅I§⪪§⪪”)‴φ<ΦηA∧⌊✂⮌.\`P⁷⸿⁼DT⟦8'R&C”¶⌊υ⁵⌈υ

Look up the resulting character in a compressed lookup table.

A port of @SuperStormer's method is also 51 bytes:

§ 碧紅騮熏綠硅紫黯黻靘﹪↔⁻℅S℅S⁹⁰

Attempt This Online! Link is to verbose version of code. (TIO unnecessarily quotes the string literal, costing three bytes.)

\$\endgroup\$
2
  • \$\begingroup\$ Why don't you put the 51-byte one at the top? \$\endgroup\$
    – The Thonnu
    Jul 27, 2023 at 8:26
  • 1
    \$\begingroup\$ @TheThonnu ... it is now! \$\endgroup\$
    – Neil
    Jul 27, 2023 at 8:45
2
\$\begingroup\$

Scala 3, 51 bytes

a=>b=>"黻綠黯熏紅紫硅碧騮靘"(a*b%6231%10)

Attempt This Online!

Same modulo trick as @SuperStormer but uses multiplication instead.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ If you use Arnauld's %25%11 you can save 2-bytes for the modulos, while only needing to add a single 1-byte character to the indexed string, so saving 1 in total... \$\endgroup\$ Jul 28, 2023 at 12:07
2
\$\begingroup\$

Ruby, 53 bytes

->n{"紅熏紫 碧綠黯硅靘  黻騮"[n.sum%23%13]}

Try it online!

A function which Takes a string with the two input codepoints, finds a checksum (which for some reason is always even) and performs a mod-fold to hash it down to a number 0..12. This is then used as in index to look up in a string. The output is then returned as a single character.

The imperfect hash means there are 3 wasted spaces in the string, but that only counts as 3 bytes total (the Chinese characters on the other hand are 3 bytes each.)

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

Wolfram Language(Mathematica), 105 bytes

Port of @SuperStormer's Python answer in Mathematica.


Golfed version, Try it online!

105 bytes, it can be golfed much more.

f[a_,b_]:=FromCharacterCode@ToCharacterCode["碧紅騮熏綠硅紫黯黻靘"][[Mod[Mod[Abs[a-b],90],11]]]

Ungolfed version. Try it online!

f[a_, b_] := 
  FromCharacterCode[
   ToCharacterCode["碧紅騮熏綠硅紫黯黻靘"][[((Abs[a - b]~Mod~ 90 )~Mod ~11)]]];

repl = {{"靑", "赤", "靘"}, {"赤", "黃", "熏"}, {"黃", "白", "硅"}, {"白", "黑", 
    "黻"}, {"黑", "靑", "黯"}, {"靑", "黃", "綠"}, {"黃", "黑", "騮"}, {"黑", 
    "赤", "紫"}, {"赤", "白", "紅"}, {"白", "靑", "碧"}};

Table[a = repl[[i, 1]]; b = repl[[i, 2]]; c = repl[[i, 3]]; 
  res = f[ToCharacterCode[a][[1]], ToCharacterCode[b][[1]]]; 
  Print[a, " ", b, " ", c, " ", res], {i, Length[repl]}];
\$\endgroup\$
2
\$\begingroup\$

C (gcc), 61 bytes

f(a,b){a=L" 碧紅騮熏綠硅紫黯黻靘"[abs(a-b)%90%11];}

Try it online!

Port of @SuperStormer's Python submission

Thanks to @Neil for knowing how to print multibyte characters, and to @Kevin Cruijssen for pointing out that my byte count was wrong.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ I don't know gcc, but does it have a custom encoding? This seems to be 41 characters, but 61 bytes (in UTF-8)? \$\endgroup\$ Jul 27, 2023 at 8:29
  • \$\begingroup\$ @KevinCruijssen Weird, TIO defaults to SBCS for gcc for some reason... \$\endgroup\$
    – Neil
    Jul 27, 2023 at 8:35
  • 1
    \$\begingroup\$ How to print wide characters. \$\endgroup\$
    – Neil
    Jul 27, 2023 at 8:35
  • 2
    \$\begingroup\$ I believe this is 51 bytes if it can be compiled using Big5. Otherwise, it should be 61 bytes for UTF-8. \$\endgroup\$
    – tsh
    Jul 27, 2023 at 12:44
  • 2
    \$\begingroup\$ @KevinCruijssen Sorry, I should have thought about that - I just copied the code golf submission from TIO. I've corrected the header now :) \$\endgroup\$
    – Peter
    Jul 27, 2023 at 19:49
1
\$\begingroup\$

Thunno 2, 32 bytes

ṛ90%»æḳṫƈe:÷/ċWƊ&ıZbȥƙNỵ`@»Ṙ⁵0Ƥi

Try it online!

Port of @SuperStormer's Python answer. I/O as codepoints.

Just in case you're wondering:

Thunno 2, 39 bytes (UTF-8)

-A90%" 碧紅騮熏綠硅紫黯黻靘"i

Try it online!

Input as codepoints, outputs the character.

Explanation

ṛ90%»...»Ṙ⁵0Ƥi  # Implicit input
ṛ               # Absolute difference
 90%            # Mod 90
    »...»Ṙ      # Compressed number
          ⁵     # Split into chunks of length 5
           0Ƥ   # With a 0 prepended
             i  # Index into the list
                # Implicit output
\$\endgroup\$
1
\$\begingroup\$

Vyxal, 33 bytes

ε90%»æ↲‡ẇf;ƈ0£Xġ'ɾ[c₆⟨OɖaA»S5ẇ0pi

Try it Online!

Port of @SuperStormer's Python answer. I/O as codepoints.

Explanation

ε90%»...»S5ẇ0pi  # Implicit input
ε                # Absolute difference
 90%             # Mod 90
    »...»S       # Compressed number
          5ẇ     # Split into chunks of length 5
            0p   # With a 0 prepended
              i  # Index into the list
                 # Implicit output
\$\endgroup\$
1
\$\begingroup\$

Go, 78 bytes

func(a,b rune)rune{return[]rune("紫騮靘熏X綠黻紅硅黯碧")[a*b%25%11]}

Attempt This Online!

Port of @Arnauld's answer.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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