27
\$\begingroup\$

Mr. Binary Counterman, son of Mr. Boolean Masker & Mrs. Even Oddify, follows in his parents’ footsteps and has a peculiar way of keeping track of the digits.

When given a list of booleans, he counts the 1s and 0s separately, numbering the 1s with the odds & the 0s with the evens.

For example, when he looks at 1 1 0 0 1 0 he counts: 1st odd, 2nd odd, 1st even, 2nd even, 3rd odd, 3rd even and copies it down as 1 3 2 4 5 6

Mr. Binary Counterman thinks it looks prettier to start counting odds at 1 and evens at 2. However the pattern is more symmetric if you start counting evens at 0. You may do either. So either 1 3 2 4 5 6 or 1 3 0 2 5 4 are good given the list above.

As input you may take any representation of a boolean list or binary number, the output should be the list of resulting numbers with any delimiter. (But the list elements should be separate & identifiable.)

This is , so least bytes wins.

Test Cases

1 0 1 0 1 0
1 2 3 4 5 6

1 1 1 1
1 3 5 7

0 0 0 0
2 4 6 8

0 1 1 0 0
2 1 3 4 6

0 1 1 0 0 1 0 1 1
2 1 3 4 6 5 8 7 9

0 0 1 0 0 1 1 1
2 4 1 6 8 3 5 7

0
2

1
1

1 1 1 0 0 0
1 3 5 2 4 6
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Can we take the bits flipped? \$\endgroup\$
    – Razetime
    Jun 15 at 3:30
  • \$\begingroup\$ Absolutely! Look forward to seeing what you've come up with. \$\endgroup\$
    – AviFS
    Jun 15 at 3:54

33 Answers 33

14
\$\begingroup\$

JavaScript (ES6), 29 bytes

a=>a.map(v=>b[v]+=2,b=[0,-1])

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Have to laugh at everyone else trying to make this as convoluted as they can while you & I take the most simplistic approach possible and both our solutions are still competitive! \$\endgroup\$
    – Shaggy
    Jun 18 at 0:27
12
\$\begingroup\$

J, 12 bytes

+2*/:<.&/:\:

Try it online!

Explanation: Self plus twice the minimum of ascending and descending ranks.

Given a boolean array 1 1 0 0 1 1 1, ascending rank /:@/: and descending rank /:@\: are computed as follows:

array:       1 1 0 0 1 1 1
asc. rank:   2 3 0 1 4 5 6
desc. rank:  0 1 5 6 2 3 4
minimum:     0 1 0 1 2 3 4

APL(Dyalog Unicode), 9 bytes SBCS

⊢+2×⍋⌊⍥⍋⍒

Try it on APLgolf!

\$\endgroup\$
2
  • 4
    \$\begingroup\$ Wow! Fantastic insight! \$\endgroup\$
    – Jonah
    Jun 15 at 2:41
  • 1
    \$\begingroup\$ Holy wow! You should def post the APL solution separately. It's one byte away from first! \$\endgroup\$
    – AviFS
    Jun 15 at 4:04
11
\$\begingroup\$

Risky, 44 bytes

__0+0+_0+0+__0+0+_0+0+__0+0+_0+0+__0+0+_0+?1__0+0+_0+0+__0+0+_0!-_0!_{1+_0+0_[2_{0+__{1

Try it online!

How it works:

This is a really low level explanation:

... + __0+0+_0+?                                                  ;  the input array
                 1                                                ;  map with the following pairs:
                   ... + __0+0+_0!-                               ;  [0, -1]
                                    _                             ;  map to
                                      0!_{1+_0+0                  ;  range with same length
                                                 _                ;  map to
                                                   [              ;  absolute value
                                                          +       ;    of the sum of
                                                     2_{0         ;      twice the index in the range and
                                                            __{1  ;      the offset (0 or -1)

That's useless, though. Here's a better description of how this works:

Risky has an operator called "map pairs" which takes an array, and maps the items according to a set of rules. The rules are arrays, starting with the item to be replaced, and with (typically) one item to map to. However, if multiple are specified, they'll be used in order.

This answer generates those mappings, which look like [[0, 2, 4, 6, ...], [1, 1, 3, 5, 7, ...]]. It does this by mapping [0, -1] to [2_{0+__{1 over a range [0, x), which is essentially (x, n) => abs(2 * x + n), where x is the number in the range and n is either 0 or -1.

\$\endgroup\$
2
  • 3
    \$\begingroup\$ No way! You used Risky for a serious problem. And it's not a half bad score despite having half the symbols. Congrats!! \$\endgroup\$
    – AviFS
    Jun 15 at 3:58
  • 2
    \$\begingroup\$ Interesting language filled with 0s \$\endgroup\$
    – wasif
    Jun 15 at 7:26
9
\$\begingroup\$

Jelly, 8 bytes

,CÄḤ×ƊS_

Try it online!

-2 bytes thanks to Bubbler

How it works

,CÄḤ×ƊS_ - Main link. Takes a binary list B on the left
 C       - Complement. Flip the bits of B
,        - Pair with B: [B, B']
     Ɗ   - Last 3 links as a monad f([B, B']):
  Ä      -   Cumulative sum of each
   Ḥ     -   Unhalve
    ×    -   Multiply modified B by B and modified B' by B'
      S  - Columnwise sum
       _ - Subtract B, elementwise
\$\endgroup\$
3
  • \$\begingroup\$ Nice!! I was about to tackle it in Jelly the same way. I made an example-based explanation for my APL answer. I wonder if this is really the best way to do it. \$\endgroup\$
    – AviFS
    Jun 15 at 1:41
  • 1
    \$\begingroup\$ @AviFS Yep, I saw your explanation and went "Oh, that's basically my approach" :P \$\endgroup\$ Jun 15 at 1:43
  • 1
    \$\begingroup\$ 8 bytes \$\endgroup\$
    – Bubbler
    Jun 15 at 2:54
7
\$\begingroup\$

Japt -m, 8 bytes

?J±2:T±2

Try it

  • J is initially -1,
  • T is initially 0, and,
  • ± is the shortcut for +=.
\$\endgroup\$
5
\$\begingroup\$

Jelly, 9 bytes

,CỤ€⁺«/Ḥ_

Try it online!

My convoluted port of my own APL/J answer.

Jelly, 9 bytes

CỤỤ«ỤỤ$Ḥ_

Try it online!

Small modification of caird's 10-byter port.

\$\endgroup\$
5
\$\begingroup\$

05AB1E, 8 6 bytes

η^_O·α

Try it online!

η       # prefixes of the input
 ^      # XOR the first value of the input with the first prefix, second value of input with second prefix, ...
  _     # boolean negate
   O    # sum each modified prefix
    ·   # double all integers
     α  # absolute difference to the input

η^_ can be replaced with δQÅl (equality table; lower-triangular matrix), which is a byte longer but might be shorter in some other language.

δQÅlO·α

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Nice! Tied for first with cairdcoinheringaahing’s Jelly answer \$\endgroup\$
    – AviFS
    Jun 15 at 6:40
5
\$\begingroup\$

PowerShell Core, 28 bytes

$b=0,-1;$args|%{($b[$_]+=2)}

Try it online!

Port of Arnauld's solution, thanks !

Initial implementation, 35 bytes

switch($args){0{++$e*2}1{$o++*2+1}}

Try it online!
Or starting with 0 (35 bytes)

Takes the input as a list of 0/1's
Returns a list of integers

Explanation

switch($args){ # For each argument passed as an integer
0{++$e*2}      # if it is 0, output an even number, starting from 2
1{$o++*2+1}}   # if it is 1, output an odd number, starting from 1
\$\endgroup\$
5
\$\begingroup\$

Jelly, 7 6 bytes

ċṪ$ƤḤ+

Try it online!

Basically a translation of an old version of ovs' 05AB1E answer.

Explanation

ċṪ$ƤḤ+ Main monadic link
   Ƥ   Map over prefixes
  $    (
ċ        Count the occurences of
 Ṫ         the last item after removing it
  $    )
    Ḥ  Unhalve
     + Add the original list
\$\endgroup\$
3
  • \$\begingroup\$ Holy gamoly— 7 bytes! This is the winning answer out of all 16 so far. Look forward to reading the explanation, congrats! \$\endgroup\$
    – AviFS
    Jun 15 at 7:04
  • \$\begingroup\$ @AviFS Added :) \$\endgroup\$
    – xigoi
    Jun 15 at 7:13
  • 1
    \$\begingroup\$ Latecomer here checking if the solution I found was here before posting it - this six byter is the same, byte for byte. \$\endgroup\$ Jun 16 at 21:04
5
\$\begingroup\$

8086 machine code, 21 18 bytes

00000000: b0 01 b2 02 d1 eb 72 01 92 aa 40 40 72 01 92 e2  ......r...@@r...
00000010: f3 c3                                            ..

Function.

        [bits 16]
        [cpu 8086]
        section .text
        ; nasm syntax
        ; INPUT:
        ;    DI: destination byte array
        ;    BX: bit pattern (little endian)
        ;    CX: count of bits
        ; OUTPUT:
        ;    stored to DI
        global  mrbitctr
mrbitctr:
        ; Count odd bits in AL
        mov     al, 1
        ; Count evens in DL
        mov     dl, 2
.loop:
        ; Shift right BX one bit. This will put
        ; the lowest bit in CF.
        shr     bx, 1
        ; Was the bit set? If so, jump.
        jc      .no_swap
        ; Even: swap
.swap:
        ; Pull the old switcheroo to select evens
        xchg    ax, dx
        ; Odd: don't swap
.no_swap:
        ; Store to DI and increment
        stosb
        ; Add 2 to AL by incrementing AX twice
        ; Note: INC does not affect the carry flag
        inc     ax
        inc     ax
        ; swap back if even
        jc      .no_swap_back
.swap_back:
        xchg    ax, dx
.no_swap_back:
        ; Loop CX times.
        loop    .loop
.end:
        ret
  • 3 bytes: swap twice
\$\endgroup\$
4
\$\begingroup\$

Dyalog APL, 24 23 bytes

(⍵ׯ1+2×+\⍵)+N×2×+\N←~⍵

The list of evens and the list of odds are generated separately and added elementwise with the + in the middle. Here's what it looks like with the problem's example input:

Evens:
    ⍵            The input                      → 1 1 0 0 1 0
    ~            Negate it                      → 0 0 1 1 0 1
    N←           Let N be the negated list      → 0 0 1 1 0 1
    +\           Take the running sum           → 0 0 1 2 2 3
    2×           Multiply by two                → 0 0 2 4 4 6
    N×           Multiply by the negated list   → 0 0 2 4 0 6

Odds:
    ⍵            The input                      → 1 1 0 0 1 0
    +\           Take the running sum           → 1 2 2 2 3 3
    2×           Multiply by two                → 2 4 4 4 6 6
    ¯1+          Subtract 1                     → 1 3 3 3 5 5
    ⍵×           Multiply by the list           → 1 3 0 0 5 0

Together:
  (~⍵)×2×+\~⍵    Evens                          → 0 0 2 4 0 6
  (⍵ׯ1+2×+\⍵)   Odds                           → 1 3 0 0 5 0
  +              Add elementwise                → 1 3 2 4 5 6

Try it online!

\$\endgroup\$
2
  • 5
    \$\begingroup\$ Not a big deal, but it's generally considered polite practice here to wait for a week or more before answering your own questions. \$\endgroup\$
    – Jonah
    Jun 15 at 1:08
  • 2
    \$\begingroup\$ Oh no, it is? Thanks for letting me know, @Jonah! \$\endgroup\$
    – AviFS
    Jun 15 at 1:10
4
\$\begingroup\$

J, 27 26 25 bytes

<@({.-~2*#\)/.~@/:~/:&;/:

Try it online!

  • /.~@/:~ Sort and group by value
  • ({.-~2*#\) Create 2 4 6 ... to the length of each group, and subtract the first element of each group from that (vectorized), so that the the 1 group becomes 1 3 5 ...
  • The grouping screws up the order though, so we have to...
  • /:&;/: Resort it according to the grade up of the original input, which makes it correct again.

J, bonus: translation of AviFS's APL answer into J (28 bytes)

([:+/**-&1 0)@,:&(2*]*+/\)-.

Try it online!

Just because I liked it and wanted to see how they'd compare.

\$\endgroup\$
4
\$\begingroup\$

Vyxal, 15 9 bytes

₌⇧⇩⇧$⇧∵d+

Try it Online!

Me when APL port

Explained

₌⇧⇩⇧$⇧∵d+
₌⇧⇩       # grade up input, grade down input
   ⇧$⇧    # grade each of those up
      ∵d  # 2 * the minimum of those two lists
        + # added to the input   
\$\endgroup\$
0
4
\$\begingroup\$

Python 2, 43 bytes

b=[2,1]
for e in input():print b[e];b[e]+=2

Try it online!

-5 bytes and fix thanks to @xnor

The program is now reusable

\$\endgroup\$
0
4
\$\begingroup\$

Haskell, 38 bytes

f(h:t)=h:f[x+mod(x-h-1)2*2|x<-t]
f e=e

Try it online!

The recursion happens on “the tail of the list, but with all elements x that have the same parity as the head incremented by 2.” Like so:

  f [1,1,0,0,1,0]
= 1 : f [3,0,0,3,0]
= 1 : 3 : f [0,0,5,0]
= 1 : 3 : 0 : f [2,5,2]
= 1 : 3 : 0 : 2 : f [5,4]
= 1 : 3 : 0 : 2 : 5 : f [4]
= 1 : 3 : 0 : 2 : 5 : 4 : f []
= [1,3,0,2,5,4]
\$\endgroup\$
3
\$\begingroup\$

Jelly, 15 bytes

ṢŒg2ḷ$\€ÄFị@ỤỤ$

Try it online!

ṢŒg2ḷ$\€ÄFị@ỤỤ$  Main Link; take a list of 0s and 1s
Ṣ                Sort the list
 Œg              Group runs of equal elements
       €         For each group
     $\          Cumulatively reduce by
   2ḷ            x => 2 (that is, all but the first element become 2)
        Ä        Cumulative sum, vectorizing to depth 1
         F       Flatten
          ị@     Index into (reverse order)
            ỤỤ$  The input graded up twice

Grading up twice returns the permutation to index into another list to get the same ordering or something like that. I think that's how it works.

\$\endgroup\$
2
3
\$\begingroup\$

K (ngn/k), 15 bytes

{x+2*(<<x)&<>x}

Try it online!

A K port of @Bubbler's J and APL solutions - don't forget to upvote it!

\$\endgroup\$
3
\$\begingroup\$

Ruby -p, 29 bytes

Takes input as space separated digits (or any other non-digit separator).

gsub(/\d/){($`*2+?1).count$&}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Stax, 9 8 bytes

╜♪N·{☼►◄

Run and debug it

Inspired by Arnauld's idea.

0-indexed, takes the bits flipped.

Explanation

AEsF{Q2+}&
AEs        swap the input with  [1,0]
   F       foreach i:
    {   }&  modify the element at i in 2,1
     Q      print without popping
      2+    add 2
\$\endgroup\$
2
\$\begingroup\$

C (clang), 52 bytes

-1 thanks to @AZTECCO, by using clang instead of gcc.

f(a,l)int*a;{for(int b[]={0,-1};l--;)*a++=b[*a]+=2;}

Try it online!


C (gcc), 53 bytes

f(a,l)int*a;{for(int b[]={0,-1};l--;a++)*a=b[*a]+=2;}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Nice trick! You can save by switching to clang and incrementing a in assignment f(*a,l){for(int b[]={0,-1};l--;)*a++=b[*a]+=2;} \$\endgroup\$
    – AZTECCO
    Jun 15 at 20:42
2
\$\begingroup\$

Raku, 21 bytes

*>>.&{(%.{$_}+=2)-$_}

Try it online!

Maps each element to the index into an anonymous hash, incrementing that value by two (initially zero), and finally subtracting the element itself to distinguish between odd and even.This could also be extended to values beyond 0 and 1 simply by changing the 2 to another number.

\$\endgroup\$
2
\$\begingroup\$

Julia, 33 30 bytes

f(x,y=[0,-1])=x.|>i->y[i+1]+=2

Try it online!

\$\endgroup\$
1
\$\begingroup\$

AWK, 42 bytes

d[1]=1{for(;a++<NF;d[b]+=2)$a=+d[b=$a%2]}1

Try it online!

So this one is one test with a codeblock, and a naked 1 to print all the commandline arguments. It replaces each commandline argument with the appropriate even/odd counter in the codeblock.

The "test" for the codeblock is always truthy and it just used to initialize the "odd" counter to 1.

d[1]=1{                                  }

The code block runs through each commandline argument,

       for(;a++<NF;       )

Then sets that argument to the current value of the even/odd counter with:

                           $a=+d[b=$a%2]

And at the end of the loop, increments the current counter by 2 in preparation for the next match.

                   d[b]+=2

Once that's done, it just need to print out all the arguments.

                                         1
\$\endgroup\$
1
\$\begingroup\$

Zsh, 23 bytes

for x
echo $[x+a$x++*2]

Attempt This Online!

Starts even numbers at 0.

Explanation:

  • for x: for each $x in the input,
  • $[]: arithmetic expansion
  • ++: increment and return original value
  • a$x: the variable named a0 or a1 (which correspond to the number of 0s and 1s seen so far)
  • x+*2: double and add x to get the correct value
  • echo : print (can't use <<< because the mutation wouldn't work in the subshell it creates)
\$\endgroup\$
1
\$\begingroup\$

Desmos, 64 bytes

a(l)=\sum_{n=1}^{[1...length(l)]}l[n]
b=1-l
f(l)=2ba(b)+2la(l)-l

Just implements the strategy shown in AviFS's Dyalog APL answer.

Try It On Desmos!

Try It On Desmos! - Prettified

Explanation:

a(l)=\sum_{n=1}^{[1...length(l)]}l[n]: Function that takes in a list \$l\$ and returns the running total of \$l\$.

b=1-l: Variable that stores the inputted list, but with each bit flipped.

f(l)=2ba(b)+2la(l)-l: Function that takes in a list of bits \$l\$ and outputs the correct answer, based on the strategy mentioned above.

\$\endgroup\$
1
\$\begingroup\$

R, 42 bytes

function(x,y=seq(x)*2){x[x]=y-1;x[!x]=y;x}

Try it online!

-8 bytes thanks to @Dominic

Takes input as booleans: TRUE(1) and FALSE(0).

Straightforward approach, but takes advantage of truncating the replacement to the length of items being replaced.


Different approach:

R, 47 bytes

function(x,n=0:-1)for(i in x)show(n[i]<-n[i]+2)

Try it online!

Takes input incremented by 1: 2 (for 1) and 1 (for 0).

\$\endgroup\$
2
  • 1
    \$\begingroup\$ 42 bytes... \$\endgroup\$ Jun 15 at 8:08
  • \$\begingroup\$ @DominicvanEssen Thanks, nice one! Didn't think of leveraging the truncating of replacement vector! \$\endgroup\$
    – pajonk
    Jun 15 at 8:21
1
\$\begingroup\$

Retina 0.8.2, 43 bytes

(.)(?<=((\1)|.)*(1)?)
$#3$*2$4¶
2
11
1+
$.&

Try it online! Link includes test cases. Takes input as a string of bits. 1-indexed. Explanation:

(.)(?<=((\1)|.)*(1)?)

For each bit, count the number of preceding identical bits. If the current bit is 1 then count it separately otherwise include the current bit in the count.

$#3$*2$4¶

Record a 2 for each duplicate plus one extra for a 1 bit.

2
11

Convert to unary.

1+
$.&

Convert the sum back to decimal.

\$\endgroup\$
1
\$\begingroup\$

Charcoal, 12 bytes

IEθ⁺Iι⊗№…θκι

Try it online! Link is to verbose version of code. Takes input as a string of bits. 0-indexed. Explanation:

  θ             Input string
 E              Map over characters
     ι          Current character
    I           Cast to integer
   ⁺            Plus
      ⊗         Doubled
       №        Count of
           ι    Current character in
         θ      Input string
        …       Truncated to length
          κ     Current index
I               Cast to string
                Implicitly print on separate lines
\$\endgroup\$
1
\$\begingroup\$

Perl 5 (-ap), 27 bytes

$_+=$x[$_]++*2for@F;$_="@F"

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Wolfram Language (Mathematica), 29 bytes

(a=0@-1;a[[#~Mod~2]]+=2&/@#)&

Try it online!

Boring answer. Mathematica's += etc. operators have different precedence than assignment = etc. operators. This gives them higher precedence than &, so unlike = expressions they don't need to be parenthesized on the left side of &. (//=, introduced in 12.2, is slightly different from both aforementioned groups).

\$\endgroup\$
1
  • \$\begingroup\$ 0@-1 is clever! \$\endgroup\$
    – Roman
    Jun 17 at 9:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.