Гравитационная сила между числами


52

Гравитационная сила - это сила, которая притягивает любые два объекта с массой. В этом вызове наши объекты будут числами, а их масса - их стоимостью. Для этого нам важна не сила, а направление.

Представьте себе этот набор чисел

[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]

Число 1не достаточно велико для перемещения 6, но число 6и т. Д. В основном числа перемещаются на самое большое соседнее число (также больше, чем само число). Если оба соседних числа равны, то это не привлекает. Это также происходит, когда число и соседние числа равны.

Это только для того, чтобы показать привлекательность, но что происходит после? Числа, которые сталкиваются из-за притяжения, суммируются:

[20 32 28]

Таким образом, основная задача состоит в том, чтобы, учитывая набор чисел, вывести результат привлеченного набора чисел.


Пример 1

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

Пример 2

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

Пример 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]

Пример 4

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

Пример 5

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

Пример 6

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

Пример 7

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

Примечания

  • Аттракцион происходит только один раз
  • Номера не привязаны к несмежным номерам
  • Набор чисел будет содержать только натуральные числа

1
Предложите добавить тестовый пример, который сворачивается в одно целое число.
лохматый



14
1 недостаточно велик, чтобы привлечь число 6. Эта формулировка беспокоит физика во мне. (Также как и некоторые другие правила, но это можно исправить, изменив формулировку без изменения определения проблемы). Сила притяжения между двумя телами G*M*m / r^2одинакова для обоих тел. Легкий движется больше, чем тяжелый из-за импульса, а не из-за недостатка притяжения. Может быть, сказать «1 не достаточно большой, чтобы двигаться 6».
Питер Кордес

4
Но на самом деле вы определяете «притягивать» как «притягивает к себе», а не «создает силу», что противоречит предыдущему предложению « Каждый из них создает силу притяжения для своих соседних чисел ». Поэтому, возможно, переделайте это открытие, чтобы сказать: «Каждый из них создает силу между собой и соседними числами. При некоторых условиях это приведет к тому, что другое число будет притягиваться (перемещаться) к числу». Я знаю, что это просто придирка к терминологии, и эта модель гравитации лишь немного похожа на реальную физику, но меня это достаточно обеспокоило, чтобы написать этот комментарий.
Питер Кордес

Ответы:


15

JavaScript (ES6),  106 104  100 байт

Сохранено 2 байта благодаря @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))

Попробуйте онлайн!

комментарии

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)

Из вашего объяснения звучит так, будто ваш код не будет работать [1,3,5,3,1,2,1]и выводиться [14,2], но на самом деле он работает правильно и выводит [13,3].
Эрик Outgolfer

@EriktheOutgolfer Я перефразировал ту часть, которая, я думаю, вводит в заблуждение. Это лучше?
Арно

2
Теперь в нем упоминается «первый аттрактор», а не просто «самое высокое предыдущее значение», так что я могу понять, что вы имеете в виду.
Эрик Outgolfer

9

Stax , 27 25 23 18 байт

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

Запустите и отладьте его

Вывод разделен переводом строки.

Эта программа работает с соседними парами в массиве и определяет, следует ли разделить их, используя эту процедуру.

Рассмотрим некоторые произвольные входные данные [... w x y z ...]. Вот как определить, должен ли быть разделитель между xи y.

  • Если x == yда, то да.
  • Если x > y, тогда iff z >= x.
  • Если y > x, тогда iff w >= y.

Суммирование оставлено как упражнение.


8

Сетчатка 0.8.2 , 64 байта

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

1+
$.&

Попробуйте онлайн! Ссылка включает тестовый набор. Объяснение:

\d+
$*

Преобразовать в одинарный.

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

Уберите разделители между привлеченными числами. (?<=(1+))устанавливает \1число перед разделителем. После разделителя есть два случая:

  • Число после разделителя больше, чем оба числа перед разделителем
  • Число перед разделителем больше, чем оба числа после разделителя

В этих случаях существует притяжение между двумя числами, и удаление разделителя приводит к столкновению чисел, складывая их вместе.

1+
$.&

Преобразовать в десятичную.


6

Желе , 23 байта

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

Попробуйте онлайн!

Монадическая ссылка, которая принимает список целых чисел в качестве аргумента и возвращает список целых чисел.

объяснение

Ø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

Некоторое вдохновение взято из Stax-ответа @ recursive .


4

C (gcc) , 111 байт

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

Попробуйте онлайн!

Принимает массив целых чисел с нулевым символом в конце.

объяснение

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 байт

Вот решение с некоторой помощью от Робин Райдер

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]

Попробуйте онлайн!

Краткий набор комментариев

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 байта с sign(e)вместо(e>0)-(e<0)
Робин Райдер

1
также {}в цикле for нет необходимости, поскольку в цикле есть только одна инструкция.
Робин Райдер

1
189 байт с указанными выше 2 комментариями + перемещение определения y.
Робин Райдер

1
179 байтов, используя тот факт, что mэто логическое значение
Робин Райдер

3

Python, 114 112 байт

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

При этом используется тот факт, что направление стрелки на самом деле не имеет значения, и что наличие стрелки между a [i] и a [i + 1] можно определить, посмотрев на диапазон четырех элементов a [i- 1: I + 3].

Изменить: Спасибо Джо Кинг за разъяснение правил



2

K (нгн / к) , 46 байтов

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

Попробуйте онлайн!

0,x,0 окружить аргумент 0с

3' тройки последовательных предметов

{ }' за каждое занятие

x 2 0получить последний и первый из текущего триплета - x[2]и x[0]. они соседи x[1], на которых центрирован триплет

x<\: сравнить, используя меньше, чем против каждого текущего триплета

+/сумма. В результате получается пара, соответствующая x[2]иx[0]

2=проверьте, больше ли один из соседей, чем другие 2 элемента x, верните пару логических значений 0 или 1

-/вычесть их. результат -1 означает x[1]притяжение слева, 1 справа и 0 означает, что он остается на месте

(!#x)+ добавьте 0 к первому элементу, 1 ко второму и т. д. Это вычисляет индексы, к которым привлекаются элементы.

{x x}/Индекс с собой до схождения. Результатом являются эффективные показатели, к которым в конечном итоге привлекается каждый элемент.

x@.=группа x(исходный аргумент) по тем. Результатом является список списков

+/' суммировать каждый


2

Clojure , 299 252 байта

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

Попробуйте онлайн!


Объяснение:

(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


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.