Lực hấp dẫn giữa các số


52

Lực hấp dẫn là một lực thu hút bất kỳ hai vật thể có khối lượng. Trong thử thách này, các đối tượng của chúng ta sẽ là Số và khối lượng của chúng sẽ là giá trị của chúng. Để làm như vậy, chúng tôi không quan tâm đến sức mạnh của lực lượng mà là hướng của nó.

Hãy tưởng tượng bộ số này

[1 6 9 4 6 9 7 6 4 4 9 8 7]

Mỗi người trong số họ tạo ra một lực giữa chính nó và nó là các số liền kề. Trong một số điều kiện, điều này sẽ khiến một số khác bị thu hút (di chuyển) về phía một số. Khi số lớn hơn liền kề, nó thu hút nó. Hãy xem ví dụ trước của chúng tôi:

[1 → 6 → 9 ← 4 6 → 9 ← 7 ← 6 ← 4 4 → 9 ← 8 ← 7]

Số 1này không đủ lớn để di chuyển 6, nhưng số đó 6là, v.v ... Về cơ bản, các số được chuyển sang số liền kề lớn nhất (cũng lớn hơn chính số đó). Nếu cả hai số liền kề đều bằng nhau thì không bị thu hút. Nó cũng xảy ra khi số lượng và nó liền kề nhau.

Điều này chỉ để thể hiện sự hấp dẫn, nhưng điều gì xảy ra sau đó? Các số va chạm do thu hút được tóm tắt:

[20 32 28]

Vì vậy, về cơ bản, thách thức là, Cho một bộ số, đưa ra kết quả của bộ số đã thu hút.


ví dụ 1

Input  => [10 15 20 10 20 10 10]
          [10 → 15 → 20 10 20 ← 10 10]
Output => [45 10 30 10]

Ví dụ 2

Input  => [9 9 9 9 8 1 8]
          [9 9 9 9 ← 8 1 8]
Output => [9 9 9 17 1 8]

Ví dụ 3

Input  => [1 6 9 4 6 9 7 6 4 4 9 8 7]
          [1 → 6 → 9 ← 4 6 → 9 ← 7 ← 6 ← 4 4 → 9 ← 8 ← 7]
Output => [20 32 28]

Ví dụ 4

Input  => [1 2 3 2 1]
          [1 → 2 → 3 ← 2 ← 1]
Output => [9]

Ví dụ 5

Input  => [1]
Output => [1]

Ví dụ 6

Input  => [1 1]
Output => [1 1]

Ví dụ 7

Input  => [2 1 4]
Output => [2 5]

Ghi chú

  • Thu hút chỉ xảy ra một lần
  • Các số không bị thu hút bởi các số không liền kề
  • Tập hợp số sẽ chỉ chứa số nguyên dương

1
Đề nghị thêm một trường hợp thử nghiệm thu gọn thành một số nguyên duy nhất.
Xù xì

2
[1 3 5 4 2]= 15?
Bạch tuộc ma thuật Urn

@MagicOctopusUrn Có
Luis felipe De jesus Munoz

14
1 không đủ lớn để thu hút số 6 Điều này làm phiền cả nhà vật lý trong tôi. (Cũng vậy, một số quy tắc khác, nhưng quy tắc này có thể được sửa chữa bằng cách thay đổi từ ngữ mà không thay đổi định nghĩa vấn đề). Lực hút giữa hai cơ thể, G*M*m / r^2bằng nhau cho cả hai cơ thể. Cái nhẹ hơn di chuyển nhiều hơn cái nặng hơn vì đà chứ không phải vì thiếu sức hấp dẫn. Có thể nói "1 không đủ lớn để di chuyển 6".
Peter Cordes

4
Nhưng thực sự bạn đang định nghĩa "thu hút" là "kéo về phía", thay vì "tạo ra một lực", điều này mâu thuẫn với câu trước đó " Mỗi người trong số họ tạo ra một lực hấp dẫn đối với các số liền kề ". Vì vậy, có thể làm lại mà mở ra để nói "mỗi người trong số họ tạo ra một lực giữa chính nó và nó là các số liền kề. Trong một số điều kiện, điều này sẽ khiến một số khác bị thu hút (di chuyển) về phía một số." Tôi biết đây chỉ là một thuật ngữ thuật ngữ, và mô hình hấp dẫn này chỉ tương tự mơ hồ với vật lý thực sự, nhưng nó làm phiền tôi đủ để muốn viết bình luận này.
Peter Cordes

Câu trả lời:


15

JavaScript (ES6),  106 104  100 byte

Đã lưu 2 byte nhờ @Shaggy

a=>a.filter(n=>n,[...a].map((v,i)=>a[a[p>v&(n=~~a[i+1])<p?k:i+(k=i,n>v&p<n)]+=x=a[i],p=v,i]-=x,p=0))

Hãy thử trực tuyến!

Đã bình luận

Trước tiên chúng tôi cập nhật mảng đầu vào ban đầu a[]bằng cách lặp trên một bản sao của nó. Trong bước này, tất cả các giá trị 'được thu hút' bởi các giá trị khác được đặt thành .0

Vì mảng được phân tích cú pháp từ trái sang phải, chúng ta chỉ cần thêm vào bất cứ khi nào một giá trị bị thu hút bởi hàng xóm bên phải của nó.aiai+1

Ví dụ: được chuyển thành và sau đó .456[0,9,6][0,0,15]

Nhưng khi một vài giá trị liên tiếp bị thu hút bởi hàng xóm bên trái của chúng, chúng ta cần thêm vào công cụ thu hút đầu tiên của chuỗi này (với ) thay vì chỉ đơn giản là .aiakk<iai1

Ví dụ: được chuyển thành và sau đó .654[11,0,4][15,0,0]

[...a]                 // create a copy of a[]
.map((v, i) =>         // for each value v in a[] at position i:
  a[                   //   this statement updates a[i]:
    a[                 //     this statement updates either a[i] or an adjacent value:
      p > v &          //       if the previous value p is greater than v
      (n = ~~a[i + 1]) //       and the next value n
      < p ?            //       is less than p (attraction to the left):
        k              //         use k (k is initially undefined, but this code cannot
                       //         be triggered during the first iteration)
      :                //       else:
        i + (          //         use either i or i + 1:
          k = i,       //           set k to i
          n > v &      //           use i + 1 if n is greater than v
          p < n        //           and p is less than n (attraction to the right)
        )              //
    ] += x = a[i],     //     add x = a[i] to the entry defined above
    p = v,             //     update the previous value to v
    i                  //     actual index to update a[i]
  ] -= x,              //   subtract x from a[i]
  p = 0                //   start with p = 0
)                      // end of map()

Sau đó chúng tôi lọc ra tất cả các mục bằng .0

a.filter(n => n)

Từ lời giải thích của bạn, có vẻ như mã của bạn sẽ thất bại [1,3,5,3,1,2,1]và xuất ra [14,2], nhưng nó thực sự hoạt động chính xác và đầu ra [13,3].
Erik the Outgolfer

@EriktheOutgolfer Tôi đã viết lại phần mà - tôi nghĩ - đã gây hiểu nhầm. Điều đó có tốt hơn không?
Arnauld

2
Bây giờ nó đề cập đến "người thu hút đầu tiên" thay vì chỉ "giá trị cao nhất trước đó", vì vậy tôi có thể hiểu ý của bạn.
Erik the Outgolfer

9

Stax , 27 25 23 18 byte

«╥╦.ê§┘h!@ÆEÿ☺╜╫♥B

Chạy và gỡ lỗi nó

Đầu ra được phân tách bằng dòng mới.

Chương trình này hoạt động trên các cặp liền kề trong mảng và xác định xem có nên phân chia giữa chúng bằng thủ tục này hay không.

Hãy xem xét một số đầu vào tùy ý [... w x y z ...]. Dưới đây là cách xác định xem có nên phân chia giữa xy.

  • Nếu x == y, thì có.
  • Nếu x > y, sau đó iff z >= x.
  • Nếu y > x, sau đó iff w >= y.

Việc tổng kết được để lại như một bài tập.


8

Võng mạc 0.8.2 , 64 byte

\d+
$*
(?<=(1+)) ((?=(1+\1))(?<!\3 \1 )|(?!\1)(?!1+ \1))

1+
$.&

Hãy thử trực tuyến! Liên kết bao gồm bộ kiểm tra. Giải trình:

\d+
$*

Chuyển đổi sang unary.

(?<=(1+)) ((?=(1+\1))(?<!\3 \1 )|(?!\1)(?!1+ \1))

Loại bỏ các dấu phân cách giữa các số thu hút. (?<=(1+))đặt \1thành số trước dấu phân cách. Sau khi phân tách, có hai trường hợp:

  • Số sau dấu phân cách lớn hơn cả hai số trước dấu phân cách
  • Số trước dấu phân cách lớn hơn cả hai số sau dấu phân cách

Trong những trường hợp này, có một sự hấp dẫn giữa hai số và xóa dấu phân cách làm cho các số đó va chạm, cộng chúng lại với nhau.

1+
$.&

Chuyển đổi thành số thập phân.


6

Thạch , 23 byte

Ø0jMÆmær0Ʋ3Ƥ×=4$o<ʋƝk⁸§

Hãy thử trực tuyến!

Một liên kết đơn thể lấy danh sách các số nguyên làm đối số của nó và trả về một danh sách các số nguyên.

Giải trình

Ø0j                     | Join [0, 0] with input list
         Ʋ3Ƥ            | For each length 3 infix, do the following as a monad:
   M                    | - Indices of maximum
    Æm                  | - Mean
      ær0               | - Round to even (so the means of [1, 2, 3], [1, 2], [2, 3] and [1, 3] will all round to 2
                  ʋƝ    | For each neighbouring pair, do the following as a dyad:
            ×           | - Multiply
             =4$        | - Check if equal to 4
                o       | - Or
                 <      | - First number less than second
                    k⁸  | Split input after truthy values of the above
                      § | Sum, vectorised

Một số cảm hứng lấy từ câu trả lời Stax của @ đệ quy .


4

C (gcc) , 111 byte

a,b,c,s;P(){s=!printf("%d ",s);}f(int*v){for(b=s=0,c=*v;a=b,b=c;a<b|b<a&c<a||P(),s+=b,b<c&c<=a|!c&&P())c=*++v;}

Hãy thử trực tuyến!

Có một dãy số nguyên không kết thúc.

Giải trình

a,b,c,  // Three consecutive elements of input array
s;      // Accumulator for sum
P(){s=!printf("%d ",s);}  // Print and clear s
f(int*v){
    for(
        // Init
        b=s=0,
        c=*v;
        // Loop test
        a=b,  // Shift b into a
        b=c;  // Shift c into b, exit if zero
        // Post loop
        a<b|b<a&c<a||P(),  // Print if a==b || (b<a && a<=c)
        s+=b,  // Accumulate
        b<c&c<=a|!c&&P()   // Print if c==0 || (b<c && c<=a)
    )
        // Loop body
        c=*++v;  // Read next number into c
}



3

R , 222 196 173 byte

Đây là một giải pháp với sự giúp đỡ của Robin Ryder

n=length(d<-diff(y<-x<-scan()));l=c(1,sign(d[-n]+d[-1]),-1);m=!!l*n&c(d[1]>0,d[-1]>0|d[-n]<0,d[n]<0);for(t in 1:n){for(i in which(m))y[a]=y[a<-i+l[i]]+x[i];y=x=y-x*m};x[!m]

Hãy thử trực tuyến!

Một bộ ý kiến ​​ngắn

n=length(d<-diff(y<-x<-scan()));  #read input and compute pairwise differences
                    #d[-n]+d[-1]: compare left and right differences
l=c(1,sign(d[-n]+d[-1]),-1)                 #direction of attraction
m=!!l*n&                          #indices of attracted numbers
  c(d[1]>0,d[-1]>0|d[-n]<0,d[n]<0)  
                                   #!!l*n eliminates zeroes in l & the case n==0
for(t in 1:n){                   #excessive loop on transfers
 for(i in which(m))
   y[a]=y[a<-i+l[i]]+x[i]         #transfer right vs. left
 y=x=y-m*x}                        #complete transfer
x[!m]                             #output

1
-4 byte sign(e)thay vì(e>0)-(e<0)
Robin Ryder

1
Ngoài ra {}, vòng lặp for là không cần thiết vì chỉ có một lệnh trong vòng lặp.
Robin Ryder

1
189 byte với 2 ý kiến ​​trên + di chuyển định nghĩa của y.
Robin Ryder

1
179 byte sử dụng thực tế mlà một boolean
Robin Ryder

3

Python, 114 112 byte

lambda a:eval('['+'+'.join(str(c)+',0'*((e<c>d)==(c<d>b))for b,c,d,e in zip([0]+a,a,a[1:]+[0],a[2:]+[0,0]))+']')

Điều này sử dụng thực tế là hướng của mũi tên không thực sự quan trọng và sự hiện diện của mũi tên giữa [i] và [i + 1] có thể được xác định bằng cách xem xét phạm vi của bốn yếu tố a [i- 1: i + 3].

Chỉnh sửa: Cảm ơn Jo King vì đã làm rõ quy tắc



2

K (ngn / k) , 46 byte

{+/'x@.={x x}/(!#x)+{-/2=+/x<\:x 2 0}'3'0,x,0}

Hãy thử trực tuyến!

0,x,0 bao quanh đối số bằng 0

3' bộ ba mục liên tiếp

{ }' cho mỗi làm

x 2 0nhận được cuối cùng và đầu tiên của bộ ba hiện tại - x[2]x[0]. họ là hàng xóm của x[1], trong đó bộ ba là trung tâm

x<\: so sánh sử dụng ít hơn so với từng bộ ba hiện tại

+/tổng kết quả là một cặp tương ứng với x[2]x[0]

2=kiểm tra xem một trong hai hàng xóm có lớn hơn 2 phần tử còn xlại không, trả về một cặp booleans 0 hoặc 1

-/trừ chúng kết quả của -1 có nghĩa x[1]là bị thu hút ở bên trái, 1 ở bên phải và 0 có nghĩa là nó ở đúng vị trí

(!#x)+ thêm 0 vào mục đầu tiên, 1 vào mục thứ hai, v.v ... điều này sẽ tính toán các chỉ số về mục nào được thu hút

{x x}/chỉ số với chính nó cho đến khi hội tụ. kết quả là các chỉ số hiệu quả mà mỗi mục cuối cùng được thu hút

x@.=nhóm x(đối số ban đầu) bởi những người. kết quả là một danh sách các danh sách

+/' tổng hợp từng


2

Clojure , 299 252 byte

(fn[l](loop[o[0]m(vec(map-indexed(fn[i v](def f #(max(nth l(+ % i)0)v))(-(f -1)(f 1)))l))i 0](defn f[x](update o(-(count o)x)#(+(l i)%)))(cond(<=(count m)i)(pop o)(>(m i)0)(recur(f 2)m(inc i))(<(m i)0)(recur(f 1)m(inc i))1(recur(conj(f 1)0)m(inc i)))))

Hãy thử trực tuyến!


Giải trình:

(fn [l]
  (loop [o [0]
         m (vec(map-indexed (fn [i v] ; This maps each element l[i] of l to max(l[i-1], l[i]) - max(l[i+1], l[i])
                              (def f #(max (nth l (+ % i) 0) v))
                              (- (f -1) (f 1)))
                            l))       ; l[x] is zero when l[x] is out of bounds of the input vector l
         i 0]
    (defn f [x] (update o (- (count o) x) #(+ (l i) %)))
    ; Defines a function f(x) that returns the result of mapping the (x-1)th to last element of o over the function g(y) = l[i] + y

    (cond
      (<= (count m) i) (pop o) ; If the length of m is less than or equal to i, there are no more elements in m, so return all but the last element of o
      (> (m i) 0) (recur (f 2) m (inc i)) ; If m[i] is positive, l[i] is pulled toward to the previous element, so add l[i] to the 2nd to last element of o
      (< (m i) 0) (recur (f 1) m (inc i)) ; If m[i] is negative, l[i] is pulled toward the next element, so add l[i] to the last element of o
      1 (recur (conj (f 1) 0) m (inc i))))) ; 1 is truthy
      ; If the length of l is less than or equal to i, and m[i] is not positive or negative, we have m[i] = 0, so l[i] is not pulled toward any other element


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.