Expandir y contraer

19

Tome un entero positivo k como entrada. Start con n:=1 y repetidamente aumentan n por la mayor potencia entera de diez i tal que in y i+nk .

Repita hasta n=k y devuelva una lista de todos los valores intermedios de n , incluidos tanto el 1 inicial como el k final .

Durante este proceso, el crecimiento estará inicialmente limitado por la primera desigualdad, y solo después por la segunda; el crecimiento tomará la forma de un período de "expansión" inicial, durante el cual n aumenta con poderes cada vez mayores, seguido de un período de "contrato", durante el cual n aumenta con poderes cada vez más pequeños para "acercarse" en el número correcto

Casos de prueba

1 => [1]
10 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
321 => [1,  2,  3,  4,  5,  6,  7,  8,  9,
        10, 20, 30, 40, 50, 60, 70, 80, 90,
        100, 200, 300, 310, 320, 321]
1002 => [1,   2,   3,   4,   5,   6,   7,   8,   9,
         10,  20,  30,  40,  50,  60,  70,  80,  90,
         100, 200, 300, 400, 500, 600, 700, 800, 900,
         1000, 1001, 1002]

Este es el , por lo que gana la respuesta más corta (en bytes).

Fruta Esolanging
fuente
2
¿Podemos imprimir los números en lugar de devolver una lista?
Adám
@ Adám Sí, puedes.
Esolanging Fruit

Respuestas:

8

Haskell , 72 68 64 63 bytes

f=(1!)
c!t|t==c=[c]|t>c=c:(c+10^(pred.length.show.min c$t-c))!t

Pruébalo en línea!

Gracias Sriotchilism O'Zaic por -4 bytes!

Uso

f 321
[1,2,3,4,5,6,7,8,9,10,20,30,40,50,60,70,80,90,100,200,300,310,320,321]

Explicación

c!t         -- c=current number, t=target number
 |t==c=[c]  -- Target is reached, return last number
 |t>c=c:(c+10^(pred.length.show.min c$t-c))!t
      c:                                        -- Add current number to list
                                min c$t-c       -- The minimum of the current number, and the difference between the current number and the target
                    length.show.                -- The length of this number
               pred.                            -- Minus 1
           10^(                          )      -- Raise 10 to this power
         c+                                     -- Add that to the current number
        (                                 )!t   -- Recursion
Paul Mutser
fuente
44
Bienvenido a PPCG! Buena primera respuesta.
Arnauld
2
No conozco a Haskell, pero quizás alguno de estos consejos podría ayudar: consejos para jugar al golf en Haskell y consejos para jugar al golf en <todos los idiomas> . Pero estoy de acuerdo, buena respuesta. +1 de mi parte
Kevin Cruijssen
2
Bienvenido al sitio! Dado que (^)tiene mayor prioridad que (+)no necesita paréntesis alrededor de la (^)expresión. Lo mismo va para (!)y(:)
Wheat Wizard
1
pred.length.show.min c$t-cse puede acortar a length(show.min c$t-c)-1. Las funciones anónimas son aceptables, por lo que puede eliminar el liderazgo f=como se explica en nuestra guía de reglas de golf en Haskell .
Laikoni
1
En lugar de guardias, se puede utilizar un solo caso y un condicional: c!t=c: if t>c then (c+10^(length(show.min c$t-c)-1))!t else []. Esto permite aplicar este consejo para guardar algunos bytes más: ¡ Pruébelo en línea!
Laikoni
6

JavaScript (ES6), 50 bytes

f=n=>n?[...f(n-(1+/(^10)?(0*$)/.exec(n)[2])),n]:[]

Pruébalo en línea!

¿Cómo?

Teoría

Los siguientes pasos se repiten hasta norte=0 0 :

  • busque el número k de ceros finales en la representación decimal de norte
  • decremento k si norte es una potencia exacta de 10
  • restar X=10k de norte

Implementación

El valor de X se calcula directamente como una cadena con la siguiente expresión:

+---- leading '1'
|
1 + /(^10)?(0*$)/.exec(n)[2]
     \____/\___/
        |    |
        |    +---- trailing zeros (the capturing group that is appended to the leading '1')
        +--------- discard one zero if n starts with '10'

Nota : Excluir el inicio '10'solo afecta a las potencias exactas de 10 (por ejemplo, norte=1000 ) pero no cambia el número de ceros finales capturados para valores como norte=102300 (debido a los dígitos intermedios adicionales distintos de cero, en '10'realidad no coincide en absoluto en tales casos).

Arnauld
fuente
¡Nota ingeniosa que puedes hacer la iteración "hacia atrás" haciendo un seguimiento de solo una variable! Es un poco confuso que se utiliza kpara algo completamente diferente que en la descripción desafío (de hecho, su nes una mezcla de OP ny kya su xes su i.)
Ørjan Johansen
2

Perl 6 , 48 41 bytes

->\k{1,{$_+10**min($_,k-$_).comb/10}...k}

Pruébalo en línea!

Explicación:

->\k{                                   }  # Anonymous code block taking k
     1,                             ...k   # Start a sequence from 1 to k
       {                           }       # Where each element is
        $_+          # The previous element plus
           10**      # 10 to the power of
                           .comb     # The length of
               min($_,k-$_)          # The min of the current count and the remainder
                                /10  # Minus one
Jo King
fuente
2

APL (Dyalog Unicode) , 30 SBCS de bytes

Función de prefijo tácito anónimo. Imprime números en líneas separadas para stdout.

{⍺=⍵:⍺⋄⍺∇⍵+10*⌊/⌊10⍟⍵,⍺-⎕←⍵}∘1

Pruébalo en línea!

{... }∘1 anónimo infijo lambda con 1 curry como inicialnorte:

⍺=⍵ Si k y norte son iguales:

   volver (e imprimir implícitamente) k

  más:

  ⎕←⍵ impresión norte

  ⍺- restar eso de k

  ⍵, anteponer norte

  10⍟Iniciar sesión10 de aquellos

   piso esos

  ⌊/ mínimo de esos

  10* diez elevado al poder de eso

  ⍵+norte mas eso

  ⍺∇ recurse usando lo mismo k y nuevo norte

Adán
fuente
2

05AB1E , 15 bytes

1[=ÐIαD_#‚ßg<°+

El puerto de la respuesta de Haskell de @PaulMutser (primero) , ¡así que asegúrate de votarlo!

Pruébelo en línea o verifique todos los casos de prueba .

Emite los números delimitados por nueva línea.
Si debe ser una lista, tendría que agregar 3 bytes:

X[DˆÐIαD_#‚ßg<°+}¯

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

1             # Push a 1 to the stack
 [            # Start an infinite loop
  =           #  Print the current number with trailing newline (without popping it)
  Ð           #  Triplicate the current number
   Iα         #  Get the absolute difference with the input
     D        #  Duplicate that absolute difference
      _       #  If this difference is 0:
       #      #   Stop the infinite loop
      ‚ß      #  Pair it with the current number, and pop and push the minimum
        g   #  Calculate 10 to the power of the length of the minimum minus 1
           +  #  And add it to the current number
Kevin Cruijssen
fuente
1

Lote, 131 bytes

@set/an=i=1
:e
@if %n%==%i%0 set i=%i%0
@echo %n%
:c
@set/an+=i
@if %n% leq %1 goto e
@set/an-=i,i/=10
@if %i% neq 0 goto c

Toma la entrada como un parámetro de línea de comando y envía la lista de números a STDOUT. Explicación:

@set/an=i=1

Comienza con n=1y i=1representa el poder de 10.

:e
@if %n%==%i%0 set i=%i%0

Multiplique ipor 10 si nha alcanzado la siguiente potencia de 10.

@echo %n%

Salida del valor actual de n.

:c
@set/an+=i
@if %n% leq %1 goto e

Repita mientras ise puede agregar nsin que exceda la entrada.

@set/an-=i,i/=10

Restaurar el valor anterior de ny dividir ipor 10.

@if %i% neq 0 goto c

Si ino es cero, entonces probar a añadir ia nnuevo.

Neil
fuente
1

R , 67 65 bytes

-2 bytes gracias a Giuseppe

k=scan();o=1;i=10^(k:0);while(T<k)o=c(o,T<-T+i[i<=T&i+T<=k][1]);o

Bastante simple. Se necesita un conjunto de potencias de 10 más allá de lo que se necesitaría en orden inversoi .

(Preferiría usar en i=10^rev(0:log10(k))lugar dei=10^(k:0) ya que este último es computacionalmente ineficiente, ¡pero el golf es golf!).

Luego, en un ciclo while, aplica las condiciones iy toma el primero (es decir, el más grande); se actualiza ny se agrega a la salida

Pruébalo en línea!

Aaron Hayman
fuente
1
Guardar un byte usando en Tlugar de n; debería ser 2, pero no creo que TRUEsea ​​una salida aceptable k=1, así que configuramos o=+T. ¡Intentalo!
Giuseppe
2
Esa es una codificación horrible, me gusta. incidentalmente, puedo configurar o=1y obtener ese segundo byte.
Aaron Hayman
1

Pip , 27 bytes

Wa>Po+:y/t*Y1Ty>o|o+y>ay*:t

Pruébalo en línea!

En pseudocódigo:

a = args[0]
o = 1
print o
while a > o {
  y = 1
  till y > o || o + y > a
    y *= 10
  o += y / 10
  print o
}

Estoy bastante satisfecho con los trucos de golf que pude aplicar para acortar este algoritmo. Al inicializar, actualizar e imprimir cosas en el encabezado del bucle, pude evitar necesitar llaves para el cuerpo del bucle. Sin embargo, probablemente haya un algoritmo de golfista.

DLosc
fuente
0

Japt , 18 bytes

ÆT±ApTmTnU)sÊÉÃf§U

Intentalo

ÆT±ApTmTnU)sÊÉÃf§U     :Implicit input of integer U
Æ                      :Map the range [0,U)
 T±                    :  Increment T (initially 0) by
   A                   :  10
    p                  :  Raised to the power of
     Tm                :    The minimum of T and
       TnU             :      T subtracted from U
          )            :    End minimum
           s           :    Convert to string
            Ê          :    Length
             É         :    Subtract 1
              Ã        :End map
               f       :Filter
                §U     :  Less than or equal to U
Lanudo
fuente
0

Prólogo (SWI) , 142 bytes

L-D-M:-append(L,[D],M).
N-L-C-X-R-I:-I=1,C is X*10,N-L-C-C-R-1;D is C+X,(D<N,L-D-M,N-M-D-X-R-I;D>N,N-L-C-(X/10)-R-0;L-D-R).
N-R:-N-[]-0-1-R-1.

Pruébalo en línea!

Explicación que viene mañana o algo

Solo ASCII
fuente