Sekwencja dodawania, mnożenia i dodawania


27

( Powiązane )

Biorąc pod uwagę liczbę całkowitą n > 1,
1) Zbuduj zakres liczb n, n-1, n-2, ... 3, 2, 1i oblicz sumę
2) Weź poszczególne cyfry tej liczby i oblicz produkt
3) Weź poszczególne cyfry tej liczby i oblicz sumę
4) Powtarzaj kroki 2 i 3, aż osiągnąć jedną cyfrę. Ta cyfra jest wynikiem.

Pierwsze dwadzieścia terminów sekwencji znajduje się poniżej:

3, 6, 0, 5, 2, 7, 9, 2, 7, 9, 1, 9, 0, 0, 9, 6, 7, 0, 0, 6

Uwaga: Ta sekwencja NIE jest w OEIS.

I / O i reguły

  • Liczby szybko się powiększą, więc rozwiązanie musi być w stanie obsłużyć liczby wejściowe do 100 000 bez awarii (w porządku, jeśli Twój kod da sobie radę z tym przekroczeniem).
  • Dane wejściowe i wyjściowe można podać dowolną dogodną metodą .
  • Dopuszczalny jest pełny program lub funkcja. Jeśli funkcja, możesz zwrócić dane wyjściowe zamiast je wydrukować.
  • Standardowe luki są zabronione.
  • To jest więc obowiązują wszystkie zwykłe zasady gry w golfa, a wygrywa najkrótszy kod (w bajtach).

Przykłady

n     output
1234   9
3005   3
5007   5
9854   8
75849  8
100000 0

3
+1 za wyzwanie sekwencyjne, którego nie ma w OEIS
JAD

2
Ilekroć n ≤ 100000 , tylko dwie iteracje kroków 2 i 3 są wystarczające, aby uzyskać wynik. Czy możemy to wykorzystać, czy też wybrany algorytm powinien działać dla większych wartości n ?
Dennis

2
@Dennis Algorytm powinien działać dla dowolnej wartości n. Opublikowane rozwiązanie musi działać tylko do n = 100000.
AdmBorkBork

3
Numbers will get very large quicklynie, nie robi
l4m2

3
@ l4m2 Nie wyjście. Ale 100000 + 99999 + ... + 1 = 5000050000 jest liczbą 33-bitową, którą twój wybrany język może lub nie może mieć problem z przedstawieniem.
Dennis

Odpowiedzi:


10

Python 2 , 77 72 71 62 60 bajtów

lambda n:reduce(lambda x,c:eval(c.join(`x`)),'*+'*n,-n*~n/2)

Dzięki @xnor za grę w golfa z 2 bajtów!

Wypróbuj online!


I właśnie włączony do pętli for, ale muszę pamiętać, że trik na przyszłość.
Dennis

Gdzie repeat until you reach a single digitjest
Tytus

2
@Titus po prostu wykonać n powtórzeń etapów 2 i 3, która jest zawsze wystarcza. W rzeczywistości, ponieważ n ≤ 100000 , wystarczą trzy iteracje.
Dennis

Teraz, gdy o tym wspominasz: w rzeczywistości najmniejsze dane wejściowe, które wymagałyby trzech iteracji, to 236172; i to jedyny poniżej 1 miliona.
Tytus

Możesz zmniejszyć
xnor


4

Galaretka , 8 bajtów

RSDPDƲÐL

Wypróbuj online!

Pełny program (zwraca tablicę singletonów zawierającą wynik, ale nawiasy nie są widoczne w STDOUT).


To najbardziej „naturalnie wyglądająca” odpowiedź na żelki, jaką widziałem. Są tylko 2 znaki spoza ASCII
RedClover


Uh, możemy nie dyskutować tutaj, dzięki. : P TNB może być alternatywnym miejscem do dyskusji na ten temat, jeśli nie będzie hałasu. ;)
Erik the Outgolfer

4

MATL , 15 13 bajtów

W hołdzie dla języka miesiąca :

:`sV!UpV!Utnq

Wypróbuj online!

Nie sądzę, że istnieje prostszy sposób na uzyskanie cyfr liczby niż konwersja liczby na ciąg V, a następnie transpozycja jej !i przekształcenie tego wektora pionowego z powrotem na numeryczny U.

Zaoszczędź 2 bajty dzięki samemu twórcy 1 ! Zapomniałem niejawnego końca, co oznacza, że ​​mógłbym usunąć ], i zamiast porównywać liczbę elementów 1, mogłem po prostu zmniejszyć tę wartość i użyć jej jako wartości logicznej bezpośrednio.

Wyjaśnienie wygląda następująco:

                 % Grab input n implicitly
:                % Range from 1 ... n inclusive
 `               % Do ... while
  s               % sum the vector
   V!U            % Convert the number to digits
      p           % Take the product of these digits
       V!U        % Convert the product into digits
          t       % Duplicate the result
           n      % Count the number of elements
            q     % Decrement the number of elements
                  % Loop until the number of elements is 1
                 % Implicit end

1 ... MATL, Luis Mendo.


3

JavaScript (ES6), 60 bajtów

f=(n,k=n*++n/2)=>k>9?f(!n,eval([...k+''].join('*+'[+!n]))):k

Wypróbuj online!

Skomentował

f = (                     // f = recursive function taking:
  n,                      //   n = original input
  k = n * ++n / 2         //   k = current value, initialized to sum(i=1..n)(i)
) =>                      //
  k > 9 ?                 // if k has more than 1 digit:
    f(                    //   recursive call to f() with:
      !n,                 //     a logical NOT applied to n
      eval(               //     the result of the expression built by:
        [...k + '']       //       turning k into a list of digits
        .join('*+'[+!n])  //       joining with '*' on even iterations or '+' on odd ones
      )                   //     end of eval()
    )                     //   end of recursive call
  :                       // else:
    k                     //   stop recursion and return the last value

Wersja alternatywna, 59 bajtów (niekonkurująca)

Wersja nierekurencyjna, która działa tylko dla n <236172 . (Obejmuje wymagany zakres, ale nie kwalifikuje się jako prawidłowy algorytm ogólny).

n=>[...'*+*+'].map(o=>n=eval([...n+''].join(o)),n*=++n/2)|n

Wypróbuj online!


Twoja główna wersja psuje się, gdy N> = 77534568790. Działa, gdy N = 7753456879; nie jestem pewien, gdzie dokładnie jest punkt przerwania. Oczywiście nie ma to znaczenia, ponieważ wymaganie dotyczy tylko N = 100 000, więc nie jestem pewien, dlaczego to napisałem ....
Ross Presser

1
@RossPresser Jako przybliżony szacunek powiedziałbym, że raczej działa Number.MAX_SAFE_INTEGER ** 0.5 ~= 94906265.
Arnauld


2

Stax , 14 13 10 bajtów

ñu┌↕a√äJ²┐

Uruchom i debuguj

Było całkiem fajnie. Zastanawiam się, czy istnieje bardziej zwięzły sposób na porównanie na końcu.

Wyjaśnienie

|+wE:*E|+c9>                 # Full Program Unpacked
|+                           # Create range and sum it
   wE:*                      # Start loop, digitize number, product of digits
       E|+                   # Digitize number, sum digits
          c9>                # Duplicate, check length is = 1
                             # Otherwise loop back to the 'w' character

-1 bajty dzięki ovs

-3 bajty dzięki Scrooble


2

R , 152 130 109 bajtów

function(w,x=w*(w+1)/2,y=prod(d(x)),z=sum(d(y)))"if"(z>9,f(,z),z)
d=function(x)x%/%10^(0:max(0,log10(x)))%%10

Wypróbuj online!

@Giuseppe znalazł 21 42 bajtów z różnymi R rzeczami, do których jeszcze nie jestem przyzwyczajony, wraz ze sposobem uzyskiwania cyfr liczby bez wymuszania ciągów znaków i wstecz oraz z mniejszą liczbą bajtów!

# Old
d=function(x)strtoi(el(strsplit(paste(x),"")))
# New
d=function(x)x%/%10^(0:max(0,log10(x)))%%10

options(scipen=9) jest wymagane w przypadku 9854 dla starej funkcji, ponieważ pierwszy etap produktu kończy się na 80000, co R drukuje jako 8e + 05.


O, rozumiem. Wynik notacji naukowej. Dobry chwyt!
AdmBorkBork

1
W końcu udało się obejść scipen: Wypróbuj online ! zwróć uwagę, max(0,log10(x))że jeśli x=0, to log10(0)=-Infco powoduje błąd.
Giuseppe

1

Pyth , 11 bajtów

usj*FjGTTsS

Wypróbuj tutaj!

usj * FjGTTsS - Pełny program. N = dane wejściowe.
          S - Zasięg. Wydajność [1, N] ⋂ ℤ.
         s - Suma.
u - Chociaż żadne dwie kolejne iteracje nie dają tego samego rezultatu, wykonaj (var: G):
   * FjGT - produkt cyfrowy.
 sj T - Suma cyfrowa.

1

Węgiel drzewny , 18 bajtów

≔Σ…·¹NθW›θ⁹≔ΣΠθθIθ

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

≔Σ…·¹Nθ

Zsumuj liczby całkowite do wartości wejściowej.

 W›θ⁹≔ΣΠθθ

Chociaż wynik jest większy niż 9, weź sumę cyfr iloczynu cyfr.

Iθ

Rzuć wynik na ciąg i niejawnie go wydrukuj.


1

Gaia , 8 bajtów

┅⟨Σ₸∨Π⟩°

Wypróbuj online!

Stare wyjaśnienie (przed naprawieniem błędu będącego winą Gaii IMO: P):

⟩Π⟩ ° - Pełny program. N = dane wejściowe.
┅ - Zasięg. Wciśnij [1, N] ⋂ ℤ na stos.
 ⟨⟩ ° - Chociaż żadne dwie kolejne iteracje nie dają tego samego wyniku, wykonaj:
  Σ - Suma (lub suma cyfrowa, gdy zastosowana do liczby całkowitej).
   Π - Produkt cyfrowy.

Oszczędność 1 bajtu dzięki Dennisowi .


┅⟨ΣΠ⟩°zapisuje bajt.
Dennis

To nie działa dla wartości, w których suma cyfrowa wynosi 0, na przykład4
Jo King

@JoKing Naprawiono, dziękuję za wykrycie tego. Niestety, w Gaia, biorąc z jakiegoś powodu cyfry 0wyników []:(
Mr. Xcoder

1

F #, 175 bajtów

let d n=seq{for i in(string n).ToCharArray() do yield string i|>uint64}
let c n=
 let mutable r=Seq.sum{1UL..n}
 while r>9UL do r<-d r|>Seq.reduce(fun a x->x*a)|>d|>Seq.sum
 r

Wypróbuj online!

Jedynym zastrzeżeniem dla tej funkcji jest to, że wartość wejściowa musi być typu uint64.

Ungolfed to trochę tak:

let d n=seq{for i in(string n).ToCharArray() do yield string i|>uint64}

let c n =
 let mutable r = Seq.sum {1UL..n}
 while r > 9UL do
  r<-d r
  |> Seq.reduce(fun a x->x*a)
  |> d
  |> Seq.sum
 r

Funkcja d nkonwertuje liczbę nna cyfry składowe. Najpierw konwertuje na ciąg, a następnie pobiera każdy znak w ciągu. Każdy znak należy następnie przekonwertować z powrotem na ciąg, w przeciwnym razie znaki zostaną przekonwertowane na ich wartości ASCII zamiast na „rzeczywiste” wartości.

Ta c nfunkcja jest główną funkcją, której nwartością początkową jest. W tej funkcji rjest nasza bieżąca wartość. whilePętla ma co następuje:

  • Konwertuj rna cyfry składowe ( d r).
  • Uzyskaj iloczyn wszystkich tych cyfr. Wykorzystuje to, Seq.reducektóre przyjmuje funkcję z wartością skumulowaną ( a) i następną wartością w sekwencji ( x), w tym przypadku zwraca produkt. Wartość początkowa jest pierwszym elementem w sekwencji.
  • Konwertuj tę wartość produktu na cyfry składowe ( d).
  • Zsumuj cyfry wcześniej i przypisz to do r.

1

Befunge, 136 bajtów

101p&::*+2/>:82+%01g*01p82+/:#v_$01gv
X      v_v# #:/+82p10+g10%+82: <p100<
v:g10$ >#<#^                 #<^
>82+/#v_.@
      >101p^

Możesz spróbować tutaj .

Chociaż nie wszyscy tłumacze mają wystarczająco duży rozmiar komórki, działa z małymi liczbami dla praktycznie każdego. W przypadku większej liczby osób nmoże być potrzebny tłumacz taki jak BefunExec .


1

Gol> <> , 35 33 bajtów

1AY:P*2,TYMR*YR+:a(?Bt
:a(qlBaSD$

Wypróbuj online!

-2 bajty autorstwa Jo Kinga.

Szerokie wykorzystanie funkcji i niejawnych nieskończonych pętli.

Przykład pełnego programu i jak to działa

1AGIE;GN
2AY:P*2,YlMR*YlR+:a(?B8R!
:a(?BaSD$

<main program>
1AG       Register row 1 as function G
   IE;    Take number input; halt on EOF
      GN  Call G and print the result as number
          Repeat indefinitely

<function G>
2AY            Register row 2 as function Y
   :P*2,       Sum of 1 to n
        Y      Call Y (break into digits)
         lMR*  Product
Y              Call Y
 lR+           Sum (an implicit zero is used)
    :a(?B      Return if the result is less than 10
         8R!   Skip initial 8 commands
               Repeat indefinitely

<function Y>
:a(?B      Return if the top is less than 10
     aSD   Divmod by 10; [... n] => [... n/10 n%10]
        $  Swap top two, so the "div" goes to the top


1

Japt, 16 14 13 bajtów

_ì ×ìx}gN®õ x

Spróbuj


Wyjaśnienie

                  :Implicit input of integer U
         ®        :Map
        N         :The array of inputs (which just contains U)
          õ       :  Range [1,U]
            x     :  Reduce by addition
_     }g          :Take the last element of N, run it through the following function and push the result to N
                  : Repeat U times and then return the last element of N
 ì                :  Split to an array of digits
   ×              :  Reduce by multiplication
    ìx            :  Split to an array of digits and reduce by addition

Zgrabne, sam próbowałem rozwiązać ten problem, ale nie znalazłem dobrego rozwiązania, więc interesujące jest zobaczenie twojego.
Nit

Dzięki, @Nit. Musi być jednak krótsza droga.
Kudłaty

@Nit, rozumiem! Wciąż przekonany, że musi być krótsza droga.
Kudłaty


0

PHP 7, 89 bajtów

for($a=$argn*-~+$argn/2;$a>9;)$a=array_sum(($s=str_split)(array_product($s($a))));echo$a;

Uruchom jako potok z -rlub spróbuj online .

  • PHP zawsze przyjmuje dane wejściowe jako ciąg znaków, więc muszę użyć +metody cast do int, ~aby działała zgodnie z oczekiwaniami.
  • Wstępna inkrementacja nie zadziała: bez względu na to, gdzie ją umieszczę, wpłynie to na oba operandy.
  • Ale: nie ma znaczenia, czy pojedyncza cyfra ma miejsce przed czy po iteracji (dodatkowe iteracje nic by nie zmieniły); więc mogę użyć for()zamiast do ... while().
  • PHP 7 lub nowszy jest wymagany do wbudowanego przypisania nazwy funkcji.
    Starsze PHP wymaga jeszcze jednego bajtu: for($s=str_split,$a=...;$a>9;)$a=array_sum($s(...));
    (Brak przypisania str_splitdo zmiennej w ogóle zmarnowałby kolejny bajt).



0

PowerShell Core , 91 101 93 bajtów

Function F($a){$o=$a*($a+1)/2;1,2|%{$o=[char[]]"$([char[]]"$o"-join'*'|iex)"-join'+'|iex};$o}

Wypróbuj online!

Ungolfed trochę ...

Function F ($a)
{
    $o=$a*($a+1)/2;
    1..2 | % {
        $o = [char[]]"$o"-join '*' | iex;
        $o = [char[]]"$o"-join '+' | iex;
    }
    $o | Write-Output
}

Pierwszymi krokami było podzielenie liczb całkowitych na cyfry - zrobiono to, dzieląc liczbę całkowitą na tablicę ciągów znaków. Następnie wstaw operand, a następnie oceń ciąg jako polecenie. Następnie należy wykonać cykl wielokrotnego dodawania, dopóki wprowadzana cyfra nie będzie zawierała jednej cyfry.

iexjest aliasem, dla Invoke-Commandktórego ocenia się ciąg znaków przekazany do pierwszej pozycji parametru.

Edycja: Zgodnie z żądaniem @AdmBorkBork dodałem nagłówek funkcji do liczby bajtów. Zrobiłem też małą matematykę i zdałem sobie sprawę, że górna granica liczby iteracji to < log log 10^6 < log 6 < 2, więc zaoszczędziłem kolejne sześć bajtów.

Edytuj x2: @AdmBorkBork znalazł bardziej zwięzły sposób na przekształcenie liczby całkowitej w wyrażenie matematyczne, a następnie zasugerował przekazanie jej iex. To zaoszczędziło 8 bajtów. Dziękuję Ci!


Miło widzieć kolejny PowerSheller w pobliżu! Myślę jednak, że musisz uwzględnić definicję funkcji Function F($a){ }w liczbie bajtów. Jednakże, powinieneś być w stanie zaoszczędzić trochę stosując [char[]]zamiast -split''-ne'', jak sądzę.
AdmBorkBork

[char[]]1234=Ӓ, który jest nieprawidłowy; Być może uda mi się sprawić, by działało, ale może to nie być teraz oczywiste. Dzieki za sugestie!
Jeff Freeman

Przepraszam, że nie było jasne - [char[]]"$o"i |iexraczej niż iex( ).
AdmBorkBork

Ta wskazówka straciła 8% mojego kodu. Niesamowite. Dzięki!
Jeff Freeman



0

Java 8, 129 bajtów

n->{long r=1,i=n;for(;i>1;r+=i--);for(;r>9;r=(i+"").chars().map(p->p-48).sum(),i=1)for(int s:(r+"").getBytes())i*=s-48;return r;}

Wypróbuj online.

Wyjaśnienie:

n->{            // Method with integer parameter and long return-type
  long r=1,     //  Result-long, starting at 1
       i=n;     //  Temp integer, starting at the input `n`
  for(;i>1;     //  Loop as long as `i` is not 1 yet
      r+=i--);  //   And increase `r` by `i`
  for(;r>9      //  Loop as long as `r` is not a single digit yet
      ;         //    After every iteration:
       r=(i+"").chars().map(p->p-48).sum(),
                //     Set `r` to the sum of digits of `i`
       i=1)     //     And reset `i` to 1
    for(int s:(r+"").getBytes())i*=s-48;
                //    Set `i` to the product of the digits of `r`
  return r;}    //  Return `r` as result

0

Julia 0.6 , 56 bajtów

f(n,k=(n+1)n÷2)=k>9?f(0,sum(digits(prod(digits(k))))):k

Wypróbuj online!

Całkiem proste: oblicz (n+1)n÷2sumę od 1..n, sprawdź, czy jest to liczba jednocyfrowa ( >9), jeśli nie, spróbuj ponownie z k ustawionym na sumę cyfr iloczynu k, w przeciwnym razie zwróć k.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.