Trwałość multiplikatywna

46

Trwałość multiplikatywna

  1. Pomnóż wszystkie cyfry w liczbie
  2. Powtarzaj, aż pozostanie Ci jedna cyfra

Jak wyjaśniono w Numberphile :

Przykład

  1. 277777788888899 → 2x7x7x7x7x7x7x8x8x8x8x8x8x9x9 = 4996238671872
  2. 4996238671872 → 4x9x9x6x2x3x8x6x7x1x8x7x2 = 438939648
  3. 438939648 → 4x3x8x9x3x9x6x4x8 = 4478976
  4. 4478976 → 4x4x7x8x9x7x6 = 338688
  5. 338688 → 3x3x8x6x8x8 = 27648
  6. 27648 → 2x7x6x4x8 = 2688
  7. 2688 → 2x6x8x8 = 768
  8. 768 → 7x6x8 = 336
  9. 336 → 3x3x6 = 54
  10. 54 → 5x4 = 20
  11. 20 → 2x0 = 0

Nawiasem mówiąc, jest to aktualny rekord: najmniejsza liczba z największą liczbą kroków.

Golf

Program, który przyjmuje dowolną liczbę całkowitą jako dane wejściowe, a następnie wypisuje wynik każdego kroku, zaczynając od samego wejścia, aż trafimy na jedną cyfrę. W przypadku 277777788888899 wyjście powinno wynosić

277777788888899
4996238671872
438939648
4478976
338688
27648
2688
768
336
54
20
0

(Liczenie liczby kroków pozostaje jako ćwiczenie dla użytkownika).

Więcej przykładów

Od A003001 :

25
10
0

Z A003001 również:

68889
27648
2688
768
336
54
20
0

Z filmu Numberphile :

327
42
8

Pojawiło się więc pytanie o trwałość addytywną , ale jest to Multiplikatywna Trwałość. To pytanie wymaga również liczby kroków jako danych wyjściowych, a ja jestem zainteresowany widzeniem wyników pośrednich.

SQB
źródło
Bonus: znajdź nowy rekord: najmniejszą liczbę z największą liczbą kroków. Zastrzeżenie: przypuszczenie głosi, że 11 jest największym możliwym.
SQB
7
Prawdopodobnie powinieneś dołączyć jeszcze kilka przypadków testowych, które nie kończą się na . 0
Arnauld
Przyszedł, aby napisać ten post, stwierdził, że już istnieje, gg
cat
czy wprowadzono jednocyfrowy numer?
dzaima
1
W filmie Numberphile Matt Parker stwierdza, że ​​przeprowadzono wyszukiwanie do kilkuset cyfr.
HardScale

Odpowiedzi:

7

Galaretka , 4 bajty

DP$Ƭ

Wypróbuj online!

Wyjaśnienie

D    | convert to decimal digits
 P   | take the product
  $  | previous two links as a monad
   Ƭ | loop until no change, collecting all intermediate results

Jako bonus, oto TIO, które znajdzie liczby o największej liczbie kroków dla danego zakresu liczb. Dobrze skaluje się nawet w TIO.

Nick Kennedy
źródło
15

TI-BASIC (TI-84), 30 32 31 bajtów

-1 bajt dzięki @SolomonUcko!

While Ans>9:Disp Ans:prod(int(10fPart(Ans10^(seq(-X-1,X,0,log(Ans:End:Ans

Wejście jest w Ans.
Dane wyjściowe są wyświetlane jako żądania wezwania. Końcowe Ansjest potrzebne do wydrukowania ostatniego kroku.

Przyznaję, że sam nie pomyślałem o tej formule, raczej znalazłem ją tutaj i zmodyfikowałem, aby lepiej pasowała do wyzwania.

EDYCJA: Po ponownym odczytaniu wyzwania zdałem sobie sprawę, że program musi zostać zakończony, jeśli produkt jest jednocyfrowy. W związku z tym należy uwzględnić 2 bajty .

Przykład:

24456756
        24456756
prgmCDGF8
        24456756
          201600
               0
11112
           11112
prgmCDGF8
           11112
               2

Wyjaśnienie:

While Ans>9               ;loop until the product is one digit
Disp Ans                  ;display the current product
prod(                     ;get the product of...
 int(                     ; the integer part of...
  10fPart(                ; ten times the fractional part of...
  Ans                     ; each element in the following list times the
                          ;  current product
  10^(                    ; multiplied by the list generated by using each
                          ;  element of the following list as an exponent
                          ;  for 10^n
   seq(-X-1),X,0,log(Ans  ; generate a list of exponents from -1 to -L where
                          ;  L = the length of the current product
End
Ans                       ;leave the final product in "Ans" and implicitly
                          ; print it

Model wizualny:
Ans zaczyna się jako 125673.
Ten model obejmuje tylko logikę mnożenia cyfr; wszystko inne jest łatwiejsze do zrozumienia.

seq(-X-1,X,0,log(Ans  =>  seq(-X-1,X,0,5.0992
   {-1 -2 -3 -4 -5 -6}
10^(...
   {.1 .01 .001 1E-4 1E-5 1E-6}
Ans...
   {12567.3 1256.73 125.673 12.5673 1.25673 .125673}
fPart(...
   {.3 .73 .673 .5673 .25673 .125673}
10...
   {3 7.3 6.73 5.673 2.5673 1.25673}
int(...
   {3 7 6 5 2 1}
   (the digits of the number, reversed)
prod(...
   1260
   (process is repeated again)

seq(-X-1,X,0,log(Ans  =>  seq(-X-1,X,0,3.1004
   {-1 -2 -3 -4}
10^(...
   {.1 .01 .001 1E-4}
Ans...
   {126 12.6 1.26 .126}
fPart(...
   {0 .6 .26 .126}
10...
   {0 6 2.6 1.26}
int(...
   {0 6 2 1}
prod(...
   0
   (product is less than 10.  loop ends)

Uwagi:

TI-BASIC jest językiem tokenizowanym. Liczba znaków nie jest równa liczbie bajtów.

10^(to ten jednobajtowy token .

Ten program nie zapewni prawidłowej sekwencji produktów o liczbach całkowitych dłuższych niż 14 cyfr ze względu na ograniczenia precyzji dziesiętnej w kalkulatorach TI.

Tau
źródło
Czy możesz zapisać bajt, wychodząc na 10^(zewnątrz seq(i pomijając nawias zamykający?
Solomon Ucko
Tak mi się wydaje!
Tau
11

K (ngn / k) , 9 bajtów

{*/.'$x}\

Wypróbuj online!

{ }\ stosuj funkcję w nawiasach klamrowych, aż sekwencja się zbiegnie

$x sformatuj argument jako ciąg znaków (lista znaków)

.'oceń siebie (inne dialekty k wymagają dwukropka .:')

*/ razy, tj. produkt

ngn
źródło
8

R , 59 bajtów

n=scan();while(print(n)>9)n=prod(n%/%10^(nchar(n):1-1)%%10)

Wypróbuj online!

Ponieważ print invisiblyzwraca on dane wejściowe, możemy użyć print(n)wewnątrz whilepętli do symulacji do-whilepętli. To jest inspirowana przez jednego z moich porad dla golfa w R .

Nagłówek pomaga zapobiegać drukowaniu dużych liczb w notacji naukowej.

Giuseppe
źródło
8

05AB1E , 7 4 bajtów

Δ=SP

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

Δ     # Loop until the number no longer changes:
 =    #  Print the number with trailing newline (without popping the number itself)
      #  (which will be the implicit input in the first iteration)
  SP  #  Convert the number to a list of digits, and calculate its product
Kevin Cruijssen
źródło
7

Python 2 ,  46  43 bajty

-3 dzięki xnor (porównanie łańcuchowe)

def f(n):print n;n>9>f(eval('*'.join(`n`)))

Wypróbuj online!

Jonathan Allan
źródło
Możesz zrobić >zamiast and.
xnor
@xnor dzięki, łatwo zapomnieć, że zadziała.
Jonathan Allan
5

PowerShell , 54 bajty

for($a=$args;$a-gt9){$a;$a=("$a"|% t*y)-join"*"|iex}$a

Wypróbuj online!


Metoda iteracyjna, która najpierw zapisuje argument wejściowy, a następnie przekształca go w ciąg znaków i potokuje w tablicę znaków. Do tej tablicy dołączone są pojedyncze gwiazdki i wykonywane jako polecenie z aliasem wyrażenia invoke. Ponieważ zapisuje to liczbę początkową do ostatniej liczby większej niż 0 (20, w danym scenariuszu testowym), dodaję końcowy $akoniec do wyniku.

KGlasier
źródło
5

C # (interaktywny kompilator Visual C #) , 79 74 68 bajtów

void f(int a){Print(a);if(a>9)f((a+"").Aggregate(1,(j,k)=>k%48*j));}

Staram się trzymać z dala od rekurencji w języku C # ze względu na długość deklaracji metody, ale w tym przypadku zapisuje się w porównaniu do pętli.

Wypróbuj online!

Wcielenie ignorancji
źródło
5

PHP , 63 bajty

<?=$n=$argn;while($n>9)echo"
",$n=array_product(str_split($n));

Wersja iteracyjna, wywołanie z php -nFwejściem od STDIN.

Wypróbuj online!

PHP ,72 71 bajtów

function h($n){echo"$n
",($n=array_product(str_split($n)))>9?h($n):$n;}

Wypróbuj online!

Wersja rekurencyjna jako funkcja.

Dane wejściowe: 277777788888899

277777788888899
4996238671872
438939648
4478976
338688
27648
2688
768
336
54
20
0

Wejście: 23

23
6
640 KB
źródło
5

Python 2 , 61 62 59 bajtów

def f(n):print n;n>9and f(reduce(int.__mul__,map(int,`n`)))

Wypróbuj online!

-3 bajty, dzięki Jonathan Allan

TFeld
źródło
Nie działa dla danych wejściowych, które nie kończą się cyfrą 0 podczas ostatniej iteracji, na przykład 23
Embodiment of Ignorance
int.__mul__jest trzy bajty mniej niżlambda a,b:a*b
Jonathan Allan
@JonathanAllan Thanks! Wiedziałem, że musi być coś takiego
TFeld
Zmień, f(reduce(int.__mul__,map(int,`n`)))aby f(eval('*'.join(`n`)))zapisać 13 bajtów.
mypetlion
@mypetlion ... Zrobiłem to już w innym poście.
Jonathan Allan
5

perl 5 ( -n -M5.01), 32 30 25 bajtów

say$_=eval;s/\B/*/g&&redo

25 bajtów

30 bajtów

32 bajty

Nahuel Fouilleul
źródło
Powinieneś wspomnieć, że to wykorzystuje-lpF//
Grimmy
1
@Grimy, mogłem zapisać 2 bajty bez użycia -lpF//, aktualizując
Nahuel Fouilleul
5

MathGolf , 9 10 bajtów

h(ôo▒ε*h(→

Wypróbuj online!

Teraz poprawnie obsługuje dane jednocyfrowe. Nie jest idealny, ale przynajmniej jest poprawny.

Wyjaśnienie

h(            check length of input number and decrease by 1
  ö       →   while true with pop using the next 6 operators
   p          print with newline
    ▒         split to list of chars/digits
     ε*       reduce list by multiplication
       h(     length of TOS without popping, subtracted by 1 (exits when len(TOS) == 1)
maxb
źródło
Dane wyjściowe dla jednej cyfry powinny być jedną kopią numeru - wyjaśnione w komentarzach
dzaima
@dzaima Zajmę się tym i zaktualizuję odpowiedź, gdy zostanie rozwiązana
maxb
4

JavaScript (ES6), 45 bajtów

Zwraca tablicę liczb całkowitych.

f=n=>[n,...n>9?f(eval([...n+''].join`*`)):[]]

Wypróbuj online!

Arnauld
źródło
4

APL (NARS), 19 znaków, 38 bajtów

{⍵≤9:⍵⋄∇×/⍎¨⍕⍵⊣⎕←⍵}

test:

   f←{⍵≤9:⍵⋄∇×/⍎¨⍕⍵⊣⎕←⍵}
   f 23     
23
6
   f 27648     
27648
2688
768
336
54
20
0
RosLuP
źródło
4

Japt -R , 9 bajtów

Strasznie nieefektywny - nawet nie próbuj uruchamiać pierwszego przypadku testowego!

_ì ×}hN â

Spróbuj

_ì ×}hN â     :Implicit input of integer U
      N       :Starting with the array of inputs (i.e., [U])
     h        :Do the following U times, pushing the result to N each time
_             :Take the last element in N and pass it through the following function
 ì            :  Convert to digit array
   ×          :  Reduce by multiplication
    }         :End function
        â     :Deduplicate N
              :Implicitly join with newlines and output
Kudłaty
źródło
3

Brachylog , 7 bajtów

ẉ?Ḋ|ẹ×↰

Wypróbuj online!

Wyjaśnienie

ẉ          Write the input followed by a linebreak
 ?Ḋ        If the input is a single digit, then it's over
   |       Otherwise
    ẹ      Split the input into a list of digits
     ×     Multiply them together
      ↰    Recursive call with the result of the multiplication as input
Fatalizować
źródło
Sam spróbowałem. Zapomniałem o Ḋ. Resztę miałem to samo.
Kroppeb
3

PowerShell , 64 59 bajtów

for($a="$args";9-lt$a){$a;$a="$(($a|% t*y)-join'*'|iex)"}$a

Wypróbuj online!

Metoda iteracyjna. Pobiera dane wejściowe i zapisuje je $a, a następnie wchodzi w forpętlę, o ile długość $awynosi dwa lub więcej (tzn. Jest większa niż 9). Wewnątrz pętli wyprowadzamy dane, $aa następnie przeliczamy je, konwertując toCharArra y, łącząc joingo razem z *, a następnie iex(skrót od Invoke-Expressioni podobny do eval). Po wyjściu z pętli pozostała nam tylko jedna cyfra do wydrukowania, więc $aponownie umieszczamy ją w rurociągu.

-5 bajtów dzięki KGlasier.

AdmBorkBork
źródło
Możesz użyć porównania 9-lt$azamiast $a.length-1zaoszczędzić 5 bajtów. A jeśli przez cały czas nie korzystałeś z łańcucha, możesz odciąć przyzwoity kawałek. Sprawdź moją próbę PowerShell, jeśli chcesz!
KGlasier
3

Węgiel drzewny , 13 bajtów

θW⊖Lθ«≔IΠθθ⸿θ

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:

θ

Wydrukuj dane wejściowe po raz pierwszy.

W⊖Lθ«

Powtarzaj, dopóki długość wejścia nie jest równa 1.

≔IΠθθ

Zastąp dane wejściowe produktem cyfrowym rzutowanym na ciąg.

⸿θ

Wydrukuj dane wejściowe w nowym wierszu.

Neil
źródło
3

Siatkówka , 24 bajty

.+~(\`

.
$&$*
^
.+¶$$.(

Wypróbuj online! Wyjaśnienie:

.+~(\`

Wydrukuj bieżącą wartość w swoim własnym wierszu na początku każdej pętli, aż przestanie się zmieniać i nie drukuj niezmienionej wartości dwa razy. Oceń bieżącą wartość na końcu każdej pętli.

.
$&$*

Dodaj *po każdej cyfrze.

^
.+¶$$.(

Zakończ przekształcanie danych wejściowych w wyrażenie wyrażające się w produkcie cyfrowym.

Dla przypomnienia, Retina może to zrobić w jednym wierszu (25 bajtów):

.+"¶"<~[".+¶$.("|'*]'*L`.
Neil
źródło
3

C (gcc) , 58 bajtów

f(n,t){for(;n=printf("%d\n",t=n)>2;)for(;n*=t%10,t/=10;);}

Wypróbuj online!

Okazuje się, że podejście iteracyjne jest o 1 bajt krótsze.

f(n,t){
    for(;n=printf("%d\n",t=n)   //print and update current number
            >2;)                //until only one digit is printed
        for(;n*=t%10,t/=10;);   //n*= product of digits of t (step)
}

C (gcc) , 61 59 bajtów (rekurencyjne)

f(n){printf("%d\n",n)>2&&f(p(n));}p(n){n=n?n%10*p(n/10):1;}

Wypróbuj online!

Rekurencja wydaje się być krótsza niż iteracja zarówno dla wydruku, jak i kroku ...

attinat
źródło