การเพิ่มพีระมิด Upside-Down ... ย้อนกลับ!


22

การเพิ่มพีระมิด Upside-Down เป็นกระบวนการของการบันทึกรายการของตัวเลขและเพิ่มเข้าด้วยกันติดต่อกันจนกว่าคุณจะไปถึงหมายเลขหนึ่ง

เมื่อกำหนดหมายเลข2, 1, 1แล้วจะเกิดกระบวนการต่อไปนี้:

 2   1   1
   3   2 
     5

5ปลายนี้ในจำนวน


งานของคุณ

ให้ด้านขวาของพีระมิด Upside-Down (เรียงจากน้อยไปมาก) เขียนโปรแกรมหรือฟังก์ชั่นที่จะส่งคืนรายการเดิม

New Extra Challenge : ลองทำสิ่งนี้ในเวลาน้อยกว่า O (n ^ 2)

ตัวอย่าง

f([5, 2, 1]) => [2, 1, 1]
f([84,42,21,10,2]) => [4,7,3,8,2]

หมายเหตุ: ปิรามิด Upside-Down จะไม่ว่างเปล่าและจะประกอบด้วยจำนวนเต็มบวกเท่านั้น


6
ยินดีต้อนรับสู่ PP&CG! ความท้าทายนี้ดีแม้ว่ามันจะดีขึ้น ฉันขอแนะนำให้โพสต์ความท้าทายของคุณในSandboxก่อนเพื่อปรับปรุงการโพสต์ก่อนที่จะเริ่มต้น
เอกภาพ

13
ข้อมูลเชิงลึกฟรีที่ฉันไม่สามารถหาภาษาที่สั้นกว่า:
f([a,b,c,d,e])=[1464101331001210001100001][abcde]
ลินน์

4
เพียง FYI นี้เป็นเช่นเดียวกับCodeWars กะตะ
ggorlen

6
@ggorlen ฉันรู้ ฉันเป็นคนหนึ่งที่ทำกะตะ :)
วิปเปอร์

8
Try doing this in less than O(n)แน่นอนว่ามันเป็นไปไม่ได้ที่จะจัดสรรอาร์เรย์ขนาด n หรือเปลี่ยนรายการ O (n) ในมันเร็วกว่าความซับซ้อน O (n)?
สรรพนามของฉันคือ monicareinstate

คำตอบ:


17

JavaScript (ES6),  62 58 49  46 ไบต์

บันทึกแล้ว 3 ไบต์ขอบคุณ @Oliver

ส่งคืนรายการเป็นสตริงที่คั่นด้วยเครื่องหมายจุลภาค

f=a=>+a||f(a.map(n=>a-(a=n),a=a.shift()))+[,a]

ลองออนไลน์!

แสดงความคิดเห็น

f = a =>              // f = recursive function taking the input list a[]
  +a                  // if a[] consists of a single positive integer:
                      //   stop recursion and return this integer
  ||                  // else:
    f(                //   do a recursive call to f:
      a.map(n =>      //     for each value n in a[]:
        a - (a = n),  //       yield the difference between the previous value and n
                      //       and update a to n
        a = a.shift() //       start by removing the first element and saving it in a
                      //       (because of the recursion, it's important here to reuse
                      //       a variable which is defined in the scope of f)
      )               //     end of map()
    )                 //   end of recursive call
    + [, a]           //   append the last entry from a[]

@Oliver ใช่
Shaggy



6

TI-BASIC, 54 ไบต์

Ans→L₁:dim(L₁→dim(L₂:While 1-Ans:L₁(Ans→L₂(Ans:-ΔList(L₁→L₁:dim(Ans:End:L₁(Ans→L₂(Ans:L₂

อินพุตคือรายการทางด้านขวาของรูปสามเหลี่ยมในAnsตามที่อธิบายไว้ในความท้าทาย
ผลลัพธ์คือแถวบนสุดของสามเหลี่ยมที่กล่าว

ตัวอย่าง:

{5,2,1
         {5 2 1}
prgmCDGF19
         {2 1 1}
{84,42,21,10,2
 {84 42 21 10 2}
prgmCDGF19
     {4 7 3 8 2}

คำอธิบาย:
วิธีนี้ใช้ในทางที่ผิดรูปสามเหลี่ยมที่เกิดขึ้นโดยใช้ทางด้านขวาของรูปสามเหลี่ยมเมื่อการเริ่มต้นสิ้นสุดลงคือการเปลี่ยนแปลงในแต่ละองค์ประกอบ

ในคำอื่น ๆ

2 1 1
 3 2
  5

กลายเป็น:

5 2 1
 3 1
  2

ดังนั้นรายการผลลัพธ์คือด้านขวาของสามเหลี่ยมใหม่นี้ซึ่งสามารถเกิดขึ้นได้โดยการตั้งค่าองค์ประกอบสุดท้ายเป็นดัชนีของความยาวของรายการหลักในรายการผลลัพธ์

Ans→L₁          ;store the input list in L₁
dim(L₁→dim(L₂   ;set the length of L₂ to the length of L₁
While 1-Ans     ;while the L₁'s length is not 1
L₁(Ans→L₂(Ans   ;set the last element of L₁ to the corresponding index in L₂
-ΔList(L₁→L₁    ;get the change in each element, then negate
                ; (elements are in descending order so the change in each
                ;  element will be negative)
                ; and store the resulting list in L₁
dim(Ans         ;leave the length of L₁ in "Ans"
End
L₁(Ans→L₂(Ans   ;set the element again
                ; (needed for final step)
L₂              ;leave L₂ in "Ans"
                ;implicit print of "Ans"

หมายเหตุ: TI-BASIC เป็นภาษาโทเค็น จำนวนตัวอักษรไม่เท่ากับจำนวนไบต์


4

เยลลี่ 6 ไบต์

ṚIƬZḢṚ

Monadic Link ยอมรับรายการจำนวนเต็มซึ่งให้รายการของจำนวนเต็ม

ลองออนไลน์!

อย่างไร?

สร้างสามเหลี่ยมทั้งหมดแล้วแยกองค์ประกอบที่ต้องการ

ṚIƬZḢṚ - Link: list of integers          e.g.  [84,42,21,10,2]
Ṛ      - reverse                               [2,10,21,42,84]
  Ƭ    - collect & apply until a fixed point:
 I     -   incremental differences            [[2,10,21,42,84],[8,11,21,42],[3,10,21],[7,11],[4],[]]
   Z   - transpose                            [[2,8,3,7,4],[10,11,10,11],[21,21,21],[42,42],[84]]
    Ḣ  - head                                  [2,8,3,7,4]
     Ṛ - reverse                               [4,7,3,8,2]

มีวิธีแก้ปัญหาที่เหมือนกันเกือบ แต่มีUs แทน!
Nick Kennedy

IƬUZḢAจะทำงานกับคำถามที่กำหนดเช่นกัน; ฉันสงสัยว่ามีไบต์บันทึกที่ใดที่หนึ่งหรือไม่ ...
Jonathan Allan

ạƝƬZṪ€ทำงานเกินไป แต่อีกหก
Nick Kennedy

ใช่ฉันสังเกตเห็นความแตกต่างนั้น ตอนนี้ฉันมีความหวังน้อยลง
Jonathan Allan

ฉันเพิ่งโพสต์ขนาด 5 ไบต์ แต่มันแตกต่างจากแนวทางของคุณเล็กน้อยเกี่ยวกับส่วนหลังการก่อสร้างพีระมิด
Erik the Outgolfer

4

MathGolf , 14 11 ไบต์

xÆ‼├│?;∟;]x

ลองออนไลน์!

คำอธิบาย

x             reverse int/array/string
 Æ     ∟      do while true without popping using 5 operators
  ‼           apply next 2 operators to TOS
   ├          pop from left of list
    │         get differences of list
     ?        rot3
      ;       discard TOS (removes rest from ├ command)
              loop ends here
        ;     discard TOS (removes empty array from stack)
         ]    wrap stack in array
          x   reverse array



3

Pari / GP , 36 ไบต์

ตามความคิดเห็นของ@Lynn :

ข้อมูลเชิงลึกฟรีที่ฉันไม่สามารถค้นหาภาษาที่มีความสั้นลง:

([a,,,d,อี])=[1-46-4101-33-1001-210001-100001][adอี]

Pari / GP มี Pascal matrix ในตัวและค่าผกผันเป็นเมทริกซ์ที่เราต้องการ:

[1000011000121001331014641]-1=[10000-110001-2100-13-3101-46-41]

a->r=Vecrev;r(r(a)/matpascal(#a-1)~)

ลองออนไลน์!


3

R , 69 67 ไบต์

function(n,x=sum(n|1):1-1,`[`=outer)(x[x,choose]*(-1)^x[x,"+"])%*%n

ลองออนไลน์!

ส่งคืนเวกเตอร์คอลัมน์

-2 ไบต์ขอบคุณKirill L.

ตามความคิดเห็นของLynnด้วยเช่นกัน:

ข้อมูลเชิงลึกฟรีที่ฉันไม่สามารถค้นหาภาษาที่มีความสั้นลง:

([a,,,d,อี])=[1-46-4101-33-1001-210001-100001][adอี]

มันนานกว่าคำตอบ R อื่น ๆ แต่มันเป็นวิธีการที่น่าสนใจในการลองกอล์ฟ


2

Javascript (ES6), 127 ไบต์

f=a=>{for(e=[a],a=[a[l=a.length-1]],i=0;i<l;i++){for(e.push(g=[]),j=-1;j<l;)g.push(e[i][j]-e[i][++j]);r.unshift(g[j])}return r}

รหัสเดิม

function f(a){
  var e=[a];
  var r=[a[a.length-1]];
  for (var i=1;i<a.length;i++){
    var g=[];
    for (var j=0;j<a.length;j++){
      g.push(e[i-1][j-1]-e[i-1][j]);
    }
    e.push(g);
    r.unshift(g[j-1]);
  }
  return r;
}

โอ้ฉันหลงทางเหมือน ... มาก ... กับคำตอบก่อนหน้า ...



2

05AB1E , 12 11 ไบต์

R.¥.Γ¥}¨ζнR

พอร์ตของ@JonathanAllanคำตอบของ Jellyแม้ว่าฉันจะเจลลี่เกี่ยวกับตัวสร้างที่สะดวกกว่าของ Jelly ในกรณีนี้ ;)
ขอบคุณ -1 ไบต์@Emigna

ลองออนไลน์หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย:

R            # Reverse the (implicit) input-list
             #  i.e. [16,7,4,3] → [3,4,7,16]
           # Undelta it (with leading 0)
             #  → [0,3,7,14,30]
    }      # Continue until the result no longer changes, and collect all steps:
     ¥       #  Get the deltas / forward differences of the current list
             #  → [[3,4,7,16],[1,3,9],[2,6],[4],[]]
       ¨     # Remove the trailing empty list
             #  → [[3,4,7,16],[1,3,9],[2,6],[4]]
        ζ    # Zip/transpose; swapping rows/column (with space as default filler)
             #  → [[3,1,2,4],[4,3,6," "],[7,9," "," "],[16," "," "," "]]
         н   # Only leave the first inner list
             #  → [3,1,2,4]
          R  # Revert it back
             #  → [4,2,1,3]
             # (after which it's output implicitly as result)

2
คุณสามารถบันทึก byte ได้R.¥.Γ¥}¨โดยเริ่มจากรายการที่ delta คืออินพุต
Emigna

@Emigna Ah, ยกเลิกการลบลงในลูปที่มีเดลตาเพื่อบันทึกไบต์บนส่วนเติม :) ขอบคุณ!
Kevin Cruijssen


2

Perl 6 , 37 ไบต์

{[R,]($_,{@(.[]Z-.skip)}...1)[*;*-1]}

ลองออนไลน์!

ลดซ้ำแล้วซ้ำอีกโดยการลบองค์ประกอบตามตัวอักษรแล้วส่งกลับจำนวนสุดท้ายของแต่ละรายการในสิ่งที่ตรงกันข้าม

คำอธิบาย:

{                                  }  # Anonymous code block
      $_,               ...   # Create a sequence starting from the input
         {             }      # Where each element is
            .[]Z-.skip          # Each element minus the next element
          @(          )         # Arrayified
                           1  # Until the list has one element left
 [R,]                                # Reverse the sequence
     (                     )[*;   ]  # For every list
                               *-1   # Take the last element



1

ถ่าน 19 ไบต์

Fθ«PI§θ±¹↑UMθ⁻§θ⊖λκ

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

Fθ«

วนซ้ำหนึ่งครั้งสำหรับแต่ละคำในรายการต้นฉบับ

PI§θ±¹↑

พิมพ์คำสุดท้ายในรายการ แต่เลื่อนเคอร์เซอร์ไปที่จุดเริ่มต้นของบรรทัดก่อนหน้าเพื่อให้คำศัพท์นั้นอยู่ในลำดับย้อนกลับ

UMθ⁻§θ⊖λκ

คำนวณเดลตาการแทรกค่าดัมมี่ที่จุดเริ่มต้นเพื่อให้เราสามารถใช้การดำเนินการที่ไม่เปลี่ยนความยาวของรายการ


1

APL + WIN, 34 หรือ 28 ไบต์

v←⊂⌽⎕⋄1↓⌽↑¨⍎∊'v',(∊⍴¨v)⍴⊂',-2-/¨v'

ลองออนไลน์! ความอนุเคราะห์จาก Dyalog Classic

พรอมต์สำหรับเวกเตอร์ด้านขวา

หรือใช้แนวทางของ @ Lynn:

0⍕⌽(⌹⍉n∘.!n←0,⍳¯1+⍴n)+.×⌽n←⎕

ลองออนไลน์ได้รับความอนุเคราะห์จาก Dyalog Classic

พรอมต์สำหรับเวกเตอร์ด้านขวา



1

C, 76 ไบต์

i=0;int*f(int*a,int n){for(;i<n;a[i++]=a[i]-a[i+1]);if(!n)return a;f(a,n-1);}  

อินพุต : (*a = pointer to array, n = last element's index of that array)
เอาต์พุต :return int* = output

คำอธิบาย
ไปจากด้านขวาขึ้นไปเนื่องจากองค์ประกอบสุดท้ายเหมือนกันทั้งอินพุทและเอาท์พุทการวนลูปภายในฟังก์ชั่นเพียงแค่ค้นหาตัวเลขที่สูงขึ้นต่อไปในรูปสามเหลี่ยมค่อย ๆ เอื้อมมือไปด้านบน

ungolfed (จาก C ++)

#include <iostream>
#define SIZE_F 5

int*recFind(int*a, int n) {
    int i = 0;
    while (i < n)
        a[i++] = a[i] - a[i+1];
    if (!n) return a;
        recFind(a, n - 1);
}
int main()
{
    int first[SIZE_F],*n;
    for (int i = 0; i < SIZE_F; i++)
        std::cin >> first[i];

    n = recFind(first, SIZE_F - 1);//size - 1
    for (int i = 0; i < SIZE_F; i++)
        std::cout << n[i];
}

1

Japt , 11 9 ไบต์

Nc¡=äa
yÌ

ลองมัน

บันทึก 2 ไบต์ขอบคุณ Oliver

12 11 ไบต์

_äa}hUÊN yÌ

ลองมัน

บันทึก 1 ไบต์ขอบคุณ Oliver



@Oliver การคิดที่จะใช้y(f)มันไม่ดีพอ แต่การลืม newline นั้นไม่อาจยกโทษให้คุณได้! จะอัปเดตในไม่ช้า ขอบคุณ :)
Shaggy

1

Julia 0.6 , 44 bytes

x->reverse([(j=x[end];x=-diff(x);j)for i=x])

ลองออนไลน์!

หลักการย้ำเดียวกับคำตอบ R ของฉัน

Julia 0.6 , 55 bytes

x->inv([binomial(i,j)for i=(l=length(x)-1:-1:0),j=l])*x

ลองออนไลน์!

อัลกอริทึมของ @ Lynn (ผกผันของเมทริกซ์ Pascal คูณด้วยอินพุต)

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