Sayılar Arasında Yerçekimi Kuvveti


52

Yerçekimi kuvveti, herhangi iki nesneyi kütle ile çeken bir kuvvettir. Bu mücadelede nesnelerimiz Sayılar olacak ve kütleleri onların değerleri olacak. Bunu yapmak için, gücün gücünü değil, yönünü önemsiyoruz.

Bu sayı kümesini hayal edin

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

Her biri, kendisiyle bitişik sayılar arasında bir güç oluşturur. Bazı şartlar altında, bu başka bir sayının bir sayıya doğru çekilmesine (taşınmasına) neden olacaktır. Sayı bitişikten büyük olduğunda, onu çeker. Önceki örneğimize bakalım:

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

Sayı 1taşınacak kadar büyük değil 6, ancak sayı 6vb. ... Temelde, sayılar en büyük bitişik sayıya taşınır (aynı zamanda sayının kendisinden de büyük). Eğer bitişik sayıların her ikisi de eşitse, o zaman çekilmez. Ayrıca, sayı ve bitişik eşit olduğunda da olur.

Bu sadece cazibe göstermek için, ama sonra ne olacak? Çekim nedeniyle çarpışan sayılar toplanır:

[20 32 28]

Bu yüzden temelde zorluk, bir sayı kümesi verildiğinde, çekilen sayı dizisinin sonucunun çıktısını almasıdır.


örnek 1

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

Örnek 2

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

Örnek 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]

Örnek 4

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

Örnek 5

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

Örnek 6

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

Örnek 7

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

notlar

  • Cazibe sadece bir kez olur
  • Rakamlar bitişik olmayan Rakamlardan etkilenmez
  • Sayı kümesi yalnızca pozitif tam sayılar içerecektir

1
Tek bir tam sayıya daraltılmış bir test vakası eklemeyi önerin.
Shaggy

2
[1 3 5 4 2]= 15
Magic Octopus Urn

@MagicOctopusUrn Evet
Luis felipe De jesus Munoz

14
1 rakamı çekecek kadar büyük değil. Bu sözler içimdeki fizikçiyi rahatsız ediyor. (Öyleyse diğer kurallardan bazılarını da yapın, ancak bu, problem tanımını değiştirmeden ifadeleri değiştirerek düzeltilebilir). İki vücut arasındaki çekim kuvveti G*M*m / r^2, her iki vücut için eşittir. En hafif olanı, çekim eksikliği nedeniyle değil, momentum nedeniyle ağır olandan daha fazla hareket eder. Belki "1, 6'yı taşıyacak kadar büyük değil" diyelim.
Peter Cordes

4
Ama aslında "önceki" cümlesiyle çelişen " her biri bitişik sayılar için bir çekim kuvveti yaratıyor " ifadesiyle çelişen "bir güç yarat" yerine "kendine çek" olarak tanımlıyorsunuz . Bu yüzden belki de açılışın “her biri kendi ile bitişik sayıları arasında bir güç yarattığını söyleyerek yeniden işleyin. Bazı şartlar altında, bu başka bir sayının bir sayıya doğru çekilmesine (taşınmasına) neden olacaktır.” Bunun sadece bir terminoloji nitpick olduğunu ve bu çekim modelinin sadece gerçek fizikle aynı olduğunu düşünüyorum, ancak bu yorumu yazmak istemek beni yeterince rahatsız etti.
Peter Cordes

Yanıtlar:


15

JavaScript (ES6),  106 104  100 bayt

@Shaggy sayesinde 2 bayt kaydedildi

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))

Çevrimiçi deneyin!

Yorumlananlar

a[]0

aiai+1

456[0,9,6][0,0,15]

aiakk<iai1

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()

0

a.filter(n => n)

Açıklamanızdan itibaren, kodunuzun başarısız olması [1,3,5,3,1,2,1]ve çıkması gibi geliyor [14,2], ancak aslında doğru çalışıyor ve çıktı veriyor [13,3].
Outgolfer Erik,

@EriktheOutgolfer - Sanırım - yanıltıcı olan kısmı değiştirdim. Bu daha iyi mi?
Arnauld

2
Şimdi sadece "en yüksek önceki değer" yerine "ilk cezbedici" den bahsediyor, yani ne demek istediğinizi anlayabiliyorum.
Outgolfer Erik,

9

Stax , 27 25 23 18 bayt

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

Koş ve hata ayıkla

Çıktı yeni satırlarla ayrılmıştır.

Bu program dizideki bitişik çiftler üzerinde çalışır ve bu prosedürü kullanarak aralarında bir boşluk olup olmayacağını belirler.

Bazı keyfi girdi düşünün [... w x y z ...]. İşte xve arasında bir bölünme olup olmayacağının nasıl belirleneceği y.

  • Eğer x == yöyleyse, evet.
  • Eğer x > yöyleyse, iff z >= x.
  • Eğer y > xöyleyse, iff w >= y.

Toplama bir egzersiz olarak bırakılmıştır.


8

Retina 0.8.2 , 64 bayt

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

1+
$.&

Çevrimiçi deneyin! Bağlantı test paketi içerir. Açıklama:

\d+
$*

Birliğe dönüştür.

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

Çekilen sayılar arasındaki ayırıcıları çıkarın. ayırıcıdan önceki sayıya (?<=(1+))ayarlar \1. Ayırıcıdan sonra, iki durum var:

  • Ayırıcıdan sonraki sayı, ayırıcıdan önceki sayıların her ikisinden de büyük
  • Ayırıcıdan önceki sayı, ayırıcıdan sonraki sayıların her ikisinden de büyük

Bu durumlarda, iki sayı arasında bir çekim vardır ve ayırıcıyı silmek, sayıların bir araya gelmesine neden olarak çarpışmasına neden olur.

1+
$.&

Ondalık dönüştür.


6

Jöle , 23 bayt

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

Çevrimiçi deneyin!

Bir tamsayı listesini argüman olarak alan ve bir tamsayı listesi döndüren bir tek renkli bağlantı.

açıklama

Ø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

@ Recursive Stax'ın cevabından alınan bazı ilham kaynakları .


4

C (gcc) , 111 bayt

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

Çevrimiçi deneyin!

Sıfırlanmış bir tamsayı dizisini alır.

açıklama

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 bayt

İşte Robin Ryder'ın yardımlarıyla birlikte bir çözüm

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]

Çevrimiçi deneyin!

Kısa bir dizi yorum

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
İle -4 byte sign(e)yerine(e>0)-(e<0)
Robin Ryder

1
Ayrıca {}for döngüsünde gereksizdir, çünkü döngüde yalnızca bir komut vardır.
Robin Ryder

1
Yukarıdaki 2 yorum ile 189 bayt + tanımının taşınması y.
Robin Ryder

1
mBoolean olanı kullanarak 179 bayt
Robin Ryder

3

Python, 114 112 bayt

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]))+']')

Bu, ok yönünün aslında önemli olmadığı ve bir [i] ve bir [i + 1] arasındaki bir okun varlığının dört element a [i - 1: i] 3 +.

Düzenleme: Kural açıklaması için Jo King'e teşekkür ederiz.


2

Perl 5 , 156 147 bayt

$q='$F[$i';map{eval"\$i++while$q]$_"}"<$q+1]",">$q+1]&&$q]>$q+2]&&\$i<\@F"if eval"$q-1]-$q+1]||$q]>$q+1]";$\.=$".sum@F[$p..$i];($p=++$i)<@F&&redo}{

Çevrimiçi deneyin!


2

K (ngn / k) , 46 bayt

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

Çevrimiçi deneyin!

0,x,0 argümanı 0s ile çevrele

3' ardışık öğelerin üçüzleri

{ }' her yapmak için

x 2 0Geçerli üçlünün son ve ilkini alır - x[2]ve x[0]. onlar x[1]üçlünün merkezlendiği komşular.

x<\: Geçerli üçlünün her birine göre daha düşük olanı kullanarak karşılaştır

+/toplamı. sonuç, karşılık gelen x[2]vex[0]

2= Komşularından birinin diğer 2 elementten büyük olup olmadığını kontrol et x , bir çift 0 veya 1 boolel döndür.

-/onları çıkarın. -1 aracının sonucux[1] sola, 1 sağa, 0 ise yerinde kaldığı anlamına gelir

(!#x)+ birinci maddeye 0, ikinciye 1 vb. ekleyin. bu, nesnelerin çekildiği endeksleri hesaplar.

{x x}/yakınsama kadar kendisi ile indeksleyin. Sonuç, her bir maddenin nihayetinde çekildiği etkili endekslerdir.

x@.= grup x (orijinal argüman) olanlar tarafından. sonuç listelerin listesidir

+/' her birini topla


2

Clojure , 299 252 bayt

(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)))))

Çevrimiçi deneyin!


Açıklama:

(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


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.