À quel point peut-il devenir petit?

42

En partant d'un entier positif N , trouvez le plus petit entier N ' pouvant être calculé en divisant plusieurs fois N par un de ses chiffres (en base 10). Chaque chiffre sélectionné doit être un diviseur de N supérieur à 1 .

Exemple 1

La sortie attendue pour N = 230 est N '= 23 :

230/2 = 115, 115/5 = 23

Exemple n ° 2

La sortie attendue pour N = 129528 est N '= 257 :

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

Méfiez-vous des chemins non optimaux!

Nous pourrions commencer par 129528/9 = 14392 , mais cela ne conduirait pas au plus petit résultat possible. Le mieux que nous puissions faire si nous divisons d'abord par 9 est:

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

Règles

  • Les entrées peuvent être prises dans n'importe quel format raisonnable (entier, chaîne, tableau de chiffres, ...).
  • C'est du , donc la réponse la plus courte en octets gagne!

Cas de test

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
Arnauld
la source
1
Je me demande si cette série (1, 1, ..., 10, 11, 1, 13, ..., 1, ...) a une entrée OEIS
Draco 18s
Ce n'est pas (encore) AFAICS.
GNiklasch

Réponses:

11

Haskell , 67 à 61 octets

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

Essayez-le en ligne!

Explication:

  • read.pure<$>show ntransforme l'entier nen entrée en une liste de chiffres.
  • Pour chaque chiffre dde cette liste, nous vérifions d>1et mod n d<1, c'est-à-dire si ddivise n.
  • Si les contrôles sont efficaces, nous divisons npar det récursive appliquer f: f$div n d.
  • Globalement, cela donne une liste des entiers minimaux de tous les sous-arbres de n.
  • Comme la liste peut être vide, nous y annexons net renvoyons le minimumde la liste.
Laikoni
la source
11

Gelée , 8 octets

÷DfḶ߀Ṃo

Essayez-le en ligne!

Version alternative, beaucoup plus rapide, 9 octets

÷DfÆḌ߀Ṃo

Essayez-le en ligne!

Comment ça marche

÷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.
Dennis
la source
5

Ruby ,52 47 octets

En compétition pour le groupe de langues non-exotiques! (Remarque: une bonne idée, sinon jouer au golf, est d'ajouter .uniqaprès .digitscar toutes les branches similaires ont des résultats similaires)

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

Essayez-le en ligne!

Explication

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
}
Unihédron
la source
Pouvez-vous utiliser x<2|n%x?n:f[n/x]pour sauvegarder deux ou trois octets (selon que vous ayez besoin d'un |ou deux)?
Neil
@Neil Malheureusement, ruby ​​traite value%zerocomme une division par zéro, ainsi les court-circuits ne fonctionneront pas. De plus, la 0valeur de vérité est en rubis (les seules valeurs de Falsey sont fausses et nulles).
Unihedron
Cela fonctionnerait-il avec deux ||s?
Neil
Non, parce que 0 est considéré comme vrai, ce serait avec >0, mais alors c'est le même nombre de caractères.
Unihedron
Désolé, je ne vois pas d'où 0vient le si vous n'utilisez pas |?
Neil
5

Common Lisp , 136 octets

(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))))

Essayez-le en ligne!

Version lisible:

(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))))
Traut
la source
3
Bienvenue chez PPCG!
Laikoni
@Laikoni merci! Ce n'est pas la plus petite soumission mais elle est quand même assez amusante
Discussion
@ Laikoni mon erreur, corrigé. Je vous remercie!
Traut
@Arnauld merci d'avoir remarqué! J'ai corrigé le fragment de code et changé le lien.
Traut
@ Laikoni en effet! Je l'ai eu à 205b.
Traut
4

Wolfram Language (Mathematica) , 44 octets

-7 octets grâce à Misha Lavrov.

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

Essayez-le en ligne!

Alephalpha
la source
1
Un peu plus gaie est cette solution de 44 octets basée sur l’utilisation du caractère Intersection. Mais il y a de gros cas qu'il ne peut plus gérer car il manque de mémoire Range[#-1].
Misha Lavrov
1
Nous pouvons utiliser Most@Divisors@#au lieu de Range[#-1]pour éviter le problème de mémoire, mais le résultat est 49 octets .
Misha Lavrov
4

JavaScript (Firefox 30-57), 49 octets

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

Version compatible ES6, 52 octets:

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>

A l’origine, j’essayais de filtrer les chiffres non pertinents, mais il s’avère légèrement plus long à 54 octets:

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

Kotlin , 100 à 99 octets

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

Embellies

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

Tester

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

Édite

jrtapsell
la source
3

Gelée , 15 octets

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

Essayez-le en ligne!

Je dois admettre que cette ߀partie est empruntée à la réponse d' Erik . Le reste est développé séparément, en partie parce que je ne comprends même pas comment fonctionne le reste de cette réponse: P.

Comment ça marche?

Æ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.

* Je suis agréablement surpris que cela ¡fonctionne comme ça sur les listes, parce que sa signification normale est appliquée n fois .

Après que Dennis ait expliqué pourquoi il ߀n’a pas besoin de condition, nous avons cette version de 12 octets , ou sa version de 8 octets: P.

M. Xcoder
la source
3

R , 101 98 octets

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)

Essayez-le en ligne!

Une tonne d'octets est utilisée pour extraire les chiffres et ceux qui se divisent x; peut-être une autre approche est-elle nécessaire.

Giuseppe
la source
3

Excel Vba, 153 octets

Premier code-golf dans la seule langue que je connaisse :( Pas tout à fait favorable au 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

Appelle comme ça:

Sub callS()

result = S(655294464)

MsgBox result

End Sub

Je ne sais pas où tester cela en ligne.

Durielblood
la source
1
Bienvenue chez PPCG! Je ne connais pas vraiment Vba mais je suppose que vous pouvez remplacer And N > 0 par N = Sune précédente. (En outre, si j'avais un moyen de le tester, mon premier réflexe serait de vérifier si l'un des espaces peut être supprimé.)
Ørjan Johansen
2

APL (Dyalog) , 33 octets

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

Essayez-le en ligne!

Comment?

⍎¨⍕⍵ - saisir les chiffres de n

1~⍨- hors 1s

o/⍨ - filtrer par

0=⍵|⍨o- divisibilité de npar le chiffre

⍬≡...:⍵ - si vide, retourne n

⌊/ - sinon, restituer le minimum de

∇¨ - récursivité pour chaque nombre en

⍵÷d- la division de npar chacun des chiffres filtrés ci-dessus

Uriel
la source
2

Perl 5, 87 + 1 ( -p) = 88 octets

$r=0,map{$\=$_,$r++if!$\|$_<$\;for$i(/[2-9]/g){$_%$i||$h{$_/$i}++}}$_,keys%h;$r&&redo}{

essayez-le en ligne

Nahuel Fouilleul
la source