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


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.


  • Given 靑 and 白, output 碧.
  • Given 赤 and 白, output 紅.

13 Answers 13


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.


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

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

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:



  • \$\begingroup\$ @tsh It seems that some 「……」 cannot be omitted on the online IDE. \$\endgroup\$
    – alephalpha
    Commented Jul 27, 2023 at 13:08

JavaScript (ES6), 50 bytes

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


Try it online!


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:


Try it online! (53 bytes)


05AB1E, 33 bytes


I/O as codepoint integers.

Port of @SuperStormer's Python answer.

Try it online or verify all test cases.


α        # Get the absolute difference of the two (implicit) input codepoint-integers
 90%     # Modulo-90
        '# 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.


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.


Charcoal, 55 51 bytes


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


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


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.)

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

Scala 3, 51 bytes


Attempt This Online!

Same modulo trick as @SuperStormer but uses multiplication instead.

  • 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\$ Commented Jul 28, 2023 at 12:07

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.)


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.


Ungolfed version. Try it online!

f[a_, b_] := 
   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]}];

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.

  • 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\$ Commented Jul 27, 2023 at 8:29
  • \$\begingroup\$ @KevinCruijssen Weird, TIO defaults to SBCS for gcc for some reason... \$\endgroup\$
    – Neil
    Commented Jul 27, 2023 at 8:35
  • 1
    \$\begingroup\$ How to print wide characters. \$\endgroup\$
    – Neil
    Commented 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
    Commented 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
    Commented Jul 27, 2023 at 19:49

Thunno 2, 32 bytes


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.


ṛ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

Vyxal, 33 bytes


Try it Online!

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


ε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

Go, 78 bytes

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

Attempt This Online!

Port of @Arnauld's answer.


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.