Перечислите каждую серию одинаковых номеров на месте


27

Получив список строго положительных целых чисел, просмотрите каждое отдельное число и замените все его вхождения последовательными индексами (от нуля до единицы) новой серии.

Примеры

[][]/[]

[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
Так в основном, сколько раз это была последовательность пока?
Джо Кинг

1
@JoKing Да, это еще один способ заявить об этом, но «до сих пор» подразумевает нулевое основание, а «до и включая это» подразумевает единичное. Я хотел сохранить выбор.
Адам

Ответы:


23

JavaScript (ES6), 26 байт

1-индексироваться.

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

Попробуйте онлайн!

комментарии

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
Я понятия не имею, как это работает, но это выглядит элегантно.
Адам

Я не видел -~раньше - это абсолютная жемчужина.
DaveMongoose

В качестве альтернативы, можно использовать aдля хранения значений, но это необходимо для -/ ~индекса, чтобы ни один байт не был сохранен.
user202729


1
@DaveMongoose -~на самом деле является широко используемой альтернативой +1(поскольку она имеет разный приоритет) во многих языках
только ASCII

10

R , 27 байт

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

Попробуйте онлайн!

Пояснение:

ave(x,x,FUN=seq)разбивает вектор xна подвекторы, используя значения xключей группировки. Затем seqвызывается функция для каждой группы, и каждый результат возвращается в исходное положение группы.

Лучше посмотрите пример:

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

Заметка :

seq(y)Функция возвращает последовательность 1:length(y)в случае , если yимеет length(y) > 1, но возвращает последовательность из 1:y[1]если yсодержит только один элемент.
К счастью, это не проблема, потому что в этом случае R - жалуется с большим количеством предупреждений - выбирает только первое значение, которое, кстати, то, что мы хотим :)


2
Brilliant! Я добавлю награду за это. Никогда не видел aveраньше.
Джузеппе

Для меня большая честь, большое спасибо! :)
digEmAll

6

MATL , 4 байта

&=Rs

Это решение на основе 1

Попробуйте это в MATL Online !

объяснение

Используется [1,2,3,2]в качестве примера

    # 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
ах, я знал, что есть старая проблема, которая заставляет меня думать о чем-то похожем, это Unique is Cheap, а в решении MATL есть один другой персонаж!
Джузеппе

5

APL (Dyalog Unicode) , 7 байтов

Большое, большое спасибо H.PWiz, Adám и dzaima за их помощь в отладке и исправлении этого.

+/¨⊢=,\

Попробуйте онлайн!

объяснение

10-байтная неявная версия будет проще объяснить

{+/¨⍵=,\⍵}

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

Молчаливая версия делает три вещи

  • Во-первых, он удаляет экземпляр « используется в», так ,\⍵как ,\справа сам по себе может неявно выяснить, что он должен работать с правильным аргументом.
  • Во- вторых, для ⍵=, заменим с , которая выступает за правый аргумент
  • В-третьих, теперь, когда у нас нет явных аргументов (в данном случае ), мы можем удалить фигурные скобки, {}поскольку неявные функции их не используют

5

AWK , 14

  • 1 байт сохранен благодаря @NahuelFouilleul
{print++a[$1]}

Попробуйте онлайн!

Вышесказанное делает индексацию по одному. Если вы предпочитаете индексирование с нуля, это дополнительный байт:

{print a[$1]++}

Попробуйте онлайн!


1
обратите внимание, что второй может сохранить один байт {print++a[$1]}без пробела, кажется, работает
Науэль Фуйе

@NahuelFouilleul Спасибо!
Цифровая травма

5

J 7 байт

1#.]=]\

Попробуйте онлайн!

1-индексироваться.

Объяснение:

]\ 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 (ок) , 11 10 байт

-1 байт благодаря ngn!

{+/'x=,\x}

Попробуйте онлайн!


1
Хех, ты счастлив, что я сделал данные строго положительными ...
Адам

@ Adám Да, иначе мне нужно было бы поставить префиксы в коробку :)
Гален Иванов

1
в к: ='->=
нгн



3


У вас есть обратный вызов прямо сейчас .. [7,7,7]должен выводить [0,1,2], а не [0,0,0].
Кевин Круйссен

1
@KevinCruijssen - Спасибо :) Похоже, я неправильно прочитал, это нужно исправить.
Дана



2

R , 41 байт

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

Попробуйте онлайн!

Как ни странно, возвращение нулевого индекса короче в R.


Джузеппе, твои превосходные знания о R побили меня. У меня был прилично гениальный метод на 60 байтов, но, увы, этого было недостаточно!
Sumner18

@ Sumner18 опубликовать это в любом случае! Я всегда многому учусь у других людей, и получение обратной связи - самый быстрый способ учиться!
Джузеппе

спасибо за поддержку! Я разместил свой сейчас и всегда открыт для предложений по улучшению!
Sumner18

2

Рубин, 35 байт

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

К сожалению, это довольно обыденно - создайте хеш, в котором хранится сумма для каждой найденной записи.

Некоторые другие забавные варианты, которые, к сожалению, не были достаточно короткими:

->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 байта

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

-19 байт благодаря Giuseppe, удалив который и таблицу, и лишь незначительные изменения в реализации

оригинал

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

Я не могу соревноваться со знаниями Джузеппе, поэтому мое представление несколько длиннее его, но, используя свои базовые знания, я почувствовал, что это решение было довольно гениальным.

r<-table(x) подсчитывает количество раз, которое появляется каждое число, и сохраняет его в r для дальнейшего использования

names() получает значения каждой уникальной записи в таблице, и мы перебираем эти имена с помощью цикла for.

Оставшаяся часть проверяет, какие записи равны итерациям, и сохраняет последовательность значений (от 1 до количества записей итерации).

Попробуйте онлайн!


Вы можете удалить, which()чтобы сохранить 7 байтов.
Джузеппе

Ваше использование 1:r[i]дало мне идею просто удалить table()полностью: x=z=scan();for(i in x)z[y]=1:sum(y<-x==i);zэто 43 байта! Это хороший подход!
Джузеппе

Похоже, что ни один из нас не может конкурировать со знанием digEmAll's R !
Джузеппе

Я видел это и был совершенно ошеломлен!
Sumner18

2

Haskell , 44 байта

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

Попробуйте онлайн!

объяснение

Обходит список слева направо, сохраняя список xпосещенных элементов, первоначально []:

Для каждой встречи yподсчитайте все равные элементы в списке x.


1
Немного дольше, но, тем не менее, интересно: (#(0*));(x:r)#g=g x:r# \y->0^abs(y-x)+g y;e#g=e попробуйте онлайн!
Лайкони

@Laikoni: Как ты вообще это придумал, ты должен полностью опубликовать это!
მოიმო



2

Haskell , 47 46 байтов

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

Попробуйте онлайн!

Другой подход, чем ответ BMO, который оказался немного длиннее. (И любезно позаимствует их хороший тестовый костюм.)

Идея состоит в том, чтобы перебрать список ввода и отследить, сколько раз каждый элемент встречался, обновляя функцию 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 []    = []

Возникли две интересные возможности для игры в гольф. Сначала для начального значения gпостоянной функции, которая игнорирует ее аргумент и возвращает 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

И, во-вторых, выражение над переменными xи yкоторое дает, 1если xравно yи в 0противном случае:

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!

Там все еще могут быть более короткие пути. У кого-нибудь есть идея?


1
Вы можете использовать 0^(x-y)^2.
Кристиан Сиверс



1

bash, 37 24 байта

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

TIO

если он действителен, то есть также этот вариант, как предлагает DigitalTrauma

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

TIO


1
Передайте список как аргументы командной строки - tio.run/##S0oszvj/Py2/SKHCuporNTkjX0ElOjG6IlZbO5ar9v///8b/… - всего 24 байта.
Цифровая травма

@DigitalTrauma, спасибо, однако я не знаю, нарушил ли он правила. также, как это было предложено заменить список и, возможно, должно быть что-то вроде tio.run/…
Науэль Фуйе

2
@NahuelFouilleul Ничего страшного, полные программы тоже разрешены, и это допустимый метод ввода / вывода списка (IMO)
только ASCII

1

Perl 5, 11 байт

$_=$h{$_}++

TIO

объяснения после комментария

  • $_специальная переменная perl, содержащая текущую строку при циклическом вводе ( -pили -nпереключателях)
  • $h{$_}++автоматически оживляет карту %hи создает запись с ключом $_и приращениями и дает значение перед приращением
  • специальная переменная выводится из-за -pпереключателя, -lпереключатель удаляет конец строки на входе и добавляет конец строки на выходе

Это выглядит потрясающе. Хотите объяснить?
Адам

@ Adám, спасибо за ваш отзыв, конечно, сделано
Науэль Фуйе



1

Атташе , 23 байта

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

Попробуйте онлайн!

объяснение

{`~&>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 байта

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

Попробуйте онлайн!

-2 байта благодаря ASCII-только


Это казалось слишком простым, но я не мог стать короче с другим подходом.



@ Только для ASCII это правильный ответ? Заголовок не включен, нет объявлений, это фрагмент кода и множество предупреждений, хотя он выводит.
AZTECCO

Предупреждения @AZTECCO в порядке (stderr игнорируется), если он делает то, что должен, это приемлемо. обратите внимание , что это является объявлением функции, а также некоторые объявления переменных - вы можете поместить его в любом месте , как выражение верхнего уровня , и он будет компилировать штраф. много из с ответами (и те , в языках с менее строгим синтаксисом) делать , как правило, довольно много предупреждений из - за bytesaves, не хороший код стиль
ASCII-только

Хорошо, я могу понять, но есть что-то не так для меня. Если мы хотим протестировать с другим набором (по размеру), мы должны изменить код, даже в цикле печати, плюс ввод должен быть только набором, а не его размером. "Учитывая список строго положительных целых чисел ... «поэтому я думаю, что вклад должен быть только список.
AZTECCO

@AZTECCO не уверен, должно ли это обсуждение быть в комментариях к этому ответу, но вы, возможно, захотите взглянуть на мета - особенно на форматы ввода / вывода и форматы ответов .
attinat

1

К (нгн / к) , 18 байт

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

Попробуйте онлайн!


СТАРЫЙ ПОДХОД

K (нгн / к) , 27 23 22 байта

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

Попробуйте онлайн!


это не красиво ... быстрое и грязное решение, я уточню это позже, когда у меня будет возможность придумать лучший подход

объяснение:

  • =xвозвращает условие, где ключи - это элементы x, а значения - их индексы ( 3 1 4 5 9 2 6!(0 9;1 3;,2;4 8 10;5 11;,6;,7))
  • i: назначить дикт i
  • #:'подсчитать значения для каждого ключа ( 3 1 4 5 9 2 6!2 2 1 3 2 1 1)
  • !:'перечислить каждое значение ( 3 1 4 5 9 2 6!(0 1;0 1;,0;0 1 2;0 1;,0;,0))
  • ,/.:извлечь значения и сгладить список ( 0 1 0 1 0 0 1 2 0 1 0 0)
  • x[,/.:i]: извлекать индексы из i, выравнивать и назначать каждое значение из правого списка по этим индексам

досадно, список обновляется, но присваивание возвращает нулевое значение, поэтому мне нужно вернуть список после точки с запятой ( ;x)

редактировать: удалены посторонние двоеточия

edit2: удалено ненужное назначение


0

Сетчатка 0.8.2 , 30 байт

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

Попробуйте онлайн! Ссылка включает в себя тестовые случаи. 1-индексироваться. Объяснение: Первая часть регулярного выражения соответствует каждому целому числу в списке по очереди. Группа lookbehind соответствует каждому вхождению этого целого числа в этой строке вплоть до текущего целого числа. Затем целое число заменяется количеством совпадений.


0

Пакет, 61 байт

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

1-индексироваться. Поскольку подстановка переменной происходит перед синтаксическим анализом, set/aкоманда в итоге увеличивает имя переменной, заданное путем объединения буквы cс целым числом из списка (числовые переменные по умолчанию равны нулю в пакетном режиме). Затем результат копируется в другое целое число для простоты вывода (точнее, он сохраняет байт).



Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.