22
\$\begingroup\$

What?

Many programming languages, both practical and esoteric, have functions, methods, etc to convert a given string to a decimal number. This is how the process might work:

  • For each character in the given string.
    • Take the character's ASCII value and subtract it by 48.
    • Multiply the output value by 10. (The output at the first iteration is 0)
    • Add the subtracted ASCII value to the output.

Let us do this process for the string "109":

  1. The ASCII value of 1 is 49. Subtract it by 48, and we get 1. We multiply the output by 10, we get 0. Finally, we add 1 to 0 and get one.

  2. Next, we subtract 0's ASCII value (48) by 48, we get 0. We multiply 1 by 10, we get 10. Nothing happens when we add 0.

  3. Then we subtract 9's ASCII value (57) by 48, we get 9. We multiply 10 by 10 and get 100. We add 9 to 100 and get 109.

There, we successfully converted "109" to 109! It is just as simple!

The problem is that most languages do not like it when the converting string has non-digital characters (characters with an ASCII value not in the range 48-57 inclusive). They would most likely throw some nasty errors or exceptions at us.

How 'bout we ignore that!

Task

Given a printable string from STDIN (you can assume that \$1 ≤ \text{Input Length} ≤ 10\$), implement a program or function to badly convert it to an integer according to the above steps, and output or return it back.

Strings can contain whitespace characters (Spaces, tabs and linefeeds).

For another example string "Hi!":

  1. The ASCII value of H is 72:
    72 - 48 = 24
    0 * 10 = 0
    0 + 24 = 24

  2. The ASCII value of i is 105:
    105 - 48 = 57
    24 * 10 = 240
    240 + 57 = 297.

  3. The ASCII value of ! is 33:
    33 - 48 = -15
    297 * 10 = 2970
    2970 + -15 = 2955

This means that "Hi!" converted to an integer is 2955!

Standard I/O rules apply.

Note: if your language does not support input, feel free to tell me in your answers (you can put the "input" strings in your source code)!

More test cases

STDIN                  Output
"123456789"         ->  123456789
"0123456789"        ->  123456789
"-12345"            -> -287655
"Lorem"             ->  350191
"Ipsum"             ->  321451
"AAAAAAAA"          ->  188888887
"        "          -> -177777776
"A"                 ->  17
" "                 -> -16
"
"                   -> -38

Standard rules apply!

\$\endgroup\$
17
  • 1
    \$\begingroup\$ What do you mean when you say "You can use Unicode values instead"? Unicode and ASCII code points line up, so there's no difference between Unicode and ASCII values \$\endgroup\$ Oct 11 '20 at 14:40
  • 3
    \$\begingroup\$ Yes, but unless we have to handle inputs with characters outside of the printable ASCII range, the two are one and the same \$\endgroup\$ Oct 11 '20 at 14:55
  • 3
    \$\begingroup\$ Just to confirm: "-12345" should convert to -287655? We don't want the conversion to be too perfect, correct? :-) \$\endgroup\$
    – ErikF
    Oct 11 '20 at 17:28
  • 1
    \$\begingroup\$ Wouldn't it make more sense to switch the first two steps and replace "multiply the output" by "multiply the previous output (if available)"? No special case anymore, a better flow and no 10*1=0. \$\endgroup\$ Oct 12 '20 at 1:17
  • 1
    \$\begingroup\$ @SunnyMoon: Sorry if I wasn't clear. I was just proposing an alternative way to explain the above process, because the current explanation is a bit confusing IMHO. "Multiply the output by 10 " seems to be referring to ASCII value - 48 even though it actually refers to the previous step. Just my 2c$, feel free to ignore it. \$\endgroup\$ Oct 12 '20 at 11:19

44 Answers 44

11
\$\begingroup\$

Shakespeare Programming Language, 258 252 bytes

-6 bytes thanks to the default.

,.Ajax,.Puck,.Act I:.Scene I:.[Exeunt][Enter Ajax and Puck]
Ajax:Open mind.
Puck:Is I nicer zero?If soYou is the sum ofI twice the difference 
     betweenthe product ofyou the sum ofa cat a big big cat the factorial 
     ofa big big cat.
     If soLet usAct I.Open heart

Try it online!

The golfiest representation of the integer 48 is as twice the factorial of a big big cat, i.e. \$48=2\times (2\times2\times1)!\$.

This corresponds to

Ajax = 0
Puck = 0
Begin Act I
Puck = read_input (as ASCII codepoint value)
if(Puck>0){
    Ajax = Puck + 2 * (Ajax * (4+1) - 4!)
    Go to Act I
}
print(Ajax) (as an integer)
\$\endgroup\$
3
  • 1
    \$\begingroup\$ 252 bytes by rearranging the code to reuse twice: Try it online! \$\endgroup\$ Oct 12 '20 at 5:07
  • \$\begingroup\$ @thedefault. Nice, thanks! \$\endgroup\$ Oct 13 '20 at 7:35
  • 4
    \$\begingroup\$ a big big cat ... \$\endgroup\$
    – matt
    Oct 13 '20 at 20:18
10
\$\begingroup\$

Jelly, 5 bytes

O_48Ḍ

Try it online!

How it works

O_48Ḍ - Main link. Takes a string s on the left
O     - Convert to ordinal code points
 _48  - Subtract 48 from each
    Ḍ - Convert from base-10
\$\endgroup\$
1
  • 10
    \$\begingroup\$ Would the downvoter mind explaining why they cast their vote? This is a perfectly valid answer \$\endgroup\$ Oct 11 '20 at 15:31
8
\$\begingroup\$

Poetic, 153 bytes

decoding a num got WRONG
I/O digits i get?converting fails,o darn
i am bummed if the I/O fails
i have a number i got based on counting it badly,i suppose

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ I tried to run it online and it says: { ERROR: Unexpected EOF Done. \$\endgroup\$ Oct 14 '20 at 16:37
  • \$\begingroup\$ Output is in the form of an ASCII byte. That is the byte with the ASCII value of 123. \$\endgroup\$ Oct 14 '20 at 23:01
7
\$\begingroup\$

MATL, 8 bytes

As long as we're doing things wrong, why not turn a string into a polynomial?

48-[X]ZQ

Try it online!

Evaluates the polynomial

enter image description here

where p is the input string (minus '0') and x is 10.

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

JavaScript (ES6/2015), 51 bytes

([...s],r=0)=>s.map(c=>r=r*10+c.charCodeAt(0)-48)|r

let f = ([...s],r=0)=>s.map(c=>r=r*10+c.charCodeAt(0)-48)|r

console.log(f("123456789" )) //  123456789
console.log(f("0123456789")) //  123456789
console.log(f("Lorem"     )) //  350191
console.log(f("Ipsum"     )) //  321451
console.log(f("AAAAAAAA"  )) //  188888887
console.log(f("        "  )) // -177777776
console.log(f("A"         )) //  17
console.log(f(" "         )) // -16

\$\endgroup\$
1
  • \$\begingroup\$ Nice first answer! (Welcome to the site, by the way!) \$\endgroup\$ Oct 14 '20 at 1:53
5
\$\begingroup\$

APL (Dyalog Unicode), 11 bytes

10⊥48-⍨⎕UCS

Try it online!

⎕UCS converts string to a vector of ASCII values, 48-⍨ subtracts 48 from each value and 10⊥ converts from base 10.

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

R, 51 48 bytes

Edit: -3 bytes thanks to Robin Ryder

function(s)(utf8ToInt(s)-48)%*%10^(nchar(s):1-1)

Try it online!

Multiplies Utf8 value of each character minus 48 by powers-of-ten from the length of the string minus one, down to zero, and outputs the sum.

\$\endgroup\$
7
  • \$\begingroup\$ Wow! You answered in just about 10 minutes after the release of this question! \$\endgroup\$
    – SunnyMoon
    Oct 11 '20 at 13:54
  • \$\begingroup\$ R is usually quite bad for text-based challenges, but the vectorization helps a lot here... \$\endgroup\$ Oct 11 '20 at 13:56
  • \$\begingroup\$ Does R have a convert to base 10 builtin? That‘s essentially what the step is after subtracting 48, so that may be shorter than vectorising over the powers and summing \$\endgroup\$ Oct 11 '20 at 14:13
  • 1
    \$\begingroup\$ There are no base conversion builtins, but you can save 3 bytes thanks to vector multiplication: Try it online! \$\endgroup\$ Oct 11 '20 at 21:58
  • 2
    \$\begingroup\$ @cairdcoinheringaahing there is strtoi but it forces you to just use 0-9a-z so it wouldn't be of any help here. I'm pretty sure this is as short as this can get. \$\endgroup\$
    – Giuseppe
    Oct 12 '20 at 19:08
5
\$\begingroup\$

Java 8, 46 bytes

a->{int r=0;for(var c:a)r=r*10+c-48;return r;}

Input as a character-array.

Try it online.

Explanation:

a->{            // Method with character-array parameter and integer return-type
  int r=0;      //  Result-integer, starting at 0
  for(var c:a)  //  Loop over the input-characters:
    r=          //   Change the result to:
      r*10      //    The current result multiplied by 10
      +c-48;    //    And add the codepoint of the current characters minus 48
  return r;}    //  After the loop, return the result
\$\endgroup\$
5
\$\begingroup\$

Scala, 18 bytes

_./:(0)(_*10+_-48)

Try it online!

Explanation:

_./:(0)(_*10+_-48)
  /:                Fold left
_                   the input string
    (0)             with an initial value of 0
       (_*10+_-48)  Multiply the accumulator by 10, and add the next character - 48
\$\endgroup\$
1
  • 1
    \$\begingroup\$ awesome answer! \$\endgroup\$
    – corvus_192
    Oct 15 '20 at 17:54
5
\$\begingroup\$

Brachylog, 13 bytes

ạ-₄₈ᵐ{×₁₀ʰ+}ˡ

Try it online!

For single-"digit" inputs, the output is wrapped in a list, since the fold isn't actually executed. If this isn't acceptable, two 15-byte alternatives exist:

ạ-₄₈ᵐ,0↻{×₁₀ʰ+}ˡ

ạ↔-₄₈ᵐ{i×₁₀ⁱ⁾}ᶠ+

ạ                Convert to codepoints.
 -₄₈ᵐ            Subtract 48 from each.
     {     }ˡ    Left fold:
      ×₁₀ʰ       multiply the accumulator (initialized to first element) by 10
          +      and add it to the next element.

Brachylog's base conversion builtin actually disallows values outside the usual range, because it's actually quite useful sometimes on top of preserving proper inverse behavior, so I'm forced to implement the described algorithm directly.

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

PowerShell Core, 35 26 bytes

$args|%{$r=$r*10+$_-48}
$r

Saved 9 bytes using splatting

Try it online!

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

Stax, 7 bytes

ëk╜ΓOíU

Run and debug it

Explanation:

{48-mA|E Unpacked source, implicit input
{   m    Map over code points of input string
 48-       Subtract 48 from each
     A|E Convert from base 10
\$\endgroup\$
4
\$\begingroup\$

Perl 5, 40 bytes

sub{my$r;map$r=$r.0-48+ord,pop=~/./g;$r}

Try it online!

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

Python 3, 53 bytes

def f(x):
 o=0
 for i in x:o=o*10+ord(i)-48
 return o

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ You can shorten this to 45 if you switch to Python 2 + a full program: Try it online! \$\endgroup\$
    – Sisyphus
    Oct 12 '20 at 0:56
  • \$\begingroup\$ @Sisyphus am I wrong, or does switching to Python 2 only save a single byte? \$\endgroup\$ Oct 13 '20 at 20:05
  • 1
    \$\begingroup\$ @MarkRansom You're not wrong! The full program gets you to 46, and switching to Python 2 gets you to 45. \$\endgroup\$
    – Sisyphus
    Oct 13 '20 at 23:16
4
\$\begingroup\$

JavaScript (Node.js),  39  38 bytes

Saved 1 byte thanks to @Shaggy

s=>Buffer(s).map(c=>p=p*10+c-48,p=0)|p

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Would map not be shorter? \$\endgroup\$
    – Shaggy
    Oct 11 '20 at 19:45
  • \$\begingroup\$ @Shaggy Not any way I can think of. You'd have to manually change an accumulator with map, while reduce has that built in. \$\endgroup\$ Oct 11 '20 at 21:09
  • \$\begingroup\$ s=>Buffer(s).map(c=>p=p*10+c-48,p=0)|p should do it. \$\endgroup\$
    – Shaggy
    Oct 11 '20 at 21:29
4
\$\begingroup\$

K (ngn/k), 7 bytes

10/-48+

Try it online!

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

brainfuck, 43 38 bytes

,[<[>++++++++++<-]>+++>+[<->+++++],]<.

Try it online!

Thanks to JosiahRyanW for -5 bytes.

Since by our consensus, output can be given as character code, this is pretty straightforward in brainfuck. Note that the brainfuck interpreter on tio.run has 8-bit wrapping cells, so the maximum value is 255.

,[                  while input
  <[>++++++++++<-]  add 10 times previous sum to input
  >+++>+[<->+++++]  add 208 to it (effectively subtracting 48 by 8 bit wrapping)
  ,                 read next character
]
<.                  output
\$\endgroup\$
2
  • 2
    \$\begingroup\$ ,[+++<[>++++++++++<-]>>+[<->+++++],]<. is 38 bytes (assumes 8-bit wrapping cells). \$\endgroup\$ Oct 12 '20 at 7:09
  • 2
    \$\begingroup\$ That"s surprisingly concise, if not readable. \$\endgroup\$ Oct 12 '20 at 18:08
4
\$\begingroup\$

Befunge-98 (PyFunge), 14 12 bytes

Thanks to Gegell for -2 bytes!

2j@.~'0-\a*+

Try it online!

Explanation:

Initially the instruction pointer (IP) is moving right and the stack is filled with 0's.
2j skips the next two instruction (@.).
~ reads one character of input.
'0- subtracts 48 from the input.
\ swaps the two elements at the top of the stack. Now the intermediate result is on the top.
a* multiplies the result by 10.
+ adds the new number.
After that the IP wraps around to process the next character.

If there is no input left ~ reflects the IP.
. prints the result at the top of the stack, and @ terminates the program.

Animation of the code with input Lorem:

enter image description here

I'm not sure why there are black bars on two frames, I blame ImageMagick :/

\$\endgroup\$
4
  • \$\begingroup\$ Instead of using movement redirection and the newline (that is also counted as an additional byte) could you not simply inline and then jump over the .@ part instead? So something like 2j@.~'0-\a*+. That would save 2 bytes. \$\endgroup\$
    – Gegell
    Oct 12 '20 at 2:17
  • \$\begingroup\$ @Gegell That works indeed, thanks a lot! \$\endgroup\$
    – ovs
    Oct 12 '20 at 7:44
  • \$\begingroup\$ Is there a tool to generate an animation like that? \$\endgroup\$
    – att
    Oct 12 '20 at 7:47
  • \$\begingroup\$ @att There is this interpreter that uses pygame to draw the code and the stack on the screen. This doesn't create an animation though so you have to do some screen recording. For this animation I used my own tool, which is currently quite platform-specific, but uses the more complete PyFunge interpreter for executing the code. \$\endgroup\$
    – ovs
    Oct 12 '20 at 7:54
4
\$\begingroup\$

05AB1E, 6 bytes

Ç48-Tβ

Similar as some other answers.

Try it online or verify all test cases.

Explanation:

Ç       # Convert the (implicit) input-string to a list of codepoint integers
 48-    # Subtract 48 from each value
    Tβ  # Convert this from a base-10 list to a base-10 integer
        # (after which it is output implicitly as result)
\$\endgroup\$
4
\$\begingroup\$

Python 3, 46 45 42 bytes

f=lambda s:s>[]and ord(s.pop())-48+10*f(s)

Try it online!

-1 thanks to Sisyphus

-3 taking a list of characters as input thanks to ovs

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

Haskell, 45 43 bytes

n#(h:t)=(n*10+fromEnum h-48)#t
n#_=n
f=(0#)

Try it online!

n#(h:t)=       - # -> infix function taking a number and a string(head:tail)
(n*10+fromEnum h-48)#t  
                 - compute first char and call recursively on tail

n#_=n          - end condition

f=(0#)         - apply 0 to #
\$\endgroup\$
1
4
\$\begingroup\$

Assembly (NASM, 32-bit, Linux), 221 185 bytes

Edit: -36 bytes + bugfix

mov eax,0
mov esi,48
push 48
mov ecx,esp
l:mov edx,10
mul edx
mov edi,esi
sub edi,48
add eax,edi
mov si,[ecx]
push eax
mov dx,1
mov ebx,0
mov eax,3
int 128
or ax,0
pop eax
jnz l
pop edi

Try it Online!

The result is in eax.

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

Vyxal, 5 bytes

C48-I

Try it Online!

Wow it's actually ASCII.

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

Husk, 9 7 bytes

Edit: -2 bytes thanks to Razetime

dmo-48c

Try it online!

How?

d           # interpret digits as base-10 number:
 m          # map function over each element of list (each character of string)
  o         # combine 2 functions into one
      c     # convert character to Utf8 value
   -48      # subtract 48
\$\endgroup\$
2
  • \$\begingroup\$ B10 becomes d \$\endgroup\$
    – Razetime
    Oct 11 '20 at 15:31
  • \$\begingroup\$ Duh! How did I miss that? Thanks a lot! \$\endgroup\$ Oct 11 '20 at 15:33
3
\$\begingroup\$

C (gcc), 48 44 bytes

Usually using a temporary variable to store the current character is shorter than doing array processing, but not this time!

i;f(char*s){for(i=0;*s;i=i*10+*s++-48);s=i;}

Try it online!

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

J, 12 bytes

10#._48+3&u:

Try it online!

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

Gol><>, 10 bytes

iEh$a*+`0-

Try it online!

i           Read one char from the input
 Eh         If last char read was EOF halt and output current sum as number
   $a*      Else swap new input and current sum, then multiply sum by 10
      +     Add the new char value to current sum
       `0-  Subtract 48 (value of '0') and wrap around implicitly to loop
\$\endgroup\$
3
\$\begingroup\$

Elixir, 36 bytes

&List.foldl&1,0,fn x,y->y*10+x-48end

Try it online!

Anonymous function that performs a simple left fold over its argument (&1) using the specified accumulating function. Relies on the fact that Elixir charlists are the same thing as the lists of integer codepoints, so that the transformation can be applied directly without any conversions.

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

Rust, 42 bytes

|s|s.chars().fold(0,|n,x|n*10+x as i32-48)

Try it online!

Takes input as an &str and outputs the number based on utf-8 codepoints.

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

Ruby, 38 bytes

->s{s.bytes.inject(0){|a,b|b-48+a*10}}

35 bytes with the new Ruby 2.7 syntax:

->s{s.bytes.inject(0){_2-48+_1*10}}

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.