14
\$\begingroup\$

Introduction

My gnome friends are writing a programming language and have asked for my help. Due to their size, the gnomes can only handle small superscript numbers instead of big numbers. However, the language they're writing the interpreter in only accepts big numbers!

Your Challenge

Given an input of a superscript number (a series of characters that can be any of ⁰¹²³⁴⁵⁶⁷⁸⁹), convert it to normal ASCII numbers and print the result. This is code golf, so shortest answer wins!

Test Cases

¹ -> 1
⁵ -> 5
¹²³ -> 123
⁶⁵⁵³⁵ -> 65535
⁰¹²³ -> 123
\$\endgroup\$
15
  • 4
    \$\begingroup\$ The reason that I ask is that I'm not absolutely confident that by copy-pasting from your question in my internet browser will give the correct characters. Please could you specify in the question exactly what the characters should (or could) be? \$\endgroup\$ Dec 13, 2021 at 14:07
  • 2
    \$\begingroup\$ @DominicvanEssen Sure. The characters have unicode codepoints 2070, 00B9, 00B2, 2074, 2075, 2076, 2077, 2078, and 2079. \$\endgroup\$
    – Ginger
    Dec 13, 2021 at 14:09
  • 4
    \$\begingroup\$ Can we return a list of digits? \$\endgroup\$ Dec 13, 2021 at 18:48
  • 11
    \$\begingroup\$ The new test case is invalidating most answers. :-/ \$\endgroup\$
    – Arnauld
    Dec 14, 2021 at 0:08
  • 4
    \$\begingroup\$ ord(⁰) = 8304, ord(¹) = 185, ord(²) = 178... Unicode, you're drunk. -.- \$\endgroup\$
    – Trang Oul
    Dec 14, 2021 at 7:02

31 Answers 31

12
\$\begingroup\$

JavaScript, 20 bytes

s=>s.normalize`NFKD`

Try it online!

\$\endgroup\$
1
  • 5
    \$\begingroup\$ +1 for finding the builtin. \$\endgroup\$
    – Neil
    Dec 13, 2021 at 19:44
12
\$\begingroup\$

JavaScript (ES6), 43 bytes

Edit: +1 to support 0123 -> 123 ...

s=>+s.replace(/./g,c=>c.charCodeAt()%92%12)

Try it online!

Conversion table

 char. | code | mod 92 | mod 12
-------+------+--------+--------
  '⁰'  | 8304 |   24   |   0
  '¹'  |  185 |    1   |   1
  '²'  |  178 |   86   |   2
  '³'  |  179 |   87   |   3
  '⁴'  | 8308 |   28   |   4
  '⁵'  | 8309 |   29   |   5
  '⁶'  | 8310 |   30   |   6
  '⁷'  | 8311 |   31   |   7
  '⁸'  | 8312 |   32   |   8
  '⁹'  | 8313 |   33   |   9
\$\endgroup\$
2
  • \$\begingroup\$ For the second one, you can get away with c/58&c . \$\endgroup\$ Dec 13, 2021 at 23:49
  • \$\begingroup\$ @dingledooper Nice one! There's also c%12&c (found by Lynn). Unfortunately, the challenge update and OP comments suggest that this kind of answer is not valid anymore, so I'm removing it for now. \$\endgroup\$
    – Arnauld
    Dec 14, 2021 at 0:16
8
\$\begingroup\$

R, 45 53 51 bytes

Edit +8 bytes to comply with the updated rules (0123 -> 123), but then -2 bytes thanks to pajonk

function(s)el(chartr("⁰¹²³⁴-⁹","0-9",s):1)

Try it online!


R, 53 51 57 bytes / 25 bytes with IO as character codes

Edit: -4 bytes thanks to pajonk, but then +6 bytes (again thanks to pajonk) to comply with the updated rules

function(s,x=utf8ToInt(s))el(intToUtf8(x%%64-8*!x-185):1)

Try it online!

Function without multi-byte character codes, but sadly the verbose utf8ToInt and intToUtf8 function names make it quite long if we want to accept input directly as a string...

The new rule that ⁰¹²³ should output 123 invalidates the second version with IO as character codes. It could be fixed for +17 bytes, but it's shorter to completely change approach (below), porting Arnauld's charcode-to-digit method.


R, 40 bytes with IO as character codes

function(c)c%%92%%12%*%10^rev(seq(!c)-1)

Try it online!

\$\endgroup\$
6
  • 1
    \$\begingroup\$ You could save some bytes by I/O as char codes (as is by default allowed for string challenges) by removing utf8ToInt and intToUtf8. \$\endgroup\$
    – pajonk
    Dec 13, 2021 at 15:22
  • \$\begingroup\$ @pajonk - That's an excellent suggestion. Thankyou. Now suddenly the nicer function seems more competitive...! \$\endgroup\$ Dec 13, 2021 at 15:34
  • 2
    \$\begingroup\$ (c==185) -> !c-185 for -2. \$\endgroup\$
    – pajonk
    Dec 13, 2021 at 20:14
  • \$\begingroup\$ @pajonk - Neat! Thanks again! \$\endgroup\$ Dec 13, 2021 at 22:26
  • 1
    \$\begingroup\$ -2 bytes for the chartr method with el(<string>:0). \$\endgroup\$
    – pajonk
    Dec 14, 2021 at 9:51
7
\$\begingroup\$

Charcoal, 2 bytes

IV

Try it online! Explanation:

 V  Eval as a Charcoal integer literal
I   Cast to string
    Implicitly print
\$\endgroup\$
4
  • \$\begingroup\$ verbose code in charcoal? \$\endgroup\$
    – Fmbalbuena
    Dec 13, 2021 at 15:42
  • \$\begingroup\$ @Fmbalbuena Correct me if I'm wrong Neil, but I don't think this program is possible in Verbose Charcoal, since it only has explicit inputs. So it would be Cast(Evaluate(StringInput())) or Cast(Evaluate(q)), which would actually be IVS or IVθ instead of IV. Unless there is a way for implicit inputs in Verbose Charcoal I'm unaware of, perhaps with a certain flag-argument? \$\endgroup\$ Dec 13, 2021 at 15:53
  • 1
    \$\begingroup\$ Ha! Right language for the job. :) \$\endgroup\$
    – DLosc
    Dec 13, 2021 at 17:04
  • 1
    \$\begingroup\$ @KevinCruijssen Technically Cast Evaluate will parse in Verbose mode, but it doesn't really read like normal Verbose Charcoal, so I don't bother in such a case. \$\endgroup\$
    – Neil
    Dec 13, 2021 at 19:40
7
\$\begingroup\$

Jelly, 7 bytes

O%12&ƊḌ

Try it online!

O         Get ordinal values
 %12&Ɗ    Apply x ↦ x%12&x
      Ḍ   Digits to number

I found the x%12&x formula by computer search. If I/O were super duper lenient, I guess %12& would be a valid 4-byte answer.

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

C (gcc), 83 \$\cdots\$ 60 46 bytes

n;f(int*s){for(n=0;*s;)n+=9*n+*s++%92%12;n=n;}

Try it online!

Inputs a pointer to a wchar_t string of superscript numbers.
Returns the normal number.

Discovered the n % 92 % 12 formula independently.

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

Hexagony, side length 4, 37 bytes

92},/%=\_@=..}{<.{\<.>".2//{%.1!}>'/_

Unwrapped code:

    9 2 } ,
   / % = \ _
  @ = . . } {
 < . { \ < . >
  " . 2 / / {
   % . 1 ! }
    > ' / _

Try it on hexagony.net

This is my first post on Code Golf, and first time using Hexagony. It's as painful as the name implies, but so satisfying to get a result! I ended up with more mirrors than I expected, but I'm pretty proud of what I achieved.

Credit to the previous users who worked out the modulo trick. My hexagon would have been a lot bigger without %92%12!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Welcome to Code Golf! I haven't seen a Hexagony answer in ages, glad to see more usage of it! \$\endgroup\$ Dec 15, 2021 at 4:29
  • 1
    \$\begingroup\$ It's rare to see a first post in Hexagony so well done! It doesn't look like is handled correctly though: for inputs of ¹⁰ and ¹⁰¹ I'm seeing outputs of 1 and 11, respectively. \$\endgroup\$
    – Dingus
    Dec 16, 2021 at 4:25
  • \$\begingroup\$ Oh yeah! my test case started with ⁰, so I just didn't print it in order to stop leading zeroes from printing. I'll have to go back and fix it :) \$\endgroup\$
    – Joundill
    Dec 16, 2021 at 4:37
6
\$\begingroup\$

Python 3.8 (pre-release), 46 50 bytes

-1 thanks to ovs!

lambda x:int(x.translate('%7d   45678923'%10*999))

Try it online!

Helper program to generate this: helper

\$\endgroup\$
4
  • \$\begingroup\$ you need an int() around the whole thing \$\endgroup\$
    – Razetime
    Dec 14, 2021 at 8:16
  • \$\begingroup\$ @Razetime other people are outputting as a string so I thought that was alright maybe \$\endgroup\$
    – rak1507
    Dec 14, 2021 at 10:04
  • \$\begingroup\$ You can save a byte with '%7d 45678923'%10*999. But with according to the new test case you will have to add int(...). \$\endgroup\$
    – ovs
    Dec 14, 2021 at 17:22
  • \$\begingroup\$ @ovs nice, clever \$\endgroup\$
    – rak1507
    Dec 15, 2021 at 8:36
5
\$\begingroup\$

Raku, 14 10 11 8 bytes

+1 and +4 to remove leading 0's.

-3 bytes thanks to Moonchild!

+~*.NFKD

Try it online!


Raku -p, 15 19 bytes

-1 byte and -1 flag thanks to Jo King!

$_=+S:g{.}=$/.EVAL

Try it online!

Raku uses superscript digits as exponents, but single digits on their own evaluate to their numeric value.

\$\endgroup\$
5
  • \$\begingroup\$ Can you not then take the 2-log of 2 with that exponent? \$\endgroup\$
    – Adám
    Dec 14, 2021 at 9:46
  • \$\begingroup\$ @Adám Yes that would work, but I think I still need EVAL, and the shortest I can do is {log2 EVAL 2~$_} at 16 bytes (Doesn't work on TIO because of old version) \$\endgroup\$
    – ovs
    Dec 14, 2021 at 10:08
  • \$\begingroup\$ @Adám that would be shorter with removing leading zeros, but as it is not working on TIO and returns Inf for the largest case, I'm not going to include it. {-1+chars EVAL 10~$_} would fix those issues, but is longer again. \$\endgroup\$
    – ovs
    Dec 14, 2021 at 10:52
  • 1
    \$\begingroup\$ I think you can shave off a couple of characters with +~*.NFKD \$\endgroup\$
    – Moonchild
    Dec 16, 2021 at 5:16
  • 1
    \$\begingroup\$ You can use $/ instead of $<> and EVAL as a method to remove that extra flag. I really wish you could do S:g{.}.=&EVAL though \$\endgroup\$
    – Jo King
    Jan 30 at 12:54
4
\$\begingroup\$

Pip, 9 12 bytes

+3 bytes to handle more stringent rules

+:A_%E#A_MJa

Replit! (Note: the Unicode input seems not to play well with Pip's interactive mode, or maybe it's a Replit issue. For best results, Ctrl-C out of the default interactive mode and enter ./pip.py -e A_%E#A_Ma ⁶⁵⁵³⁵ at the command prompt.)

Or, here's a 14-byte equivalent in Pip Classic: Try it online!

Explanation

After some trial and error, I found a really nice property of these numbers' codepoints:

  • ¹, ², and ³ have codepoints 185, 178, and 179. Mod 8 (or 4), these become 1, 2, and 3.
  • The other superscript numbers have codepoints equal to the corresponding digit plus 8304. Mod 16 (or 12, or many other options), these become their respective digits.

So all we need to do is take the codepoint of each digit mod 8 if it's 3 digits and mod 16 if it's 4 digits...

          a  First command-line argument
        MJ   Map this function to each character, joining the results together:
  A_          Codepoint of the character
    %         Mod
     E        2 to the power of
      #       Length of
       A_     Codepoint of the character
+:           Treat the resulting string as a number (removing leading 0s)
\$\endgroup\$
4
\$\begingroup\$

JavaScript, 65 62 61 60 bytes

s=>s.replace(/./g,x=>-~'¹²³⁴⁵⁶⁷⁸⁹'.search(x))

Saved 3 bytes thanks to Neil.

Saved 1 byte thanks to Shaggy.

Saved 1 byte thanks to Arnauld.

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ s=>s.replace(/./g,x=>'⁰¹²³⁴⁵⁶⁷⁸⁹'.indexOf(x)) saves 3 bytes. \$\endgroup\$
    – Neil
    Dec 13, 2021 at 19:50
  • 1
    \$\begingroup\$ Save another byte \$\endgroup\$
    – Shaggy
    Dec 13, 2021 at 21:49
  • 1
    \$\begingroup\$ It should be safe to use search in place of indexOf. \$\endgroup\$
    – Arnauld
    Dec 14, 2021 at 20:15
3
\$\begingroup\$

Python 3, 53 bytes

from unicodedata import*
lambda s:normalize("NFKC",s)

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ if unicodedata module is not bulitin then change Python 3 to Python 3 + Unicodedata \$\endgroup\$
    – Fmbalbuena
    Dec 13, 2021 at 14:11
  • 1
    \$\begingroup\$ @Fmbalbuena I think it is builtin. \$\endgroup\$
    – Bgil Midol
    Dec 13, 2021 at 14:24
  • \$\begingroup\$ Docs. \$\endgroup\$
    – Trang Oul
    Dec 14, 2021 at 6:52
3
\$\begingroup\$

Retina 0.8.2, 19 bytes

T`⁰-⁹_¹²³`dd

Try it online! Link includes test cases. Explanation: d is a shorthand for 0123456789. As ⁰-⁹ expands to ⁰ⁱ⁲⁳⁴⁵⁶⁷⁸⁹, and assuming none of ⁱ⁲⁳ will appear in the input, those supserscript digits will get mapped to ASCII digits, while the _¹²³ gets mapped to 0123 (the remaining digits in d get ignored). _ is actually a placeholder on the LHS and does nothing except to skip 0 on the RHS (on the RHS it causes the character on the LHS to be deleted).

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

Japt -m, 7 bytes

Use Arnauld's formula so be sure to upvote him.

c %#\%C

Try it

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

Vyxal 2.4.1 K, 7 bytes

92%12%ṅ

Try it Online!

The K flag turns input into a list of charcodes and the forms a list of digits. You can probably guess the rest.

Vyxal, 7 bytes

C92%12%

Try it Online!

Port of Arnauld's answer. C stands for charcodes, you can probably guess the rest.

\$\endgroup\$
3
  • \$\begingroup\$ I just commented for clarification that this was allowed before posting it lol, guess I got ninja'd. Sadge, since I already had the answer written up and everything. \$\endgroup\$ Dec 13, 2021 at 18:50
  • \$\begingroup\$ That being said, you can use the K flag in 2.4.1 to get 6 bytes: Try it Online! \$\endgroup\$ Dec 13, 2021 at 18:51
  • \$\begingroup\$ According to OP, I guess a list of digits is invalid, so here's a valid 7 bytes: Try it Online! \$\endgroup\$ Dec 13, 2021 at 18:55
3
\$\begingroup\$

05AB1E, 11 8 bytes

Ç92%12%J

-3 bytes porting @Arnauld's JavaScript method (thanks @Neil for the heads up).

Add a trailing ï (+1 byte) if you want to remove leading 0s..

Try it online or verify all test cases.

Explanation:

Ç         # Convert the (implicit) input to a list of its codepoint-integers
          #  e.g. "⁰¹²³⁴⁵⁶⁷⁸⁹" → [8304,185,178,179,8308,8309,8310,8311,8312,8313]
 92%      # Modulo-92
          #  → [24,1,86,87,28,29,30,31,32,33]
    12%   # Modulo-12
          #  → [0,1,2,3,4,5,6,7,8,9]
       J  # Join the list together
          #  → 0123456789
        ï # (Optionally) Remove leading 0s by casting to an integer
          #  → 123456789
          # (after which the result is output implicitly)
\$\endgroup\$
3
  • \$\begingroup\$ Apparently a list of digits isn't allowed? \$\endgroup\$
    – Neil
    Dec 13, 2021 at 19:53
  • \$\begingroup\$ @Neil Ah ok.. Added a join after it, thanks for the heads up. \$\endgroup\$ Dec 13, 2021 at 21:32
  • 1
    \$\begingroup\$ Also, everyone seems to be porting @Arnauld's answer which I assume would be Ç92%12%J in this case. \$\endgroup\$
    – Neil
    Dec 14, 2021 at 0:33
3
\$\begingroup\$

C (gcc) with -funsigned-char, 63 bytes

This version takes a string of UTF-8 characters. If the leading byte is E2 then I mask the third byte with 15; otherwise I mask the second byte with 3. It's useful that B9 (the trailing byte of ¹) is odd!

i;f(char*s){for(i=0;*s;s++)i=(*s++-226?*s&3:*++s&15)+i*10;i=i;}

Try it online!

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

APL (dzaima/APL), 16 15 bytes

−1 byte thanks to rak1509

Anonymous tacit prefix function. Requires 0-based indexing.

10⊥'⁰¹²³⁴⁵⁶⁷⁸'⍳

Try it online!

10⊥ evaluate in base 10

'⁰¹²³⁴⁵⁶⁷⁸'⍳ the respective indices of the argument characters in this string (any character not in the string gets the first index beyond the end, i.e. 9)

\$\endgroup\$
2
  • \$\begingroup\$ Don't need the 9 in the string right? \$\endgroup\$
    – rak1507
    Dec 13, 2021 at 14:19
  • \$\begingroup\$ @rak1507 Of course not. Silly me. \$\endgroup\$
    – Adám
    Dec 13, 2021 at 14:20
3
\$\begingroup\$

APOL, 46 27 bytes

I(j(ƒ(i %(%(↶(∋) 92) 12))))

Uses Arnauld's 92/12 solution.

Note: 3 bytes can be saved by removing the I instruction, however this version is not case 5-compliant.

Explanation

I(               Cast to integer
  j(             Join string (default is no seperator)
    ƒ(           List-builder for loop (returns a list of every returned value of the passed instruction)
      i          Get input
      %(         Modulo 2 (12)
        %(       Modulo 1 (92)
          ↶(     Get codepoint
            ∋    The current item in the for loop
          )
        92
        )
      12
      )
    )
  )
)
Implicit print

Old code (uses lookup table instead):

v(0 []);f(i a(0 t(⌕("⁰¹²³⁴⁵⁶⁷⁸⁹" ∋))));I(j(⁰))

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

Python 3, 63 62 bytes

lambda n: int("".join([str("⁰¹²³⁴⁵⁶⁷⁸⁹".index(c))for c in n]))

Thanks @Fmbalbuena!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ lambda n:int("".join([str("⁰¹²³⁴⁵⁶⁷⁸⁹".index(c))for c in n])) -2 bytes \$\endgroup\$
    – Fmbalbuena
    Dec 13, 2021 at 14:08
  • 1
    \$\begingroup\$ lambda n:int("".join(str("⁰¹²³⁴⁵⁶⁷⁸⁹".index(c))for c in n)) will work, i think \$\endgroup\$
    – Bgil Midol
    Dec 13, 2021 at 14:08
2
\$\begingroup\$

PHP, 35 bytes

<?=+iconv('','US//TRANSLIT',$argn);

Try it online!

Some nice PHP builtin

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

Nim, 63 bytes

import strutils,unidecode
stdin.readAll.unidecode.parseInt.echo

Try it online!

If removing leading zeros is not required:

Nim, 45 bytes

import unidecode
stdin.readAll.unidecode.echo

Try it online!

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

Ruby, 40 bytes

->s{s.tr("⁰-⁹¹²³","0-9123").to_i}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Doesn't work for the last testcase. \$\endgroup\$
    – pajonk
    Dec 14, 2021 at 13:10
2
\$\begingroup\$

Factor, 13 bytes

[ nfkd dec> ]

nfkd postdates the build TIO uses, so have a screenshot:

enter image description here

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

Java, 67 bytes

s->java.text.Normalizer.normalize(s,java.text.Normalizer.Form.NFKD)

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Java wins longest builtin again? \$\endgroup\$
    – Neil
    Dec 13, 2021 at 19:46
1
\$\begingroup\$

Haskell, 75 bytes

f=mapM(\x->[putStr$show k|k<-[0..],x=="⁰¹²³⁴⁵⁶⁷⁸⁹"!!k]!!0)

Try it online!

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

Husk, 10 9 bytes

dm(Sn%12c

Try it online!

Port of Arnauld's Javascript answer Lynn's Jelly answer.

The 'charcode-to-charcode' modulo-except-when-it's-185 approach is discouragingly long in Husk, but Lynn's 'charcode-to-digit' modulo-AND approach is very well-suited to Husk's d (digits to decimal number) function.

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

Turing Machine Code, 99 bytes

* ⁰ 0 r *
* ¹ 1 r *
* ² 2 r *
* ³ 3 r *
* ⁴ 4 r *
* ⁵ 5 r *
* ⁶ 6 r *
* ⁷ 7 r *
* ⁸ 8 r *
* ⁹ 9 r *

Try it online!

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

Excel, 72 bytes

=VALUE(TEXTJOIN(,,MOD(MOD(UNICODE(MID(A1,SEQUENCE(LEN(A1)),1)),92),12)))

Not very exciting, really. It's the Excel version of Arnauld's answer.

  • MID(A1,SEQUENCE(LEN(A1)),1) pulls each character from the input one at a time.
  • MOD(MOD(UNICODE(MID(~)),92),12)) converts that character to unicode and then takes the mod 92 and mod 12.
  • VALUE(TEXTJOIN(,,MOD(~))) combines all those code values into a string and then returns the value of that string which will drop any leading zeros.
\$\endgroup\$
1
\$\begingroup\$

Lua, 94 bytes

r=0 t={[185]=1,[178]=2,[179]=3}for _,c in utf8.codes(...)do r=r*10+(t[c]or c-8304)end print(r)

Try it online!

\$\endgroup\$

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.