Підрахунок у пірамідах


17

Вам слід написати програму або функцію, яка отримує список різних цілих чисел як вхідних та вихідних даних або повертає кількість вхідних чисел вхідних номерів у наступній піраміді перевернутого числа.

Починаючи з початкового списку на кожному кроці, ми створюємо нове з максимальними значеннями кожної пари сусідніх чисел (наприклад, 5 1 2 6стає 5 2 6). Ми зупиняємось, коли в списку є лише одне число.

Повна піраміда для 5 1 2 6є

5 1 2 6
 5 2 6 
  5 6  
   6   

Отримана кількість випадків 3 1 2 4( 5 1 2 6відповідно).

Вхідні дані

  • Список одного чи кількох цілих чисел без повторення. (наприклад 1 5 1 6, недійсний.)

Вихідні дані

  • Список натуральних чисел. i- Й елемент списку є число входженьi го вхідного числа в пірамідах.

Приклади

Вхід => Вихід

-5 => 1

8 4 => 2 1

5 9 7 => 1 4 1

1 2 3 9 8 6 7 => 1 2 3 16 3 1 2

6 4 2 1 3 5 => 6 4 2 1 3 5

5 2 9 1 6 0 => 2 1 12 1 4 1

120 5 -60 9 12 1 3 0 1200 => 8 2 1 3 16 1 4 1 9

68 61 92 58 19 84 75 71 46 69 25 56 78 10 89 => 2 1 39 2 1 27 6 5 1 6 1 2 14 1 12

Це кодовий гольф, тому найкоротший запис виграє.

Бонусна головоломка: чи можете ви O(n*log n)вчасно вирішити проблему ?


Для подання функції я повинен надрукувати їх до STDOUT або просто вивести їх?
Оптимізатор

Відповіді:


4

Піт, 19 17 байт

m/smmeSb.:QhkUQdQ

Перегляньте Інтернет-демонстрацію або повний тестовий набір (перші 4 байти ітерайте приклади).

Цей трохи розумніший за наївний підхід. Кожне число трикутника може бути представлене як максимальне значення зв'язаного підмножиниQ . У першому рядку використовується підмножини довжиною 1, у другому рядку трикутника використовуються підмножини довжиною 2, ...

Пояснення

m/smmeSb.:QhkUQdQ    implicit: Q = input()
   m         UQ         map each k in [0, 1, 2, ..., len(Q)-1] to:
        .:Qhk              all subsets of Q of length (k + 1)
    meSb                   mapped to their maximum
  s                     join these lists together
m               Q    map each d of Q to:
 /             d        its count in the computed list

Щоб це трохи візуалізувати. m.:QhdUQі вхід [5, 1, 2, 6]дає мені всі можливі підмножини:

[[[5], [1], [2], [6]], [[5, 1], [1, 2], [2, 6]], [[5, 1, 2], [1, 2, 6]], [[5, 1, 2, 6]]]

І mmeSk.:QhdUQдає мені кожну їх максимум (що точно відповідає рядкам у піраміді):

[[5, 1, 2, 6], [5, 2, 6], [5, 6], [6]]

Pyth, 23 22 байти

|u&aYGmeSd.:G2QQm/sYdQ

Це просто простий підхід "робити те, що тобі сказано".

Перегляньте Інтернет-демонстрацію або повний тестовий набір (перші 4 байти ітерайте приклади).

Пояснення

meSd.:G2відображає кожну пару [(G[0], G[1]), (G[1], G[2]), ...]на максимальний елемент.

Yє порожнім списком, тому aYGдодається Gдо Y.

u...QQнеодноразово застосовує ці дві функції ( len(Q)рази), починаючи з G = Qта оновлюючись Gпісля кожного запуску.

m/sYdQвідображає кожен елемент вхідного списку на їх кількість у сплющеному Yсписку.


Ваша 17-байтна версія використовує той самий алгоритм, що і мій, я думаю, що зараз це і наївно: P
Оптимізатор

13

Пітона, 81

def f(L):
 if L:i=L.index(max(L));L=f(L[:i])+[~i*(i-len(L))]+f(L[i+1:])
 return L

Рішення розділити і перемогти. Максимальний елемент Mпронизує всю піраміду вниз, розділяючи її на прямокутник M's та дві підпіраміди.

* * * M * *
 * * M M *
  * M M M
   M M M
    M M
     M

Отже, загальним результатом є вихід для лівого підпису, а потім область прямокутника, а потім вихід для правого підспису.

Вхідну змінну Lповторно використовують для збереження результату, так що порожній список відображається у порожній список.

Конструкції, що знаходяться в рішенні, в Python багатослівні. Можливо, якась мова з відповідності шаблону може реалізувати наступний псевдокод?

def f(L):
 [] -> []
 A+[max(L)]+B -> f(A)+[(len(A)+1)*(len(B)+1)]+f(B)

Я можу зробити один байт коротше з узгодженням шаблону Mathematica, але це навіть не переможе існуюче подання Mathematica:f@{}=##&@@{};f@{a___,l_,b___}/;l>a~Max~b:={f@{a},Length@{a,0}Length@{b,0},f@{b}}
Мартін Ендер,

6

CJam, 23 22 байти

Ще шукаю варіанти для гольфу.

{]_,{)W$ew::e>~}%fe=~}

Це функція CJam (свого роду). Це очікує вхідних чисел на стеку і повертає відповідні підрахунки виводу на стек. Приклад:

5 1 2 6 {]_,{)W$ew::e>~}%fe=~}~

листя

3 1 2 4

на стеку.

Досить впевнений, що це не O(n log n)вчасно.

Розширення коду :

]_                     e# Wrap the input numbers on stack in an array and take a copy
  ,{          }%       e# Take length of the copy and run the loop from 0 to length - 1
    )W$                e# Increment the iterating index and copy the parsed input array
       ew              e# Get overlapping slices of iterating index + 1 size
         ::e>          e# Get maximum from each slice
             ~         e# Unwrap so that there can be finally only 1 level array
                fe=    e# For each of the original array, get the occurrence in this
                       e# final array created by the { ... }%
                   ~   e# Unwrap the count array and leave it on stack

Давайте подивимось, як це працює, опрацювавши приклад 5 1 2 6

У другому ряду 5 1 2 6стає 5 2 6через те, що 5, 2 and 6є максимумом [5 1], [1 2] and [2 6]відповідно. У третьому ряду це стає 5 6тому 5 and 6, що максимум [5 2] and [2 6]відповідно. Це також можна записати як максимум [5 1 2] and [1 2 6]відповідно. Аналогічно для останнього ряду 6- максимум [5 1 2 6].

Таким чином, ми в основному створюємо відрізки належної довжини, починаючи з фрагмента довжини 1, який в основному є оригінальними числами, кожен загорнутий у масив, і, нарешті, відрізок довжини Nдля останнього рядка, де Nкількість цілих чисел.

Спробуйте його онлайн тут



3

Пітона, 81

lambda L:[sum(x==max(L[i:j])for j in range(len(L)+1)for i in range(j))for x in L]

Кожен запис піраміди - це максимум підспису на верхньому конусі. Отже, ми генеруємо всі ці підлісти, індексовані інтервалами [i,j]з 0 < i < j <= len(L), і підраховуємо, скільки разів кожен елемент відображається як максимум.

Коротший спосіб перерахування субінтервалів, ймовірно, збереже символи. Одноіндексна параметризація пар [i,j]була б правдоподібним підходом.


1

Піп , 56 + 1 = 57 байт

Я боюся, що не дуже змагаюся з вуду CJam. Схоже, мені потрібен кращий алгоритм. Запустіть -sпрапором, щоб отримати вихід з обмеженням місця.

l:gr:0*,#gg:0*g+1WrFir:{c:r@[a--a]c@($<l@c)}M1,#r++(gi)g

Безголовка, з коментарями:

l:g                              l = input from cmdline args
r:0*,#g                          r = current row as a list of indices into l
g:0*g+1                          Repurpose g to store the frequencies
Wr                               Loop until r becomes empty
 Fir:{c:r@[a--a]c@($<l@c)}M1,#r  Redefine r (see below) and loop over each i in it
  ++(gi)                         Increment g[i]
g                                Output g

Перевизначення rкожного разу за допомогою наступних робіт:

{c:r@[a--a]c@($<l@c)}M1,#r
{                   }M1,#r       Map this function to each a from 1 to len(r) - 1:
 c:r@[a--a]                      c is a two-item list containing r[a] and r[a-1]
                l@c              The values of l at the indices contained in c
              $<                 Fold/less-than: true iff l[c[0]] < l[c[1]]
           c@(     )             Return c[0] if the former is greater, c[1] otherwise

1

APL (24)

{+/⍵∘.={⍵≡⍬:⍵⋄⍵,∇2⌈/⍵}⍵}

Це функція, яка приймає список, як-от так;

      {+/⍵∘.={⍵≡⍬:⍵⋄⍵,∇2⌈/⍵}⍵}68 61 92 58 19 84 75 71 46 69 25 56 78 10 89
2 1 39 2 1 27 6 5 1 6 1 2 14 1 12

Пояснення:

  • {... }⍵: застосувати таку функцію до ⍵:
    • ⍵≡⍬:⍵: якщо ⍵ порожній, поверніть ⍵
    • 2⌈/⍵: генерувати наступний список
    • ⍵,∇: return return з подальшим результатом застосування цієї функції до наступного списку
  • ⍵∘.=: порівняйте кожен елемент у ⍵ з кожним елементом у результаті функції
  • +/: підсумовуйте рядки (представляючи елементи у ⍵)

1

Haskell, 78 байт

l=length
f x=[l[b|b<-concat$take(l x)$iterate(zipWith max=<<tail)x,a==b]|a<-x]

Використання: f [68,61,92,58,19,84,75,71,46,69,25,56,78,10,89]-> [2,1,39,2,1,27,6,5,1,6,1,2,14,1,12].

Як це працює

zipWith max=<<tail   -- apply 'max' on neighbor elements of a list
iterate (...) x      -- repeatedly apply the above max-thing on the
                     -- input list and build a list of the intermediate
                     -- results
take (l x) ...       -- take the first n elements of the above list
                     -- where n is the length of the input list
concat               -- concatenate into a single list. Now we have
                     -- all elements of the pyramid in a single list.
[ [b|b<-...,a==b] | a<-x]
                     -- for all elements 'a' of the input list make a 
                     -- list of 'b's from the pyramid-list where a==b.
 l                   -- take the length of each of these lists    

1

JavaScript, 109 байт

Я думаю, що я знайшов цікавий шлях для цього, але лише після того, як я закінчив, зрозумів, що код задовго конкурував. Ну добре, розміщуйте це все одно у випадку, якщо хтось побачить подальший потенціал для гольфу.

f=s=>{t=[];for(i=-1;s.length>++i;){j=k=i;l=r=1;for(;s[--j]<s[i];l++);for(;s[++k]<s[i];r++);t[i]=l*r}return t}

Тут я використовую наступну формулу:

входження i = (кількість послідовних чисел, менших від i зліва + 1) * (кількість послідовних чисел, менших, ніж я праворуч + 1)

Таким чином, не потрібно насправді генерувати всю піраміду або її підмножини. (Ось чому я спочатку думав, що це буде працювати в O (n), але, якщо не вдається, нам все одно потрібні внутрішні петлі.


1

МАТЛАБ: (266 б)

  • виправлення коду коштує більше байтів, я буду боротися, як зменшити його пізніше.
v=input('');h=numel(v);for i=1:h,f=(v(i)>v(1));l=(v(i)>v(h));for j=h-1:-1:i+1,l=(v(i)>v(j))*(1+l);end,if(i>1),l=l+(v(i)>v(i-1))*l;end;for j=2:i-1,f=(v(i)>v(j))*(1+f);end,if(i<h),f=f+(v(i)>v(i+1))*f;end;s=f+l+1;if(i<h&&i>1),s=s-((v(i)>v(i+1))*(v(i)>v(i-1)));end;s
end

ВХОД

вектор повинен мати форму [abcd ...]

  • приклад:

    [2 4 7 11 3]

ВИХІД

випадки виникнення.

s =

 1


s =

 2


s =

 3


s =

 8


s =

 1

ПОЯСНЕННЯ:

якщо [abcd] - вхід, програма обчислює результат ghij як

g = (a> b) + (a> b) (a> c) + (a> b) (a> c) * (a> d) = (a> b) (1+ (a> c) ( 1+ (a> c))))

h = (b> a) + (b> c) + (b> a) (b> c) + (b> c) (b> d) + (b> a) (b> c) (b> d ) = ... 'спрощено'

i = (c> b) + (c> d) + (c> b) (c> d) + (c> b) (c> a) + (c> d) (c> b) (c> a ) = ..

j = (d> c) + (d> c) (d> b) + (d> c) (d> b) * (d> a) = ...


0

J (49)

Я припускаю, що є можливість для вдосконалення ...

[:+/~.="1 0[:;([:i.#)<@:(4 :'(}:>.}.)^:x y')"0 1]
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.