피라미드에서 계산


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리스트 의 th 요소 i는 피라미드에서 th 입력 숫자 의 발생 횟수입니다 .

입력 => 출력

-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에 인쇄하거나 간단히 출력해야합니까?
Optimizer

답변:


4

Pyth, 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
Optimizer

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과 2 개의 서브 피라미드로 나뉩니다.

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

따라서 전체 결과는 왼쪽 하위 목록에 대한 출력, 사각형 영역, 오른쪽 하위 목록에 대한 출력입니다.

L빈 변수 가 빈 목록에 매핑되도록 입력 변수 를 사용하여 결과를 저장합니다.

솔루션의 구문은 파이썬에서 장황합니다. 패턴 일치를 가진 일부 언어는 다음 의사 코드를 구현할 수 있습니까?

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

Mathematica의 패턴 매칭으로 1 바이트 더 짧을 수는 있지만 기존 Mathematica 제출물을 능가하지는 않습니다.f@{}=##&@@{};f@{a___,l_,b___}/;l>a~Max~b:={f@{a},Length@{a,0}Length@{b,0},f@{b}}
Martin Ender

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 65 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]입니다.

그래서 우리는 기본적으로 length of 슬라이스부터 시작 1하여 배열에 래핑 된 원래의 숫자부터 N마지막 행 의 길이 슬라이스 까지의 적절한 길이 슬라이스를 생성합니다 . 여기서 N입력 정수의 수입니다.

여기에서 온라인으로 사용해보십시오


3

Mathematica, 72 바이트

Last/@Tally[Join@@NestList[MapThread[Max,{Most@#,Rest@#}]&,#,Length@#]]&

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

설명:

  • {... }⍵: function에 다음 기능을 적용합니다.
    • ⍵≡⍬:⍵: ⍵가 비어 있으면 ⍵을 반환합니다.
    • 2⌈/⍵: 다음 목록을 생성
    • ⍵,∇: ⍵를 반환하고이 함수를 다음 목록에 적용한 결과
  • ⍵∘.=: 함수 결과에서 ⍵의 각 요소를 각 요소와 비교
  • +/: 행 합계 (⍵의 요소를 나타냄)

1

하스켈, 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

자바 스크립트, 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보다 작은 연속 숫자의 양 + 1) * (오른쪽에 i보다 작은 연속 숫자의 양 + 1)

이 방법으로 실제로 피라미드 전체 또는 일부를 생성 할 필요는 없습니다. (처음에 O (n)에서 실행될 것이라고 생각한 이유는 있지만 운이 좋으면 여전히 내부 루프가 필요합니다.)


1

MATLAB : (266b)

  • 코드를 수정하는 데 더 많은 바이트가 필요하므로 나중에 줄이는 방법에 어려움이 있습니다.
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]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.