In Pyramiden zählen


17

Sie sollten ein Programm oder eine Funktion schreiben, die eine Liste unterschiedlicher Ganzzahlen als Ein- und Ausgabe empfängt oder die Anzahl der Vorkommen der Eingabenummern in der folgenden umgedrehten Zahlenpyramide zurückgibt.

Ausgehend von der ursprünglichen Liste erstellen wir in jedem Schritt eine neue Liste mit den Maximalwerten jedes Paars benachbarter Zahlen (zB 5 1 2 6wird 5 2 6). Wir hören auf, wenn die Liste nur eine Nummer enthält.

Die volle Pyramide für 5 1 2 6ist

5 1 2 6
 5 2 6 
  5 6  
   6   

Die resultierende Anzahl der Vorkommen ist 3 1 2 4(für 5 1 2 6).

Eingang

  • Eine Liste mit einer oder mehreren Ganzzahlen ohne Wiederholung. (zB 1 5 1 6ist ungültig.)

Ausgabe

  • Eine Liste positiver Ganzzahlen. Das idritte Element der Liste ist die Anzahl der Vorkommen der idritten Eingabenummer in der Pyramide.

Beispiele

Eingabe => Ausgabe

-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

Dies ist Code-Golf, also gewinnt der kürzeste Eintrag.

Bonus Puzzle: Kannst du das Problem O(n*log n)rechtzeitig lösen ?


Muss ich sie für eine Funktionsübermittlung auf STDOUT drucken oder einfach ausgeben?
Optimierer

Antworten:


4

Pyth, 19 17 Bytes

m/smmeSb.:QhkUQdQ

Schauen Sie sich die Online-Demonstration oder die vollständige Testsuite an (erste 4-Byte-Iteration über die Beispiele).

Dieser ist ein bisschen schlauer als der naive Ansatz. Jede Zahl des Dreiecks kann als Maximalwert einer verbundenen Teilmenge von dargestellt werden Q. In der ersten Zeile werden die Teilmengen der Länge 1 verwendet, in der zweiten Zeile des Dreiecks die Teilmengen der Länge 2, ...

Erläuterung

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

Um dies ein wenig zu visualisieren. m.:QhdUQund die Eingabe [5, 1, 2, 6]gibt mir alle möglichen Teilmengen:

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

Und mmeSk.:QhdUQgibt mir jedes ihrer Maxima (was genau den Reihen in der Pyramide entspricht):

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

Pyth, 23 22 Bytes

|u&aYGmeSd.:G2QQm/sYdQ

Dies ist nur der einfache Ansatz "Mach, was dir gesagt wird".

Schauen Sie sich die Online-Demonstration oder eine vollständige Testsuite an (erste 4-Byte-Iteration über die Beispiele).

Erläuterung

meSd.:G2ordnet jedes Paar von [(G[0], G[1]), (G[1], G[2]), ...]dem maximalen Element zu.

Yist eine leere Liste, aYGhängt also Gan die Y.

u...QQWendet diese beiden Funktionen ( len(Q)Zeiten) wiederholt an, beginnend mit G = Qund Gnach jedem Lauf aktualisierend .

m/sYdQOrdnet jedes Element der Eingabeliste der Anzahl in der reduzierten YListe zu.


Ihre 17 - Byte - Version den gleichen Algorithmus wie ich verwendet, denke ich , dass jetzt naiv ist zu: P
Optimizer

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

Eine Lösung zum Teilen und Erobern. Das maximale Element Msickert durch die Pyramide Mund teilt es in ein Rechteck aus 's und zwei Subpyramiden.

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

Das Gesamtergebnis ist also die Ausgabe für die linke Unterliste, gefolgt vom Bereich des Rechtecks, gefolgt von der Ausgabe für die rechte Unterliste.

Die Eingabevariable Lwird zum Speichern des Ergebnisses wiederverwendet, sodass die leere Liste der leeren Liste zugeordnet wird.

Die Konstrukte in Lösung sind in Python wortreich. Vielleicht kann eine Sprache mit Mustererkennung den folgenden Pseudocode implementieren?

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

Ich kann mit Mathematics Pattern Matching ein Byte kürzer machen, aber es übertrifft nicht einmal die bestehende Mathematica-Einreichung: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 Bytes

Immer noch auf der Suche nach Golfmöglichkeiten.

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

Dies ist eine CJam-Funktion. Dies erwartet die Eingabenummern auf dem Stapel und gibt auch die entsprechenden Ausgabezahlen auf dem Stapel zurück. Ein Beispiel:

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

Blätter

3 1 2 4

auf stapel.

Ich bin mir ziemlich sicher, dass dies nicht O(n log n)rechtzeitig ist.

Code-Erweiterung :

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

Schauen wir uns an einem Beispiel an, wie es funktioniert 5 1 2 6

In der zweiten Reihe 5 1 2 6wird 5 2 6da jeweils 5, 2 and 6das Maximum aus [5 1], [1 2] and [2 6]. In der dritten Reihe wird es 5 6weil 5 and 6maximal [5 2] and [2 6]jeweils. Dies kann jeweils auch als Maximum geschrieben [5 1 2] and [1 2 6]werden. Ebenso ist für die letzte Reihe 6maximal [5 1 2 6].

Wir erstellen also im Grunde genommen die Slices der richtigen Länge, beginnend mit dem Slice der Länge 1, also den ursprünglichen Zahlen, die jeweils in ein Array eingeschlossen sind, bis zum Slice der Länge Nfür die letzte Zeile, in der Ndie Anzahl der Eingabe-Ganzzahlen angegeben ist.

Probieren Sie es hier online aus


3

Mathematica, 72 Bytes

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

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]

Jeder Eintrag in der Pyramide ist das Maximum der Unterliste auf dem Kegel nach oben. Also generieren wir alle diese Unterlisten, die durch Intervalle [i,j]mit indiziert sind 0 < i < j <= len(L), und zählen, wie oft jedes Element maximal erscheint.

Eine kürzere Aufzählung der Teilintervalle würde wahrscheinlich Zeichen sparen. Eine Single-Index-Parametrisierung der Paare [i,j]wäre ein plausibler Ansatz.


1

Pip , 56 + 1 = 57 Bytes

Ich fürchte, ich konkurriere nicht viel mit dem CJam-Voodoo. Ich brauche wohl einen besseren Algorithmus. Mit -sflag ausführen, um eine durch Leerzeichen getrennte Ausgabe zu erhalten.

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

Ungolfed, mit Kommentaren:

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

Die Neudefinition rjeder Zeit durch funktioniert wie folgt:

{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⌈/⍵}⍵}

Dies ist eine Funktion, die eine Liste annimmt.

      {+/⍵∘.={⍵≡⍬:⍵⋄⍵,∇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

Erläuterung:

  • {... }⍵: Wende die folgende Funktion auf ⍵ an:
    • ⍵≡⍬:⍵: Wenn ⍵ leer ist, gib ⍵ zurück
    • 2⌈/⍵: Erzeugt die nächste Liste
    • ⍵,∇: return ⍵, gefolgt vom Ergebnis der Anwendung dieser Funktion auf die nächste Liste
  • ⍵∘.=: Vergleiche jedes Element in ⍵ mit jedem Element im Ergebnis der Funktion
  • +/: summiere die Zeilen (die Elemente in ⍵ darstellen)

1

Haskell, 78 Bytes

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

Verwendung: 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].

Wie es funktioniert

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 Bytes

Ich denke, ich habe einen interessanten Weg gefunden, aber erst, als mir klar wurde, dass der Code zu lang war, um mithalten zu können. Na ja, poste das trotzdem, falls jemand weiteres Golfpotential sieht.

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}

Ich verwende hier die folgende Formel:

Vorkommen von i = (Anzahl der aufeinanderfolgenden Zahlen, die kleiner sind als i links davon + 1) * (Anzahl der aufeinanderfolgenden Zahlen, die kleiner sind als i rechts davon + 1)

Auf diese Weise muss man nicht die gesamte Pyramide oder Teilmengen davon generieren. (Deshalb dachte ich anfangs, es würde in O (n) laufen, aber Pech, wir brauchen immer noch innere Schleifen.)


1

MATLAB: (266 b)

  • die korrektur des codes kostet mehr bytes, ich werde mich später schwer tun, ihn zu reduzieren.
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

EINGANG

ein Vektor muss die Form haben [abcd ...]

  • Beispiel:

    [2 4 7 11 3]

AUSGABE

Muster tritt auf.

s =

 1


s =

 2


s =

 3


s =

 8


s =

 1

ERLÄUTERUNG:

Wenn [abcd] eine Eingabe ist, berechnet das Programm das Ergebnis ghij als

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 ) = ... 'vereinfacht'

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)

Ich nehme an, es gibt Raum für Verbesserungen ...

[:+/~.="1 0[:;([:i.#)<@:(4 :'(}:>.}.)^:x y')"0 1]
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.