Скільки маленьких він може отримати?


42

Починаючи з натурального цілого числа N , знайдіть найменше ціле число N ', яке можна обчислити шляхом багаторазового ділення N на одну з його цифр (у базі-10). Кожна обрана цифра повинна бути дільником на N, що перевищує 1 .

Приклад №1

Очікуваний вихід для N = 230 - N '= 23 :

230/2 = 115, 115/5 = 23

Приклад №2

Очікуваний вихід для N = 129528 становить N '= 257 :

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

Остерігайтеся неоптимальних шляхів!

Ми могли б почати з 129528/9 = 14392 , але це не призведе до найменшого можливого результату. Найкраще, що ми можемо зробити, якщо спочатку поділимо на 9, це:

129528/9 = 14392, 14392/2 = 7196, 7196/7 = 1028, 1028/2 = 514 -> неправильно!

Правила

  • Введення може бути прийнято у будь-якому розумному форматі (ціле число, рядок, масив цифр, ...).
  • Це , тому найкоротша відповідь у байтах виграє!

Тестові справи

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
Цікаво, чи в цій серії (1, 1, ..., 10, 11, 1, 13, ..., 1, ...) є запис OEIS
Draco18s

Це ще (поки що), АФАЙКС.
GNiklasch

Відповіді:


11

Haskell , 67 61 байт

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

Спробуйте в Інтернеті!

Пояснення:

  • read.pure<$>show nперетворює вхідне ціле число nу список цифр.
  • Для кожної цифри dз цього списку, ми перевіряємо d>1і mod n d<1, тобто чи dвододіли n.
  • Якщо перевірка успішна, ми розділимо nна dі рекурсивно застосовуються f: f$div n d.
  • У цілому це дає список мінімальних цілих чисел з усіх під-дерев n.
  • Оскільки список може бути порожнім, ми додаємо nйого до нього та повертаємо його minimum.

11

Желе , 8 байт

÷DfḶ߀Ṃo

Спробуйте в Інтернеті!

Альтернативна версія, набагато швидша, 9 байт

÷DfÆḌ߀Ṃo

Спробуйте в Інтернеті!

Як це працює

÷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

Рубі ,52 47 байт

Конкурує група неекзотичних мов! (Примітка: хороша ідея, якщо не гольф, - це додавати .uniqпісля, .digitsтому що всі подібні гілки мають схожі результати)

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

Спробуйте в Інтернеті!

Пояснення

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
}

Чи можете ви скористатися x<2|n%x?n:f[n/x]для збереження двох-трьох байтів (залежно від того, чи потрібен вам один |чи два)?
Ніл

@Neil На жаль, рубін розглядає value%zeroяк поділ на нуль, тому коротке замикання не буде працювати. Крім того, 0є трибічним значенням у рубіні (єдині значення фальси - хибні та нульові).
Unihedron

Так би це працювало з двома ||s?
Ніл

Ні, тому що 0 вважається істинним, це було б з >0, але тоді це те саме число граф.
Unihedron

Вибачте, я не бачу, куди 0йде, якщо ви не використовуєте |?
Ніл

5

Лист звичайний , 136 байт

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

Спробуйте в Інтернеті!

Читаема версія:

(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
Ласкаво просимо до PPCG!
Лайконі

@Laikoni дякую! Не найменше подання, але все-таки досить веселе
Траут

@Laikoni моя помилка, виправлена. спасибі!
Траут

@Arnauld дякую за те, що помітили! Я виправив фрагмент і змінив посилання.
Траут

@Laikoni справді! Я дійшов до 205b.
Траут


4

Мова Вольфрама (Mathematica) , 44 байти

-7 байт завдяки Міші Лаврову.

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

Спробуйте в Інтернеті!


1
Дещо гольфіст - це 44- байтне рішення, засноване на використанні символу для Intersection. Але є великі випадки, з якими він більше не може впоратися, оскільки у нього закінчується генерування пам'яті Range[#-1].
Міша Лавров

1
Ми можемо використовувати Most@Divisors@#замість цього, Range[#-1]щоб уникнути проблеми з пам'яттю, але результат - 49 байт .
Міша Лавров

4

JavaScript (Firefox 30-57), 49 байт

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

Версія, сумісна з ES6, 52 байти:

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>

Спочатку я спробував відфільтрувати невідповідні цифри, але виявляється трохи довше в 54 байти:

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

3

Котлін , 100 99 байт

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

Прикрасили

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

Тест

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

Правки


3

Желе , 15 байт

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

Спробуйте в Інтернеті!

Треба визнати, що ߀частина запозичена з відповіді Еріка . Решта розробляється окремо, частково тому, що я навіть не розумію, як все-таки працює ця відповідь: P.

Як це працює?

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

* Я приємно здивований, що ¡працює так у списках, оскільки його нормальне значення застосовується це n разів .

Після того, як Денніс пояснив, чому ߀не потрібен умовний, у нас є цей 12-байтний або його 8-байтний варіант: P.



3

Excel Vba, 153 байти

Перший в історії код-гольф єдиною мовою, яку я знаю :( Не зовсім зручна для гольфу ...

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

Телефонуйте так:

Sub callS()

result = S(655294464)

MsgBox result

End Sub

Я не маю поняття, де перевірити це в Інтернеті.


1
Ласкаво просимо до PPCG! Я дійсно не знаю Vba, але я підозрюю, що ви можете замінити And N > 0 його N = Sна попередній рядок. (Також, якби у мене був спосіб перевірити це, моїм першим інстинктом було б перевірити, чи можна видалити будь-який пробіл.)
Ørjan Johansen

2

APL (Dyalog) , 33 байти

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

Спробуйте в Інтернеті!

Як?

⍎¨⍕⍵ - схоплюйте цифри n

1~⍨- виключаючи 1s

o/⍨ - фільтрувати за

0=⍵|⍨o- подільність nна цифру

⍬≡...:⍵ - якщо порожній, поверніть n

⌊/ - в іншому випадку поверніть мінімум

∇¨ - рекурсія для кожного числа в

⍵÷d- поділ nкожної з цифр, відфільтрованих вище




Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.