26
\$\begingroup\$

Negadecimal, also known as base -10, is a non-standard positional numeral system.

Take the number \$1337_{10}\$. In decimal, this has the value one thousand three hundred thirty seven, and can be expanded to:

$$1\cdot10^3+3\cdot10^2+3\cdot10^1+7\cdot10^0$$

$$(1000)+(300)+(30)+(7)$$

In negadecimal, instead of \$10^n\$, each digit would be multiplied by \$(-10)^n\$:

$$1\cdot(-10)^3+3\cdot(-10)^2+3\cdot(-10)^1+7\cdot(-10)^0$$

$$(-1000)+(300)+(-30)+(7)$$

Thus, \$1337_{-10}\$ is \$-723_{10}\$ in decimal. (An interesting consequence of this is that negative signs are unnecessary in negadecimal; any integer can be represented as /[0-9]+/.)

In this challenge, your score is the sum of the lengths of two programs or functions:

  • One to convert a number in negadecimal to decimal
  • One to convert a number in decimal to negadecimal

All inputs will be integers. You must be able to handle negative numbers. You can take input and output in any reasonable way. This is code golf, so the shortest answer in bytes per language wins.

Test cases

Negadecimal to decimal:

1337   -> -723
0      -> 0
30     -> -30
101    -> 101
12345  -> 8265

Decimal to negadecimal:

-723   -> 1337
0      -> 0
1      -> 1
21     -> 181
-300   -> 1700
1000   -> 19000
-38493 -> 179507
\$\endgroup\$
14
  • 1
    \$\begingroup\$ Can I take/output the negadecimal number as an array of single digit numbers? Can I take it in reverse? \$\endgroup\$ – Bubbler Dec 1 '20 at 0:16
  • \$\begingroup\$ @Bubbler Yes and yes. \$\endgroup\$ – Redwolf Programs Dec 1 '20 at 0:21
  • 1
    \$\begingroup\$ If I use an array of digits, may I output the negadecimal number with leading zeros? \$\endgroup\$ – Bubbler Dec 1 '20 at 0:47
  • 2
    \$\begingroup\$ @Bubbler Seems reasonable. I guess you can. \$\endgroup\$ – Redwolf Programs Dec 1 '20 at 0:49
  • 1
    \$\begingroup\$ @user Sounds reasonable \$\endgroup\$ – Redwolf Programs Dec 1 '20 at 15:01

17 Answers 17

8
\$\begingroup\$

05AB1E, 6 bytes

Nega to Deca

T(ö

Try it online!

Deca to Nega

T(в

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ If my understanding is correct, this fails for \$-723\$? If the first program goes \$x_{10} \to y_{-10}\$ (decimal to negadecimal) then \$-723\$ should output \$1337\$ no? \$\endgroup\$ – caird coinheringaahing Dec 1 '20 at 0:32
  • \$\begingroup\$ @cairdcoinheringaahing Looks like the first one is negadecimal to decimal, not the other way around. \$\endgroup\$ – Redwolf Programs Dec 1 '20 at 0:39
8
\$\begingroup\$

JavaScript (Node.js), 59 bytes

f=(p,e=n=>n&&(i=(n%10+10)%10)-p*e((n-i)/p))=>e
f(10)
f(-10)

Try it online! f defines a helper function. f(10) returns a function that converts from negadecimal to decimal while f(-10) returns a function that converts from decimal to negadecimal.

\$\endgroup\$
1
  • 4
    \$\begingroup\$ This is a really cool answer \$\endgroup\$ – user Dec 1 '20 at 14:24
8
\$\begingroup\$

JavaScript (ES6), 25 + 55 = 80 bytes

Negadecimal to decimal (25 bytes)

f=n=>n&&n%10-10*f(n/10|0)

Try it online!

How?

This one is pretty straightforward. We recursively compute:

$$f(n) = \cases{ 0, n=0\\ (n \bmod 10) - 10\times f\left(\left\lfloor\dfrac{n}{10}\right\rfloor\right), n>0}$$

Decimal to negadecimal (55 bytes)

f=(n,i=n%10,k=n>0?-n:~n-i+(i+=10))=>n?f(k/10|0)+i%10:''

Try it online!

How?

In JS, the result of the % operator has the same sign as the dividend. For instance, -17 % 10 is -7 rather than 3 (like in Python), which is what we'd really like to get here. A possible workaround would be:

(n % 10 + 10) % 10

Besides, we also need to compute \$\left\lfloor n/-10\right\rfloor\$ with \$n\$ either positive or negative. This can be done with:

Math.floor(n / -10)

but this expression is a bit lengthy.

Rather than dealing with both issues separately, we explicitly test the sign of \$n\$ and compute the variables i and k accordingly:

  • We unconditionally set i = n % 10.
  • If \$n>0\$, we define k = -n and leave i unchanged.
  • If \$n\le 0\$, we define k = ~n + 10 and add \$10\$ to i. Both operations are merged into k = ~n - i + (i += 10).

We then can use k / 10 | 0 and i % 10 in both cases.

\$\endgroup\$
7
  • \$\begingroup\$ Second function returns an empty string for n=0. \$\endgroup\$ – att Dec 1 '20 at 1:40
  • \$\begingroup\$ @att '' == 0 is true in JS. But I'll ask the OP if that's acceptable. \$\endgroup\$ – Arnauld Dec 1 '20 at 1:50
  • \$\begingroup\$ Math.floor(n/-10) can be simplified to (n-i)/-10, resulting in the naïve solution of f=n=>n&&(i=(n%10+10)%10)+10*f((n-i)/-10). \$\endgroup\$ – Neil Dec 1 '20 at 11:26
  • \$\begingroup\$ @Neil This is much easier indeed. You can save another byte with (i-n)/10. \$\endgroup\$ – Arnauld Dec 1 '20 at 11:32
  • \$\begingroup\$ I'm not surprised, I didn't really try to golf it down. \$\endgroup\$ – Neil Dec 1 '20 at 11:38
5
\$\begingroup\$

Jelly, 8 bytes

Negadecimal to decimal:

ḅ-10

Try it online!

Decimal to negadecimal

b-10

Try it online!

Input as an integer, output as a list of digits. +2 total bytes (+1 to each) to I/O as integers

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

Wolfram Language (Mathematica), 17+35 = 52 bytes

From negadecimal:

#~FromDigits~-10&

Try it online!

Straightforward base conversion from a string or list of digits.

To negadecimal:

f@0=0
f@a_:=f@-⌊a/10⌋||a~Mod~10

Try it online!

Outputs a list of digits, including a leading zero, wrapped in Or.

+1 byte to output as an integer: Try it online!

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

Lisp Flavored Erlang, 33 + 59 + 59 = 153 151 bytes

(defun m(X Y)(rem(+(rem X Y)Y)Y))
(defun n(N)(if(== N 0)0(-(m N 10)(*(n(floor(/ N 10)))10))))
(defun d(N)(if(== N 0)0(+(m N 10)(*(d(ceil(/ N -10)))10))))

n computes the decimal, given a negadecimal. d computes the reverse.

Both functions take & return a regular integer.

Erlang's rem function works like JavaScript's instead of like Python's, which is why the m function is necessary. I save some total bytes by reusing it — if this were 2 separate challenges, it would be inlined as each function only uses it once.

Edit: Rearranged some of the function calls to save a couple bytes without changing logic

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

Factor, 28 + 59 = 87 bytes

Negadecimal to decimal

[ 0 [ swap 10 * - ] reduce ]

Try it online!

Takes an array of negadecimal digits and returns an integer.

[
  0 [ ... ] reduce   ! Reduce over the digits with starting value of 0...
    swap 10 * -      ! ( accum digit -- accum' ) Evaluate accum * -10 + digit
]

Decimal to negadecimal

[ [ dup 0 = not ] [ -10 2dup / ceiling -rot rem ] produce ]

Try it online!

Takes an integer and returns an array of negadecimal digits in reverse order. Does not produce any leading zeros, which means the input of 0 gives an empty array.

[
  [ cond ] [ loop ] produce   ! Starting with the value of n, loop until cond gives false
                              ! and collect the top values during the loop
    dup 0 = not               !   Cond: stop if top is 0
                              !   Loop: yield the last digit and keep the higher value
    -10 2dup / ceiling        !   ( n -- n -10 keep ) keep = ceil(n/-10)
    -rot rem                  !   ( keep yield ) yield = n%-10 (non-negative mod)
]
\$\endgroup\$
4
\$\begingroup\$

Husk, 8 bytes

Negadecimal to decimal, 4 bytes

B_10

Try it online!

input as list of digits, output as integer.

Decimal to Negadecimal, 4 bytes

B_10

Try it online!

input as integer, output as list of digits.

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

K (oK), 40 bytes

Negadecimal to decimal, 10 bytes

{y+x*-10}/

Try it online!

Decimal to negadecimal, 30 bytes

-8 bytes thanks to coltim!

{$[~x;0;(10*o@-_-x%-10)+10!x]}

Try it online!

\$\endgroup\$
7
  • 1
    \$\begingroup\$ The "canonical" ceil idiom is -_-, e.g. here \$\endgroup\$ – coltim Dec 1 '20 at 15:05
  • \$\begingroup\$ @coltim Many thanks for your improvements! \$\endgroup\$ – Galen Ivanov Dec 1 '20 at 15:11
  • 2
    \$\begingroup\$ Yep! In addition to individual characters, the k's also overload emoticons :) \$\endgroup\$ – coltim Dec 1 '20 at 15:24
  • 1
    \$\begingroup\$ Although it's the same byte count, the $[;;] cond can be replaced, e.g. {(10!x)+10*(o;:)[~x;-_x%10]} (although this only works in the repl). It also turns out a couple more bytes can be saved by replacing -_-x%-10 with -_x%10! \$\endgroup\$ – coltim Dec 1 '20 at 19:44
  • 1
    \$\begingroup\$ Yeh, it's a bit weird. (o;:) is a list containing the two functions we want to call, depending on the ~x condition. Since ~x returns 0 or 1 we use that to index into that list (thus giving us the "code" we want to run). I think : in this case is acting as an identity function, so it'll just return the input. Also, I think [~x;-_x%10] is equivalent to [~x][-_x%10] (i.e. pass the updated arg into whichever function we selected). It's basically a hack to mimic how $[;;] doesn't evaluate its arguments. \$\endgroup\$ – coltim Dec 1 '20 at 19:58
4
\$\begingroup\$

Python 2, 31 + 34 = 65 bytes

Negadecimal to decimal, 32 31 bytes

Saved a byte thanks to xnor!!!

f=lambda n:n and~9*f(n/10)+n%10

Try it online!

Decimal to negadecimal, 42 35 34 bytes

Saved 7 bytes thanks to att!!!
Saved another byte thanks to xnor!!!

g=lambda n:n and n%10+10*g(0-n/10)

Try it online!

\$\endgroup\$
5
  • \$\begingroup\$ 35 bytes on the second. \$\endgroup\$ – att Dec 1 '20 at 19:19
  • \$\begingroup\$ @att Nice one - thanks! :D \$\endgroup\$ – Noodle9 Dec 1 '20 at 19:35
  • \$\begingroup\$ The second one can save a byte with 0-n/10. And the first one has this weird save: f=lambda n:n and~9*f(n/10)+n%10 \$\endgroup\$ – xnor Dec 2 '20 at 0:04
  • \$\begingroup\$ @xnor Force the use of binary operator - nice one - thanks! : D \$\endgroup\$ – Noodle9 Dec 2 '20 at 0:10
  • \$\begingroup\$ @xnor Are you a practitioner of the dark arts by any chance? -9=~9+1 so -10=~9, very nice - thanks! :D \$\endgroup\$ – Noodle9 Dec 2 '20 at 0:24
3
\$\begingroup\$

Racket, 106 bytes

Negadecimal to decimal, 39 bytes

(λ(x)(foldl(λ(a b)(+(* -10 b)a))0 x))

Try it online!

Takes an array of negadecimal digits and returns an integer.

Decimal to negadecimal, 67 bytes

(define(d x)(if(= 0 x)0(+(modulo x 10)(*(d(ceiling(/ x -10)))10))))

Try it online!

Takes the input as an integer and returns an integer.

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

Scala, 15 + 71 = 86 bytes

Negadecimal to decimal

_.:\(0)(_-10*_)

Try them both online!

Takes input as a reversed list of digits.

This is rather straightforward - multiply the first digit by -10, add the second digit to that, multiply that by -10, and so on.

Decimal to negadecimal

Seq.unfold(_){x=>val m=(x%10+10)%10;Option.when(x*x>0)(m->(m-x)/10)}:+0

Returns a reversed list of digits, with a leading zero (at the end).

This is not so trivial. Because of the way Scala's % works, we can't just use x%10, as it maintains the sign of x and not 10. 10 has to be added to x%10 to ensure it is positive, and then %10 is done again.

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

Brachylog, 19 bytes

{×₁₀ʰ↔-}ˡ

Try it online!

≜{×₁₀ʰ↔-}ˡ

Try it online!

Negadecimal input and output is as digit lists. The decimal to negadecimal program uses reversed I/O and is also impressively slow, as it uses pure brute force (coming out 6 bytes shorter than a saner implementation).

{      }ˡ    Left fold over input negadecimal digits:
 ×           multiply
    ʰ        the accumulator
  ₁₀         by 10,
     ↔-      subtract it from the next digit.

≜             Try outputting all integers until the output
 {×₁₀ʰ↔-}ˡ    is the negadecimal representation of the input.
\$\endgroup\$
3
\$\begingroup\$

C (gcc), 28 + 43 = 71 bytes

Negadecimal to decimal, 28 bytes

f(n){n=n?n%10-10*f(n/10):0;}

Try it online!

Decimal to negadecimal, 48 45 43 bytes

Saved 3 bytes thanks to xnor!!!
Saved 2 bytes thanks to rtpax!!!

g(n){n=n?n%~9+10*(g(n/~9+(n=n%~9<0))+n):0;}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ @rtpax Nice reuse of n - thanks! :D \$\endgroup\$ – Noodle9 Dec 2 '20 at 17:23
3
\$\begingroup\$

R, 71 bytes

Combined negadec_to_dec and dec_to_negadec code thanks to user, and inspired by Neil's answer

b=function(p)d=function(x)`if`(x,(y=x%%10)-p*d((x-y)/p),0)
b(10)
b(-10)

Try it online!


R, 49 47 41 + 47 = 88 bytes

Separate functions

negadecimal to decimal (49 47 41 bytes):

Edit: -2 bytes (and, as a consequence, -6 more bytes) thanks to att

d=function(x)`if`(x,x%%10-10*d(x%/%10),0)

Try it online!

decimal to negadecimal (47 bytes):

d=function(x)`if`(x,(y=x%%10)+10*d((y-x)/10),0)

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ 47 bytes from negadecimal \$\endgroup\$ – att Dec 2 '20 at 18:43
  • \$\begingroup\$ @att - That's lovely! Not only was it right under my nose, but I even had to line-up the dec_to_neg and your neg_to_dec function to spot the differences! Thanks! \$\endgroup\$ – Dominic van Essen Dec 2 '20 at 23:02
  • \$\begingroup\$ You can put them together, like Neil did, and get even fewer bytes \$\endgroup\$ – user Dec 2 '20 at 23:10
  • \$\begingroup\$ @user - That is a very, very good idea! Thanks! And thanks too to Neil! \$\endgroup\$ – Dominic van Essen Dec 2 '20 at 23:24
2
\$\begingroup\$

Charcoal, 5 + 18 = 23 bytes

Negadecimal to decimal:

I↨S±χ

Try it online! Link is to verbose version of code. This is just custom base conversion with a base of -10.

Decimal to negadecimal:

NθP0Wθ«←I﹪θχ≔±÷θχθ

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

Nθ

Input the decimal number.

P0

Print a 0 in case the input is zero.

Wθ«

Repeat until the input is zero.

←I﹪θχ

Print the next digit in right-to-left order.

≔±÷θχθ

Divide the input by 10 and change its sign. (Sadly this is not the same thing as dividing the input by -10.

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

Ruby 2.7, 69 68 66 bytes


24 23 bytes

-1 byte thanks to Bubbler

->x{x.reduce{_2-_1*10}}

Try it online!

TIO uses an older version of Ruby, while in Ruby 2.7, we've numbered parameters, which saves 3 bytes.


45 43 bytes

f=->x,s=''{x!=0?f[-~~(x/10),"#{x%10}"+s]:s}

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Your second function is invalid because taking extra parameter not specified in the challenge is not allowed. \$\endgroup\$ – Bubbler Dec 1 '20 at 8:05
  • \$\begingroup\$ @Bubbler - Oops, I thought it would be allowed. \$\endgroup\$ – vrintle Dec 1 '20 at 8:12
  • 1
    \$\begingroup\$ For the first function, I think _2-10*_1 should work (-1 byte)? \$\endgroup\$ – Bubbler Dec 1 '20 at 8:22

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.