Count trailing truths

59

4

Inspired by, and in memory of, my dear friend and colleague,

Dan Baronet

Dan Baronet, 1956 – 2016. R.I.P.

He found the shortest possible APL solution to this task:

Task

Given a Boolean list, count the number of trailing truth values.

Example cases

{}0

{0}0

{1}1

{0, 1, 1, 0, 0}0

{1, 1, 1, 0, 1}1

{1, 1, 0, 1, 1}2

{0, 0, 1, 1, 1}3

{1, 1, 1, 1, 1, 1}6

Adám

Posted 2016-11-06T12:35:56.947

Reputation: 37 779

Can we take the list as a string of zeros and ones? e.g. 01100? – Adnan – 2016-11-06T12:57:58.223

@Adnan only if that is the most normal way for your language to represent boolean lists. – Adám – 2016-11-06T15:42:10.700

71Sorry for your loss. – Martin Ender – 2016-11-06T17:03:37.233

6@MartinEnder Thank you. It will be tough going forward. Dan taught me all I needed to know to work for Dyalog. – Adám – 2016-11-06T17:32:02.163

5Farewell to Dan. RIP... – Erik the Outgolfer – 2016-11-07T12:46:17.323

Are we allowed to take the input as actual bits in a row instead of individual bytes? i.e. {1,0,1,0} would be 1010000 not 10000000 00000000 10000000 00000000 – moonheart08 – 2018-10-04T19:05:31.697

@moonheart08 Only if that is the most normal way for your language to represent boolean lists. – Adám – 2018-10-04T19:58:12.397

Answers

36

Dyalog APL, 6 2 bytes

⊥⍨

Test it on TryAPL.

How it works

(uptack, dyadic: decode) performs base conversion. If the left operand is a vector, it performs mixed base conversion, which is perfect for this task.

For a base vector b = bn, ⋯, b0 and a digit vector a = an, ⋯, a0, b ⊥ a converts a to the mixed base b, i.e., it computes b0⋯bn-1an + ⋯ + b0b1a2 + b0a1 + a0.

Now, (tilde dieresis, commute) modifies the operator to the left as follows. In a monadic context, it calls the operator with equal left and right arguments.

For example, ⊥⍨ a is defined as a ⊥ a, which computes a0⋯an + ⋯ + a0a1a2 + a0a1 + a0, the sum of all cumulative products from the right to the left.

For k trailing ones, the k rightmost products are 1 and all others are 0, so their sum is equal to k.

Dennis

Posted 2016-11-06T12:35:56.947

Reputation: 196 637

14Hint: Dan did it in only two bytes. – Adám – 2016-11-06T17:27:09.130

3Mixed base conversion! That's clever. – Dennis – 2016-11-06T18:03:40.817

1

Oh. Mixed base conversion, how it strikes again.

– Conor O'Brien – 2016-11-06T18:39:34.017

Bravo! In fact, because of Dan, we special-cased b⊥b and ⊥⍨b giving up to infinite speed-up. – Adám – 2016-11-06T19:18:37.590

19

JavaScript (ES6), 21 bytes

f=l=>l.pop()?f(l)+1:0

Test cases

f=l=>l.pop()?f(l)+1:0

console.log(f([])); // → 0
console.log(f([0])); // → 0
console.log(f([1])); // → 1
console.log(f([0, 1, 1, 0, 0])); // → 0
console.log(f([1, 1, 1, 0, 1])); // → 1
console.log(f([1, 1, 0, 1, 1])); // → 2
console.log(f([0, 0, 1, 1, 1])); // → 3
console.log(f([1, 1, 1, 1, 1, 1])); // → 6

Arnauld

Posted 2016-11-06T12:35:56.947

Reputation: 111 334

How does this work? How does f(l)+1 return a value > 2? – Oliver – 2018-06-04T14:46:35.707

@Oliver This is a recursive process, evaluated as l.pop()?(l.pop()?(l.pop()?(...etc...)+1:0)+1:0)+1:0. – Arnauld – 2018-06-04T14:51:35.287

I see. Thanks for the explanation. – Oliver – 2018-06-04T14:53:02.993

11

Jelly, 4 bytes

ŒrṪP

Try it online! or Verify all test cases.

For the case where the list is empty, there are some curious observations. First, run-length encoding the empty list [] returns another empty list []. Then retreiving the last element from that using tail returns 0 instead of a pair [value, count] which are the regular elements of a run-length encoded array. Then product P returns 0 when called on 0 which is the expected result.

Explanation

ŒrṪP  Main link. Input: list M
Œr    Run-length encode
  Ṫ   Tail, get the last value
   P  Product, multiply the values together

miles

Posted 2016-11-06T12:35:56.947

Reputation: 15 654

Alternatively, ŒgṪS works, too! – Lynn – 2016-11-06T13:20:40.507

It gives the right output for the empty list as input, but I'm surprised given the dissection. Would you mind walking through that special case? – Peter Taylor – 2016-11-06T13:25:29.160

@PeterTaylor I'm surprised too that it worked. Also, I just noticed that the first link has the wrong code. – miles – 2016-11-06T13:32:42.743

@PeterTaylor in Jelly is implemented as: lambda z: iterable(z).pop() if iterable(z) else 0. iterable when called on a list just returns the list, and the empty list is of course falsy. – FryAmTheEggman – 2016-11-06T13:36:48.390

10

Haskell, 26 25 bytes

a%b|b=1+a|0<3=0
foldl(%)0

Usage:

Prelude> foldl(%)0 [True,False,True,True]
2

Pointfree version (26 bytes):

length.fst.span id.reverse

Using an integer list instead of a bool list (21 bytes, thanks to Christian Sievers):

a%b=b*(a+1)
foldl(%)0

Usage:

Prelude> foldl(%)0 [1,0,1,1]
2

Pointfree version (25 bytes)

sum.fst.span(==1).reverse

Laikoni

Posted 2016-11-06T12:35:56.947

Reputation: 23 676

For integer lists the foldl idea works with a%b=b*(a+1) – Christian Sievers – 2016-12-07T16:09:25.370

10

Brachylog, 7 6 5 bytes

@]#=+

Try it online!

Explanation

@]        A suffix of the Input...
  #=      ...whose elements are all equal
    +     Sum its elements

Since @] - Suffix starts from the biggest suffix all the way up to the smallest one, it will find the longest run first.

Fatalize

Posted 2016-11-06T12:35:56.947

Reputation: 32 976

10

CJam (8 bytes)

{W%0+0#}

Online test suite

Dissection

{    e# begin a block
  W%  e# reverse the array
  0+  e# append 0 so there's something to find
  0#  e# find index of first 0, which is number of nonzeros before it
}

Peter Taylor

Posted 2016-11-06T12:35:56.947

Reputation: 41 901

9

05AB1E, 12 10 6 5 bytes

Saved 1 byte thanks to carusocomputing.

Î0¡¤g

Try it online!

Explanation

Î      # push 0 and input
 0¡    # split on 0
   ¤   # take last item in list
    g  # get length

Emigna

Posted 2016-11-06T12:35:56.947

Reputation: 50 798

0¡¤g is four bytes. – Magic Octopus Urn – 2016-11-07T15:44:57.820

@carusocomputing: Nice! It wasn't yet clarified if string input was okay when I wrote this, but I see now that it is :) – Emigna – 2016-11-07T15:49:56.800

J0¡¤g is also still shorter ;). – Magic Octopus Urn – 2016-11-07T15:54:19.383

@carusocomputing: Unfortunately we need Î to handle the empty input, but it's still a byte saved thanks :) – Emigna – 2016-11-07T15:54:59.607

9

Retina, 7 5 bytes

r`1\G

Try it online! (The first line enables a linefeed-separated test suite.)

Defining the input format for Retina isn't entirely unambiguous. Since Retina has no concept of any type except strings (and also no value that can be used for our usual definition of truthy and falsy), I usually use 0 and 1 (or something positive in general) to correspond to truthy and falsy, as they represent zero or some matches, respectively.

With single-character representations, we also don't need a separator for the list (which in a way, is more the more natural list representation for a language that only has strings). Adám confirmed that this is an acceptable input format.

As for the regex itself, it matches from right to left and \G anchors each match to the previous one. Hence, this counts how many 1s we can match from the end of the string.

Martin Ender

Posted 2016-11-06T12:35:56.947

Reputation: 184 808

"Yes, for Retina, being that it handles only strings, I think a "01" or "FT" string is in order. – Adám – 2016-11-06T17:23:17.617

8

Python, 31 bytes

lambda a:(a[::-1]+[0]).index(0)

Mitch Schwartz

Posted 2016-11-06T12:35:56.947

Reputation: 4 899

7

Mathematica, 25 24 bytes

Fold[If[#2,#+1,0]&,0,#]&

alephalpha

Posted 2016-11-06T12:35:56.947

Reputation: 23 988

3Just recording a port of Dan's cool mixed-base solution: FromDigits[b=Boole@#,MixedRadix@b]& (35 bytes). – Greg Martin – 2016-11-07T07:31:37.817

7

Jelly, 4 bytes

ṣ0ṪL

TryItOnline!, or all tests

How?

ṣ0ṪL - Main link: booleanList
ṣ0   - split on occurrences of 0 ([] -> [[]]; [0] -> [[],[]]; [1] -> [[1]]; ...)
  Ṫ  - tail (rightmost entry)
   L - length

Jonathan Allan

Posted 2016-11-06T12:35:56.947

Reputation: 67 804

7

MATL, 4 bytes

PYps

Try it online!

P       % Flip
 Yp     % Cumulative product
   s    % Sum

Luis Mendo

Posted 2016-11-06T12:35:56.947

Reputation: 87 464

5

Pyth, 6 bytes

x_+0Q0

Try it here!

Appends a 0, reverses and finds the index of the first 0

Blue

Posted 2016-11-06T12:35:56.947

Reputation: 26 661

@Jakube fixed now - different algorithm – Blue – 2016-11-07T09:54:05.350

5

C90 (gcc), 46 bytes

r;main(c,v)int**v;{while(0<--c&*v[c])r++;c=r;}

Input is via command-line arguments (one integer per argument), output via exit code.

Try it online!

How it works

r is a global variable. Its type defaults to int and, being global, it value defaults to 0.

The function argument c defaults to int as well. It will hold the integer n + 1 for arrays of n Booleans; the first argument of main is always the path of the executable.

The function argument v is declared as int**. The actual type of v will be char**, but since we'll only examine the least significant bit of each argument to tell the characters 0 (code point 48) and 1 (code point 49) apart, this won't matter on little-endian machines.

The while loop decrements c and compares it to 0. Once c reaches 0, we'll break out of the loop. This is needed only if the array contains no 0's.

As long as 0<--c returns 1, we takes the cth command-line argument (v[c]) and extract its first character with by dereferencing the pointer (*). We take the bitwise AND of the Boolean 0<--c and the code point of the character (and three garbage bytes that follow it), so the condition will return 0 once a 0 is encountered, breaking out of the loop.

In the remaining case, while the command-line arguments are 1, r++ increments r by 1, thus counting the number of trailing 1's.

Finally, c=r stores the computed value of r in c. With default settings, the compiler optimize and remove the assignment; it actually generates the movl %eax, -4(%rbp) instruction. Since ret returns the value of the EAX register, this generates the desired output.

Note that this code does not work with C99, which returns 0 from main if the end of main is reached.

Dennis

Posted 2016-11-06T12:35:56.947

Reputation: 196 637

Isn´t argc at least 1 (with argv[0] containing the file name)? You could save one byte with --c&& instead of 0<--c&. gcc´s exit code is taken from argc? Neat. – Titus – 2016-12-07T17:50:08.603

@Titus That won't work. *v[c] is the code point of 1 or 0, so it's either 49 or 48 and thus always truthy. – Dennis – 2016-12-07T18:19:40.013

With C89 and C90, gcc returns whatever is in RAX at that moment. C99 always returns 0 from main if the end is reached. – Dennis – 2016-12-07T18:22:59.500

4

R, 40 39 25 bytes

Completely reworked solution thanks to @Dason

sum(cumprod(rev(scan())))

Read input from stdin, reverse the vector and if the first element of is !=0 then output the the first length of the run-length encoding (rle), else 0.

Billywob

Posted 2016-11-06T12:35:56.947

Reputation: 3 363

1You can save a byte by changing the second line to ifelse(r$v,r$l,0)[1]. (Vectorized if, and then take the first element.) – rturnbull – 2016-11-06T15:10:13.737

1no need for the iflelse - just multiply r$v and r$l. – Dason – 2016-11-08T15:22:03.660

But the sum(cumprod(rev(.))) route should save a lot of bytes anyways – Dason – 2016-11-08T15:23:56.757

4

k, 6 bytes

+/&\|:

This function composition translates to sum mins reverse in q, the language's more readable sibling, where mins is a rolling minimum.

skeevey

Posted 2016-11-06T12:35:56.947

Reputation: 4 139

Can the : be dropped? – streetster – 2018-10-05T06:33:38.680

4

J, 9 3 bytes

#.~

This is reflexive mixed base conversion. Because this is the same as mixed base conversion. Again.

Test cases

   v =: #.~
   ]t =: '';0;1;0 1 1 0 0;1 1 1 0 1;1 1 0 1 1;0 0 1 1 1;1 1 1 1 1 1
++-+-+---------+---------+---------+---------+-----------+
||0|1|0 1 1 0 0|1 1 1 0 1|1 1 0 1 1|0 0 1 1 1|1 1 1 1 1 1|
++-+-+---------+---------+---------+---------+-----------+
   v&.> t
+-+-+-+-+-+-+-+-+
|0|0|1|0|1|2|3|6|
+-+-+-+-+-+-+-+-+
   (,. v&.>) t
+-----------+-+
|           |0|
+-----------+-+
|0          |0|
+-----------+-+
|1          |1|
+-----------+-+
|0 1 1 0 0  |0|
+-----------+-+
|1 1 1 0 1  |1|
+-----------+-+
|1 1 0 1 1  |2|
+-----------+-+
|0 0 1 1 1  |3|
+-----------+-+
|1 1 1 1 1 1|6|
+-----------+-+

Conor O'Brien

Posted 2016-11-06T12:35:56.947

Reputation: 36 228

2Hint: This can be done in only 3 bytes, using the J translation of Dan's solution. – Adám – 2016-11-06T17:25:21.487

1@Adám I tried looking for a solution. Didn't think of base conversion. That's really quite clever of him! – Conor O'Brien – 2016-11-06T18:44:52.873

1Yes. That was Dan. :-( – Adám – 2016-11-06T19:20:48.177

3

Pyke, 10 6 bytes

_0+0R@

Try it here!

Blue

Posted 2016-11-06T12:35:56.947

Reputation: 26 661

3

Haskell, 24 bytes

foldl(\a b->sum[a+1|b])0

Iterates over the list, adding one for each element, resetting to 0 after it hits a False.

16 bytes with 0/1 input:

foldl((*).(+1))0

If the list were guaranteed non-empty, we could get 14 bytes:

sum.scanr1(*)1

This computes the cumulative product from the back, then sums them. The cumulative product remains 1 until a 0 is hit, and then becomes 0. So, the 1's correspond to trailing 1's.

xnor

Posted 2016-11-06T12:35:56.947

Reputation: 115 687

3

C#6, 103 72 bytes

using System.Linq;
int a(bool[] l)=>l.Reverse().TakeWhile(x=>x).Count();

Using non-generic list beats generic list by 1 byte lol

-31 bytes thanks to Scott

Link Ng

Posted 2016-11-06T12:35:56.947

Reputation: 593

If you use an array of ints, you can get away with int a(int[] l)=>l.Reverse().TakeWhile(i=>i>0).Sum(); – Scott – 2016-11-07T20:52:58.127

@Scott Of course what was I thinking... I will stick with bool though. Question specifies boolean list and it's not C. – Link Ng – 2016-11-08T12:24:37.000

Compile to a Func<bool[], int> for 57 bytes i.e. using System.Linq;l=>l.Reverse().TakeWhile(x=>x).Count(); – TheLethalCoder – 2016-11-08T13:45:10.140

2

Pip, 8 bytes

WDQg++ii

Takes input as command-line arguments of 0 and 1 (or any truthy value). Try it online!

Explanation

          g is cmdline args, i is 0
 DQg      Dequeue item from end of g
W   ++i   While this is truthy, increment i
       i  Print i

(Dequeueing from an empty list gives nil, which is falsey.)

DLosc

Posted 2016-11-06T12:35:56.947

Reputation: 21 213

2

PHP, 40 34 bytes

Along with $argv comes $argc ... and both are variable.
Either one of the arguments or +$argv[0]==+"-" is 0.

while(+$argv[--$argc])$i++;echo$i;

takes input from command line arguments. Empty output for 0.
Run with php -nr '<code>' <space separated values>

unary output, 35 29 bytes

while(+$argv[--$argc])echo 1;

Titus

Posted 2016-11-06T12:35:56.947

Reputation: 13 814

2

brainfuck, 99 bytes

Takes input like 11011. Output is a single byte/character value.

-[>+<-----]>---[>>,]<-[>+<-----]>---[-<+>>>+<<]<[->+<]>+>>+[<+[-<<+>>]<<<[-<+>>>-<<]<[->+<]>>>-]<-.

Try it online - Run with input, then click "view memory" to see the value under the pointer that was printed.

Explanation:

-[>+<-----]>---             put constant 48 (ASCII '0') at start of list
[>>,]                       receive all input, with an empty cell between each
<-[>+<-----]>---            constant 48 near end of list
[-<+>>>+<<]<[->+<]>+>>      move to right and copy right, add one to make 49 (ASCII '1')
                            TAPE: 48 _ i0 _ i1 _ ... in _ 49 _ 48< (pointer)

+[<+[-<<+>>]<<              LOOP. Put counter+=1 in empty cell. Move it left 2 cells.
<[-<+>>>-<<]<[->+<]>        Subtract value from value 2 cells right.
>>-]<-.                     Subtract one more. If zero, print counter-1, Else loop again.

Close, but must contain a zero, and it doesn't handle trailing zeros or an empty list. (49 bytes)

,[>>,]>>+[<+[-<<+>>]<<<[-<+>>>-<<]<[->+<]>>>-]<-.

mbomb007

Posted 2016-11-06T12:35:56.947

Reputation: 21 944

,[>,]-[>+<-----]>---[-<<[<]>[->]>]<<[>[-<+>]<<]>. – Jo King – 2018-10-04T09:30:33.373

1@JoKing Go ahead and create your own answer. That doesn't resemble mine at all. – mbomb007 – 2018-10-04T16:28:11.107

2

Pushy, 6 bytes

$v;FL#

Arguments given a list on command line: $ pushy truths.pshy 0,1,1,0,0. Like my binary conversion program, this takes advantage of the second stack in an interesting way. Here's how it works:

         \ Implicit: Input on stack
$        \ While last item is not 0:
 v;      \   Move last item to auxiliary stack
   FL#   \ Output length of auxiliary stack.

Note that the loop will not run if the list is empty, so the output will be 0.

FlipTack

Posted 2016-11-06T12:35:56.947

Reputation: 13 242

How many stacks does Pushy have? – user41805 – 2016-12-07T17:09:58.997

@KritixiLithos Two, input is automatically on stack 1 and that's where main operations take place. Stack 2 is just for storing counters / variables that need to be kept out of the way. – FlipTack – 2016-12-07T17:15:52.853

2

PHP, 38 bytes

a totally different approach

<?=strpos(strrev(join([0]+$argv)),48);

takes input from command line arguments. Save to file.

[0]+$argv sets the first element (script name) to 0.
Join that without a delimiter, reverse and find the first occurence of the 0 character.

While my first solution works with any truthy and falsy values, this one obviously depends on single characters: 0 is falsy, every other character (apart from maybe the 0 byte) truthy.

Titus

Posted 2016-11-06T12:35:56.947

Reputation: 13 814

-4 Bytes for using $_GET – Jörg Hülsermann – 2017-05-03T13:32:11.953

@JörgHülsermann That would have empty output for any list full of 1s. – Titus – 2017-05-03T14:50:51.640

Okay now I have realize it – Jörg Hülsermann – 2017-05-03T16:48:50.043

2

Japt -hx, 3 bytes

i ô

Try it online!

Japt's flag combinations rock.

How it works

Ui ô

Ui  Insert `undefined` at index 0
ô   Split at falsy items

-h  Take last element
-x  Sum

If we didn't have to handle the special case [], we could get away with 1 byte ô, winning over APL.

Bubbler

Posted 2016-11-06T12:35:56.947

Reputation: 16 616

1Half the job is done by flags‽ – Adám – 2018-06-01T08:22:04.273

2

Taxi, 1580 1576 1564 bytes

-4 bytes because of a less complex route to the Crime Lab (string equality checker). Also, you don't run out of gas for a sufficiently large number of truthy values anymore!

-12 bytes by getting rid of the quotes.

Go to the Post Office:w 1 l 1 r 1 l.
Pickup a passenger going to Chop Suey.
Go to Chop Suey:n 1 r 1 l 4 r 1 l.
[B]
Switch to plan C if no one is waiting.
Pickup a passenger going to Cyclone.
Go to Cyclone:n 1 l 3 l.
Pickup a passenger going to Narrow Path Park.
Pickup a passenger going to Joyless Park.
Go to Zoom Zoom:n.
Go to Narrow Path Park:w 1 l 1 l 1 r.
Go to Joyless Park:e 1 r 3 l.
Go to Chop Suey:w 1 r 1 r 1 l.
Switch to plan B.
[C]
0 is waiting at Starchild Numerology.
Go to Starchild Numerology:n 1 l 3 l 3 l 2 r.
Pickup a passenger going to Sunny Skies Park.
Go to Sunny Skies Park:w 1 r.
Go to Narrow Path Park:n 1 r 1 r 1 l 1 r.
[D]
Switch to plan F if no one is waiting.
Pickup a passenger going to Crime Lab.
1 is waiting at Writer's Depot.
Go to Writer's Depot:w 1 l 1 r 2 l.
Pickup a passenger going to Crime Lab.
Go to Zoom Zoom:n.
Go to Crime Lab:w 1 l 2 r.
Switch to plan E if no one is waiting.
Pickup a passenger going to The Babelfishery.
Go to The Babelfishery:s.
Pickup a passenger going to Addition Alley.
Go to Sunny Skies Park:n 1 l 1 l 1 r.
Pickup a passenger going to Addition Alley.
Go to Addition Alley:n 1 r 1 r 1 r.
Pickup a passenger going to Sunny Skies Park.
Go to Sunny Skies Park:n 1 l 1 l 1 l.
Go to Narrow Path Park:n 1 r 1 r 1 l 1 r.
Switch to plan D.
[E]
Go to Narrow Path Park:n 5 l.
[F]
Go to Sunny Skies Park:w 1 l 1 r 2 l 1 l.
Pickup a passenger going to The Babelfishery.
Go to The Babelfishery:s 1 l 1 r 1 r.
Pickup a passenger going to Post Office.
Go to Post Office:n 1 l 1 r.
Go to Taxi Garage:n 1 r 1 l 1 r.

Input is in the form of a string of 0's and 1's (for example: 11101).

Try it online!

Taxi is an esolang in which all programming is done by picking up and dropping off passengers at various stops in the fictional town of Townsburg. Of course, your taxicab will sometimes run out of gas, so you also need to visit gas stations every so often, and pay using the credits you receive as fare.

I had to do some strange management of fuel in this program. Specifically, I have a loop at the beginning (between plans B and C) which pushes each character of the input to Narrow Path Park (which is a LIFO queue, or a stack) by going back and forth between Narrow Path Park and Chop Suey (which split the input string into characters in the first place). However, for sufficiently large inputs, this can cause me to run out of gas. Simply going to a gas station every iteration is insufficient, because I'm not earning enough money from actually bringing passengers to their destinations. The best way I've figured out to earn enough money to make going to a gas station every iteration "worth it" is bringing each new passenger to Cyclone (which clones them), and taking one of those clones to Narrow Path Park while leaving one forever trapped at Joyless Park (which is a FIFO queue, but for the purposes of this program is a dumping ground).

(Note: Bringing passengers to Riverview Bridge is a good way to get rid of them, but they don't pay you - because they always seem to fall off the bridge into the river before they can pay - so I couldn't do this either.)

JosiahRyanW

Posted 2016-11-06T12:35:56.947

Reputation: 2 600

2

Brain-Flak, 30 bytes

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

Try it online!

Explanation

(()) #{ Start Loop.  Used instead of ([]) so that the loop will run at least once on empty input. }
{{}  #{Remove the stack height. }
 (
  {}{{}}  #{ Add the TOS with any 1s below it (until a zero). }
  <><{}>  #{ Remove a value on the other stack if there. }
 )     #{ Push the result (# of 1s just removed) to the other stack. } 
 <>    #{ Switch stacks back. }
 ([])  #{ Push stack height for the loop. }
}  #{ Once the loop is done (stack is empty)... }
<> #{ Switch stacks to the most recent # of 1s removed. }

Post Rock Garf Hunter

Posted 2016-11-06T12:35:56.947

Reputation: 55 382

2

Perl, 22 bytes

21 bytes of code + 1 byte for -p flag.

s/.(?=.*0)//g;$_=y;1;

To run it :

perl -pE 's/.(?=.*0)//g;$_=y;1;' <<< "0 1 1 0 1 1 1"

(Actually, the format of the input doesn't matter a lot : 0110111, 0 1 1 0 1 1 1, [0,1,1,0,1,1,1] etc. would all work)


18 bytes version from @Dom Hastings but it requires to supply the input as a string of 0 and 1, which isn't allowed :
perl -pE '/1*$/;$_=length$&' <<< '0110111'

Dada

Posted 2016-11-06T12:35:56.947

Reputation: 8 279

Loving that ; trick :) If format is one continuous string: perl -pE '/1*$/;$_=length$&' <<< '0110111' for 18, not sure if that's bending the rules or not though... – Dom Hastings – 2016-11-07T12:42:50.310

@DomHastings yea, me too! (Thanks Ton for showing me that!) The first and second comments of the question kinda disallow the format of input you need for your solution... But I'll edit my post to suggest your version if the format of the input was more free. – Dada – 2016-11-07T13:39:05.377

2

Python, 37 bytes

f=lambda l:len(l)and-~f(l[:-1])*l[-1]

orlp

Posted 2016-11-06T12:35:56.947

Reputation: 37 067

2

DASH, 16 bytes

@len mstr"1+$"#0

It's not the shortest possible DASH solution, but the shortest possible DASH solution is bugging out on me. I'm posting this novel approach in its place.

Usage:

(@len mstr"1+$"#0)"100111"

Explanation

@(                 #. Lambda
  len (            #. Get the length of the array after...
    mstr "1+$" #0  #. ... matching the argument with regex /1+$/
  )                #. * mstr returns an empty array for no matches
)

Mama Fun Roll

Posted 2016-11-06T12:35:56.947

Reputation: 7 234

2

Scala, 25 bytes

l=>l.reverse:+0 indexOf 0

Ungolfed:

l=>(l.reverse :+ 0).indexOf(0)

Reverses the list, appends a 0 and find the first index of 0, which is the number of elements before the first 0

corvus_192

Posted 2016-11-06T12:35:56.947

Reputation: 1 889

2

Batch, 57 bytes

@set n=0
@for %%n in (%*)do @set/an=n*%%n+%%n
@echo %n%

Takes input as command-line parameters. Works by multiplying the accumulator by the current value before adding it on, so that any zeros in the command line reset the count. Note that %%n is not the same as the n or %n% variable.

Neil

Posted 2016-11-06T12:35:56.947

Reputation: 95 035

2

GolfSharp, 14 bytes

n=>n.V().O(F);

downrep_nation

Posted 2016-11-06T12:35:56.947

Reputation: 1 152

2

Java 7, 62 bytes

int c(boolean[]a){int r=0;for(boolean b:a)r=b?r+1:0;return r;}

Ungolfed & test code:

Try it here.

class M{
  static int c(boolean[] a){
    int r = 0;
    for (boolean b : a){
      r = b ? r+1 : 0;
    }
    return r;
  }

  public static void main(String[] a){
    System.out.print(c(new boolean[]{}) + ", ");
    System.out.print(c(new boolean[]{ false }) + ", ");
    System.out.print(c(new boolean[]{ true }) + ", ");
    System.out.print(c(new boolean[]{ false, true, true, false, false }) + ", ");
    System.out.print(c(new boolean[]{ true, true, true, false, true }) + ", ");
    System.out.print(c(new boolean[]{ true, true, false, true, true }) + ", ");
    System.out.print(c(new boolean[]{ false, false, true, true, true }) + ", ");
    System.out.print(c(new boolean[]{ true, true, true, true, true, true }));
  }
}

Output:

0, 0, 1, 0, 1, 2, 3, 6

Kevin Cruijssen

Posted 2016-11-06T12:35:56.947

Reputation: 67 575

2

Perl 5.10, 22 bytes

21 bytes + 1 byte for -a flag. Since the regex-based expression was done... :p

The input values for the array must be separated by a space.

$n++while pop@F;say$n

Try it online!

Paul Picard

Posted 2016-11-06T12:35:56.947

Reputation: 863

1Slightly shorter if you take arguments via command line: perl -E '$_++while pop;say' 0 1 1 0 1 1 1 but this doesn't output anything for 0 (not sure if that's a problem though!) – Dom Hastings – 2016-11-07T12:43:54.823

2

Ruby 37 32 bytes

->n{n.size-1-(n.rindex(!0)||-1)}

Creates an anonymous function that finds the right-most instance of a false value, and counts the size of the subarray starting at that value.

It uses !0 as false, as 0 are truthy values in Ruby. rindex finds the last index of a value in an array.

Usage:

boolean_list = [true, false, false, true]
->n{n.size-1-(n.rindex(!0)||-1)}[boolean_list]

Returns 1


If I was allowed to be passed a string of 0s and 1s as command line parameters (which is not how ruby represents lists of booleans), I could get it down to 24:

$*[0]=~/(1*)\z/;p$1.size

This uses regular expressions and prints the length of the string returned by the regular expression /(1*)\z/, where \z is the end of the string. $*[0] is the first argument passed and is a string of 0s and 1s.

Usage:

trailing_truths.rb 011101

Returns 1.

IMP1

Posted 2016-11-06T12:35:56.947

Reputation: 510

1Once you have the index of the last false value, why do you need to retrieve elements from the array again? – Lee W – 2016-11-07T16:14:22.043

You're right, I don't. Thanks. 5 bytes off! – IMP1 – 2016-11-08T08:48:03.280

2

C++17, 82 66 bytes

int f(){return 0;}int f(int H,auto... L){return(H*...*L)+f(L...);}

Uses the C++17 template parameter fold expression and essentially the same idea as Dennis. Saving 16 bytes by using Generic Variadic Lambda.

Explanation:

int f(){return 0;} //base case for empty list

int f(int H, auto... L) { //first element, variadic arguments
    return (H*...*L)      //a_0*a_1*a_2*...
         + f(L...);       //+ f(a_1,a_2,...)
}

Usage:

f(1,1,0,1,1,0,1,1,1,1,1) -> 5
f() -> 0
f(1,0,1,0) -> 0

Non competing

Albeit longer, this also works with template constants:

template <int...L> int C=0;
template <int H, int...L> int C<H,L...> = (H*...*L)+C<L...>;

Usage:

std::cout << C<1,0,1,1>  << std::endl;
std::cout << C<1,0,1,0,1>  << std::endl;
std::cout << C<1,1,1,0,1,0,1,1>  << std::endl;
std::cout << C<1,1,1,0,1,0,1,1,1,1,1,1>  << std::endl;
std::cout << C<> << std::endl;

Karl Napf

Posted 2016-11-06T12:35:56.947

Reputation: 4 131

2

PHP, 50 bytes

<?=strlen(preg_filter('/.*[^1]/','',join($argv)));

Weirdly my first try with a regex turned out shorter than my try with arrays...
Use like:

php tt.php 1 1 0 1 1

user59178

Posted 2016-11-06T12:35:56.947

Reputation: 1 007

1

Swift 3, 49 bytes

func a(b:[Bool]){print(b.reduce(0,{$1 ?$0+1:0}))}

Otávio

Posted 2016-11-06T12:35:56.947

Reputation: 161

1

Minkolang, 32 bytes

0$nI1-[1=?v0g1+1R]N.
      .Ng0<

Try it online!

Explanation

0                             pushes 0 (this is the number that will keep track of the number of 1s)
 $n                           pushes all of input as numbers (pushes -1 if there is no input)
   I1-                        pushes stack minus 1 (to exclude the 0)
      [          ]            for loop with the previous number as the number of iterations
       1=?                     check equality with 1 (this is for the empty input testcase)
                               where -1 will be pushed by the interpreter

If number is not 1 (ie 0 or -1[-1 will be pushed if there is no input]):

         <                     start going left
       g0                      gets the first element in stack
     .N                       output it as number and stop program

If number is 1:

          v                    gets jumped over by ? since true has been evaluated
           0g1+                gets the first element and adds 1 to it
               1R              rotates stack once clockwise
                  N.          outputs as number and stops program

user41805

Posted 2016-11-06T12:35:56.947

Reputation: 16 320

1

Clojure, 39 36 bytes

#(count(take-while{1 1}(reverse %)))

Input as integers [1 0 1 1 0 1 1 1], anything other than 1 is falsy. {1 1} is a hash-map with key 1 and value 1 which can also used as a function. For example ({1 999} 1) is 999 (truthy) whereas ({1 999} 0) is nil (falsy).

Original, based on booleans:

#(count(take-while(fn[i]i)(reverse %)))

Amazing how (fn[i]i) is shorter than identity and also doesn't force you to put a space after take-while. Must take a list or vector of booleans, integers can be converted like this: (map #(= 1 %) [1 0 1 1 0 1 1 1])

NikoNyrh

Posted 2016-11-06T12:35:56.947

Reputation: 2 361

1

PHP, 33 Bytes

<?=strspn(strrev(join($_GET)),1);

Online Version

strspn

Jörg Hülsermann

Posted 2016-11-06T12:35:56.947

Reputation: 13 026

1

Pari/GP, 30 bytes

p->valuation(Pol(p)*(x-1)+1,x)

Converts the list to a polynomial, say p, then finds the valuation of p*(x-1)+1 with respect to x, i.e., the minimal degree of its nonzero terms.

For example, if we take [1, 0, 1, 1, 1] as input, then the polynomial p is x^4 + x^2 + x + 1, and p*(x-1)+1 is x^5 - x^4 + x^3, whose valuation is 3.

Try it online!

alephalpha

Posted 2016-11-06T12:35:56.947

Reputation: 23 988

Well, that is truly an original method. +1 – Adám – 2017-07-13T05:47:28.247

1

brainfuck, 33 bytes

,[+++>-[<->-----],]<[>[-<+>]<<]>.

Try it online!

Takes input via a string like 101011, and then outputs via byte value. I've added some code in the footer to add 48 to the value to output a digit.

 ,[  Loop over input
   +++>-[<->-----]  Subtract 48 from each value to form a tape of 0s and 1s
 ,]
 <[>[-<+>]<<]   Add up all the trailing ones
 >.             And print the value

Jo King

Posted 2016-11-06T12:35:56.947

Reputation: 38 234

1

Python2, 42 41 Byes

t=input()[::-1];print len(t[:t.index(0)])

takes input as [1, 1, 0, 1, 1]

Dignissimus - Spammy

Posted 2016-11-06T12:35:56.947

Reputation: 449

No joy with the empty list test case. – Jonathan Allan – 2016-11-06T15:11:12.670

1

ABCR, 14 bytes

c7iA)7a!xcx!Bp

Accepts the formatting [0,1,0,1,0, where any non-numeric character can be replaced with any other non-numeric character. Empty input is the empty list.

Explanation: Every 7 input number i is queued up A; every "0" input number (or rather, non-"1") )7 will pop from the queue until it's empty 7a!x; before another input number is queued, a delimiter character is grabbed cx to check for the end of queue. After all the integers are grabbed, !Bp prints the length of the queue of input numbers (which will be all the trailing "1" values.)

Steven H.

Posted 2016-11-06T12:35:56.947

Reputation: 2 841

1

PHP, 58 54 53 bytes

function f($a){while(array_pop($a))$i++;return+$i;}

Since PHP has no list I use an array instead

-4 bytes thanks to user59178

All tests

Sefa

Posted 2016-11-06T12:35:56.947

Reputation: 582

Assigning $i=0; is unnecessary if you echo/return +$i. Having this as a command line program rather than a function is much shorter as well, though you need to account for the fact that $argv[0] is truthy. With both of these you could save 19 bytes. – user59178 – 2016-11-07T16:50:34.763

return+$i; needs no space. – Titus – 2016-12-07T16:08:39.760

0

Braingolf, 7 bytes

!?&gGL|

Try it online!

Explanation

!?&gGL|  Implicit input from commandline args
!?       If last item on stack is > 0..
  &g     ..Combine all items into single number (1, 1, 0, 1 becomes 1101)
    G    ..Split into digit runs (1101 becomes 11, 0, 1)
     L   ..Pop last item and push length of item (111 becomes 3)
      |  Endif
         Implicit output of last item on stack, either number of trailing ones, or zero

Skidsdev

Posted 2016-11-06T12:35:56.947

Reputation: 9 656

You use 3 chars for the conditional. Could you maybe multiply by the parity instead? – Adám – 2017-07-13T09:46:31.413

@Adám that would still be 3 bytes, 2 bytes to get the parity (2%) and one byte to multiply (*) – Skidsdev – 2017-07-13T09:49:42.040

0

Backhand, 17 bytes

v I^: ]|{]1$|{O @

Try it online!

Explanation:

v I^: ]|{]1$|{O @
v                  Decrease step value to 2
  I                Get input as a number
    : ]|{          Reflect if not EOF
   ^               Increase step value to 3
v                  Decrease to 2 and repeat the loop
         ]         The leftover EOF (-1) is now our counter. Increment it to 0
           $|{     Reflect if the top value is truthy
       |{ 1        Reflect and repeat
         ]         Increment the counter for every truthy value
              O @  Output the final state of the counter

Jo King

Posted 2016-11-06T12:35:56.947

Reputation: 38 234

0

Ohm v2, 5 bytes

Ö⁾ì]*

RLE encodes the string, takes the last element, flattens, and multiplies

Try it online!

ThePlasmaRailgun

Posted 2016-11-06T12:35:56.947

Reputation: 383

0

Mathematica, 36 bytes

Length[#/.({___,0,x___/;x==1}:>{x})]&

Not the shortest, but short enough where I was proud to submit it :)

user6014

Posted 2016-11-06T12:35:56.947

Reputation: 288

0

V, 7 bytes

Ó1*0
ø1

Try it online! Takes input as a string of 0 and 1.

Explanation

Ó1*0     Remove all occurences of any number of ones followed by a zero
ø1       Count the number of remaining ones

Herman L

Posted 2016-11-06T12:35:56.947

Reputation: 3 611

0

MBASIC, 112 bytes

1 INPUT B$:T=0:FOR I=LEN(B$) TO 1 STEP -1:C$=MID$(B$,I,1):IF C$="0" THEN 4
2 IF C$="1" THEN T=T+1
3 NEXT
4 PRINT T

Just wanted to see if I could do it.

Explanation

Input is a string of 1's and 0's. String is traversed from right to left. If the current digit is a 0, bail out and print the total. If the digit is a 1, increment the total and continue to loop.

Output

? 01100
 0

? 11011
 2

? 11101
 1

? 111111
 6

wooshinyobject

Posted 2016-11-06T12:35:56.947

Reputation: 171