Salida N en base -10


18

Desafío:

En el lenguaje de programación que elija, acepte un número entero como entrada en la base 10 y emítalo en la notación negadecimal , que también se conoce como base -10

Algoritmo de ejemplo:

Este es un algoritmo tomado de Wikipedia para convertir la base 10 a cualquier base negativa en 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

Obviamente, puede usar cualquier algoritmo, siempre que cumpla el desafío

Ejemplo de entradas / salidas:

Entrada:

12

Salida:

192

Otro ejemplo:

Entrada:

2048

Salida:

18168

Regla:

No debe usar ningún método incorporado que resuelva este problema que exista en su lenguaje de programación

Este es un código de golf , por lo que gana el código más corto.


3
Creo que solo desea prohibir los elementos integrados que resuelven este problema específico y no todos los componentes existentes.
Denker

OEIS relacionado: A039723
devRicher

66
Debe agregar un caso de prueba negativo.
xnor

1
¿ [0, 1, 8, 1, 6, 8]Sería una salida aceptable para la entrada 2048?
Dennis

2
Vale la pena mencionarlo en la especificación. Parece que su código VB devuelve una lista.
Dennis

Respuestas:


12

JavaScript (ES6), 51 45 37 bytes

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

Casos de prueba


¿Hay alguna referencia para este algoritmo?
dfernan

@Dfernan No lo sé realmente. Este es el resultado de varias iteraciones de golf, comenzando con el algoritmo sugerido.
Arnauld

5

Japt , 11 bytes

_ì ìAn)¥U}a

¡Pruébalo en línea!

Explicación

_ì ì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

4

Lote, 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

La división de Batch se trunca a cero, por lo que si el resto es negativo, necesito agregar 1 (y también agregar 10 al resto) para compensar. Los dígitos se acumulan %2hasta que el resultado sea cero.


4

Jalea , 9 bytes

Dḅ-10=ð1#

Esta es una inversa de fuerza bruta de conversión de negadecimal a entero.

Pruébalo en línea!

Cómo funciona

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.


3

Python 3, 35 bytes

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

Puerto de Python del algoritmo de Arnauld .

Alternativamente, para 102 bytes, una función genérica que utiliza el algoritmo de la publicación original:

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 ""

Python no le permite declarar una entrada predeterminada que depende de otra entrada.
xnor

@xnor Funciona en mi instalación de Python: Python 3.5.1 (v3.5.1:37a07cee5969, Dec 5 2015, 21:12:44).
dfernan

Como lo llamas Estoy haciendo esto (en 3.5.2). ¿Podría estar declarando ko nen otra parte del código?
xnor

1
Se ve bien, buena mejora! Ya no necesita los parens alrededor de la llamada de función.
xnor

1
El último lo puedo explicar como precedencia del operador. -n//10does -(n//10): niega n, luego floor-divide entre 10, que se redondea hacia el infinito negativo, no 0. En contraste, 0-n//10does 0-(n//10), que primero floor-divide por 10, luego niega. Por alguna razón, Python trata la negación unaria con mayor precedencia que el binario menos. Ver esta tabla de precedencia . Me he encontrado con esta misma situación antes en el golf.
xnor

2

Jalea , 10 bytes

:⁵NµÐĿ%⁵ṚḌ

Pruébalo en línea!

Antecedentes

La conversión de una lista de no negativo de base b a entero se puede lograr doblando a la izquierda mediante la función x, y ↦ bx + y . Para convertir y un entero a base b , simplemente debemos invertir esa función, es decir, encontrar una expresión para bx + y ↦ x, y .

En Python (y, por extensión, Jelly), el resultado del operador de módulo siempre es no negativo, entonces (bx + y)% | b | = y .

Además, la división entera siempre se redondea hacia abajo, asegurándose de que si q = n / d y r = n% d , se mantenga la igualdad n = qd + r . Si s es el signo de b , entonces (sx) | b | + y = bx + y , entonces sx = (bx + y) / | b | y, por lo tanto, s ((bx + y) / | b |) = x.

Cómo funciona

:⁵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.

2

SimpleTemplate , 147 bytes

Este es un lenguaje de plantilla en el que he estado trabajando.
De ninguna manera está destinado a jugar al golf.
Incluso carece de matemática básica completa, pero permite escribir pequeños fragmentos de PHP directamente.
Esto funciona alrededor de ese problema.

{@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}

Esto arroja un montón de advertencias.
El código se "compila" en PHP.

Sin golf, con espacio en blanco de basura:

{@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}

Si es necesario, se puede agregar una explicación paso a paso, pero creo que es bastante sencillo.


Descargo de responsabilidad :

La última confirmación, al momento de escribir esta respuesta, fue en 2017-01-07 20:36 UTC + 00: 00.
Esto funciona en commit 140e56ff38f45fa4fd40fd3ec382094e707b1bad desde 2017-01-06 23:27 UTC + 00: 00.
Esa es la versión utilizada para ejecutar esta respuesta.

El código PHP está disponible en https://raw.githubusercontent.com/ismael-miguel/SimpleTemplate/140e56ff38f45fa4fd40fd3ec382094e707b1bad/SimpleTemplate.php

Recomiendo ejecutar esto con la última versión, pero esa funciona bien para esta pregunta.


¿Como correr?

Cree un archivo con el código y ejecútelo así:

<?php

    include 'path/to/SimpleTemplate.php';

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

    $template->render(<number>);

El valor se mostrará en la pantalla.


2

PHP, 71 67 bytes

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

o 62 bytes para un puerto de la respuesta de Arnauld :

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

1

Mathematica, 49 bytes

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

Define una función que dtoma un argumento entero y devuelve una cadena. Un algoritmo recursivo: se parece al mismo algoritmo en la respuesta de Arnauld . Funciona también en números negativos. (Devuelve la cadena vacía entre comillas de "0" si la entrada es 0.) Nota para los golfistas de Mathematica: el uso ±requiere un conjunto adicional de paréntesis y, por lo tanto, no parece ser más corto.


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;}

En lugar de imprimir el número resultante, el programa simplemente lo devuelve. Obviamente, esta es la respuesta de Arnauld , la única diferencia es que, dado que C no es un lenguaje interpretado, sentí que debería convertirlo en un programa completo en lugar de solo una función.


1
¿Cómo lo está devolviendo? fsale del alcance cuando la función regresa a menos que sea realmente tonto.
Abligh

@abligh No estás siendo realmente tonto, es solo GCC siendo realmente tonto. Si una función no nula termina sin retorno, simplemente usará la última asignación.
Etaoin Shrdlu

0

Óxido, 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}}

Esta es solo una versión recursiva del algoritmo proporcionado en la pregunta.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.