¿Qué tan pequeño puede ser?


42

Comenzando con un número entero positivo N , encuentre el número entero más pequeño N ' que se puede calcular dividiendo repetidamente N por uno de sus dígitos (en base-10). Cada dígito seleccionado debe ser un divisor de N mayor que 1 .

Ejemplo 1

La salida esperada para N = 230 es N '= 23 :

230/2 = 115, 115/5 = 23

Ejemplo # 2

La salida esperada para N = 129528 es N '= 257 :

129528/8 = 16191, 16191/9 = 1799, 1799/7 = 257

¡Cuidado con los caminos no óptimos!

Podríamos comenzar con 129528/9 = 14392 , pero eso no llevaría al resultado más pequeño posible. Lo mejor que podemos hacer si primero dividimos entre 9 es:

129528/9 = 14392, 14392/2 = 7196, 7196/7 = 1028, 1028/2 = 514 -> ¡mal!

Reglas

  • La entrada se puede tomar en cualquier formato razonable (entero, cadena, matriz de dígitos, ...).
  • Este es el , por lo que gana la respuesta más corta en bytes.

Casos de prueba

1         --> 1
7         --> 1
10        --> 10
24        --> 1
230       --> 23
234       --> 78
10800     --> 1
10801     --> 10801
50976     --> 118
129500    --> 37
129528    --> 257
8377128   --> 38783
655294464 --> 1111

1
Me pregunto si esta serie (1, 1, ..., 10, 11, 1, 13, ..., 1, ...) tiene una entrada OEIS
— Draco18s

No lo hace (todavía), AFAICS.
— GNiklasch

Respuestas:


11

Haskell , 67 61 bytes

f n=minimum$n:[f$div n d|d<-read.pure<$>show n,d>1,mod n d<1]

Pruébalo en línea!

Explicación:

  • read.pure<$>show ntransforma el entero de entrada nen una lista de dígitos.
  • Para cada dígito dde esta lista, verificamos d>1y mod n d<1, es decir, si se ddivide n.
  • Si las comprobaciones tienen éxito, dividimos npor dy aplicar de forma recursiva f: f$div n d.
  • En total, esto produce una lista de los enteros mínimos de todos los subárboles de n.
  • Como la lista puede estar vacía, la agregamos ny le devolvemos minimumla lista.

11

Jalea , 8 bytes

÷DfḶ߀Ṃo

Pruébalo en línea!

Versión alternativa, mucho más rápida, 9 bytes.

÷DfÆḌ߀Ṃo

Pruébalo en línea!

Cómo funciona

÷DfḶ߀Ṃo  Main link. Argument: n

 D        Decimal; yield the digits of n.
÷         Divide n by each of its digits.
   Ḷ      Unlength; yield [0, ..., n-1].
  f       Filter; keep quotients that belong to the range.
    ߀    Recursively map this link over the resulting list.
      Ṃ   Take the minimum. This yields 0 if the list is empty.
       o  Logical OR; replace 0 with n.


5

rubí ,52 47 bytes

¡Compitiendo por el grupo de idiomas no exóticos! (Nota: una buena idea, si no es golf, es agregar .uniqdespués .digitsporque todas las ramas similares tienen resultados similares)

f=->n{n.digits.map{|x|x>1&&n%x<1?f[n/x]:n}.min}

Pruébalo en línea!

Explicación

f=->n{      # Function "f" n ->
   n.digits # n's digits (in reverse order (<- doesn't matter))
            # fun fact: all numbers always have at least one digit
    .map{|x|# Map function for every digit "x" ->
       x>1&&    # x is 2-9 and
       n%x<1    # n mod x == 0, or, "n is divisible by x"
       ? f[n/x] # then recursively find smallest of f[n/x]
       : n      # otherwise: n (no shortest path in tree)
     }.min  # Smallest option out of the above
            # if we reach a dead end, we should get n in this step
}

¿Se puede usar x<2|n%x?n:f[n/x]para guardar dos o tres bytes (dependiendo de si necesita uno |o dos)?
— Neil

@Neil Desafortunadamente, ruby ​​trata la value%zerodivisión por cero, por lo que el cortocircuito no funcionará. Además, 0es un valor verdadero en ruby ​​(los únicos valores falsey son falso y nulo).
— Unihedron

Entonces, ¿funcionaría con dos ||s?
— Neil

No, porque 0 se considera verdadero, sería con >0, pero es el mismo recuento de caracteres.
— Unihedron

Lo siento, no veo de dónde 0viene si no lo estás usando |.
— Neil

5

Lisp común , 136 bytes

(defun f(n)(apply 'min(or(loop for z in(map'list #'digit-char-p(write-to-string n))if(and(> z 1)(<(mod n z)1))collect(f(/ n z)))`(,n))))

Pruébalo en línea!

Versión legible:

(defun f (n)
  (apply 'min
         (or (loop for z in (map 'list
                                 #'digit-char-p
                                 (write-to-string n))
                   if (and (> z 1)
                           (< (mod n z) 1))
                   collect (f (/ n z)))
             `(,n))))

3
Bienvenido a PPCG!
— Laikoni

@Laikoni gracias! No es la presentación más pequeña pero sigue siendo bastante divertida
— Traut

@Laikoni mi error, solucionado. ¡gracias!
— Traut

@Arnauld gracias por notarlo! Arreglé el fragmento y cambié el enlace.
— Traut

@Laikoni de hecho! Lo bajé a 205b.
— Traut


4

Wolfram Language (Mathematica) , 44 bytes

-7 bytes gracias a Misha Lavrov.

Min[#0/@(#/IntegerDigits@#⋂Range[#-1]),#]&

Pruébalo en línea!


1
Algo más elegante es esta solución de 44 bytes basada en el uso del ⋂carácter Intersection. Pero hay casos grandes que ya no puede manejar porque se queda sin generación de memoria Range[#-1].
— Misha Lavrov

1
Podemos usar en Most@Divisors@#lugar de Range[#-1]evitar el problema de memoria, pero el resultado es 49 bytes .
— Misha Lavrov

4

JavaScript (Firefox 30-57), 49 bytes

f=n=>Math.min(...(for(c of''+n)c<2|n%c?n:f(n/c)))

Versión compatible con ES6, 52 bytes:

f=n=>Math.min(...[...''+n].map(c=>c<2|n%c?n:f(n/c)))
<input type=number oninput=o.textContent=f(this.value)><pre id=o>

Originalmente intenté filtrar dígitos irrelevantes, pero resulta ser un poco más largo a 54 bytes:

f=n=>Math.min(n,...(for(c of''+n)if(c>1&n%c<1)f(n/c)))

3

Kotlin , 100 99 bytes

fun f(i:Int):Int{return i.toString().map{it.toInt()-48}.filter{it>1&&i%it<1}.map{f(i/it)}.min()?:i}

Embellecido

fun f(i:Int):Int{
    return i.toString()
        .map { it.toInt()-48 }
        .filter { it >1 && i % it < 1}
        .map { f(i/it) }
        .min() ?: i
}

Prueba

fun f(i:Int):Int{return i.toString().map{it.toInt()-48}.filter{it>1&&i%it<1}.map{f(i/it)}.min()?:i}

val tests = listOf(
        1 to 1,
        7 to 1,
        10 to 10,
        24 to 1,
        230 to 23,
        234 to 78,
        10800 to 1,
        10801 to 10801,
        50976 to 118,
        129500 to 37,
        129528 to 257,
        8377128 to 38783,
        655294464 to 1111)

fun main(args: Array<String>) {
    for ( test in tests) {
        val computed = f(test.first)
        val expected = test.second
        if (computed != expected) {
            throw AssertionError("$computed != $expected")
        }
    }
}

Ediciones


3

Jalea , 15 bytes

ÆDḊfD
:Ç߀µÇ¡FṂ

Pruébalo en línea!

Debo admitir que la ߀parte está tomada de la respuesta de Erik . El resto se desarrolla por separado, en parte porque ni siquiera entiendo cómo funciona el resto de esa respuesta de todos modos: P.

¿Cómo funciona?

ÆDḊfD ~ Helper link (monadic). I'll call the argument N.

ÆD    ~ Take the divisors.
  Ḋ   ~ Dequeue (drop the first element). This serves the purpose of removing 1.
   fD ~ Take the intersection with the decimal digits.

:Ç߀µÇ¡FṂ ~ Main link.

 Ç        ~ Apply the helper link to the first input.
:         ~ And perform element-wise integer division.
     Ç¡   ~ If the helper link applied again is non-empty*, then...
  ߀µ     ~ Apply this link to each (recurse).
       FṂ ~ Flatten and get the maximum.

* Estoy gratamente sorprendido de que ¡funcione así en las listas, porque su significado normal es aplicar esto n veces .

Después explicó Dennis por eso ߀no necesita un condicional, tenemos este 12-byter , o su versión de 8 bytes: P.


3

R , 101 98 bytes

f=function(x,e=(d=x%/%10^(0:nchar(x))%%10)[d>1])"if"(sum(y<-which(!x%%e)),min(sapply(x/e[y],f)),x)

Pruébalo en línea!

Una tonelada de bytes se destina a extraer los dígitos y cuáles se dividen x; Quizás otro enfoque sea necesario.


3

Excel Vba, 153 bytes

Primer código de golf en el único idioma que conozco :( No es exactamente amigable para el golf ...

Function S(X)
S = X
For I = 1 To Len(CStr(X))
A = Mid(X, I, 1)
If A > 1 Then If X Mod A = 0 Then N = S(X / A)
If N < S And N > 0 Then S = N
Next I
End Function

Llama así:

Sub callS()

result = S(655294464)

MsgBox result

End Sub

No tengo idea de dónde probar esto en línea.


1
Bienvenido a PPCG! Realmente no conozco Vba, pero sospecho que puedes reemplazarlo And N > 0 con un N = Sen una línea anterior. (Además, si tuviera una forma de probarlo, mi primer instinto sería verificar si se pueden eliminar algunos de los espacios).
— Ørjan Johansen

2

APL (Dyalog) , 33 bytes

{⍬≡d←o/⍨0=⍵|⍨o←1~⍨⍎¨⍕⍵:⍵⋄⌊/∇¨⍵÷d}

Pruébalo en línea!

¿Cómo?

⍎¨⍕⍵ - agarrar dígitos de n

1~⍨- excluyendo 1s

o/⍨ - filtrado por

0=⍵|⍨o- divisibilidad de npor el dígito

⍬≡...:⍵ - si está vacío, regrese n

⌊/ - de lo contrario, devolver un mínimo de

∇¨ - recursividad para cada número en

⍵÷d- la división de npor cada uno de los dígitos filtrados arriba




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.