Разложить двоичный файл на чередующиеся подпоследовательности


30

Это был вдохновлен задачи 13 - неповторяющихся Binary о недавнем конкурсе НР CodeWars.

Давайте возьмем случайное десятичное число, скажем

727429805944311

и посмотрите на его двоичное представление:

10100101011001011111110011001011101010110111110111

Теперь разбейте это двоичное представление на подпоследовательности, где цифры 0и 1чередуются.

1010 010101 10 0101 1 1 1 1 1 10 01 10 0101 1 1010101 101 1 1 1 101 1 1

И преобразовать каждую подпоследовательность обратно в десятичную.

10 21 2 5 1 1 1 1 1 2 1 2 5 1 85 5 1 1 1 5 1 1

Задание

Возьмите одно положительное целое число в качестве входных данных и выведите последовательность положительных целых чисел, полученных в результате вышеуказанного процесса.

Детали

  • Вход и выход должны быть десятичными или одинарными.
  • Числа в выходных данных должны быть разделены разумным, понятным для человека способом, и они должны быть в десятичной или одинарной форме. Нет ограничений на пустое пространство. Допустимые стили вывода: [1,2,3], 1 2 3, 1\n2\n3где \nесть буквальные переводы строки и т.д.

Контрольные примеры

 Input | Output
     0 | 0
     1 | 1
     2 | 2
     3 | 1 1
     4 | 2 0
     5 | 5
     6 | 1 2
     7 | 1 1 1
     8 | 2 0 0
     9 | 2 1
    10 | 10
    50 | 1 2 2
   100 | 1 2 2 0
  1000 | 1 1 1 1 10 0 0
 10000 | 2 1 1 2 0 2 0 0 0
 12914 | 1 2 2 1 1 2 2
371017 | 5 42 10 2 1

Дополнительное примечание: все числа в выходных данных должны иметь форму (2^k-1)/3или 2*(2^k-1)/3. То есть, 0 1 2 5 10 21, 42, 85, 170, ...это A000975 в OEIS.


@DigitalTrauma: Хммм ... нет, я не думаю, что это в духе задачи.
El'endia Starman

Хорошо. |tacтогда останется в моем ответе :)
Digital Trauma

Ответы:


11

Pyth, 17 16 байт

1 байт благодаря Якубе

iR2cJ.BQx1qVJ+dJ

демонстрация

Хорошее, умное решение. Использует некоторые менее известные особенности Pyth, такие как x<int><list>и c<str><list>.

iR2cJ.BQx1qVJ+dJ
                    Q = eval(input())
    J.BQ            Store in J the input in binary.
          qV        Vectorize equality function over
            J+dJ    J and J with a leading dummy char, to get the offset right.
                    This calculates whether each element matches its successor.
        x1          Find all of the indexes of 1 (True) in this list.
   cJ                Chop J at those locations.
iR2                  Convert from binary back to base ten and output.

1
Если вы замените tJ, +dJвы можете удалить hM.
Якуб

@Jakube Хороший!
Исаак

7

Mathematica, 47 байт

#+##&~Fold~#&/@#~IntegerDigits~2~Split~Unequal&

Ungolfed:

FromDigits[#,2]&/@Split[IntegerDigits[#,2],Unequal]&

Split[list,f]разбивает список на несколько списков, разбивая на позиции между aи bесли f[a,b]не возвращает True.

FromDigits[n,2] => Fold[#+##&,n]это аккуратный наконечник от алефальфа.


7

Python, 86 байт

Так как я получил ужасное превосходство в Pyth, давайте просто сделаем это снова в Python.

import re
lambda n:[int(s,2)for s in re.sub("(?<=(.))(?=\\1)"," ",bin(n)[2:]).split()]

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

объяснение

Мы начнем с преобразования входного числа nв двоичную строку. bin(n)[2:]заботится об этом. Нам нужно отбросить первые 2 символа этой строки, так как bin()возвращает строку в формате 0b10101.
Далее нам нужно определить границы подпоследовательностей. Это можно сделать с помощью регулярного выражения, (?<=(.))(?=\1)которое соответствует позициям нулевой длины в строке, имеющим одинаковое число слева и справа.
Очевидным способом получения списка всех подпоследовательностей было бы использование метода, re.split()который разбивает строку на определенное регулярное выражение. К сожалению, эта функция не работает для совпадений нулевой длины. Но, к счастью, re.sub()это так, поэтому мы просто заменяем эти совпадения нулевой длины пробелами и разделяем строку на них после этого.
Затем мы просто должны разобрать каждую из этих подпоследовательностей обратно в десятичное число с помощью int(s,2)и все готово.


4

Желе, 12 байт

BI¬-ẋż@BFṣ-Ḅ

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

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

BI¬-ẋż@BFṣ-Ḅ  Main link. Argument: n

B             Convert n to base 2.
 I            Compute the increments, i.e., the differences of consecutive digits.
  ¬           Apply logical NOT.
   -ẋ         Repeat -1 that many times, for the logical NOT of each difference.
              [0, 0] / [1, 1] ->   0    -> 1 -> [-1]
              [0, 1] / [1, 0] -> 1 / -1 -> 0 -> []
       B      Yield n in base 2.
     ż@       Zip the result to the right with the result to the left.
        F     Flatten the resulting list of pairs.
         ṣ-   Split at occurrences of -1.
           Ḅ  Convert each chunk from base 2 to integer.

Конечно, 12 символов, но 20 байтов. Или вы используете систему с CHAR_BIT >> 8?
Джеймс Янгман

1
@JamesYoungman Jelly по умолчанию не использует UTF-8. Фактически, он имеет свою собственную кодовую страницу, которая кодирует каждый из 256 символов, которые он понимает как один байт каждый.
Денис

4

Утилиты Bash + GNU, 51

dc -e2o?p|sed -r ':;s/(.)\1/\1 \1/;t'|dc -e2i?f|tac

Ввод взят из STDIN.

  • dc -e2o?p читает входное целое число из STDIN и выводит строку base 2
  • sed -r ':;s/(.)\1/\1 \1/;t' разбивает строку base 2 с пробелом везде, где есть одинаковые цифры
  • dc -e2i?fчитает разделенный двоичный файл за один раз, помещая каждую часть в стек, а затем fвыгружает весь dcстек (выходные числа в обратном порядке) ...
  • ... который исправлен tac.

4

JavaScript (ES6) 58 62 63

Редактировать 1 байт, сохраненный thx @ETHproductions

Редактирование 4 байт сохраненного ТНХ @Neil

x=>x.toString(2).replace(/((.)(?!\2))*./g,x=>'0b'+x-0+' ')

f=x=>x.toString(2).replace(/((.)(?!\2))*./g,x=>'0b'+x-0+' ')

 
console.log=x=>O.textContent+=x+'\n'

;[
[     0,'0'],
[     1,'1'],
[     2,'2'],
[     3,'1 1'],
[     4,'2 0'],
[     5,'5'],
[     6,'1 2'],
[     7,'1 1 1'],
[     8,'2 0 0'],
[     9,'2 1'],
[    10,'10'],
[    50,'1 2 2'],
[   100,'1 2 2 0'],
[  1000,'1 1 1 1 10 0 0'],
[ 10000,'2 1 1 2 0 2 0 0 0'],
[ 12914,'1 2 2 1 1 2 2'],
[371017,'5 42 10 2 1']
].forEach(t=>{
  var i=t[0],k=t[1],r=f(i)
  console.log(i+' -> '+r+(r.trim()==k.trim() ? ' ok':'ko (should be '+k+')'))
})
<pre id=O></pre>


Не могли бы вы сохранить два байта с регулярным выражением /(01)*0?|(10)*1?/g, или это что-то испортит ??
ETHproductions

1
Кроме того, я думаю, что вы могли бы сделать, x=>'0b'+x-0+' 'чтобы сохранить байт.
ETHproductions

@ETHproductions Я попробовал более короткое регулярное выражение, ничего хорошего :(. Спасибо за другой намек
edc65

Leadboard говорит, что у вас есть 1-байтовый ответ. Я предполагаю, что это потому, что у вас есть исправленное число (62) до старого номера (63), а не после.
Кайл Канос

Я думаю, что регулярное выражение /((.)(?!\2))*./gэкономит вам крутые 4 байта.
Нил

3

Pyth, 26 байт

iR2c:.BQ"(?<=(.))(?=\\1)"d

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

объяснение

iR2c: .BQ "(? <= (.)) (? = \\ 1)" d # Q = номер входа

     .BQ # Конвертировать ввод в двоичный
    : "(? <= (.)) (? = \\ 1)" d # вставить пробел между подпоследовательностями
   c # разбить строку на пробелах
iR2 # конвертировать каждую подпоследовательность в десятичную

Поскольку функция Python split () не разбивает совпадения нулевой длины, я должен заменить эти совпадения пробелом и разделить результат на этом.


3

Pyth, 22 21 байт

&Qu?q%G2H&
GH+yGHjQ2Z

Попробуйте онлайн: демонстрация

Действительно утомительное задание в Pyth.

Объяснение:

&Qu?q%G2H&\nGH+yGHjQ2Z   implicit: Q = input number
                  jQ2    convert Q to base 2
  u               jQ2Z   reduce ^: for each digit H update the variable G=0:
   ?q%G2H                   if G%2 == H:
          \nG                  print G
         &   H                 then update G with H
              +yGH           else: update G with 2*G+H
  u                      print the last G also
&Q                       handle Q=0 special: only print 0 once

3

05AB1E , 18 байт

Код:

b2FNð«N«Dð-s:}ð¡)C

Объяснение:

b                   # Convert input to binary
 2F          }      # Do the following twice ( with N as range variable)
   Nð«N«            #    N + space + N
        D           #    Duplicate this
         ð-         #    Delete spaces from the duplicate string
           s        #    Swap the top two elements
            :       #    Replace the first string with the second
              ð¡    # Split on spaces
                )   # Wrap into an array
                 C  # Convert all element back to decimal

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

Использует кодировку CP-1252 .


3

MATL , 18 17 байт

YBTyd~Thhfd1wY{ZB

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

YB      % input number. Convert to binary string
T       % push true value
y       % duplicate binary string and push it at the top of the stack
d~      % true for each value that equals the previous one
T       % push true value
hh      % concatenate: true, indices, true
f       % find indices of true values
d       % consecutive differences: lenghts of alternating sequences
1wY{    % split binary string according to those lengths
ZB      % convert each substring into decimal number

3

зш, 67 63 55 байт

for i in `grep -oP '1?(01)*0?'<<<$[[##2]$1]`;<<<$[2#$i]

Я не знаю почему, но это не работает в Bash.

Спасибо Денису за 8 байтов!


Это forсинтаксис. ... Подожди, нет forс?
CalculatorFeline

Арифметическое расширение Bash не позволяет вам указать выходную базу. Чтобы избавиться от xargs, вы можете использовать for i in `grep -oP '1?(01)*0?'<<<$[[##2]$1]`;<<<$[2#$i].
Деннис

2

PHP, 171 168 162 160 158 121 120 131 124 118 116 113 112 байт

function d($i){for(;$d<$l=strlen($b=decbin($i));){$c.=$u=$b[$d];echo$u==$b[++$d]||$d==$l?bindec($c).$c=" ":"";}}
В разобранном виде
function d($i) {
  for ( ; $d < $l = strlen($b = decbin($i)); ) {
    $c .= $u = $b[$d];
    echo $u == $b[++$d] || $d == $l ? bindec($c) . $c = " "
                                    : "";
  }
}

Используйте, d(int)и вы выключены, вывод - echoстрока ed, intразделенная пробелом.

Редактирует:
-3: перенес $bопределение в strlen()вызов.
-6: Удалено $cсоздание экземпляров.
-2: наконец исправлена ​​проблема конкатенации.
-2: без скобок для одной строки for().
-37: капитальный ремонт. Идти с Arraychunklets вместо повторных вызовов Array-> String-> Array.
-1: хитрый $cсброс.
+11: Исправление. Отсутствовал последний кусок. Больше не надо.
-7: Не нужно создавать экземпляры $dвообще? Ницца.
-6: return -> echo.
-2: хруст $c.
-3:Тернар, моя первая любовь.
-1: подлый подлый $u.


Я думаю , что вы можете сохранить 2 байта: function d($i){for(;$d<$l=strlen($b=decbin($i));print$u==$b[++$d]||$d==$l?bindec($c).$c=" ":"")$c.=$u=$b[$d];}.
Blackhole

2

Выпуклый 0.2+, 25 байт

Convex - это новый язык, который я разрабатываю и который основан на CJam и Golfscript. Интерпретатор и IDE можно найти здесь . Ввод - это целое число в аргументах командной строки. Это использует кодировку CP-1252 .

2bs®(?<=(.))(?=\\1)"ö2fbp

Объяснение:

2bs                         Convert to binary string
   ®(?<=(.))(?=\\1)"        Regex literal
                    ö       Split string on regex
                     2fb    Convert each split string into decimal integer
                        p   Print resulting array

2

Java 8, 127 119 байт

l->new java.util.ArrayList<Long>(){{for(String s:l.toBinaryString(l).split("(?<=(.))(?=\\1)"))add(l.parseLong(s,2));}};

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

-8 байт благодаря @FryAmTheEggman


2

APL (APL) , 21 25 байтов

Теперь обрабатывает и 0.

{0::0⋄2⊥¨⍵⊂⍨1,2=/⍵}2⊥⍣¯1⊢

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

2⊥⍣¯1⊢ преобразовать в base-2, используя столько битов, сколько необходимо (буквенное обратное преобразование из base-2)

{} Применить следующую анонимную функцию

0:: если произойдет какая-либо ошибка:

  0 вернуть 0

 Теперь попробуйте:

  2=/⍵ попарное равенство аргумента (потерпит неудачу в двоичном представлении длины 0)

  1, подготовить 1

  ⍵⊂⍨ использовать это для разделения аргумента (начинается новый раздел на каждом 1)

  2⊥¨ конвертировать каждый из базы-2


1
здесь действительно полезно. Я должен добавить это к Желе.
Деннис

@Dennis Помните о двух версиях R←X⊂Y: С ⎕ML<3(т. Е. В стиле Dyalog) новый раздел запускается в результате, соответствующем каждому 1 в X, до позиции до того, как следующий 1 в X (или последний элемент X) станет последовательные элементы R. С ⎕ML=3(т. е. стиль IBM) новый результат запускается в результате всякий раз, когда соответствующий элемент в X больше, чем предыдущий. Элементы в Y, соответствующие 0 в X, не включаются в результат. Так что ⎕ML←1 ⋄ 1 0 0 1 0 1 1 ⊂ ⍳7это эквивалентно ⎕ML←33 4 3 2 4 4 5 7 ⊂ ⍳7`
Адам


1

Python 3, 115 байт

def f(s):
 s=bin(s);r=[s[2]]
 for i in s[3:]:
  if i==r[-1][-1]:r+=[i]
  else:r[-1]+=i
 return[int(x,2)for x in r]

объяснение

def f(s):
 s=bin(s)                   # convert input in binary
 r=[s[2]]                   # initialize the result with the first char after the 'b' in binary string
 for i in s[3:]:            # loop on other element
  if i==r[-1][-1]:          # if the last element of the last string equal the current element 
   r+=[i]                   # we add the current element in a new string
  else:
   r[-1]+=i                 # we add the current element to the last sting
 return[int(x,2)for x in r] # convert binary string in integer 

Полученные результаты

>>> [print(i,f(i)) for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 50, 100, 1000, 10000, 12914, 371017]]
0 [0]
1 [1]
2 [2]
3 [1, 1]
4 [2, 0]
5 [5]
6 [1, 2]
7 [1, 1, 1]
8 [2, 0, 0]
9 [2, 1]
10 [10]
50 [1, 2, 2]
100 [1, 2, 2, 0]
1000 [1, 1, 1, 1, 10, 0, 0]
10000 [2, 1, 1, 2, 0, 2, 0, 0, 0]
12914 [1, 2, 2, 1, 1, 2, 2]
371017 [5, 42, 10, 2, 1]

предыдущее решение (118 байт)

def f(s):
 s=bin(s);r=s[2]
 for i in s[3:]:
  if i==r[-1]:r+='a'+i
  else:r+=i
 return[int(x,2)for x in r.split('a')]

1

Haskell, 147 , 145 байтов

x%[]=[x]
x%(y:z)|or.(zipWith(==)<*>tail)$y:x=x:[]%(y:z)|1<2=(y:x)%z
b x|x<2=[x]|1<2=b(div x 2)++[mod x 2]
map(sum.zipWith((*).(2^))[0..]).([]%).b

map(sum.zipWith((*).(2^))[0..]).([]%).b это безымянная функция, которая вычисляет список.

Менее гольф:

alternating :: Eq a => [a] -> Bool
alternating = or . (zipWith (==) <*> tail)

-- (%) is the partitioning function
(%) :: Eq a => [a] -> [a] -> [[a]]
x % [] = [x]

x % (y:z) | alternating (y : x) = x : [] % (y:z)
          | otherwise = (y : x) % z

bits :: Integral t => t -> [t]
bits x | x < 2     = [x] 
       | otherwise = bits (div x 2) ++ [mod x 2]

unBits :: Num c => [c] -> c
unBits = sum . zipWith ((*) . (2^)) [0..]

f :: Integer -> [Integer]
f = map unBits . ([]%) . bits

1

Perl, 53 байта

Включает +1 для -p

Запустить с номером на STDIN

perl -p alterbits.pl <<< 371017

alterbits.pl:

$_=sprintf"0b%b",$_;s/(.)\K(?=\1)/ 0b/g;s/\S+/$&/eeg

1

PowerShell, 103 байта

[regex]::Matches([convert]::ToString($args[0],2),"(01)+0?|(10)+1?|.").Value|%{[convert]::toint32($_,2)}

Поскольку я ужасен в регулярных выражениях, я использую то же выражение, что и в ответе edc65 .

Абсолютно уничтожены длительными вызовами .NET для преобразования в / из двоичного файла и вызовом .NET для получения совпадений регулярных выражений. В остальном довольно просто. Принимает входные данные $args[0], converts это в двоичном формате, Matchesпередает их, принимает результирующие .Values, направляет их через цикл |%{...}и convertвозвращает эти значения обратно int. Вывод остается в конвейере и неявно печатается с новыми строками.


Для дополнительного кредита - (в основном) версия без регулярных выражений в 126 байтах

$l,$r=[char[]][convert]::ToString($args[0],2);$l+-join($r|%{(" $_",$_)[$l-bxor$_];$l=$_})-split' '|%{[convert]::toint32($_,2)}

Мы снова берем входные данные, $args[0]и convertэто в двоичном виде. Мы повторно приводим как массив символов, сохраняя первый символ в, $lа остальные символы в $r. Затем мы отправляем $rчерез цикл, в |%{...}котором каждую итерацию мы выбираем из символа с добавлением пробела или только из символа, в зависимости от результата двоичного xor с $l, и затем устанавливаем $lравным символу. Это эффективно гарантирует, что если у нас будет один и тот же символ дважды в строке, мы добавим пробел между ними.

Выходные данные цикла -joinредактируются вместе и добавляются к первому символу $l, а затем -splitк пробелам (что технически является регулярным выражением, но я не собираюсь его считать). Затем мы делаем тот же цикл, что и регулярное выражение для ответа, convertи выводим целые числа.


1

Java 345 байт

package com.ji.golf;
import java.util.regex.*;
public class Decompose {
  public static String decompose(long l) {
    String o="";
    String s=Long.toBinaryString(l);
    Matcher m=Pattern.compile("(01)+(0)?|(10)+(1)?|(1)|(0)").matcher(s);
    while(m.find()){String c=s.substring(m.start(),m.end());o+=Integer.parseInt(c, 2)+" ";}
    return o;
  }
}

Тест

package com.ji.golf;
public class DecompseTest {
  public static void main(String[] args) {
    String[] inOut = new String[]{
        "0,0",
        "1,1",
        "2,2",
        "3,1 1",
        "4,2 0",
        "5,5",
        "6,1 2",
        "7,1 1 1",
        "8,2 0 0",
        "9,2 1",
        "10,10",
        "50,1 2 2",
        "100,1 2 2 0",
        "1000,1 1 1 1 10 0 0",
        "10000,2 1 1 2 0 2 0 0 0",
        "12914,1 2 2 1 1 2 2",
        "371017,5 42 10 2 1"
    };
    for (String s : inOut) {
      String[] io = s.split(",");
      String result = Decompose.decompose(Long.parseLong(io[0]));
      System.out.println("in: " + io[0] + ", reusult: [" +  result.trim() + "], validates? " + result.trim().equals(io[1].trim()));
    }
  }
}

Выход

in: 0, reusult: [0], validates? true
in: 1, reusult: [1], validates? true
in: 2, reusult: [2], validates? true
in: 3, reusult: [1 1], validates? true
in: 4, reusult: [2 0], validates? true
in: 5, reusult: [5], validates? true
in: 6, reusult: [1 2], validates? true
in: 7, reusult: [1 1 1], validates? true
in: 8, reusult: [2 0 0], validates? true
in: 9, reusult: [2 1], validates? true
in: 10, reusult: [10], validates? true
in: 50, reusult: [1 2 2], validates? true
in: 100, reusult: [1 2 2 0], validates? true
in: 1000, reusult: [1 1 1 1 10 0 0], validates? true
in: 10000, reusult: [2 1 1 2 0 2 0 0 0], validates? true
in: 12914, reusult: [1 2 2 1 1 2 2], validates? true
in: 371017, reusult: [5 42 10 2 1], validates? true

4
Добро пожаловать в Программирование Пазлов и Код Гольф! Так как это соревнование по коду в гольф , вы должны сделать свой код как можно короче. Вот несколько советов для игры в гольф на Яве. Вы можете начать с определения вашей функции без шаблонного packageи class, и удаления ненужных пробелов. Дайте знать, если у вас появятся вопросы!
Алекс А.

1

Юлия, 70 57 байт

n->map(i->parse(Int,i,2),split(bin(n),r"(?<=(.))(?=\1)"))

Это анонимная функция, которая принимает целое число и возвращает массив целых чисел. Чтобы вызвать его, назначьте его переменной.

Подход здесь похож на хороший ответ DenkerAffe на Python . Мы получаем двоичное представление nиспользования bin(n)и разбиваем результирующую строку на все совпадения регулярного выражения (?<=(.))(?=\1). Это на самом деле совпадение нулевой длины; (?<=(.))является положительным взглядом сзади, который находит любой отдельный символ, и (?=\1)является положительным взглядом вперед, который находит совпавший символ во взгляде сзади. Это находит места, где число следует за собой в двоичном представлении. Просто parseкаждый как целое число в базе 2, используя mapи вуаля!


1

C 137 129 байт

main(){unsigned long a,b=scanf("%lu",&a),c=!!a;while(a>=b*2)b*=2;while(b)b/=2,c=c*(~(a^a/2)&b|!b?!printf("%lu\n",c):2)+!!(a&b);}

Ввод и вывод ведутся по стандартным потокам.


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

@FryAmTheEggman Я бы предпочел не создавать неполную последнюю строку. Но за стоимость одного байта (все еще чистое сокращение) я могу изменить разделитель от пробела до новой строки.
Fox

1

J , 16 байт

#:#.;.1~1,2=/\#:

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

объяснение

#:#.;.1~1,2=/\#:  Input: integer n
              #:  Convert from decimal to list of binary digits
          2  \    For each overlapping sublist of size 2
           =/       Reduce using equals
        1,        Prepend 1
#:                Binary digits
    ;.1~          Partition those binary digits at the 1s in the previous list
  #.                Convert each partition from a list of binary digits to decimal

1

q / kdb +, 52 байта

Решение:

{2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}

Примеры:

q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}0
,0
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}1
,1
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}3
1 1
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}8
2 0 0
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}10000
2 1 1 2 0 2 0 0 0
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}12914
1 2 2 1 1 2 2
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}371017
5 42 10 2 1
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}727429805944311
10 21 2 5 1 1 1 1 1 2 1 2 5 1 85 5 1 1 1 5 1 1

Объяснение:

q интерпретируется справа налево.

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

{2 sv'cut[0,where not differ a]a:(63^first where a)_a:0b vs x} / ungolfed solution
{                                                            } / lambda function
      cut[                    ]                                / cut a list at indices, cut[indices]list
                                                      0b vs x  / converts to 64bit binary representation
                                                    a:         / save as a
                                                   _           / drop 'n' elements from a
                                 (                )            / evaluate this
                                     first where a             / returns first occurance of true in list a
                                  63^                          / fill result with 63 if null (to handle input of 0)
                               a:                              / save as a, we've stripped off all the left-most 0s
                      differ a                                 / whether or not item in list a is different to previous
                  not                                          / the inversion of this result
            where                                              / these are the points where we have 00 or 11
          0,                                                   / add the first index too!
  2 sv'                                                        / 2 sv converts binary back to base-10, ' for each list

0

PHP, 147

$b=decbin($argv[1]);$a=[$t=$b[0]];$k=0;for($i=1;$i<strlen($b);$i++){$v=$b[$i];if($v==$t)$k++;$t=$v;$a[$k].=$v;}foreach($a as$c)echo bindec($c).' ';

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

Неуправляемая версия

$n=$argv[1];
$b=decbin($n);
$l=strlen($b);
$t=$b[0];
$a=[0=>$t];$k=0;
for($i=1;$i<$l;$i++){
    $v=$b[$i];
    if($v==$t){
        $k++;
    }
    $t=$v;$a[$k].=$v;    
}
foreach($a as $c){
    echo bindec($c).' ';
}

0

Сетчатка, 60

+`(1+)\1
$1a
a1
1
(?<=(.))(?=\1)
¶
+`1(a*)\b
a$.1$*1;
a

;
1

Попробуйте онлайн! Или попробуйте слегка модифицированную версию для всех тестовых случаев (с десятичным вводом / выводом).

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

Принимает входные данные как унарные, выходные данные как унарные. Не совсем уверен в использовании различных унарных значений ввода / вывода, но это сэкономит 4 байта.


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