Zählen Sie jede Reihe identischer Nummern auf


27

Gehen Sie anhand einer Liste mit streng positiven ganzen Zahlen jede einzelne Zahl durch und ersetzen Sie alle Vorkommen durch aufeinanderfolgende Indizes (null oder eins basierend) einer neuen Reihe.

Beispiele

[][]/[]

[42][0]/[1]

[7,7,7][0,1,2]/[1,2,3]

[10,20,30][0,0,0]/[1,1,1]

[5,12,10,12,12,10][0,0,0,1,2,1]/[1,1,1,2,3,2]

[2,7,1,8,2,8,1,8,2,8][0,0,0,0,1,1,1,2,2,3]/[1,1,1,1,2,2,2,3,3,4]

[3,1,4,1,5,9,2,6,5,3,5,9][0,0,0,1,0,0,0,0,1,1,2,1]/[1,1,1,2,1,1,1,1,2,2,3,2]


2
Also im Grunde die Anzahl, wie oft es die Sequenz bisher erschienen ist?
Jo King

1
@JoKing Ja, das ist eine andere Art, es zu formulieren, aber "bisher" impliziert nullbasiert und "bis und einschließlich" impliziert einsbasiert. Ich wollte die Wahl behalten.
Am

Antworten:


23

JavaScript (ES6), 26 Byte

1-indiziert.

a=>a.map(o=x=>o[x]=-~o[x])

Probieren Sie es online!

Kommentiert

a =>                // a[] = input array
  a.map(o =         // assign the callback function of map() to the variable o, so that
                    // we have an object that can be used to store the counters
    x =>            // for each value x in a[]:
      o[x] = -~o[x] //   increment o[x] and yield the result
                    //   the '-~' syntax allows to go from undefined to 1
  )                 // end of map()

1
Ich habe keine Ahnung, wie das funktioniert, aber es sieht auf jeden Fall elegant aus.
Adám

Das habe ich noch nie gesehen -~- das ist ein absolutes Juwel.
DaveMongoose

Alternativ ist es möglich , zu verwenden , um adie Werte zu speichern, aber es ist erforderlich , um -/ ~der Index , so dass kein Byte gespeichert wird.
user202729


1
@ DaveMongoose -~ist tatsächlich eine häufig verwendete Alternative zu +1(da es unterschiedliche Priorität hat) in vielen Sprachen
ASCII

10

R , 27 Bytes

function(x)ave(x,x,FUN=seq)

Probieren Sie es online!

Erklärung:

ave(x,x,FUN=seq) teilt Vektor x in Untervektoren unter Verwendung von Werten xals Gruppierungsschlüssel auf. Dann seqwird für jede Gruppe eine Funktion aufgerufen und jedes Ergebnis wird an der ursprünglichen Gruppenposition neu angeordnet.

Besser ein Beispiel sehen:

x <- c(5,7,5,5,7,6)
ave(x, x, FUN=seq) # returns 1,1,2,3,2


 ┌───┬───┬───┬───┬───┐
 │ 57557 │
 └───┴───┴───┴───┴───┘            
   |   |   |    |  ||   ▼    ▼  |
 GROUP A : seq(c(5,5,5)) = c(1,2,3)
   |   |   |    |  ||   ▼    ▼  |
 ┌───┐ | ┌───┬───┐ |1|23|
 └───┘ | └───┴───┘ |
       ▼           ▼
 GROUP B : seq(c(7,7)) = c(1,2)
       |           |
       ▼           ▼
     ┌───┐       ┌───┐
     │ 1 │       │ 2 │
     └───┘       └───┘ 

   |   |   |   |   |
   ▼   ▼   ▼   ▼   ▼ 
 ┌───┬───┬───┬───┬───┐
 │ 11232 │
 └───┴───┴───┴───┴───┘  

Hinweis :

seq(y)Funktion gibt eine Sequenz für 1:length(y)den Fall yhat length(y) > 1, aber gibt eine Sequenz aus , 1:y[1]wenn yenthält nur ein Element.
Dies ist zum Glück kein Problem, denn in diesem Fall wählt R - mit vielen Warnungen beklagend - nur den ersten Wert aus, der übrigens das ist, was wir wollen :)


2
Brillant! Ich werde eine Prämie dafür hinzufügen. Nie avezuvor gesehen .
Giuseppe

Ich fühle mich geehrt, vielen Dank! :)
digEmAll

6

MATL , 4 Bytes

&=Rs

Diese Lösung basiert auf 1

Probieren Sie es bei MATL Online aus !

Erläuterung

Verwendet [1,2,3,2]als Beispiel

    # Implicitly grab the input array of length N
    #
    #   [1,2,3,2]
    #
&=  # Create an N x N boolean matrix by performing an element-wise comparison
    # between the original array and its transpose:
    #
    #     1 2 3 2
    #     -------
    # 1 | 1 0 0 0
    # 2 | 0 1 0 1
    # 3 | 0 0 1 0
    # 2 | 0 1 0 1
    #
R   # Take the upper-triangular portion of this matrix (sets below-diagonal to 0)
    #
    #   [1 0 0 0
    #    0 1 0 1
    #    0 0 1 0
    #    0 0 0 1]
    #
s   # Compute the sum down the columns
    #
    #   [1,1,1,2]
    #
    # Implicitly display the result

2
ah, ich wusste, dass es ein altes Problem gab, bei dem ich an etwas Ähnliches dachte. Es ist einzigartig, ist billig, und die MATL-Lösung dort unterscheidet sich von einem Charakter!
Giuseppe

5

APL (Dyalog Unicode) , 7 Bytes

Vielen, vielen Dank an H.PWiz, Adám und dzaima für ihre Hilfe beim Debuggen und Korrigieren.

+/¨⊢=,\

Probieren Sie es online!

Erläuterung

Die nicht stillschweigende 10-Byte-Version wird zunächst einfacher zu erklären sein

{+/¨⍵=,\⍵}

{         } A user-defined function, a dfn
      ,\⍵  The list of prefixes of our input list 
           (⍵ more generally means the right argument of a dfn)
           \ is 'scan' which both gives us our prefixes 
           and applies ,/ over each prefix, which keeps each prefix as-is
    ⍵=     Checks each element of  against its corresponding prefix
           This checks each prefix for occurrences of the last element of that prefix
           This gives us several lists of 0s and 1s
 +/¨       This sums over each list of 0s and 1s to give us the enumeration we are looking for

Die implizite Version macht drei Dinge

  • Erstens entfernt es die Instanz von used in ,\⍵as ,\on the right von sich aus und kann implizit herausfinden, dass es auf das richtige Argument angewendet werden soll.
  • Zweitens ⍵=ersetzen wir das mit , was für das richtige Argument steht
  • Drittens können wir jetzt, da wir keine expliziten Argumente haben (in diesem Fall ), die geschweiften Klammern entfernen, {}da implizite Funktionen sie nicht verwenden


5

J , 7 Bytes

1#.]=]\

Probieren Sie es online!

1-indiziert.

Erläuterung:

]\ all the prefixes (filled with zeros, but there won't be any 0s in the input):
   ]\ 5 12 10 12 12 10
5  0  0  0  0  0
5 12  0  0  0  0
5 12 10  0  0  0
5 12 10 12  0  0
5 12 10 12 12  0
5 12 10 12 12 10

]= is each number from the input equal to the prefix:
   (]=]\) 5 12 10 12 12 10
1 0 0 0 0 0
0 1 0 0 0 0
0 0 1 0 0 0
0 1 0 1 0 0
0 1 0 1 1 0
0 0 1 0 0 1

1#. sum each row:
   (1#.]=]\) 5 12 10 12 12 10
1 1 1 2 3 2

K (OK) , 11 10 Bytes

-1 Byte danke an ngn!

{+/'x=,\x}

Probieren Sie es online!


1
He, du bist froh, dass ich die Daten streng positiv gemacht habe…
Adám

@ Adám Ja, sonst müsste ich die Präfixe einkreuzen :)
Galen Ivanov

1
in k: ='->=
ngn






2

R , 41 Bytes

function(x)diag(diffinv(outer(x,x,"==")))

Probieren Sie es online!

Seltsamerweise ist die Rückgabe eines auf Null basierenden Index in R kürzer.


Wieder Giuseppe, dein überlegenes Wissen über R hat mich geschlagen. Ich hatte eine anständige geniale Methode bei 60 Bytes, aber leider war es nicht genug!
Sumner18

@ Sumner18 poste es trotzdem! Ich lerne immer viel von den Herangehensweisen anderer Leute, und Feedback ist der schnellste Weg, um zu lernen!
Giuseppe

Danke für die Ermutigung! Ich habe meine jetzt gepostet und bin immer offen für Verbesserungsvorschläge!
Sumner18

2

Ruby, 35 Bytes

->a{f=Hash.new 0;a.map{|v|f[v]+=1}}

Es ist leider ziemlich banal - erstelle einen Hash, der die Gesamtsumme für jeden bisher angetroffenen Eintrag speichert.

Einige andere, lustige Optionen, die leider nicht kurz genug waren:

->a{a.dup.map{a.count a.pop}.reverse}   # 37
->a{i=-1;a.map{|v|a[0..i+=1].count v}}  # 38

2

R , 62 43 Bytes

x=z=scan();for(i in x)z[y]=1:sum(y<-x==i);z

-19 Bytes dank Giuseppe, durch Entfernen von which und table und nur geringfügigen Änderungen an der Implementierung

Original

x=z=scan();for(i in names(r<-table(x)))z[which(x==i)]=1:r[i];z

Ich kann mit Giuseppes Wissen nicht mithalten, daher ist meine Einreichung etwas länger als seine, aber mit meinem Grundwissen fand ich diese Lösung ziemlich genial.

r<-table(x) zählt, wie oft jede Zahl erscheint und speichert sie in r, um später darauf zurückgreifen zu können

names() Ruft die Werte jedes eindeutigen Eintrags in der Tabelle ab und wir iterieren über diese Namen mit einer for-Schleife.

Der verbleibende Teil prüft, welche Einträge den Iterationen entsprechen, und speichert eine Folge von Werten (von 1 bis zur Anzahl der Einträge der Iteration).

Probieren Sie es online!


Sie können das entfernen which(), um 7 Bytes zu sparen.
Giuseppe

Ihre Verwendung von 1:r[i]gab mir die Idee, nur table()vollständig zu entfernen : x=z=scan();for(i in x)z[y]=1:sum(y<-x==i);zist 43 Bytes! Das ist ein schöner Ansatz!
Giuseppe

Sieht so aus, als ob keiner von uns mit digEmAlls R-Kenntnissen mithalten kann !
Giuseppe

Ich habe das gesehen und war absolut verblüfft!
Sumner,

2

Haskell , 44 Bytes

([]#)
x#(y:z)=sum[1|a<-x,a==y]:(y:x)#z
_#e=e

Probieren Sie es online!

Erläuterung

Durchläuft die Liste von links nach rechts und behält zunächst die Liste xder besuchten Elemente bei[] :

Für jede Begegnung yzählen alle gleichen Elemente in der Liste x.


1
Etwas länger, aber vielleicht trotzdem interessant: (#(0*));(x:r)#g=g x:r# \y->0^abs(y-x)+g y;e#g=e Probieren Sie es online aus!
Laikoni,

@Laikoni: Wie bist du überhaupt dazu gekommen, du solltest es unbedingt posten!
10.


2

Perl 6 , 15 Bytes

*>>.&{%.{$_}++}

Probieren Sie es online!

Sie können das Feld ++vor das Feld %für einen einseitigen Index verschieben.

Erläuterung:

*>>.&{        }  # Map the input to
      %          # An anonymous hash
       .{$_}     # The current element indexed
            ++   # Incremented

2

Haskell , 47 46 Bytes

(#(*0))
(x:r)#g=g x:r# \y->0^(y-x)^2+g y
e#g=e

Probieren Sie es online!

Ein anderer Ansatz als die Antwort von BMO, die sich als etwas länger herausstellte. (Und leiht freundlicherweise ihren schönen Testanzug aus.)

Die Idee ist, über die Eingabeliste zu iterieren und zu verfolgen, wie oft jedes Element aufgetreten ist, indem eine Funktion aktualisiert wird g. Ungolfed:

f (const 0)
f g (x:r) = g x : f (\ y -> if x==y then 1 + g y else g y) r
f g []    = []

Es ergaben sich zwei interessante Golfmöglichkeiten. Zuerst für den Anfangswert von g, eine konstante Funktion, die ihr Argument ignoriert und zurückgibt 0:

const 0  -- the idiomatic way
(\_->0)  -- can be shorter if parenthesis are not needed
min 0    -- only works as inputs are guaranteed to be non-negative
(0*)     -- obvious in hindsight but took me a while to think of

Und zweitens ein Ausdruck über Variablen xund ywelche Erträge , 1wenn xequals yund 0sonst:

if x==y then 1else 0  -- yes you don't need a space after the 1
fromEnum$x==y         -- works because Bool is an instance of Enum
sum[1|x==y]           -- uses that the sum of an empty list is zero
0^abs(x-y)            -- uses that 0^0=1 and 0^x=0 for any positive x
0^(x-y)^2             -- Thanks to  Christian Sievers!

Es könnte noch kürzere Wege geben. Hat jemand eine Idee?


1
Sie können verwenden 0^(x-y)^2.
Christian Sievers


1

Ruby , 34 Bytes

->a{r=[];a.map{|x|(r<<x).count x}}

Probieren Sie es online!


Ich kann nicht glauben, dass ich es versucht habe ->a{i=-1;a.map{|v|a[0..i+=1].count v}}und nicht daran gedacht habe, nur ein neues Array zu bauen, lol. Gute Arbeit.
DaveMongoose

1

Bash, 37 24 Bytes

f()(for x;{ r+=$[a[x]++]\ ;};echo $r)

TIO

Wenn gültig, gibt es auch diese Variante, wie von DigitalTrauma vorgeschlagen

for x;{ echo $[a[x]++];}

TIO


1

@DigitalTrauma, danke, aber ich weiß nicht, ob es die Regeln gebrochen hat. auch als er gefragt Liste zu ersetzen und vielleicht so etwas wie sein sollte tio.run/...
Nahuel FOUILLEUL

2
@NahuelFouilleul Es ist in Ordnung, vollständige Programme sind ebenfalls erlaubt, und das ist eine gültige Methode zum Eingeben / Ausgeben einer Liste (IMO)
ASCII

1

Perl 5, 11 Bytes

$_=$h{$_}++

TIO

Erläuterungen nach Kommentar

  • $_Perls spezielle Variable, die die aktuelle Zeile enthält, wenn ein Loop über einen Eingang ( -poder -nSchalter) läuft
  • $h{$_}++Autoviviert die Karte %hund erstellt einen Eintrag mit Schlüssel $_und Inkrementen und gibt den Wert vor dem Inkrement
  • Die spezielle Variable wird aufgrund von -pswitch -lausgegeben. switch entfernt das Zeilenende bei der Eingabe und fügt das Zeilenende bei der Ausgabe hinzu

Das sieht toll aus. Möchtest du das erklären?
Am

@ Adám, danke für dein Feedback, klar, fertig
Nahuel Fouilleul



1

Attache , 23 Bytes

{`~&>Zip[_,_[0:#_::0]]}

Probieren Sie es online!

Erläuterung

{`~&>Zip[_,_[0:#_::0]]}
{                     }    _: input (e.g., [5, 12, 10, 12, 12, 10])
             0:#_          range from 0 to length of input (inclusive)
                           e.g., [0, 1, 2, 3, 4, 5, 6]
                 ::0       descending range down to 0 for each element
                           e.g., [[0], [1, 0], [2, 1, 0], [3, 2, 1, 0], [4, 3, 2, 1, 0], [5, 4, 3, 2, 1, 0], [6, 5, 4, 3, 2, 1, 0]]
           _[       ]      get input elements at those indices
                           e.g., [[5], [12, 5], [10, 12, 5], [12, 10, 12, 5], [12, 12, 10, 12, 5], [10, 12, 12, 10, 12, 5], [nil, 10, 12, 12, 10, 12, 5]]
     Zip[_,          ]     concatenate each value with this array
                           e.g., [[5, [5]], [12, [12, 5]], [10, [10, 12, 5]], [12, [12, 10, 12, 5]], [12, [12, 12, 10, 12, 5]], [10, [10, 12, 12, 10, 12, 5]]]
   &>                      using each sub-array spread as arguments...
 `~                            count frequency
                               e.g. [12, [12, 10, 12, 5]] = 12 ~ [12, 10, 12, 5] = 2

1

C (gcc) , 65 62 Bytes

c,d;f(a,b)int*a;{for(;c=d=b--;a[b]=d)for(;c--;d-=a[c]!=a[b]);}

Probieren Sie es online!

-2 Bytes nur dank ASCII


Das fühlte sich zu einfach an, aber ich konnte mit einem anderen Ansatz nicht kürzer werden.



@ Nur ASCII - ist das eine gültige Antwort? Kein Header enthalten, keine Deklarationen, es ist ein Snippet und viele Warnungen, obwohl es ausgegeben wird.
AZTECCO

@AZTECCO-Warnungen sind in Ordnung (stderr wird ignoriert), solange es das tut, was es sollte, ist es akzeptabel. Beachten Sie, dass dies ist eine Funktionsdeklaration, sowie einige Variablendeklarationen - Sie können es Ausdruck überall als Top - Level gesetzt und es wird in Ordnung kompilieren. Viele c-Antworten (und solche in Sprachen mit weniger strenger Syntax) enthalten im Allgemeinen einige Warnungen wegen Bytesaves, die keinen guten Codestil haben
ASCII-

Ok, ich kann verstehen, aber es stimmt immer noch etwas nicht mit mir. Wenn wir mit einer anderen Menge (in der Größe) testen möchten, müssen wir den Code ändern, auch in der Druckschleife. Außerdem sollte die Eingabe nur die Menge und nicht die Größe sein. "Angesichts einer Liste von streng positiven ganzen Zahlen ... "also ich denke eingabe sollte nur die liste sein.
AZTECCO

@AZTECCO ist sich nicht sicher, ob diese Diskussion in den Kommentaren dieser Antwort enthalten sein soll, aber Sie möchten sich vielleicht Meta ansehen - speziell zu E / A- und Antwortformaten .
15.

1

K (ngn / k) , 18 Bytes

(,/.!'#'=x)@<,/.=x

Probieren Sie es online!


ALTER ANSATZ

K (NGN / k) , 27 23 22 Bytes

{x[,/.=x]:,/.!'#'=x;x}

Probieren Sie es online!


Das ist keine schöne ... schnelle und schmutzige Lösung, ich werde sie später verfeinern, wenn ich die Chance bekomme, über einen besseren Ansatz nachzudenken

Erläuterung:

  • =x Gibt ein Dikt zurück, in dem Schlüssel Elemente von x und Werte ihre Indizes sind (3 1 4 5 9 2 6!(0 9;1 3;,2;4 8 10;5 11;,6;,7) )
  • i: diktieren i
  • #:' Zählwerte für jeden Schlüssel (3 1 4 5 9 2 6!2 2 1 3 2 1 1 )
  • !:' jeden Wert aufzählen (3 1 4 5 9 2 6!(0 1;0 1;,0;0 1 2;0 1;,0;,0) )
  • ,/.: Werte extrahieren und Liste reduzieren (0 1 0 1 0 0 1 2 0 1 0 0 )
  • x[,/.:i]: extrahieren Sie die Indizes aus i, reduzieren Sie sie und weisen Sie jeden Wert aus der Liste auf der rechten Seite diesen Indizes zu

ärgerlicherweise wird die Liste aktualisiert, aber durch die Zuweisung wird ein Nullwert zurückgegeben, sodass ich die Liste nach dem Semikolon zurückgeben muss (;x ) zurückgeben muss

bearbeiten: entfernte überflüssige Doppelpunkte

edit2: unnötige Zuordnung entfernt


0

Retina 0.8.2 , 30 Bytes

\b(\d+)\b(?<=(\b\1\b.*?)+)
$#2

Probieren Sie es online! Link enthält Testfälle. 1-indiziert. Erläuterung: Der erste Teil des regulären Ausdrucks entspricht der Reihe nach jeder Ganzzahl in der Liste. Die Gruppe des Lookbehinds entspricht jedem Vorkommen dieser Ganzzahl in dieser Zeile bis einschließlich der aktuellen Ganzzahl. Die ganze Zahl wird dann durch die Anzahl der Übereinstimmungen ersetzt.


0

Batch, 61 Bytes

@setlocal
@for %%n in (%*)do @set/ac=c%%n+=1&call echo %%c%%

1-indiziert. Da die Variablensubstitution vor dem Parsen erfolgt, set/aerhöht der Befehl den angegebenen Variablennamen, indem der Buchstabe cmit der Ganzzahl aus der Liste verkettet wird (numerische Variablen werden in Batch standardmäßig auf Null gesetzt). Das Ergebnis wird dann zur Vereinfachung der Ausgabe in eine andere Ganzzahl kopiert (genauer gesagt, es wird ein Byte gespeichert).



0

Japt, 8 Bytes

£¯YÄ è¶X

Probieren Sie es hier aus

£¯YÄ è¶X
             :Implicit input of array U
£            :Map each X at 0-based index Y
 ¯           :  Slice U to index
  YÄ         :    Y+1
     è       :  Count the elements
      ¶X     :    Equal to X
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.