Wymień każdą serię identycznych liczb w miejscu


27

Biorąc pod uwagę listę ściśle dodatnich liczb całkowitych, przejrzyj każdą odrębną liczbę i zamień wszystkie jej wystąpienia na kolejne indeksy (oparte na zero lub jeden) nowej serii.

Przykłady

[][]/[]

[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
Więc w zasadzie ile razy pojawiła się sekwencja?
Jo King

1
@JoKing Tak, to inny sposób na stwierdzenie tego, ale „jak dotąd” oznacza zero, a „do momentu włączenia” oznacza jeden. Chciałem zachować wybór.
Adám

Odpowiedzi:


23

JavaScript (ES6), 26 bajtów

1-indeksowany.

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

Wypróbuj online!

Skomentował

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
Nie mam pojęcia, jak to działa, ale z pewnością wygląda elegancko.
Adám

Nie widziałem -~wcześniej - to absolutny klejnot.
DaveMongoose

Alternatywnie można użyć ado przechowywania wartości, ale jest to wymagane do -/ ~indeksu, aby żaden bajt nie został zapisany.
user202729


1
@DaveMongoose -~jest w rzeczywistości powszechnie używaną alternatywą dla +1(ponieważ ma inny priorytet) w wielu językach
tylko ASCII

10

R , 27 bajtów

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

Wypróbuj online!

Objaśnienie:

ave(x,x,FUN=seq)dzieli wektor xna podektory, używając wartości xjako kluczy grupujących. Następnie seqwywoływana jest funkcja dla każdej grupy i każdy wynik jest ponownie układany w pierwotnej pozycji grupy.

Lepiej zobacz przykład:

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
 └───┴───┴───┴───┴───┘  

Uwaga :

seq(y)funkcja zwraca sekwencję, 1:length(y)jeśli yma length(y) > 1, ale zwraca sekwencję, 1:y[1]jeśli yzawiera tylko jeden element.
Na szczęście nie stanowi to problemu, ponieważ w takim przypadku R - narzekając na wiele ostrzeżeń - wybiera tylko pierwszą wartość, która, nawiasem mówiąc, jest tym, czego chcemy :)


2
Znakomity! Dodam za to nagrodę. Nigdy avewcześniej nie widziałem .
Giuseppe

Jestem zaszczycony, wielkie dzięki! :)
digEmAll

6

MATL , 4 bajty

&=Rs

To rozwiązanie jest oparte na 1

Wypróbuj to w MATL Online !

Wyjaśnienie

Używa [1,2,3,2]jako przykładu

    # 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, wiedziałem, że był stary problem, który sprawił, że pomyślałem o czymś podobnym, Unique jest tani, a rozwiązanie MATL ma jedną postać inną!
Giuseppe

5

APL (Dyalog Unicode) , 7 bajtów

Ogromne podziękowania dla H.PWiz, Adáma i dzaimy za ich pomoc w debugowaniu i poprawianiu tego.

+/¨⊢=,\

Wypróbuj online!

Wyjaśnienie

10-bajtowa, niejawna wersja będzie łatwiejsza do wyjaśnienia w pierwszej kolejności

{+/¨⍵=,\⍵}

{         } 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

Milcząca wersja robi trzy rzeczy

  • Po pierwsze, usuwa wystąpienie użyte w, ,\⍵ponieważ ,\po prawej stronie może domyślnie domyślić się, że ma działać na podstawie właściwego argumentu.
  • Po drugie, dla ⍵=, my zastąpić z , który stoi na prawym argumencie
  • Po trzecie, skoro nie mamy wyraźnych argumentów (w tym przypadku ), możemy usunąć nawiasy klamrowe, {}ponieważ funkcje ukryte ich nie używają


5

J , 7 bajtów

1#.]=]\

Wypróbuj online!

1-indeksowany.

Wyjaśnienie:

]\ 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 bajtów

-1 bajt dzięki ngn!

{+/'x=,\x}

Wypróbuj online!


1
Heh, cieszę się, że sprawiłem, że dane były całkowicie pozytywne…
Adám

@ Adám Tak, inaczej musiałbym zapakować prefiksy :)
Galen Iwanow

1
in k: ='->=
ngn






2

R , 41 bajtów

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

Wypróbuj online!

Co dziwne, zwracanie indeksu zerowego jest krótsze w R.


Po raz kolejny Giuseppe, twoja lepsza znajomość R pokonała mnie. Miałem przyzwoicie genialną metodę na 60 bajtów, ale niestety to nie wystarczyło!
Sumner18

@ Sumner18 i tak opublikuj! Zawsze dużo się uczę od podejść innych ludzi, a uzyskiwanie informacji zwrotnych to najszybszy sposób na naukę!
Giuseppe

dzięki za zachętę! Opublikowałem teraz mój i zawsze jestem otwarty na propozycje ulepszeń!
Sumner18

2

Rubin, 35 bajtów

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

Niestety, jest dość przyziemny - zbuduj skrót, który przechowuje sumę dla każdego napotkanego do tej pory wpisu.

Inne zabawne opcje, które niestety nie były dość krótkie:

->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 bajty

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

-19 bajtów dzięki Giuseppe, usuwając je i zapisując tabelę oraz tylko niewielkie zmiany w implementacji

Oryginalny

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

Nie mogę konkurować z wiedzą Giuseppe, więc moje poddanie jest nieco dłuższe niż jego, ale korzystając z mojej podstawowej wiedzy, czułem, że to rozwiązanie było dość pomysłowe.

r<-table(x) zlicza liczbę wyświetleń każdej liczby i zapisuje ją w r, do wykorzystania w przyszłości

names() pobiera wartości każdego unikalnego wpisu w tabeli i iterujemy te nazwy za pomocą pętli for.

Pozostała część sprawdza, które wpisy są równe iteracjom, i przechowuje sekwencję wartości (od 1 do liczby wpisów iteracji)

Wypróbuj online!


możesz usunąć, which()aby zapisać 7 bajtów.
Giuseppe

Twój sposób użycia 1:r[i]podsunął mi pomysł table()całkowitego usunięcia : x=z=scan();for(i in x)z[y]=1:sum(y<-x==i);zma 43 bajty! To miłe podejście!
Giuseppe

Wygląda na to, żaden z nas nie może konkurować z R wiedzy digEmAll za !
Giuseppe

Widziałem to i byłem całkowicie oszołomiony!
Sumner18

2

Haskell , 44 bajty

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

Wypróbuj online!

Wyjaśnienie

Przechodzi przez listę od lewej do prawej, zachowując listę xodwiedzanych elementów, początkowo []:

Dla każdego spotkania yzliczaj wszystkie równe elementy na liście x.


1
Trochę dłużej, ale może jednak ciekawie: (#(0*));(x:r)#g=g x:r# \y->0^abs(y-x)+g y;e#g=e Wypróbuj online!
Laikoni

@Laikoni: Jak to wymyśliłeś, powinieneś to całkowicie opublikować!
ბიმო


2

Perl 6 , 15 bajtów

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

Wypróbuj online!

Możesz przenieść ++do przed %indeksem opartym na jednym.

Wyjaśnienie:

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

2

Haskell , 47 46 bajtów

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

Wypróbuj online!

Inne podejście niż odpowiedź BMO, która okazała się nieco dłuższa. (I uprzejmie pożycza swój ładny kombinezon testowy.)

Chodzi o to, aby iterować listę wejściową i śledzić liczbę wystąpień każdego elementu poprzez aktualizację funkcji g. Nie golfowany:

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

Pojawiły się dwie interesujące możliwości gry w golfa. Po pierwsze dla wartości początkowej gfunkcji stałej, która ignoruje argument i zwraca 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

A po drugie wyrażenie nad zmiennymi xi yco daje 1w razie xrówności yi 0inaczej:

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!

Wciąż mogą istnieć krótsze drogi. Czy ktoś ma pomysł?


1
Możesz użyć 0^(x-y)^2.
Christian Sievers,



1

bash, 37 24 bajtów

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

TIO

jeśli jest to ważne, istnieje również ta odmiana, zgodnie z sugestią DigitalTrauma

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

TIO


1
Przekaż listę jako argumenty wiersza poleceń - tio.run/##S0oszvj/Py2/SKHCuporNTkjX0ElOjG6IlZbO5ar9v///8b/… - tylko 24 bajty.
Digital Trauma

@DigitalTrauma, dzięki, ale nie wiem, czy to złamało zasady. także, ponieważ poproszono go o zastąpienie listy i być może powinno to być coś w rodzaju tio.run/…
Nahuel Fouilleul

2
@NahuelFouilleul W porządku, dozwolone są również pełne programy, i to jest poprawna metoda wprowadzania / wysyłania listy (IMO)
tylko ASCII

1

Perl 5, 11 bajtów

$_=$h{$_}++

TIO

wyjaśnienia po komentarzu

  • $_specjalna zmienna perla zawierająca linię prądu podczas zapętlania wejścia ( -plub -nprzełączników)
  • $h{$_}++automatycznie uwiarygodnia mapę %hi tworzy pozycję z kluczem $_i przyrostami oraz podaje wartość przed przyrostem
  • specjalna zmienna jest drukowana z powodu -pprzełącznika, -lprzełącznik usuwa koniec linii na wejściu i dodaje koniec linii na wyjściu

To wygląda niesamowicie. Chcesz to wyjaśnić?
Adám

@ Adám, dziękuję za opinię,
jasne



1

Attache , 23 bajty

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

Wypróbuj online!

Wyjaśnienie

{`~&>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 bajtów

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

Wypróbuj online!

-2 bajty dzięki tylko ASCII


To wydawało się zbyt proste, ale nie mogłem wydawać się krótszy z innym podejściem.



@ Tylko ASCII czy to poprawna odpowiedź? Bez nagłówka, bez deklaracji, to fragment kodu i wiele ostrzeżeń, mimo że generuje.
AZTECCO

Ostrzeżenia @AZTECCO są w porządku (stderr jest ignorowany), o ile robi to, co powinien, jest do przyjęcia. zwróć uwagę, że jest to deklaracja funkcji plus niektóre deklaracje zmiennych - możesz umieścić ją w dowolnym miejscu jako wyrażenie najwyższego poziomu i będzie dobrze kompilować. wiele odpowiedzi C (i tych w językach z mniej ścisłym składni) nie mają zwykle sporo ostrzeżeń powodu bytesaves które nie są dobrym stylu code
ASCII tylko

Ok, rozumiem, ale wciąż coś jest nie tak. Jeśli chcemy przetestować z innym zestawem (rozmiarem), musimy zmodyfikować kod, nawet w pętli drukowanej, a dodatkowo dane wejściowe powinny być tylko zestawem, a nie jego rozmiarem. ”Biorąc pod uwagę listę ściśle dodatnich liczb całkowitych ... „więc myślę, że dane wejściowe powinny być tylko listą.
AZTECCO

@AZTECCO nie jest pewny, czy ta dyskusja powinna należeć do komentarzy w tej odpowiedzi, ale możesz rzucić okiem na meta - szczególnie na formatach We / Wy i odpowiedzi .
attinat

1

K (ngn / k) , 18 bajtów

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

Wypróbuj online!


STARE PODEJŚCIE

K (ngn / k) , 27 23 22 bajtów

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

Wypróbuj online!


to nie jest dość ... szybkie i nieprzyzwoite rozwiązanie, dopracuję to później, kiedy będę miał szansę wymyślić lepsze podejście

wyjaśnienie:

  • =xzwraca dyktando, w którym klucze są elementami x, a wartości są ich indeksami ( 3 1 4 5 9 2 6!(0 9;1 3;,2;4 8 10;5 11;,6;,7))
  • i: przypisać dyktować do i
  • #:'policzyć wartości dla każdego klucza ( 3 1 4 5 9 2 6!2 2 1 3 2 1 1)
  • !:'wyliczyć każdą wartość ( 3 1 4 5 9 2 6!(0 1;0 1;,0;0 1 2;0 1;,0;,0))
  • ,/.:wyodrębnij wartości i spłaszcz listę ( 0 1 0 1 0 0 1 2 0 1 0 0)
  • x[,/.:i]: wyodrębnij indeksy z i, spłaszcz i przypisz każdą wartość z listy po prawej stronie dla tych indeksów

denerwująco, lista jest aktualizowana, ale przypisanie zwraca wartość zerową, więc muszę zwrócić listę po średniku ( ;x)

edycja: usunięto obce okrężnice

edit2: usunięto niepotrzebne przypisanie


0

Retina 0.8.2 , 30 bajtów

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

Wypróbuj online! Link zawiera przypadki testowe. 1-indeksowany. Objaśnienie: Pierwsza część wyrażenia regularnego pasuje kolejno do każdej liczby całkowitej na liście. Grupa lookbehind dopasowuje każde wystąpienie tej liczby całkowitej w tej linii do bieżącej liczby całkowitej włącznie. Liczba całkowita jest następnie zastępowana liczbą dopasowań.


0

Partia, 61 bajtów

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

1-indeksowany. Ponieważ podstawianie zmiennych następuje przed analizą, set/apolecenie kończy inkrementację nazwy zmiennej podanej przez konkatenację litery cz liczbą całkowitą z listy (zmienne numeryczne domyślnie zero w pakiecie). Wynik jest następnie kopiowany do innej liczby całkowitej w celu ułatwienia wyjścia (dokładniej, oszczędza bajt).



0

Japt, 8 bajtów

£¯YÄ è¶X

Wypróbuj tutaj

£¯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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.