Quanto può essere piccolo?


42

Partendo con un numero intero positivo N , trova il numero intero più piccolo N ' che può essere calcolato dividendo ripetutamente N per una delle sue cifre (in base-10). Ogni cifra selezionata deve essere un divisore di N maggiore di 1 .

Esempio 1

L'output previsto per N = 230 è N '= 23 :

230/2 = 115, 115/5 = 23

Esempio n. 2

L'output previsto per N = 129528 è N '= 257 :

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

Attenzione ai percorsi non ottimali!

Potremmo iniziare con 129528/9 = 14392 , ma ciò non porterebbe al risultato più piccolo possibile. Il meglio che possiamo fare se prima dividiamo per 9 è:

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

Regole

  • L'input può essere preso in qualsiasi formato ragionevole (intero, stringa, matrice di cifre, ...).
  • Questo è , quindi vince la risposta più breve in byte!

Casi 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

1
Mi chiedo se questa serie (1, 1, ..., 10, 11, 1, 13, ..., 1, ...) abbia una voce OEIS
Draco18s,

Non (ancora), AFAICS.
GNiklasch,

Risposte:


11

Haskell , 67 61 byte

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

Provalo online!

Spiegazione:

  • read.pure<$>show ntrasforma il numero intero di input nin un elenco di cifre.
  • Per ogni cifra ddi questo elenco, controlliamo d>1e mod n d<1, cioè se ddivide n.
  • Se le verifiche hanno esito positivo, dividiamo nda de applichiamo in modo ricorsivo f: f$div n d.
  • Complessivamente, questo produce un elenco degli interi minimi da tutti i sotto-alberi di n.
  • Poiché l'elenco potrebbe essere vuoto, lo aggiungeremo ne restituiremo minimuml'elenco.

11

Gelatina , 8 byte

÷DfḶ߀Ṃo

Provalo online!

Versione alternativa, molto più veloce, 9 byte

÷DfÆḌ߀Ṃo

Provalo online!

Come funziona

÷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

rubino ,52 47 byte

Competere per il gruppo di lingue non esotiche! (Nota: una buona idea, se non il golf, è quella di aggiungere .uniqdopo .digitsperché tutti i rami simili hanno risultati simili)

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

Provalo online!

Spiegazione

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
}

Puoi usare x<2|n%x?n:f[n/x]per salvare due o tre byte (a seconda che tu ne abbia bisogno uno |o due)?
Neil,

@Neil Sfortunatamente, il rubino considera value%zerola divisione per zero, quindi il corto circuito non funzionerà. Inoltre, 0è un valore di verità in rubino (gli unici valori di falsità sono falso e zero).
Unihedron,

Funzionerebbe quindi con due ||secondi?
Neil,

No, perché 0 è considerato vero, sarebbe con >0, ma poi è lo stesso conteggio dei caratteri.
Unihedron,

Mi dispiace, non vedo da dove 0viene se non stai usando |?
Neil,

5

Lisp comune , 136 byte

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

Provalo online!

Versione leggibile:

(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
Benvenuti in PPCG!
Laikoni,

@Laikoni grazie! Non la più piccola presentazione, ma comunque abbastanza divertente
Traut,

@Laikoni il mio errore, risolto. grazie!
Traut,

@Arnauld grazie per averlo notato! Ho corretto lo snippet e modificato il collegamento.
Traut,

@Laikoni infatti! L'ho portato a 205b.
Traut il


4

Wolfram Language (Mathematica) , 44 byte

-7 byte grazie a Misha Lavrov.

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

Provalo online!


1
Un po 'più golfista è questa soluzione a 44 byte basata sull'uso del carattere per Intersection. Ma ci sono grandi casi che non può più gestire perché si esaurisce la generazione di memoria Range[#-1].
Misha Lavrov,

1
Possiamo usare Most@Divisors@#invece di Range[#-1]evitare il problema di memoria, ma il risultato è di 49 byte .
Misha Lavrov,

4

JavaScript (Firefox 30-57), 49 byte

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

Versione compatibile ES6, 52 byte:

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>

Inizialmente ho provato a filtrare le cifre irrilevanti, ma risulta essere leggermente più lungo a 54 byte:

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

3

Kotlin , 100 99 byte

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

Abbellire

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

Test

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

Le modifiche


3

Gelatina , 15 byte

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

Provalo online!

Devo ammettere che la ߀parte è presa in prestito dalla risposta di Erik . Il resto è sviluppato separatamente, in parte perché non capisco nemmeno come funziona il resto di quella risposta: P.

Come funziona?

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

* Sono piacevolmente sorpreso che ¡funzioni così negli elenchi, perché il suo significato normale si applica questo n volte .

Dopo che Dennis ha spiegato perché ߀non è necessario un condizionale, abbiamo questa versione a 12 byte o la sua versione a 8 byte: P.


3

R , 101 98 byte

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)

Provalo online!

Una tonnellata di byte va nell'estrarre le cifre e quali si dividono x; forse è necessario un altro approccio.


3

Excel Vba, 153 byte

Il primo golf di sempre in codice nell'unica lingua che conosco :( Non proprio per il 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

Chiama in questo modo:

Sub callS()

result = S(655294464)

MsgBox result

End Sub

Non ho idea di dove testarlo online.


1
Benvenuti in PPCG! Non conosco davvero Vba ma sospetto che tu possa sostituirlo And N > 0 con un N = Ssu una riga precedente. (Inoltre, se avessi un modo per testarlo, il mio primo istinto sarebbe quello di verificare se uno degli spazi può essere rimosso.)
Ørjan Johansen,

2

APL (Dyalog) , 33 byte

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

Provalo online!

Come?

⍎¨⍕⍵ - afferrare cifre di n

1~⍨- esclusi 1s

o/⍨ - filtra per

0=⍵|⍨o- divisibilità nper cifra

⍬≡...:⍵ - se vuoto, ritorna n

⌊/ - in caso contrario, restituire almeno

∇¨ - ricorsione per ogni numero in

⍵÷d- la divisione di nper ciascuna delle cifre filtrate sopra




Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.