Output N in base -10

18

1

Challenge:

In the programming language of your choice, accept an integer as input in base 10, and output it in the negadecimal notation, which is also known as base -10

Example algorithm:

This is an algorithm taken from Wikipedia to convert base 10 to any negative base in VB.NET:

Function toNegativeBase(Number As Integer , base As Integer) As System.Collections.Generic.List(Of Integer)

    Dim digits As New System.Collections.Generic.List(Of Integer)
    while Number <> 0
        Dim remainder As Integer= Number Mod base
        Number = CInt(Number / base)

        if remainder < 0 then
            remainder += system.math.abs(base)
            Number+=1
        end if

        digits.Insert(0, remainder)
    end while

    return digits
end function

Obviously, you can use any algorithm, as long as it fulfills the challenge

Example inputs / outputs:

Input:

12

Output:

192

Another example:

Input:

2048

Output:

18168

Rule:

You must not use any built-in methods that solve this problem that exist in your programming language

This is a code-golf, so shortest code wins!

P. Ktinos

Posted 2017-01-07T14:59:40.057

Reputation: 2 742

3I think you only want to forbit built-ins that solve this specifiic problem and not all existing builltins. – Denker – 2017-01-07T15:08:02.423

Related OEIS: A039723

– devRicher – 2017-01-07T15:08:39.330

Whoops you are right @DenkerAffe , fixed. – P. Ktinos – 2017-01-07T15:09:17.567

Must we handle negative integers as well as positive ones? – user41805 – 2017-01-07T15:31:06.877

Yup, otherwise I woud say whole numbers @KritixiLithos – P. Ktinos – 2017-01-07T15:39:52.147

@P.Ktinos Negative whole numbers are as much whole numbers as positive whole numbers. – Toothbrush – 2017-01-07T16:14:44.830

@P.Ktinos I just looked up the definition of “whole number”. It seems that some people refer to (so-called) natural numbers when they say whole numbers while others (including me) refer to integers when they say whole numbers. I guess it is a matter of perspective. I've always been taught that “integer” is a synonym of “whole number”. – Toothbrush – 2017-01-07T16:19:19.343

@Toothbrush I guess you are right. I'll edit the question to avoid confusion. – P. Ktinos – 2017-01-07T16:32:58.813

6You should add a negative test case. – xnor – 2017-01-07T21:48:10.647

1Would [0, 1, 8, 1, 6, 8] be an acceptable output for input 2048? – Dennis – 2017-01-08T02:20:37.727

@Dennis No, sorry. You should join the digits and output it as an integer. – P. Ktinos – 2017-01-08T23:39:40.803

2That might be worth mentioning in the spec. Your VB code looks like it returns a list. – Dennis – 2017-01-08T23:46:50.360

@Dennis It's an example of an algorithm used to do the conversion, as some people may not know the way to convert decimal to negadecimal. It's not meant to showcase the way it should be done, and it is not mine, it is taken from wikipedia. – P. Ktinos – 2017-01-09T12:23:06.083

Answers

12

JavaScript (ES6), 51 45 37 bytes

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

Test cases

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

console.log("12 -> " + f(12))
console.log("2048 -> " + f(2048))

Arnauld

Posted 2017-01-07T14:59:40.057

Reputation: 111 334

Is there a reference for this algorithm? – dfernan – 2017-01-07T21:36:07.190

@dfernan I don't really know. This is the result of several golfing iterations, starting with the suggested algorithm. – Arnauld – 2017-01-07T22:47:20.827

5

Japt, 11 bytes

_ì ìAn)¥U}a

Test it online!

Explanation

_ì ìAn)¥U}a  // Implicit: U = input integer, A = 10
_        }a  // Return the smallest non-negative integer Z that returns a truthy value
             // when run through this function:
 ì           //   Convert Z to a list of its base 10 digits.
   ìAn)      //   Interpret this as a list of base -10 digits and convert to a base 10 integer.
       ¥U    //   Return (the result == U).
             // Implicit: output result of last expression

ETHproductions

Posted 2017-01-07T14:59:40.057

Reputation: 47 880

4

Batch, 82 bytes

@set/a"d=%1%%10,n=%1/-10-(a=d>>4),d-=a*10
@if %n% neq 0 %0 %n% %d%%2
@echo %d%%2

Batch's division truncates to zero, so if the remainder is negative I need to add 1 (and also add 10 to the remainder) to compensate. The digits are then accumulated in %2 until the result becomes zero.

Neil

Posted 2017-01-07T14:59:40.057

Reputation: 95 035

4

Jelly, 9 bytes

Dḅ-10=ð1#

This is a brute-force inverse of negadecimal-to-integer conversion.

Try it online!

How it works

Dḅ-10=ð1#  Main link. Argument: n

      ð    Combine the links to the left into a chain and start a new, dyadic
           chain with left and right argument n.
       1#  Repeatedly execute the chain with left argument k = n, n + 1, ... and
           right argument n until the first match is found.
D          Convert k to decimal.
 ḅ-10      Convert the result from base -10 to integer.
     =     Compare the result with n.

Dennis

Posted 2017-01-07T14:59:40.057

Reputation: 196 637

3

Pyth - 9 bytes

Lel it has the crying emoji in it.

fqQijT;_;

Test Suite.

Maltysen

Posted 2017-01-07T14:59:40.057

Reputation: 25 023

1Why are you crying?? You are on par! – NoOneIsHere – 2017-01-08T06:52:45.890

Because he has the crying emoji on Pyth answer. – user75200 – 2017-12-28T15:38:07.177

3

Python 3, 35 bytes

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

Python port of Arnauld's algorithm.

Alternatively, for 102 bytes a generic function using the algorithm of the original post:

def f(n,b,r=0):
 if n:
  r,n=n%b,n//b
  if r<0:r+=abs(b);n+=1
  return f(n,b,r)+str(r)
 else:return ""

dfernan

Posted 2017-01-07T14:59:40.057

Reputation: 528

Python doesn't let you declare a default input that depends on another input. – xnor – 2017-01-07T21:46:54.953

@xnor It works on my Python installation: Python 3.5.1 (v3.5.1:37a07cee5969, Dec 5 2015, 21:12:44). – dfernan – 2017-01-07T21:49:55.243

How are you calling it? I'm doing this (in 3.5.2). Might you be declaring k or n elsewhere in the code?

– xnor – 2017-01-07T21:53:25.897

You were right. I had an n previously declared. For some reason, anyway, k is not needed as per the current solution. Can you try it? – dfernan – 2017-01-07T22:15:15.847

1Looks good, nice improvement! You don't need the parens around the function call any more. – xnor – 2017-01-07T22:16:32.677

Not sure how it comes to work, though, as per Arnauld's algorithm. Why is that 0-n needs 0 too (-n only yields wrong results)? – dfernan – 2017-01-07T22:24:39.787

1

The last one I can explain as operator precedence. -n//10 does -(n//10): negate n, then floor-divide by 10, which rounds down towards negative infinity, not 0. In contrast, 0-n//10 does 0-(n//10), which first floor-divides by 10, then negates. For whatever reason, Python treats unary negation with a higher precedence than binary minus. See this precedence table. I've run into this same situation before in golfing.

– xnor – 2017-01-07T22:27:33.167

2

PHP, 71 67 bytes

for(;$n=&$argn;$n=$g-$n/10|0)$d=($r=$n%10)+10*($g=$r<0).$d;echo+$d;

or 62 bytes for a port of Arnauld´s answer:

function n($n){return$n?$n%10+(($k=$n<0)+f($k-$n/10|0))*10:0;}

Titus

Posted 2017-01-07T14:59:40.057

Reputation: 13 814

2

Jelly, 10 bytes

:⁵NµÐĿ%⁵ṚḌ

Try it online!

Background

Converting a list of non-negative from base b to integer can be achieved by left-folding by the function x, y ↦ bx + y. To convert and integer to base b, we must simply reverse that function, i.e., find an expression for bx + y ↦ x, y.

In Python (and, by extension, Jelly), the result of the modulo operator is always non-negative, so (bx + y) % |b| = y.

Also, integer division always rounds down, making sure that if q = n / d and r = n % d, the equality n = qd + r holds. If s is the sign of b, then (sx)|b| + y = bx + y, so sx = (bx + y) / |b| and, therefore, s((bx + y) / |b|) = x.

How it works

:⁵NµÐĿ%⁵ṚḌ  Main link. Argument: n

   µ        Combine the links to the left into a monadic chain.
    ÐĿ      Iteratively apply the chain until the results are no longer unique.
            Collect all unique results in an array.
:⁵            Divide the previous return value (initially n) by 10.
  N           Negate; multiply the result by -1.
      %⁵    Take all results modulo 10.
        Ṛ   Reverse the results.
         Ḍ  Convert from base 10 to integer.

Dennis

Posted 2017-01-07T14:59:40.057

Reputation: 196 637

2

SimpleTemplate, 147 bytes

This is a template language I've been working on.
By no means it is meant to be for golfing.
It even lacks complete basic math, but it allows to write tiny snippets of PHP directly.
This works around that issue.

{@setN argv.0}{@whileN}{@setM N}{@php$DATA[N]=($DATA[M]/-10)|0;$DATA[R]=$DATA[M]%-10}{@ifR is lower0}{@incby10 R}{@incN}{@/}{@setD R,D}{@/}{@echoD}

This throws a bunch of warnings.
The code is "compiled" into PHP.

Ungolfed, with trash whitespace:

{@set no argv.0}
{@while no}
    {@set temp_no no}
    {@php $DATA["no"] = ($DATA["temp_no"] / -10) | 0}
    {@php $DATA["remainder"] = $DATA["temp_no"] % 10}

    {@if remainder is lower than 0}
        {@inc by 10 remainder}
        {@inc no}
    {@/}
    {@set digits remainder, digits}
{@/}
{@echo digits}

If required, a set-by-step explanation can be added, but I believe that it is pretty straightforward.


Disclaimer:

The last commit, as of the time of writting this answer, was on 2017-01-07 20:36 UTC+00:00.
This works on commit 140e56ff38f45fa4fd40fd3ec382094e707b1bad from 2017-01-06 23:27 UTC+00:00.
That is the version used to run this answer.

The PHP code is available on https://raw.githubusercontent.com/ismael-miguel/SimpleTemplate/140e56ff38f45fa4fd40fd3ec382094e707b1bad/SimpleTemplate.php

I do recommend running this with the last version, but that one works fine for this question.


How to run?

Create a file with the code and run it like this:

<?php

    include 'path/to/SimpleTemplate.php';

    $template = new SimpleTemplate('<code>');

    $template->render(<number>);

The value will then be displayed on the screen.

Ismael Miguel

Posted 2017-01-07T14:59:40.057

Reputation: 6 797

1

Mathematica, 49 bytes

d@0="";d@n_:=d[-Floor[n/10]]<>ToString[n~Mod~10];

Defines a function d taking one integer argument, and returning a string. A recursive algorithm—looks like the same algorithm in Arnauld's answer. It does work on negative numbers as well. (It returns the empty string intsead of "0" if the input is 0.) Note for Mathematica golfers: using ± requires one extra set of parentheses and thus seems not to be any shorter.

Greg Martin

Posted 2017-01-07T14:59:40.057

Reputation: 13 940

0

C, 68 bytes

main(f,a){f&&scanf("%d",&a);f=a?a%10+((f=a<0)+main(0,f-a/10))*10:0;}

Instead of printing the resulting number the program just returns it. Obviously this is Arnauld's answer, the only difference is that since C isn't an interpreted language I felt like I should make it a full program as opposed to just a function.

Etaoin Shrdlu

Posted 2017-01-07T14:59:40.057

Reputation: 145

1How is it returning it? f goes out of scope when the function returns unless I'm being really dumb. – abligh – 2017-01-08T19:14:31.390

@abligh You aren't being really dumb, it's just GCC being really dumb. If a non-void function terminates without a return it'll simply use the last assignment. – Etaoin Shrdlu – 2017-01-09T20:27:13.197

0

Rust, 88 bytes

fn g(mut n:i32)->i32{let mut r=n%10;n/=-10;if r<0{r+=10;n+=1;}if n==0{r}else{r+g(n)*10}}

This is just a recursive version of the algorithm provided in the question.

bearbear2k

Posted 2017-01-07T14:59:40.057

Reputation: 71