ピラミッドで数える


17

入力として個別の整数のリストを受け取り、次の逆さまのピラミッドで入力番号の出現回数を出力または返すプログラムまたは関数を作成する必要があります。

すべてのステップで元のリストから開始して、隣接する番号のすべてのペアの最大値を持つ新しいリストを作成します(たとえばに5 1 2 6なります5 2 6)。リストに番号が1つしかない場合は停止します。

完全なピラミッド5 1 2 6

5 1 2 6
 5 2 6 
  5 6  
   6   

結果の発生回数は3 1 2 45 1 2 6それぞれ)です。

入力

  • 繰り返しのない1つ以上の整数のリスト。(たとえば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に出力するか、単に出力する必要がありますか?
オプティマイザー

回答:


4

Pyth、19 17バイト

m/smmeSb.:QhkUQdQ

チェックアウトオンラインデモンストレーションまたは完全なテストスイート(例以上の最初の4バイトの反復を)。

これは、単純なアプローチよりも少し賢いです。三角形の各番号は、の接続されたサブセットの最大値として表すことができますQ。最初の行では長さ1のサブセットを使用し、三角形の2行目は長さ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これらの2つの関数(len(Q)回)を繰り返し実行し、各実行から開始しG = Qて更新Gします。

m/sYdQ入力リストの各要素を、フラット化されたYリストのカウントにマップします。


あなたの17バイトバージョンは私のものと同じアルゴリズムを使用しています、私はそれが今も素朴だと思います:P-
オプティマイザー

13

Python、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は結果を保存するために再利用されるため、空のリストは空のリストにマッピングされます。

ソリューションの構成要素は、Pythonでは冗長です。たぶん、パターンマッチングを備えたいくつかの言語は、次の擬似コードを実装できますか?

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}}
マーティン・エンダー

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

2行目では、それぞれが最大であるために5 1 2 6なります。3行目では、それぞれの最大値になるためになります。これはそれぞれ最大値として書くこともできます。同様に、最後の行の最大値はです。5 2 65, 2 and 6[5 1], [1 2] and [2 6]5 65 and 6[5 2] and [2 6][5 1 2] and [1 2 6]6[5 1 2 6]

したがって1、基本的に元の数値であるlengthのスライスから始まり、最終的には入力整数の数でNある最終行の長さのスライスに至るまで、基本的に適切な長さのスライスを作成しNます。

こちらからオンラインでお試しください



3

Python、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

Ungolfed、コメント付き:

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

説明:

  • {... }⍵:次の関数をtoに適用します。
    • ⍵≡⍬:⍵:⍵が空の場合、returnを返します
    • 2⌈/⍵:次のリストを生成する
    • ⍵,∇:⍵を返し、この関数を次のリストに適用した結果が続きます
  • ⍵∘.=:inの各要素を関数の結果の各要素と比較します
  • +/:行の合計(⍵の要素を表す)

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)*(右にiより小さい連続番号の量+ 1)

この方法では、ピラミッド全体またはそのサブセットを実際に生成する必要はありません。(これが最初にO(n)で実行されると思った理由ですが、残念ながら、まだ内部ループが必要です。)


1

MATLAB:(266 b)

  • コードの修正にはより多くのバイトがかかりますが、後でそれを減らす方法に苦労します。
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)= ...


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.