Последовательные 1-битные увеличиваются


36

Учитывая шаблон (формат строки или массива) битов: [0,1,1,1,0,1,1,0,0,0,1,1,1,1,1,1]

Задача состоит в том, чтобы заменить любое количество последовательных 1-битовых последовательностей по возрастанию, начиная с 1.

вход

  • Шаблон (может быть получен в виде строки или массива) Пример:
    • Строка: 1001011010110101001
    • Массив: [1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1]

Выход

  • Последовательность по возрастанию (может быть возвращена в виде строки или массива). Пример:
    • Строка: 1 0 0 1 0 1 2 0 1 0 1 2 0 1 0 1 0 0 1
    • Массив: [1, 0, 0, 1, 0, 1, 2, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 0, 1]

правила

  • (применяется только для строк) Ввод не будет содержать пробелы между 1и0
  • Предположим ввод length > 0
  • (применяется только для строк) Вывод разделяется пробелом (используйте любой другой разделитель, если вам нужно, если это не число или буква из алфавита)

Пример:

Given [0,1,1,1,0,1,1,0,0,0,1,1,1,1,1,1] 
Output [0,1,2,3,0,1,2,0,0,0,1,2,3,4,5,6]

--------------------------------------------------------------------------

Given 0110101111101011011111101011111111     
Output 0 1 2 0 1 0 1 2 3 4 5 0 1 0 1 2 0 1 2 3 4 5 6 0 1 0 1 2 3 4 5 6 7 8

---------------------------------------------------------------------------

Given 11111111111101    
Output 1 2 3 4 5 6 7 8 9 10 11 12 0 1

Критерии победы: Codegolf

Ответы:


19

05AB1E , 4 байта

γ€ƶ˜

Попробуйте онлайн! или как тестовый костюм

объяснение

γ      # split input into groups of consecutive equal elements
 €ƶ    # multiply each number in each sublist by its 1-based index in the sublist
   ˜   # flatten

1
Слава лучше, чем у меня. Я бы никогда не подумал об этом.
Волшебная Урна Осьминога

3
Я не на 100% знаком с правилами подсчета байтов codegolf (и поиск в Google нашел только этот пост, который не пришел к выводу). Хотя ваш ответ состоит из 4 символов, он не должен быть не менее 8 байтов (например, utf-16-be без спецификации 03 B3 20 AC 01 B6 02 DC) или 9 байтов (utf-8:) CE B3 E2 82 AC C6 B6 CB 9Cили 10 байтов (например, UTF-16, включая 2-байтовые спецификации) в любой не игрушечной кодировке? (Да, можно создать игрушечную 8-битную кодировку, аналогичную кодировке iso-8859, с этими 4 символами, представленными в виде 1-байта, но это похоже на обман.)
dr jimbob

6
@drjimbob Да, хороший вопрос. Код может быть преобразован в двоичный файл с использованием кодовой страницы 05AB1E . Например, γ€ƶ˜будет представлен как 04 80 8F 98. Кодовая страница в первую очередь существует для облегчения написания кода. Чтобы запустить этот 4-байтовый файл, вам нужно запустить интерпретатор с --osabieфлагом.
Аднан

18

Haskell , 15 байт

scanl1$(*).succ

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

Объяснение / Ungolfed

scanl1 выполняет итерацию слева над списком, используя функцию, которая получает последний результат, а текущий элемент генерирует новый список с результатами, оставляя пустые списки и одиночные элементы "неизмененными".

(*).succ является эквивалентом \x y-> (x+1)*y

Использование этой функции вместе с scanl1работает только потому, что увеличивающиеся последовательности ( 1,2,3, .. ) начинаются с 1 и не имеют предшествующего элемента (в этом случае это первый элемент в списке, который не будет «изменен») или у них ведущий 0 .



14

Шелуха , 5 4 3 байта

ṁ∫g

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

объяснение

ṁ∫g  -- full function, example input: [1,1,1,0,1]
  g  -- group: [[1,1],[0],[1]]
ṁ    -- map the following and concatenate result (example with [1,1,1])
 ∫   -- | cumulative sum: [1,2,3]
     -- : [1,2,3,0,1]

Редактировать историю

-1 байт, используя scanl1болееzipWith

-1 байт путем переноса Dennis «S решение



11

JavaScript (ES6), 22 байта

Принимает ввод в виде массива.

a=>a.map(s=n=>s=n*-~s)

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

К a=>a.map(n=>a=n*-~a)сожалению, более короткое (20 байт) не сработает [1]из-за приведения массивов синглтона к целому числу, которое они содержат.



8

Python 2 , 39 38 байт

-1 байт благодаря Эрику Аутгольферу

i=1
for x in input():i*=x;print i;i+=1

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


1
Я не думаю, что вам нужно ,.
Эрик Outgolfer

@EriktheOutgolfer так выглядит симпатичнее c:
Род

1
Извините, но иногда в жизни приходится приносить жертвы.
Эрик Outgolfer

9
Покойся с миром, ,ты больше не в коде, но ты навсегда останешься в моем сердце
Род


6

K (ок) , 11 8 байт

Решение:

{y*1+x}\

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

Объяснение:

Переберите список. Увеличить аккумулятор, умножить на текущий элемент (который сбрасывает аккумулятор, если элемент равен 0):

{y*1+x}\ / the solution
{     }\ / iterate (\) over lambda function
     x   / accumulator
   1+    / add 1
 y*      / multiply by current item

5

Желе , 4 байта

ŒgÄF

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

Как это работает

ŒgÄF  Main link. Argument: A (bit array)

Œg    Group adjacent, identical bits.
  Ä   Accumulate; take the cumulative sum of each chunk.
   F  Flatten.

С быстрым бегом группы Эрик предположил, что это будет три байта! (Если бы я понял, что он будет делать правильно)
Дилнан

@dylnan Проблема в том, что трудно так быстро определиться с поведением. :( Вот почему быстрый все еще в перерыве.
Эрик Outgolfer

Для основных возможных реализаций может быть несколько пиков
dylnan

5

R , 46 31 байт

function(a)sequence(rle(a)$l)*a

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

sequence, который «в основном существует в почтении к самой ранней истории R» , здесь очень удобен.

function(a)                       # function, taking a vector as argument
                    rle(a)$l      # take the lengths of the run-length encoding
           sequence(        )     # and generate the list [1:x for x in lengths]
                             *a   # multiply by a to maintain 0s, and return

5

RAD, 8 байт

(⊢×1+⊣)⍂

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

Как?

  • (⊢×1+⊣), если правый аргумент есть 0, вернуть 0, в противном случае увеличить левый аргумент
  • , LTR Scan ( (A f B) f Cвместо A f (B f C)), примените это через массив


4

Java 8, 55 48 байт

a->{int p=0,i=0;for(int v:a)a[i++]=v<1?p=0:++p;}

Изменяет массив ввода вместо того, чтобы возвращать новый для сохранения байтов.

-7 байт благодаря @TimSeguine .

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

Объяснение:

a->{             // Method with integer-array parameter and no return-type
  int p=0,       //  Previous integer, starting at 0
      i=0;       //  Index-integer, starting at 0
  for(int v:a)   //  Loop over the values of the input-array:
    a[i++]=v<1?  //   If the current value is 0:
          p=0    //    Reset the previous integer to 0
         :       //   Else:
          ++p;}  //    Increase `p` by 1 first with `++p`
                 //    and set the current item to this new value of `p`

1
Вы можете побрить его до 48:a->{int p=0,i=0;for(int b:a)a[i++]=b<1?p=0:++p;}
Тим Сегин

@TimSeguine Спасибо! Теперь, когда я вижу это, я не могу поверить, что сам не думал об этом.
Кевин Круйссен,

1
Я смог избавиться от р, но он того же размера :( a->{int i=0;for(int v:a)a[i]+=v*i++<1?0:a[i-2];}
Тим Сегин

4

TIS , 68 + 33 = 101 байт

Код (68 байт):

@0
MOV UP ACC
SUB 47
MOV ACC ANY
@1
ADD 1
JRO UP
SUB ACC
MOV ACC ANY

Макет (33 байта):

2 1 CC I0 ASCII - O0 NUMERIC - 32

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

Объяснение:

|    Input 0    |    Input is given in ASCII (`0` is 48, `1` is 49)
+--------+------+
| Node 0 |      |    This node prepares the input data
+--------+      |
| MOV UP ACC    |    Read in a character
| SUB 47        |    Subtract 47 to map [48, 49] to [1, 2]
| MOV ACC ANY   |    Send the 1 or 2 to the next node
|               |    Implicitly wrap back to top of node
+--------+------+
| Node 1 |      |    This node does the incrementing/printing
+--------+      |
| ADD 1         |    Increment counter (starts at zero)
| JRO UP        |    Get value from above, and jump forward that many lines  (skip next line or not)
| SUB ACC       |    Reset counter to zero (if input was zero)
| MOV ACC ANY   |    Send the counter value downward to be printed
|               |    Implicitly wrap back to top of node
+---------------+
|   Output 0    |    Output is space-delimited numeric values

4

Gaia , 5 байт

ẋ+⊣¦_

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

объяснение

ẋ+⊣¦_     Full program
ẋ         Split into chunks of equal adjacent values.
   ¦_     And for each chunk, flattening the result afterwards...
 +⊣       Reduce it cumulatively on + (addition); aka cumulative sums

Тьфу, я думал, что шрифты SE кода были моноширинными ....


Они монокосмические ... В первой строке отсутствует пробел.
micsthepick

Посмотри на правку. Это все еще смещено.
Мистер Кскодер

Вы, должно быть, смотрите с мобильного устройства или чего-то еще - мне это кажется прекрасно
micsthepick



4

Perl 6 , 29 24 18 байт

-6 байт благодаря Шону!

*.map:{($+=1)*=$_}

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

Внутренняя функция может ($+=1)*=* , но тогда анонимная переменная сохранялась бы при вызовах функций. Мы получаем это, оборачивая его в явный блок кода.

Объяснение:

*.map:               # Map the array to
      {($+=1)    }   # The anonymous variable incremented
             *=$_    # Multiplied by the element

Я получил тот же самый основной подход вниз до 16 байт: *.map(($+=1)*=*). Это решение имеет условие, что переменная состояния $сохраняется при вызовах функции, поэтому, если последний элемент, переданный одному вызову, и первый элемент, переданный следующему вызову, оба не равны нулю, то подсчет начнется с неправильного номера.
Шон

@Sean, да, я помню, как боролся с этим, когда я первоначально ответил. К счастью, с тех пор я научился обходить это
Джо Кинг

Вы можете постучать еще один байт прочь: *.map:{...}.
Шон


3

Haskell , 19 байтов

scanl1$((*)=<<).(+)

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

Объяснение: Код эквивалентен scanl1(\b a->(b+a)*a), где b- текущий бит и aаккумулятор. scanl1берет список, создает первый элемент списка в качестве накопителя, сворачивает список и собирает промежуточные значения в новый список.

Изменить: BMO избили меня на несколько секунд и 4 байта .


3

Pyth , 6 байт

m=Z*hZ

Попробуй это здесь!

Как это работает

m = Z * hZ - полная программа. Q = оцененный ввод.
m - для каждого целого числа d в ​​Q.
 = Z - присвоить переменной Z (предварительно инициализированной 0) значение ...
   * hZ - (Z + 1) * d; (d подразумевается в конце).

3

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

PowerShell Core , 86 байт

Filter F{($_-split"(0)(\B|\b)"|?{$_-ne''}|%{$_-replace'(1+)',(1..$_.Length)})-join' '}

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



3

QBasic, 60 байт

INPUT s$
FOR i=1TO LEN(s$)
b=MID$(s$,i)>="1
v=-b*v-b
?v
NEXT

Принимает ввод в виде строки; дает вывод в виде чисел, разделенных символами новой строки.

объяснение

Мы читаем строку s$и цикл iс 1точностью до ее длины.

MID$(s$,i)получает подстроку от символа i(1-индексированный) до конца строки. Если это начинается с 1, это будет лексикографически >=строка "1"; если это начинается с 0, это не будет. Так bполучается, 0если символ в индексе iесть 0, или -1если символ есть 1.

Далее мы обновляем текущее значение v. Если мы просто читаем 0, мы хотим vстать 0; в противном случае мы хотим увеличить vна единицу. Другими словами, v = (-b) * (v+1); упрощение математики дает более короткое выражение, видимое в коде. Наконец, мы печатаем vи зацикливаем.


3

Brain-Flak , 60 байт

([]){{}<>(())<>{{}<>({}({}))(<>)}{}([])}{}<>{({}[()]<>)<>}<>

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

Объяснение:

([]){  For each element in the input
    {}
    <>(())<>  Push a one to the other stack
    { If the element is one,
       {}<>({}({}))(<>)  Add the one to a copy of the previous number in the series
    }{}  Pop the element
([])}  End loop
{}<>   Pop extra zero
{({}[()]<>)<>}<>   And reverse the output stack, subtracting one from each element


3

C (gcc), 57 52 51 байт

f(a,l,c,i)int*a;{for(c=i=0;i<l;)a[i++]=c=a[i]*-~c;}

JavaScript-код Port of Arnauld изменяет массив на месте. Попробуйте это онлайн здесь .


Разве не было бы точнее сказать, что это K & R C?
Тим Сегин

Возможно, но это было бы верно для многих ответов. Я не эксперт, но вполне возможно, что это даже не относится к K & R C. Дело в том, что нам не очень важны языковые стандарты на этом сайте. Если gcc позволяет вам смешивать K & R C с более современными вещами, то это действительно C для игры в гольф, потому что gcc скомпилирует его. См. Также: codegolf.stackexchange.com/questions/2203/tips-for-golfing-in-c
OOBalance,

До настоящего момента я не осознавал, что C11 все еще поддерживает старый синтаксис функции списка идентификаторов, так что не берите в голову. Но твоя точка зрения остается верной.
Тим Сегин

1
Предложитьf(a,l,c)int*a;{for(c=0;l--;)c=*a++*=c+1;}

3

Шекспир, 365 байт

I.Ajax,.Ford,.Act I:.Scene I:.[enter Ajax and Ford]Ajax:Open mind!Scene V:.Ford:Am I nicer than the sum of a big red old cute hard cat a big red old cute joy?Ford:If so,you is the sum of thyself a son!Ford:If not,you is zero!Ford:Open heart!Ajax:you is a big red old cute hard cat.Ajax:Speak mind!Ajax:Open mind!Ford:Am I nicer than zero?Ajax:If so, let us Scene V.

попробуйте здесь

менее гольф-версия

I.Ajax,.Ford,.
Act I:.
Scene I:.
[enter Ajax and Ford]
Ajax:Open mind!
Scene V:.
Ford:Am I nicer than the sum of a big red old cute hard cat a big red old cute joy?     <- smallest way to 48 (ascii "0") I could think of
Ford:If so,you is the sum of thyself a son!
Ford:If not,you is zero!
Ford:Open heart!
Ajax:you is a big red old cute hard cat.    <- get value of 32 or space
Ajax:Speak mind!                            <- then output it
Ajax:Open mind!
Ford:Am I nicer than zero?
Ajax:If so, let us Scene V.                 <- loop through inputs

280 байт . Проверьте страницу подсказок SPL для подсказок игры в гольф.
Джо Кинг

3

C ++, 47 байт

[](int*a,int*b){for(int c=0;a!=b;)c=*a++*=1+c;}

Лямбда, которая изменяет массив на месте, учитывая указатели начала и конца.


Попробуйте онлайн! (требуется Javascript)


Общая версия в 55 байтов (это работает для любого контейнера с элементами арифметического типа):

[](auto a,auto b){for(auto c=*a-*a;a!=b;)c=*a++*=1+c;};
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.