Розкласти бінарне на чергування підрядів


30

Це надихнуло проблему 13 - нещодавній конкурс бінарних програм HP 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 в ОЕІС .


@DigitalTrauma: Хммм ...... ні, я не думаю, що це в дусі виклику.
El'endia Starman

Добре. |tacзалишиться у моїй відповіді тоді :)
Digital Trauma

Відповіді:


11

Pyth, 17 16 байт

1 байт завдяки Jakube

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 Гарний!
isaacg

7

Математика, 47 байт

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

Безголовки:

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

Split[list,f]розбиває список на кілька списків, розбиваючи в положенні між aта bтоді і тільки тоді f[a,b]; не повертається True.

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


7

Пітон, 86 байт

Оскільки я жахливо перевершив Pythhon, давайте просто знову це зробити в 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 і виводить базовий рядок 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 байти, збережені thx @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 Я спробував коротший regexp, не добре :(. Thx для іншого натяку
edc65

Таблиця лідерів говорить, що у вас є відповідь на 1 байт. Я припускаю, що ви маєте виправлене число (62) перед старим числом (63) замість після.
Кайл Канос

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

3

Pyth, 26 байт

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

Спробуйте тут!

Пояснення

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

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

Оскільки функція split () Python не ділиться на матчі нульової довжини, я повинен замінити ці збіги пробілом і розділити результат на цьому.


3

Піта, 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

zsh, 67 63 55 байт

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

Я не знаю чому, але це не працює в Bash.

Дякуємо Деннісу за 8 байт!


Це forсинтаксис. ... Зачекайте, ні for?
CalculatorFeline

Арифметичне розширення Баша не дозволяє вказати вихідну базу. Щоб позбутися 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рядок edint , розділений пробілом.

Зміни:
-3:$b визначення переміщено у strlen()виклик.
-6: Видалена $cінстанція.
-2: Нарешті виправлено питання конкатенації.
-2: Немає дужок для однорядних for().
-37: Загальний ремонт. Перехід із Arrayшматками замість повторних дзвінків 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-0)

  1, наперед 1

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

  2⊥¨ перетворити кожен із бази-2


1
тут дійсно корисно. Я повинен додати це до Jelly.
Денніс

@Dennis Будьте в курсі двох версій R←X⊂Y: With ⎕ML<3(тобто стиль Dyalog), запускається новий розділ в результаті, що відповідає кожному 1 в X аж до позиції, перш ніж стане наступний 1 в X (або останній елемент X) послідовні елементи R. With ⎕ML=3(тобто стиль IBM), в результаті починається новий розділ, коли відповідний елемент у X більший за попередній. Елементи в Y, відповідні 0s у X, не включаються в результат. Так що ⎕ML←1 ⋄ 1 0 0 1 0 1 1 ⊂ ⍳7еквівалентно ⎕ML←3⋄ 4 3 2 4 4 5 7 ⊂ ⍳7`
Adám


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], convertпередає його на бінарний, подає в нього 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його до двійкового. Ми повторно подаємо у вигляді масиву char, зберігаючи перший символ у $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

С, 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 Я б краще не генерував неповний останній рядок. Але для вартості одного байта (все-таки чистого зменшення) я можу змінити роздільник від простору до нового рядка.
Фокс

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 інтерпретується справа наліво.

Відкиньте вхід до двійкових, обріжте провідні нулі, знайдіть індекси, де різні, інвертуйте, щоб отримати індекси, де однаковий, розділити список за цими індексами, перетворити назад на базову-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.