ลำดับ Add-Multiply-Add


27

( ที่เกี่ยวข้อง )

ได้รับจำนวนเต็มn > 1,
1) สร้างช่วงของตัวเลขn, n-1, n-2, ... 3, 2, 1และคำนวณผลรวม
2) ใช้ตัวเลขของแต่ละตัวเลขที่และคำนวณผลิตภัณฑ์
3) ใช้ตัวเลขของแต่ละที่จำนวนและคำนวณผลรวม
4) ทำซ้ำขั้นตอนที่ 2 และ 3 จนกว่าคุณ ถึงหลักเดียว หลักนั้นคือผลลัพธ์

ยี่สิบคำแรกของลำดับอยู่ด้านล่าง:

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

หมายเหตุ: ลำดับนี้ไม่ได้อยู่ใน OEIS

I / O และกฎ

  • ตัวเลขจะมีขนาดใหญ่มากอย่างรวดเร็วดังนั้นวิธีการแก้ปัญหาจึงต้องสามารถจัดการกับตัวเลขที่ป้อนได้มากถึง 100,000 โดยไม่ล้มเหลว (ไม่เป็นไรถ้ารหัสของคุณสามารถจัดการกับมันได้)
  • อินพุตและเอาต์พุตจะได้รับโดยวิธีการที่สะดวกใด
  • ยอมรับได้ทั้งโปรแกรมหรือฟังก์ชั่น หากฟังก์ชั่นคุณสามารถส่งคืนผลลัพธ์มากกว่าการพิมพ์
  • ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม
  • นี่คือเพื่อให้ใช้กฎการตีกอล์ฟตามปกติทั้งหมดและรหัสที่สั้นที่สุด (เป็นไบต์) ชนะ

ตัวอย่าง

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

3
+1 สำหรับการท้าทายต่อเนื่องที่ไม่ได้อยู่ใน OEIS
JAD

2
เมื่อใดก็ตามที่n ≤ 100000 , เพียงสองซ้ำขั้นตอนที่ 2 และ 3 มีเพียงพอที่จะได้รับผล เราสามารถใช้ประโยชน์จากอัลกอริทึมที่เราเลือกใช้สำหรับค่าn ที่มากขึ้นได้ไหม?
เดนนิส

2
@Dennis nอัลกอริทึมควรจะทำงานให้คุ้มค่าใด n = 100000การแก้ปัญหาการโพสต์เท่านั้นที่มีการทำงานได้
AdmBorkBork

3
Numbers will get very large quicklyไม่ไม่ได้
l4m2

3
@ l4m2 ไม่ใช่เอาท์พุท แต่100000 + 99999 + ... + 1 = 5000050000เป็นหมายเลข 33 บิตซึ่งภาษาที่คุณเลือกอาจมีหรือไม่มีปัญหาในการเป็นตัวแทน
เดนนิส

คำตอบ:


10

Python 2 , 77 72 71 62 60 ไบต์

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

ขอบคุณ @xnor สำหรับการเล่นกอล์ฟ 2 ไบต์!

ลองออนไลน์!


ฉันเพิ่งเปลี่ยนไปใช้ for for loop แต่ฉันต้องจำเคล็ดลับนั้นไว้สำหรับอนาคต
เดนนิส

อยู่repeat until you reach a single digitที่ไหน
ติตัส

2
@Titus ผมก็ดำเนินการnทำซ้ำขั้นตอนที่ 2 และ 3 ซึ่งมักจะเป็นพอ ในความเป็นจริงตั้งแต่n ≤ 100000การทำซ้ำสามครั้งจะเพียงพอ
Dennis

ตอนนี้คุณพูดถึงมัน: ที่จริงการป้อนข้อมูลที่เล็กที่สุดที่จะต้องมีการทำซ้ำสามคือ236172; และนั่นเป็นเพียงต่ำกว่า 1 ล้านเท่านั้น
ติตัส



4

เยลลี่ขนาด 8 ไบต์

RSDPDƲÐL

ลองออนไลน์!

โปรแกรมแบบเต็ม (จะส่งกลับอาร์เรย์แบบซิงเกิลที่มีผลลัพธ์ แต่วงเล็บจะไม่ปรากฏใน STDOUT)


นี่คือคำตอบที่เจลลี่ "ดูเป็นธรรมชาติ" ที่สุดที่ฉันเคยเห็น มีอักขระที่ไม่ใช่ ASCII เพียง 2 ตัว
RedClover


เอ่อเราจะโปรดไม่มีการอภิปรายที่นี่ขอบคุณ : P TNB อาจเป็นทางเลือกอื่นในการพูดคุยเรื่องนี้หากไม่มีเสียงรบกวน ;)
Erik the Outgolfer

4

MATL , 15 13 ไบต์

ในการยกย่องให้เป็นภาษาของเดือน :

:`sV!UpV!Utnq

ลองออนไลน์!

ผมไม่คิดว่ามีวิธีที่ง่ายที่จะได้รับตัวเลขของจำนวนมากกว่าที่จะแปลงหมายเลขที่สตริงVแล้ว transposing มันและแปลงนี้กลับเวกเตอร์แนวตั้งเข้ากับอย่างใดอย่างหนึ่งที่เป็นตัวเลข!U

บันทึก 2 ไบต์ด้วยผู้สร้าง1เอง! ฉันลืมจุดสิ้นสุดโดยนัยซึ่งหมายความว่าฉันสามารถลบออก]ได้และแทนที่จะเปรียบเทียบจำนวนองค์ประกอบด้วย1ฉันสามารถลดค่านั้นลงและใช้เป็นบูลีนโดยตรง

ดังนั้นคำอธิบายจะเป็นดังนี้:

                 % 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 ไบต์

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

ลองออนไลน์!

ความคิดเห็น

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

รุ่นสำรอง 59 ไบต์ (ไม่แข่งขัน)

รุ่นที่ไม่ใช่ recursive ที่ทำงานเฉพาะสำหรับn <236172 (ครอบคลุมช่วงที่ร้องขอ แต่ไม่ถือว่าเป็นอัลกอริทึมทั่วไปที่ถูกต้อง)

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

ลองออนไลน์!


เวอร์ชันหลักของคุณหยุดทำงานเมื่อ N> = 77534568790 มันทำงานได้เมื่อ N = 7753456879; ไม่แน่ใจว่าเบรกพอยต์อยู่ตรงไหน ของหลักสูตรนี้ไม่ได้เรื่องเพราะ requirment เป็นเพียงที่จะจัดการได้ถึง N = 100,000 ดังนั้นฉันไม่แน่ใจว่าทำไมผมเขียนนี้ ....
รอสส์ Presser

1
@RossPresser ประมาณคร่าวๆฉันจะบอกว่ามันใช้งานได้Number.MAX_SAFE_INTEGER ** 0.5 ~= 94906265ดี
Arnauld


2

Stax , 14 13 10 ไบต์

ñu┌↕a√äJ²┐

เรียกใช้และแก้ไขข้อบกพร่อง

เป็นเรื่องสนุกที่จะทำ ฉันสงสัยว่ามีวิธีรัดกุมกว่าในการทำการเปรียบเทียบในตอนท้ายหรือไม่

คำอธิบาย

|+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 ไบต์ขอบคุณ ovs

-3 ไบต์ขอบคุณ Scrooble


2

R , 152 130 109 ไบต์

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

ลองออนไลน์!

@Giuseppe พบ21 42 ไบต์ด้วยสิ่งต่าง ๆ R ฉันยังไม่คุ้นเคยพร้อมกับวิธีการรับตัวเลขโดยไม่ต้องบังคับให้สตริงและกลับและน้อยไบต์!

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

options(scipen=9) เป็นสิ่งจำเป็นสำหรับกรณีของ 9854 สำหรับฟังก์ชั่นเก่าเพราะเวทีผลิตภัณฑ์แรกสิ้นสุดลงที่ 80000 ซึ่ง R พิมพ์เป็น 8e + 05


อ่าฉันเข้าใจแล้ว เอาท์พุทสัญลักษณ์ทางวิทยาศาสตร์ จับดี!
AdmBorkBork

1
ในที่สุดก็มาถึงรอบscipen: ลองออนไลน์ ! ทราบmax(0,log10(x))เป็นเพราะถ้าx=0แล้วlog10(0)=-Infซึ่งทำให้เกิดข้อผิดพลาด
Giuseppe

1

Pyth , 11 ไบต์

usj*FjGTTsS

ลองที่นี่!

usj * FjGTTsS - โปรแกรมเต็มรูปแบบ N = อินพุต
          S - พิสัย ผลตอบแทน [1, N] ⋂ℤ
         s - ผลรวม
u - ในขณะที่ไม่มีการวนซ้ำสองครั้งติดต่อกันให้ผลลัพธ์เดียวกันทำ (var: G):
   * FjGT - ผลิตภัณฑ์ดิจิตอล
 sj T - ผลรวมดิจิตอล

1

ถ่าน 18 ไบต์

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

ลองออนไลน์! การเชื่อมโยงคือการใช้รหัสเวอร์ชันอย่างละเอียด คำอธิบาย:

≔Σ…·¹Nθ

รวมจำนวนเต็มจนถึงอินพุต

 W›θ⁹≔ΣΠθθ

ในขณะที่ผลลัพธ์มากกว่า 9 ให้นำผลรวมของตัวเลขของผลคูณของตัวเลข

Iθ

ส่งผลลัพธ์ให้กับสตริงและพิมพ์โดยปริยาย


1

Gaiaขนาด 8 ไบต์

┅⟨Σ₸∨Π⟩°

ลองออนไลน์!

คำอธิบายเก่า (ก่อนแก้ไขข้อผิดพลาดที่เป็นความผิดของ Gaia IMO: P):

┅⟨ΣΠ⟩° - โปรแกรมเต็มรูปแบบ N = อินพุต
┅ - พิสัย กด [1, N] ⋂ℤไปที่สแต็ก
 ⟨⟩° - แม้ว่าจะไม่มีการวนซ้ำสองครั้งติดต่อกันให้ผลลัพธ์เดียวกันให้ทำ:
  Σ - ผลรวม (หรือผลรวมดิจิตอลเมื่อใช้กับจำนวนเต็ม)
   Π - ผลิตภัณฑ์ดิจิตอล

ที่บันทึกไว้ 1 ไบต์ขอบคุณที่เดนนิส


┅⟨ΣΠ⟩°บันทึกเป็นไบต์
Dennis

สิ่งนี้ใช้ไม่ได้กับค่าเพราะผลรวมดิจิตอลคือ 0 เช่น4
โจคิง

@ โจกิ้งคงที่ขอบคุณที่ได้ทราบว่า น่าเสียดายที่ Gaia รับตัวเลข0ผลลัพธ์[]ด้วยเหตุผลบางอย่าง: (
Mr. Xcoder

1

F #, 175 ไบต์

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

ลองออนไลน์!

uint64ข้อแม้เพียงเพื่อฟังก์ชั่นที่คุ้มค่าการป้อนข้อมูลจะต้องเป็นชนิด

Ungolfed มันเป็นแบบนี้:

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

ฟังก์ชั่นd nแปลงตัวเลขnเป็นตัวเลขส่วนประกอบ มันจะแปลงเป็นสตริงก่อนจากนั้นรับอักขระแต่ละตัวในสตริง แต่ละอักขระต้องถูกแปลงกลับเป็นสตริงมิฉะนั้นอักขระจะถูกแปลงเป็นค่า ASCII แทนค่า "จริง"

c nฟังก์ชั่นฟังก์ชั่นหลักที่มีnเป็นค่าเริ่มต้น ในฟังก์ชั่นนี้rเป็นค่าการทำงานของเรา การwhileวนซ้ำทำสิ่งต่อไปนี้:

  • แปลงrเป็นตัวเลของค์ประกอบ ( d r)
  • รับผลิตภัณฑ์ของตัวเลขเหล่านั้นทั้งหมด สิ่งนี้ใช้Seq.reduceซึ่งใช้ฟังก์ชันที่มีค่าสะสม ( a) และค่าถัดไปในลำดับ ( x) และในกรณีนี้ส่งคืนผลิตภัณฑ์ ค่าเริ่มต้นคือองค์ประกอบแรกในลำดับ
  • แปลงมูลค่าผลิตภัณฑ์นี้เป็นตัวเลขส่วนประกอบ ( d)
  • rสรุปตัวเลขจากก่อนและกำหนดนี้

1

Befunge ขนาด 136 ไบต์

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

คุณสามารถทดลองใช้งานได้ที่นี่

ในขณะที่ล่ามไม่ได้มีขนาดเซลล์ที่ใหญ่พอ แต่ก็ใช้งานได้กับตัวเลขขนาดเล็กสำหรับทุกคนที่อยู่ที่นั่น สำหรับจำนวนมากของnคุณอาจต้องล่ามเหมือนBefunExec


1

Gol> <> , 35 33 ไบต์

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

ลองออนไลน์!

-2 bytes โดย Jo King

การใช้งานอย่างกว้างขวางของฟังก์ชั่นและการวนซ้ำไม่สิ้นสุด

ตัวอย่างโปรแกรมเต็มรูปแบบและวิธีการทำงาน

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 ไบต์

_ì ×ìx}gN®õ x

ลองมัน


คำอธิบาย

                  :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

ไม่เรียบร้อยฉันพยายามที่จะแก้ปัญหานี้ด้วยตัวเอง แต่ไม่พบวิธีแก้ปัญหาที่ดีดังนั้นมันจึงน่าสนใจที่จะเห็นคุณ
Nit

ขอบคุณ @Nit แม้ว่าจะมีวิธีที่สั้นกว่า แต่
Shaggy

@Nit เข้าใจแล้ว! แม้ว่าจะยังคงเชื่อมั่นว่าจะต้องมีวิธีที่สั้นกว่า
Shaggy


0

PHP 7, 89 ไบต์

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

ทำงานเป็นท่อที่มี-rหรือลองออนไลน์

  • PHP มักจะใส่ข้อความเป็นสตริงดังนั้นฉันต้องใช้+เพื่อส่งข้อความ~เพื่อทำงานตามที่ต้องการ
  • การเพิ่มล่วงหน้าจะไม่ทำงาน: ไม่ว่าฉันจะวางไว้ที่ใดมันจะส่งผลต่อตัวถูกดำเนินการทั้งสอง
  • แต่: ไม่สำคัญว่าจะมีการใช้เลขหลักเดียวก่อนหรือหลังการทำซ้ำ (การทำซ้ำเพิ่มเติมจะไม่เปลี่ยนแปลงสิ่งใด); เพื่อให้สามารถใช้แทนfor()do ... while()
  • ต้องการ PHP 7 หรือใหม่กว่าสำหรับการกำหนดอินไลน์ของชื่อฟังก์ชั่น
    PHP ที่เก่ากว่านั้นต้องการไบต์เพิ่มอีกหนึ่งตัว: for($s=str_split,$a=...;$a>9;)$a=array_sum($s(...));
    (หากไม่กำหนดให้str_splitกับตัวแปรจะทำให้ไบต์อื่นเสียอีก)



0

PowerShell Core , 91 101 93 ไบต์

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

ลองออนไลน์!

Ungolfed เล็กน้อย ...

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

ขั้นตอนแรกคือการแยกออกเป็นจำนวนเต็มตัวเลข - ทำอย่างนี้โดยแยกจำนวนเต็มลงในอาร์เรย์ของสตริงตัวอักษร หลังจากนั้นให้ใส่ตัวถูกดำเนินการแล้วประเมินสตริงเป็นคำสั่ง จากนั้นเป็นเรื่องของการทำหลายรอบเพิ่มจนกระทั่งอินพุตเป็นตัวเลขหนึ่งตัว

iexเป็นนามแฝงInvoke-Commandที่ประเมินสตริงที่ส่งผ่านไปยังตำแหน่งพารามิเตอร์แรก

แก้ไข: ตามที่ร้องขอโดย@AdmBorkBorkฉันได้เพิ่มส่วนหัวของฟังก์ชั่นในการนับจำนวนไบต์ นอกจากนี้ฉันทำคณิตศาสตร์เล็กน้อยและตระหนักว่าขอบเขตบนของจำนวนการวนซ้ำ< log log 10^6 < log 6 < 2นั้นช่วยให้ประหยัดได้อีกหกไบต์

แก้ไข x2: @AdmBorkBorkiexพบวิธีที่สั้นมากขึ้นของการแปลงจำนวนเต็มลงในนิพจน์คณิตศาสตร์แล้วปัญหามันลงไปในท่อ บันทึกแล้ว 8 ไบต์ ขอขอบคุณ!


ดีใจที่ได้เห็น PowerSheller อีกรอบ! อย่างไรก็ตามฉันคิดว่าคุณต้องรวมฟังก์ชั่นการกำหนดFunction F($a){ }ในจำนวนไบต์ของคุณ อย่างไรก็ตามคุณควรจะสามารถบันทึกการใช้บางอย่าง[char[]]แทน-split''-ne''ฉันคิดว่า
AdmBorkBork

[char[]]1234=Ӓซึ่งไม่ถูกต้อง ฉันอาจทำให้มันใช้งานได้ แต่ตอนนี้อาจไม่ชัดเจน ขอบคุณสำหรับคำแนะนำ!
Jeff Freeman

ขออภัยผมไม่ชัดเจน - [char[]]"$o"และมากกว่า|iex iex( )
AdmBorkBork

เคล็ดลับนี้โกนรหัสของฉันออกไป 8% น่ากลัว ขอบคุณ!
Jeff Freeman



0

Java 8, 129 ไบต์

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;}

ลองออนไลน์

คำอธิบาย:

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 bytes

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

ลองออนไลน์!

ค่อนข้างตรงไปตรงมา: คำนวณ(n+1)n÷2หาผลรวมจาก 1..n ตรวจสอบว่าเป็นตัวเลขหลักเดียว ( >9) ถ้าไม่ใช่ลองอีกครั้งโดยตั้งค่า k เป็นผลรวมของตัวเลขของผลิตภัณฑ์ของตัวเลขของ k หรือส่งคืน k

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.