13
\$\begingroup\$

In Emoji Math, a user created module for the video game Keep Talking And Nobody Explodes, numbers are written as strings of emoticons, where each emoticon represents a base 10 digit. Below is the conversion table between digits and emoticons.

Digit | Emoticon
  0   |    :) 
  1   |    =(  
  2   |    (: 
  3   |    )=  
  4   |    :(    
  5   |    ):  
  6   |    =)  
  7   |    (= 
  8   |    :|  
  9   |    |: 

Given a number, output it in Emoji Math encoding. You may assume the absence of non-numeric characters.

This is , so the shortest answer in bytes wins.

\$\endgroup\$
  • 4
    \$\begingroup\$ Are we allowed to take the input number as a string? \$\endgroup\$ – Tau May 5 '19 at 16:43
  • 3
    \$\begingroup\$ ... Or an array of digits. \$\endgroup\$ – Shaggy May 5 '19 at 18:57
  • 1
    \$\begingroup\$ @Tau sounds like the intention was to accept a string - "You may assume the absence of non-numeric characters."; we should be asking "May we take the input as an integer?" \$\endgroup\$ – Jonathan Allan May 6 '19 at 11:29
  • 1
    \$\begingroup\$ I've voted to close as unclear until the points above are addressed. But don't hesitate to ping me once it's fixed so that I can retract my vote or vote to reopen. \$\endgroup\$ – Arnauld May 7 '19 at 10:30
  • 1
    \$\begingroup\$ @Tau I was asking because of this. The OP needs to answer. \$\endgroup\$ – mbomb007 May 7 '19 at 19:39

17 Answers 17

5
\$\begingroup\$

Japt, 29 24 bytes

-5 bytes thanks to @Shaggy

s":)=((:)=:():=)(=:||:"ò

Takes input as a string

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Welcome to Japt :) m@ can be replaced with £ to save a byte. But this can be done in 24 bytes using base conversion. \$\endgroup\$ – Shaggy May 5 '19 at 16:06
  • \$\begingroup\$ Oops, seems this isn't actually your first Japt solution! You do still qualify for this bounty, though, if you want to try for it. \$\endgroup\$ – Shaggy May 5 '19 at 18:58
5
\$\begingroup\$

C (gcc), 62 58 bytes

-4 bytes thanks to ceilingcat

f(n){n&&write(1,":)=((:)=:():=)(=:||:"+n%10*2,2,f(n/10));}

Try it online!

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

05AB1E, 26 bytes

"|:(=):)=:)"2ôºJ2ô`Šr)sSèJ

Try it online!

\$\endgroup\$
  • \$\begingroup\$ This is not working for numbers with multiple digits. \$\endgroup\$ – izlin May 7 '19 at 6:55
  • 1
    \$\begingroup\$ @izlin: Indeed. I hadn't realized that was part of the challenge. Fixed now though. Thanks :) \$\endgroup\$ – Emigna May 7 '19 at 8:18
4
\$\begingroup\$

Python 2, 65 62 bytes

lambda n:''.join(':=():)=(:|)(:=(:)=|:'[int(c)::10]for c in n)

Try it online!

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

TI-BASIC, 79 bytes

Ans→Str1:" :For(I,1,length(Str1:Ans+sub(":)=((:)=:():=)(=:||:",1+2expr(sub(Str1,I,1)),2:End:sub(Ans,2,length(Ans)-1

Input is a string of digits in Ans.
Output is the Emoji Math-encoded number.

Examples:

"134
134
prgmCDGF1C
:)(:)=
"2213894
2213894
prgmCDGF1C
(:(:=()=:||::(

Explanation:

Ans→Str1                                                 ;store the input in Ans
"                                                        ;leave " " in Ans
For(I,1,length(Str1                                      ;loop over each character in the
                                                         ; input string
Ans+sub(":)=((:)=:():=)(=:||:",1+2expr(sub(Str1,I,1)),2  ;convert the current character
                                                         ; to a number and use it as the
                                                         ; index into the encoding string
                                                         ; then append the encoded digit
End
sub(Ans,2,length(Ans)-1                                  ;remove the prepended space and
                                                         ; store the result in Ans
                                                         ;implicit print of Ans

Alternatively, here's a 94 byte solution that takes a number as input instead of a string:

int(10fPart(Ans₁₀^(seq(⁻X-1,X,0,log(Ans→L₁:" :For(I,dim(L₁),1,-1:Ans+sub(":)=((:)=:():=)(=:||:",1+2L₁(I),2:End:sub(Ans,2,length(Ans)-1

Examples:

134
             134
prgmCDGF1C
:)(:)=
2213894
         2213894
prgmCDGF1C
(:(:=()=:||::(

Explanation:

int(10fPart(Ans₁₀^(seq(⁻X-1,X,0,log(Ans→L₁     ;generate a list of the input's digits
                                             ; reversed and store it in L₁
"                                            ;leave " " in Ans
For(I,dim(L₁),1,-1                            ;loop over L₁ backwards
Ans+sub(":)=((:)=:():=)(=:||:",1+2L₁(I),2     ;use the value of the I-th element in L₁ as
                                              ; the index into the encoding string then
                                              ; append the encoded digit
End
sub(Ans,2,length(Ans)-1                       ;remove the prepended space and store the
                                              ; result in Ans
                                              ;implicit print of Ans

Notes:

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

Perl 5 -p, 42 bytes

s/./substr":)=((:)=:():=)(=:||:",$&*2,2/ge

Try it online!

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

Java 8, 80 bytes

n->n.forEach(i->System.out.print(":)=((:)=:():=)(=:||:".split("(?<=\\G..)")[i]))

Try it online.

Explanation:

n->                           // Method with IntStream parameter and no return-type
  n.forEach(i->               //  For each digit `i` in the input:
    System.out.print(         //   Print without newline:
      ":)=((:)=:():=)(=:||:"  //    Push this String
        .split("(?<=\\G..)")  //    Split into parts of size 2
          [i]))               //    And print the `i`'th part
\$\endgroup\$
3
\$\begingroup\$

JS ES6, 77 66 bytes

Down to 66 thanks to suggestions from @Charlie Harding and @asgallant

Had to finally make an account on codegolf since this was such a fun little challenge!

The most minimal form of the original answer, when expecting string-only input:

n=>[...n].map(c=>":)=((:)=:():=)(=:||:".match(/../g)[c]).join("")

Secondly, my original answer which uses a longer regex and first coerces the input into a string, This works with both number type input and a string of digits input.

I first coerce the input into a string, which is then destructured into an array using es6 spread. Then I map it through a matcher cb that grabs the correct emoticon from an array made with the regex /.{1,2}/g. Finally the resulting array of emoticons is joined back to a string.

n=>[...(""+n)].map(c=>":)=((:)=:():=)(=:||:".match(/.{1,2}/g)[c]).join("")

JS array stuff is fun. I'm sure there's still some room for optimization, this re-matches the regex on every loop of the map.

Crappily tested with the following:

let emoticonize = n=>[...(""+n)].map(c=>":)=((:)=:():=)(=:||:".match(/../g)[c]).join("")

let test = arr => 
console.log(arr.map(x => ({ask:x, ans: emoticonize(x)})))

test([1,40,3697, 2330])
test(["1","40","3697", "2330"])

\$\endgroup\$
  • 1
    \$\begingroup\$ Why are there spaces around the => arrow in the map? That could save two bytes, couldn't it? \$\endgroup\$ – Charlie Harding May 6 '19 at 14:38
  • 1
    \$\begingroup\$ And I believe the regex /../g does the same job too, saving another four bytes \$\endgroup\$ – Charlie Harding May 6 '19 at 14:41
  • \$\begingroup\$ Finally, if the input is necessarily a string then [...(""+n)] can be simplified to [...n], saving a further five bytes \$\endgroup\$ – Charlie Harding May 6 '19 at 14:46
  • 1
    \$\begingroup\$ map and regex search is actually costing you characters here; replace and substr work just as well, with fewer characters: 58 bytes: n=>n.replace(/./g,c=>':)=((:)=:():=)(=:||:'.substr(2*c,2)), assuming input as a string of digits. \$\endgroup\$ – asgallant May 6 '19 at 17:22
  • \$\begingroup\$ man, that's a neat way to use replace @asgallant! Seems I gotta get to know my string functions as well :) \$\endgroup\$ – Roope May 6 '19 at 18:44
3
\$\begingroup\$

Haskell, 64 56Laikoni bytes

((words":) =( (: )= :( ): =) (= :| |: "!!).read.pure=<<)

Try it online

Ungolfed

Apply the function words to our space-separated string of symbols ":) =( (: )= :( ): =) (= :| |: " to get a list, and get the nth element (!!) for every n in our input string, combining the results. n.b. (=<<) is equivalent to concatMap in this case, mapping a string to a list of strings and concatenating the results. read . pure converts a character to an int, by lifting a character to a string, then reading to an int.

f x = ((words ":) =( (: )= :( ): =) (= :| |: " !!) . read . pure) =<< x
\$\endgroup\$
3
\$\begingroup\$

[R], 59 48 bytes

different approach:

 substr(":)=((:)=:():=)(=:||:",n<-2*scan()+1,n+1)

thanks to @aaron for directing me on again :)

original:

 el(strsplit(":)x=(x(:x)=x:(x):x=)x(=x:|x|:","x",T))[scan()]

beats

 c(":)","=(","(:",")=",":(","):","=)","(=",":|","|:")[scan()]

by 1 byte

\$\endgroup\$
  • 1
    \$\begingroup\$ The different approach is a bit off, you need to add one to the doubled scanned number 2*scan()+1, with a bit of rearrangement though you can still keep it as 48 bytes. Try it online! \$\endgroup\$ – Aaron Hayman May 7 '19 at 10:27
2
\$\begingroup\$

Jelly, 21 bytes

“=:)|(”“ØḟƝoṣẈ’ṃs2ị@D

Try it online!

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

PowerShell, 64 60 59 bytes

-1 byte thanks to mazzy

-join($args|% t*y|%{':)=((:)=:():=)(=:||:'|% S*g(2*"$_")2})

Try it online!

Takes a string, splits it in toCharArray, and then indexes into the emoji key by casting the character to its numerical value, doubles it because each emoji is two wide, and then takes the substring from that spot plus one higher. Finally it joins this all up into one string and pushes it to output.

\$\endgroup\$
  • 1
    \$\begingroup\$ 59 bytes \$\endgroup\$ – mazzy May 6 '19 at 18:38
  • \$\begingroup\$ @mazzy Yeah, I spaced on how to cast to int without getting the ASCII value, thanks. \$\endgroup\$ – Veskah May 6 '19 at 19:15
2
\$\begingroup\$

Icon, 78 75 bytes

procedure f(n);s:="";s||:=":)=((:)=:():=)(=:||:"[!n*2+1+:2]&/n;return s;end

Try it online!

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

C# (Visual C# Interactive Compiler), 87, 86, 82, 67 bytes

Props to @Artholl and @someone for helping to optimize

n=>$"{n}".SelectMany(x=>":)=((:)=:():=)(=:||:".Substring(x*2-96,2))

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ You can save 2 bytes. 1 byte if you use Substring instead of Skip & Take and 1 byte if you hardcode the zero char value. \$\endgroup\$ – Artholl May 7 '19 at 9:12
  • \$\begingroup\$ @Artholl thank you! Could you show me what you mean by hardcoding the zero char value? \$\endgroup\$ – Innat3 May 7 '19 at 9:40
  • \$\begingroup\$ As you can see in the example. Just write 48 instead of '0'. \$\endgroup\$ – Artholl May 7 '19 at 9:42
  • \$\begingroup\$ Several simple optimizations; 67 bytes. Try it online! \$\endgroup\$ – my pronoun is monicareinstate May 7 '19 at 9:59
  • 1
    \$\begingroup\$ @someone didn't know changing the type of output was allowed outside of the function \$\endgroup\$ – Innat3 May 7 '19 at 10:15
1
\$\begingroup\$

JavaScript (ES6), 87 bytes

n=>{for(s=":)=((:)=:():=)(=:||:",i=0;i<20;)n=n.split(i/2).join(s[i++]+s[i++]);return n}
\$\endgroup\$
  • \$\begingroup\$ This outputs ): instead of (: for 3 \$\endgroup\$ – Herman L May 5 '19 at 15:46
  • \$\begingroup\$ @Herman L Yes, thanks! \$\endgroup\$ – Naruyoko May 5 '19 at 18:41
1
\$\begingroup\$

Jelly, 24 bytes

“LƇ§×Yþ’ḃ5$s2ị“:)=(|”ị@D

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Attache, 34 bytes

Chop[":)=((:)=:():=)(=:||:",2]&Get

Try it online!

\$\endgroup\$

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