59
\$\begingroup\$

Intro

Every year, Dyalog Ltd. holds a student competition. The challenge there is to write good APL code. This is a language agnostic edition of this year's eighth problem.

I have explicit permission to post this challenge here from the original author of the competition. Feel free to verify by following the provided link and contacting the author.

Problem

Given a Boolean* list, "turn off" all the Truthies after the first Truthy.

No Truthies? No problem! Just return the list unmodified.

Examples

[falsy,truthy,falsy,truthy,falsy,falsy,truthy] → [falsy,truthy,falsy,falsy,falsy,falsy,falsy]

[] → []

[falsy,falsy,falsy,falsy] → [falsy,falsy,falsy,falsy]

* All your truthies must be identical, and all your falsies must be identical. This includes output.

\$\endgroup\$
24
  • 2
    \$\begingroup\$ Can we use bit lists or other truthy/falsy list representations that are more natural in our language of choice? \$\endgroup\$ May 7, 2017 at 20:32
  • 2
    \$\begingroup\$ Well yeah, if you talk about "truthy" and "falsy" in the challenge instead of "booleans", "true" and "false". ;) \$\endgroup\$ May 7, 2017 at 20:36
  • 1
    \$\begingroup\$ I'm not clear on the booleans. Can we use 0/1 even if our language has True/False? \$\endgroup\$
    – xnor
    May 7, 2017 at 20:59
  • 1
    \$\begingroup\$ @xnor Ah, good point. I think it would be fair to allow choosing input, but output must match, don't you think so? \$\endgroup\$
    – Adám
    May 7, 2017 at 21:12
  • 1
    \$\begingroup\$ @xnor I hear you, but if Haskell cannot treat numbers as Booleans, or cannot do arithmetic on Booleans, then that is a real limitation in the golfing power of Haskell, and ought to be reflected in the byte count by necessitating conversions or other work-arounds. What do you think of the footnote formulation? \$\endgroup\$
    – Adám
    May 7, 2017 at 21:19

75 Answers 75

1 2
3
0
\$\begingroup\$

Retina, 16 bytes

+T`1`0`(?<=1)0*1

Try it online! My first Retina submission ever.

\$\endgroup\$
1
  • \$\begingroup\$ 0*1 can be replaced with .* \$\endgroup\$
    – eush77
    May 20, 2017 at 22:38
0
\$\begingroup\$

C++, 77 75 bytes

Yay pointers and memset!

void f(bool*a,int b){bool*c=&a[b];while(a<c)if(*a++)break;memset(a,0,c-a);}

Function takes in a pointer to a bool array, and the length of that array as parameters. It loops through the array until it finds the first true, increments one more cell, and memsets the remainder of the memory from that pointer until the end. 0 length arrays work too since the loop is skipped entirely and the memset gets 0 bytes as the length, however passing in null instead of an empty array will break things.

Ungolfed + tests

#include <iostream>
#include <cstdlib>
#include <cassert>

//void f(bool*a,int b){bool*c=&a[b];while(a<c)if(*a++)break;memset(a,0,c-a);}

void f(bool* a, int b)
{
    bool* c = &a[b];
    while (a < c)
        if (*a++)
            break;
    memset(a, 0, c - a);
}

void print(bool* a, int b)
{
    for (int i = 0; i < b; i++)
    {
        std::cout << a[i] << '\t';
    }
    std::cout << std::endl;
}

int main()
{
    size_t s = sizeof(bool);
    assert(s == 1);
    bool* t1 = new bool[5] { false, false, false, false, false };
    bool* t2 = new bool[0];
    bool* t3 = new bool[6] { false, false, true, false, true, true };
    bool* t4 = new bool[10] { true, true, true, true, true, true, true, true, true, true };
    f(t1, 5);
    f(t2, 0);
    f(t3, 6);
    f(t4, 10);
    print(t1, 5);
    print(t2, 0);
    print(t3, 6);
    print(t4, 10);
    delete[] t1;
    delete[] t2;
    delete[] t3;
    delete[] t4;
}
\$\endgroup\$
0
\$\begingroup\$

Befunge-98, 19 bytes

&:1`#@_1*:.70g\-70p

Try it online!

Input: stream of numbers, 0 (false), 1 (true), or 2 (EOF).

Output: stream of numbers, 0/1.

Explanation

The program works by reading the next number in a loop, multiplying it by a constant, and printing the result to stdout. The operation described in the problem statement is performed by modifying that constant:

&:1`#@_1*:.70g\-70p
       ^          v
       [ P[7]-= x ]
\$\endgroup\$
0
\$\begingroup\$

Whitespace, 66 bytes

[S S S N
_Push_0][N
S S N
_Create_Label_LOOP][S N
S _Dupe_0][S N
S _Dupe_0][S N
S _Dupe_0][T    N
T   T   _Read_STDIN_as_integer][T   T   T   _Retrieve_integer][T    S S T   _Subtract][N
T   T   S N
_If_negative_Jump_to_Label_FIRST_TRUTHY][S S S N
_Push_0][T  N
S T _Print_as_integer][N
S N
N
_Jump_to_Label_LOOP][N
S S S N
_Create_Label_FIRST_TRUTHY][S S S T N
_Push_1][S N
S _Dupe_1][T    N
S T _Print_as_integer][N
S N
N
_Jump_to_Label_LOOP]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Try it online (with raw spaces, tabs and new-lines only).

The input is newline separated, and the output is all joined together. If this is not allowed, it's 80 bytes (both newline separated) or 82 bytes (both joined together) instead.
Uses 1 for truthy and 0 for falsey.

Explanation in pseudo-code:

Integer flag = 0
Start LOOP:
  Integer input = STDIN as integer
  If(flag - input < 0):
     Jump to Label FIRST_TRUTHY
  Print 0 as integer to STDOUT
  Go to next iteration of LOOP

FIRST_TRUTHY:
  flag = 1
  Print 1 as integer to STDOUT
  Go to next iteration of LOOP
\$\endgroup\$
0
\$\begingroup\$

Kotlin, 31 bytes

{List(size){it==indexOf(true)}}

{                             }  // lambda; input is `this`
 List(    )                      // build new list
      size                       // same size as input
           {                 }   // based on lambda
            it==                 // index of this element equal to
                indexOf(true)    // index of first true in input

To actually solve this challenge you only need to know two things about the input:

  • its length
  • where the first true is.

The shotgun approach of just generating a new list worked out best here.

Try it online!

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

Io, 38 bytes

method(x,x map(i,v,i==x indexOf(1<2)))

Try it online!

Explanation

method(x, // Take an operand x
    x map(i,v, // Map every item with index/value
        i==    // Is the index equal to
        x indexOf(1<2) // the index of true in x?
    )
)
\$\endgroup\$
0
\$\begingroup\$

Processing.js (Khanacademy version), 67 bytes

var a=[];for(var i=0;i<a.length;i++){if(i!==0){a[i]=0;}}print(a);

A is the input (khanacademy version of processing has no real input method)

The output is printed to console. Truth = 1, false = 0;

Try it online!

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

sed, 8 bytes

0,/./!c

Try it online!

Note the trailing linefeed.

Inputs are linefeed separated. Any single character is truthy (I used 1) and an empty line is falsey.

Input should not have a trailing linefeed, as that will be interpreted as an extra falsey value. Note that TIO adds a final linefeed, and thus a falsey value, at the end. This is a limitation of TIO, the program works just fine without.

Commented:

0,/./ #Run the following commands from the first line to the first line containing a character
#If we are *not* in the previous range, replace the line with an empty line
!c 

To make it easier to read the output, you can make 0 falsey and replace the program with

0,/1/!c0

at the cost of one byte. Try it online!

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

Vyxal, 3 bytes

¦=*

Try it Online!

Explained

¦=*
¦   # cumulative sum
 =  # equal
  * # multiply bits
\$\endgroup\$
1
  • \$\begingroup\$ ÞU* would also work \$\endgroup\$
    – naffetS
    Oct 12, 2022 at 17:39
0
\$\begingroup\$

BQN, 3 bytes

×⟜∊

Anonymous tacit function; takes and returns a list of 0's and 1's. Try it at BQN online!

Explanation

  ∊  Mark firsts: a list the same length as the argument, containing 1 at the first
     occurrence of each element of the argument and 0 for subsequent occurrences
×⟜  Multiply by the argument, itemwise
\$\endgroup\$
2
  • \$\begingroup\$ Nice. An alternative would be ⊢×∊ right? And makes me wonder why there's no APL answer here: ⊢×≠. Hopefully, we'll be able to write your solution as ≠⍛× soon. \$\endgroup\$
    – Adám
    Oct 12, 2022 at 18:31
  • \$\begingroup\$ Yes; ∊⊸× also works, and × can be replaced with or in any of them. \$\endgroup\$
    – DLosc
    Oct 12, 2022 at 19:12
0
\$\begingroup\$

Go, 129 bytes

func f(i[]int)(o[]int){k:=0
for _,e:=range i{if e>0&&k<1{k=1
o=append(o,1)}else if k>0{o=append(o,0)}else{o=append(o,e)}}
return}

Attempt This Online!

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

x86-64 machine code, 9 bytes

56 59 31 C0 F3 AE F3 AA C3

Try it online!

Following the standard calling convention for Unix-like systems (from the System V AMD64 ABI), this takes in RDI the address of an array of 8-bit integers and its length in RSI, and modifies it in place, taking 0 as a falsy value and any nonzero value as a truthy value.

In assembly:

f:  push rsi; pop rcx   # Put the length into RCX.
    xor eax, eax        # Set EAX to 0. In particular, its low byte AL is 0.
    repe scasb  # Read bytes from the array and compare them with AL,
                #  advancing the pointer and counting down from the length in RCX,
                #  stopping when the comparison result is not equal or RCX is 0.
    rep stosb   # Repeatedly write AL into the array, advancing the pointer,
                #  and counting down RCX, stopping when RCX is 0.
                # This writes 0 into all the remaining places.
    ret         # Return.
\$\endgroup\$
0
\$\begingroup\$

TI-Basic, 7 bytes

Ans and 1=cumSum(Ans

Takes input as Ans (last input value)

demo

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

Thunno 2, 3 bytes

ṡ=&

Attempt This Online!

Explanation

ṡ=&  # Implicit input      ->  [0,1,0,1,0,0,1]
ṡ    # Cumulative sums     ->  [0,1,1,2,2,2,3]
 =   # Check for equality  ->  [1,1,0,0,0,0,0]
  &  # Logical AND         ->  [0,1,0,0,0,0,0]
     # Implicit output
\$\endgroup\$
-1
\$\begingroup\$

PowerShell, 25 bytes

$args|%{$_-and!$f;$f+=$_}

Previous "non legal" version

{$_*!$f;if($_){$f=1}}

Try it online!

The one more version with the same length of 25 bytes

$args|%{!!$f-lt$_;$f+=$_}

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ Is this a legal answer? I am honestly not sure. You cannot run this on its own as a function or program. It is a process scriptblock for the foreach-object cmdlet. I would have expected you to use $args \$\endgroup\$
    – Matt
    May 8, 2017 at 18:34
  • \$\begingroup\$ @Matt I would say no, it's not legal. \$\endgroup\$
    – briantist
    May 9, 2017 at 20:05
  • \$\begingroup\$ @briantist Well that is good then. I don't feel the need to go back to my old answers now. \$\endgroup\$
    – Matt
    May 9, 2017 at 20:06
  • 1
    \$\begingroup\$ @Matt here's the relevant clarification for PowerShell specifically. \$\endgroup\$
    – briantist
    May 9, 2017 at 20:08
1 2
3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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