Złóż liczbę całkowitą, aby zaoszczędzić miejsce!

20

Szalony matematyk posiada szeroką kolekcję liczb, dlatego przestrzeń, którą zostawił, jest dość ograniczona. Aby uratować trochę, musi złożyć liczby całkowite, ale niestety jest naprawdę leniwy. Twoim zadaniem, jeśli chcesz mu pomóc, jest stworzenie funkcji / programu, który złoży daną liczbę całkowitą dodatnią dla naszego maniaka liczb.

Jak złożyć liczbę całkowitą?

Jeśli jest równomiernie podzielny przez sumę jego cyfr, podziel go przez sumę jego cyfr. Jeśli nie spełnia tego wymogu, weź jego resztę po podzieleniu przez sumę jego cyfr. Powtarzaj proces aż do osiągnięcia wyniku 1. Złożona liczba całkowita to liczba operacji, które musiałeś wykonać. Weźmy przykład (powiedzmy 1782):

  1. Get sumę cyfr: 1 + 7 + 8 + 2 = 18. 1782jest równomiernie podzielny przez 18, więc następną liczbą jest 1782 / 18 = 99.

  2. 99nie jest podzielna przez 9 + 9 = 18, stąd bierzemy resztę: 99 % 18 = 9.

  3. 9jest oczywiście podzielny przez 9, więc dzielimy go i otrzymujemy 1.

Rezultat jest taki 3, ponieważ do osiągnięcia potrzebne były 3 operacje 1.

Zasady i specyfikacje

  • Niektóre liczby całkowite mogą mieć sumę cyfr równą 1, np. 10Lub 100. Twój program nie musi obsługiwać takich przypadków. Oznacza to, że będziesz mieć pewność, że liczba całkowita podana jako dane wejściowe nie ma sumy cyfr równej 1, i żadna operacja z podaną liczbą całkowitą nie spowoduje liczby, której suma cyfr to 1(z wyjątkiem 1samej, która jest „ cel"). Na przykład nigdy nie otrzymasz 10lub 20jako dane wejściowe.

  • Wejście będzie dodatnią liczbą całkowitą wyższą niż 1.

  • Obowiązują domyślne luki .

  • Możesz przyjmować dane wejściowe i dostarczać dane wyjściowe dowolnym standardowym środkiem .


Przypadki testowe

Wejście -> Wyjście

2 -> 1
5 -> 1
9 -> 1
18 -> 2
72 -> 2
152790 -> 2
152 -> 3
666 -> 3
777 -> 3
2010 -> 3
898786854 -> 4

Oto program, który pozwala zwizualizować proces i wypróbować więcej przypadków testowych.


To jest , więc wygrywa najkrótszy kod w każdym języku (oceniany w bajtach)!

Pan Xcoder
źródło
Zainspirowany tym wyzwaniem , choć na pierwszy rzut oka może się nie wydawać.
Mr. Xcoder,
3
Będzie to działać jako rozwiązanie zatrzymujące, ale w dłuższej perspektywie matematyk powinien naprawdę rozważyć zakup jednego z hoteli Hilberta . Zawsze możesz znaleźć niewykorzystany pokój w jednym z nich.
Ray
mimo że 8987868546jest prawidłowym wejściem, spowoduje uszkodzenie narzędzia testowego, a także wielu (jeśli nie wszystkich) odpowiedzi ...
Mischa,
@MischaBehrend Twój przykład nie jest prawidłowym wejściem. Myślę, że źle opisałeś mój ostatni przypadek testowy. Prawidłowe dane wejściowe to 898786854: nie 8987868546(dodałeś 6na końcu)
Pan Xcoder
nvm ... powinien przeczytać całą pierwszą zasadę ... zostawiając to tutaj, więc wiesz, dlaczego myślałem, że to jest poprawne: to nie był błąd ... Zmieniłem celowo testowanie tych skryptów ... i czytając reguły to jest prawidłowym wejściem. Suma wszystkich cyfr 8987868546 nie jest równa 1 ( spełniona reguła 1 ) i 8987868546jest liczbą całkowitą dodatnią wyższą niż 1 ( spełniona reguła 2 ).
Mischa,

Odpowiedzi:

6

05AB1E , 13 12 bajtów

[¼DSO‰0Kθ©#®

Wypróbuj online!

Wyjaśnienie

[               # start loop
 ¼              # increment counter
  D             # duplicate current value
   SO           # sum the digits in the copy
     ‰          # divmod the current value by its digit-sum
      0K        # remove 0 from the resulting list
        θ       # pop the last element
         ©      # store a copy in register
          #     # if the current value is 1, break
           ®    # push the copy from register
                # implicitly output counter
Emigna
źródło
6

Python 2 , 63 57 bajtów

-1 dzięki totalnie ludzkiemu
-1 dzięki Mr. Xcoder
-4 dzięki reffu

def f(n):a=sum(map(int,`n`));return n>1and-~f(n%a or n/a)

Wypróbuj online!

Arfie
źródło
1
57 bajtów Również przepraszam, że na początku uczyniłem z tego własną odpowiedź. To ma więcej sensu jako komentarz
reffu
5

Haskell, 85 78 bajtów

f 1=0
f n|r<1=1+f(n`div`s)|1<2=1+f r where s=sum(read.pure<$>show n);r=n`rem`s

Zaoszczędź 7 bajtów dzięki Bruce'owi Forte.

Wypróbuj online.

Cristian Lupascu
źródło
Zaoszczędź więcej bajtów za pomocą divMod i upuszczając where: Wypróbuj online!
Laikoni
@Laikoni Wow, to duża poprawa! Proszę zamieścić jako inną odpowiedź; wystarczająco różni się od mojego. BTW: Szukałem sztuczki, aby się jej pozbyć where. Użyję tego w przyszłości. :)
Cristian Lupascu
sum[read[d]|d<-show n]zapisuje bajt
nimi
5

JavaScript (ES6), 66 58 51 49 bajtów

Pobiera dane wejściowe jako liczbę całkowitą. Powraca falsedo 0lub 1i zgłasza błąd przepełnienia gdy napotka dowolną liczbę którego cyfry dodać maksymalnie 1.

f=n=>n>1&&f(n%(x=eval([...""+n].join`+`))||n/x)+1
  • 8 bajtów zapisanych z pomocą Justina .

Sprawdź to

o.innerText=(

f=n=>n>1&&f(n%(x=eval([...""+n].join`+`))||n/x)+1

)(i.value=898786854);oninput=_=>o.innerText=f(+i.value)
<input id=i type=number><pre id=o>

Kudłaty
źródło
1
Czy możesz zapisać niektóre bajty, sumując cyfry za pomocą eval(array.join`+`)?
Justin Mariner,
Mógłbym, @JustinMariner - do tego mnie ninja! Dzięki :)
Kudłaty
4

Łuska , 12 bajtów

←€1¡Ṡ§|÷%oΣd

Wypróbuj online!

Wyjaśnienie

←€1¡Ṡ§|÷%oΣd  Implicit input, e.g. n=1782
    Ṡ§|÷%oΣd  This part defines the transformation.
         oΣ   Sum of
           d  digits: s=18
    Ṡ   %     n mod s: 0
     §|       or (take this branch if last result was 0)
       ÷      n divided by s: 99
   ¡          Iterate the transformation: [1782,99,9,1,1,1,...
 €1           Index of 1 (1-based): 4
←             Decrement: 3
              Print implicitly.
Zgarb
źródło
3

C # (.NET Core) , 87 bajtów

n=>{int i=0,k,l;for(;n>1;++i){for(l=n,k=0;l>0;l/=10)k+=l%10;n=n%k>0?n%k:n/k;}return i;}

Wypróbuj online!

Funkcja Lambda, która przyjmuje i zwraca liczbę całkowitą.

jkelm
źródło
3

Japt , 22 19 17 bajtów

-3 bajty dzięki @Shaggy.
-2 bajty dzięki @ETHproductions


ìx
>1©1+ßU%VªU/V

Wypróbuj online!

Justin Mariner
źródło
1
<s> 20 bajtów </s> 19 bajtów
Kudłaty
1
W rzeczywistości możesz zmienić, s_¬aby ìzapisać kolejne dwa bajty :-)
ETHproductions
@ETHproductions Och, to naprawdę fajne, dzięki!
Justin Mariner,
2

Siatkówka , 100 bajtów

$
;
{`(.+);
$1$*1;$&
(?<=;.*)\d(?=.*;)
$*
.*;1;(.*)
$.1
r`(1)*(\3)*;(1+);
$#1;$#2;1
0;(.*);|;.*;
$1;

Wypróbuj online! Link zawiera tylko mniejsze przypadki testowe, ponieważ większe trwają zbyt długo.

Neil
źródło
2

Mathematica, 73 bajty

(t=#;For[r=0,t>1,r++,If[(s=Mod[t,g=Tr@IntegerDigits@t])<1,t=t/g,t=s]];r)&
J42161217
źródło
Można ==0zastąpić <1?
Pan Xcoder,
@ Mr.Xcoder tak, oczywiście! Zrobiłem wersję sortującą ...
J42161217,
2

PHP, 68 + 1 bajtów

wyjście jednostkowe:

for($n=$argn;$n>1;$n=$n%($s=array_sum(str_split($n)))?:$n/$s)echo 1;

wyjście dziesiętne, 73 + 1 bajtów:

for($n=$argn;$n>1;$i++)$n=$n%($s=array_sum(str_split($n)))?:$n/$s;echo$i;

Uruchom jako potok z -nRlub spróbuj online .


Operator Elvisa wymaga PHP 5.3 lub nowszego. Dla starszego PHP, wymień ?:z ?$n%$s:(+5 bajtów).

Tytus
źródło
2

Rubinowy, 46 bajtów

f=->n{s=n.digits.sum;n<2?0:1+f[n%s<1?n/s:n%s]}
m-chrzan
źródło
2

Haskell , 94 93 89 88 bajtów

To wydaje się naprawdę długie ...

length.fst.span(/=1).iterate g
g x|(d,m)<-x`divMod`sum[read[d]|d<-show x]=last$m:[d|m<1]

Wypróbuj online!

Dzięki @Laikoni i @nimi za grę w golfa po 1 bajcie każdy!

ბიმო
źródło
1

Galaretka , 12 bajtów

dDS$Ṛȯ/µÐĿL’

Wypróbuj online!

Erik the Outgolfer
źródło
Ciekawe podejście! Teraz czekamy na Jonathan: P
Mr. Xcoder
@ Mr.Xcoder Nie sądzę, tym razem :)
Erik the Outgolfer,
Ja też nie, to był żart :)
Mr. Xcoder
1

Perl, 71 bajtów, 64 bajtów, 63 bajty

-pl

$c=0;while($_>1){$s=0;$s+=$_ for/./g;$_=$_%$s?$_%$s:$_/$s;++$c};$_=$c

Wypróbuj online

EDYCJA: zapisano 7 bajtów, dzięki komentarzowi Xcali

-p

while($_>1){$s=0;$s+=$_ for/./g;$_=$_%$s?$_%$s:$_/$s;++$c}$_=$c

EDYCJA: od 5.14 nieniszczące podstawienie s /// r

-pl

while($_>1){$s=eval s/\B/+/gr;$_=$_%$s?$_%$s:$_/$s;++$c}$_=$c
Nahuel Fouilleul
źródło
Czy -plzamiast tego na wierzchu powinna znajdować się flaga wiersza poleceń?
Erik the Outgolfer,
tak, są to opcje perla
Nahuel Fouilleul
Powinieneś liczyć -plflagę zgodnie z tym postem .
Erik the Outgolfer,
Naliczyłem 69 bajtów +2 dla opcji pl, czy to prawda?
Nahuel Fouilleul
Możesz trochę pograć w golfa. $cnie trzeba inicjować. Rozpocznie się od wartości undef0. Średnik po zamknięciu while może przejść. Nie potrzebujesz też -l. Nie jest wymagane pobieranie wielu danych wejściowych w jednym przebiegu.
Xcali,
1

Dyalog APL, 36 bajtów

{x←+/⍎¨⍕⍵⋄1=⍵:00=x|⍵:1+∇⍵÷x1+∇x|⍵}

Wypróbuj online!

W jaki sposób?

{
   x←+/⍎¨⍕⍵       x = digit sum
   1=⍵:0          if arg = 1: bye
   0=x|⍵:1+∇⍵÷x   if arg divisible by x: recurse with arg/x
   1+∇x|⍵         recurse with arg mod x
}
Uriel
źródło
1

Gaia , 13 bajtów

-@{:ΣZ¤∨)‡}°\

Wypróbuj online!

Wyjaśnienie

-              Push -1 (this will be the counter)
 @             Push input (the starting number)
  {:ΣZ¤∨)‡}°   Repeat this block until the results of 2 consecutive runs are the same:
   :            Copy the number
    Σ           Digital sum
     Z          Divmod number by digital sum
      ¤         Swap
       ∨        Logical or: left-most non-zero out of (number mod sum, number div sum)
        )‡      Increment the counter
            \  Delete the final 1, implicitly print the counter
Business Cat
źródło
1

Matlab, 150 bajtów

function[d]=X(x) 
d=0;while ~strcmp(x,'1')z='sum(str2num(x(:)))';a=eval(['rem(',x,',',z,')']);y=num2str(a*(a>0)+eval([x,'/',z])*(a==0));x=y;d=d+1;end

Wejściom należy podać funkcję jako ciąg znaków, taki jak X („152”).

Funkcja działa podczas zapętlania i zwiększania wartości d. Thex=y;Linia była konieczna, aby uniknąć błędu w Matlab próbuje odczytać i nadpisać wartość zmiennej w tym samym czasie, widocznie, który był nowy jeden na mnie.

Nie golfowany:

function[d]=X(x) 
d=0;
while ~strcmp(x,'1')
    z='sum(str2num(x(:)))';
    a=eval(['rem(',x,',',z,')']);
    y=num2str(a*(a>0)+eval([x,'/',z])*(a==0));
    x=y;
    d=d+1;
end
sintax
źródło