44
\$\begingroup\$

My mom really wants me to eat broccoli, but I hate it and never want to eat it. Mom wants to trick me so she cuts it into small pieces, puts it in a salad and mixes it. Help me find out if the salad contains broccoli!

Input:

Array of mixed letters of all the ingredients. For a single broccoli ingredient it could be:

[c,o,r,b,l,c,i,o]

Output:

Boolean or other convienient output allowing to distinguish if a salad contains broccoli or not.

Rules:

  • all possible ingredients are onion, broccoli, celery and beans
  • input array is always formed of mixing valid ingredients (meaning that it can be always decoded back to the original ingredients array)
  • input array cannot be decoded into more than one valid ingredient combination
  • each ingredient can occur 0 or more times in the salad

Sample test cases:

true stands for a salad with broccoli

[c,o,r,b,l,c,i,o] //true
[o,b,n,o,i,i,e,l,n,a,o,r,n,s,b,o,c,c] //true
[l,c,b,r,r,o,r,c,i,i,c,o,c,b,o,c,c,b,i,o,l,o,l,o] //true

[] //false
[o,n,i,o,n] //false
[b,n,s,i,a,o,n,b,a,s,e,e,n,o,n] //false
[b,r,o,c,c,o,l,i,e,y,e,r,l,a,e,e,n,s,y] //false
[e,n,s,o,e,n,i,o,a,o,o,e,n,n,e,l,n,l,e,o,e,r,c,l,o,y,i,r,y,r,y,b,e,l,n,n,c,c,r,c,e,y,i,e] //false

This is so the shortest code in bytes wins!

\$\endgroup\$
10
  • \$\begingroup\$ Can we take the input as a string instead of array? \$\endgroup\$ Commented May 13, 2020 at 15:13
  • \$\begingroup\$ @KevinCruijssen yes \$\endgroup\$
    – Elgirhath
    Commented May 13, 2020 at 15:24
  • 3
    \$\begingroup\$ Poor broccoli! I haven't heard anyone who wants to eat it. \$\endgroup\$
    – user92069
    Commented May 14, 2020 at 5:29
  • 6
    \$\begingroup\$ This challenge would have been much more interesting with soya. \$\endgroup\$
    – Wrzlprmft
    Commented May 14, 2020 at 10:31
  • 2
    \$\begingroup\$ @Λ̸̸ Great, now I feel like I'm weird for liking broccoli /: \$\endgroup\$
    – rydwolf
    Commented May 14, 2020 at 21:06

22 Answers 22

39
\$\begingroup\$

Python 2, 34 32 bytes

-2 bytes thanks to @dingledooper

lambda a:cmp(*map(a.count,'bs'))

Try it online!

Returns 1 for true, 0 for false

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

J, 14 bytes

[:=/1#.'cy'=/]

Try it online!

Idea of invariant based on letter counts from mathjunkie's clever answer -- be sure to upvote him.

  • 0 for contains broccoli
  • 1 for not

Tests if the number cs is equal to the number of ys. This will only be true when no broccoli is present.

\$\endgroup\$
16
\$\begingroup\$

perl -ple, 14 bytes

$_=y-y---y-c--

Try it online!

Prints 0 if no broccoli is present, something else if there is.

\$\endgroup\$
2
  • 4
    \$\begingroup\$ How does this work? \$\endgroup\$
    – Wezl
    Commented May 14, 2020 at 15:08
  • 4
    \$\begingroup\$ It counts the number of ys in the string, and subtracts the number of cs. If equal, no broccoli is present. Adding spaces to the code, it reads $_ = y-y-- - y-c--. Using more traditional delimiters, and using the usual name for the operator, this becomes $_ = tr/y// - tr/c//. tr/y// replaces any y in $_ by, well, itself, because the replacement part is empty. But it returns the number of ys replaced, hence, counting the number of ys. tr/c// does the same, but for cs. \$\endgroup\$
    – Abigail
    Commented May 14, 2020 at 21:58
8
\$\begingroup\$

MATLAB/Octave, 26 bytes

@(b)b&&diff(sum(b'=='cl'))

Try it online!

Credit to @mathjunkie's answer for the idea. Interestingly comparing c and l counts also works because celery has one of each, but broccoli has a different number.

MATLAB likes to expand == into 2D arrays if the inputs are vectors in differing orientations. However this doesn't work with empty arrays. Fortunately empty is false in MATLAB and non-empty with any non-zero elements is true, so we can simply use the input as a logical true-false to capture that case.

\$\endgroup\$
1
  • \$\begingroup\$ Have you tried MATL? \$\endgroup\$
    – Wezl
    Commented May 14, 2020 at 14:53
8
\$\begingroup\$

05AB1E, 7 6 bytes

„bsS¢Ë

-1 byte by reversing the output: will output 0 if it contains broccoli and 1 if not.

Try it online or verify all test cases.

6 bytes alternative which outputs 1 if it contains broccoli and 0 if not:

AS¢üÊн

Try it online or verify all test cases.

Explanation:

„bs     # Push string "bs"
   S    # Convert it to a character-list: ["b","s"]
    ¢   # Count each in the (implicit) input
     Ë  # Check if the counts are the same for both letters (1 if truthy; 0 if falsey)
        # (after which it is output implicitly as result)

A       # Push the lowercase alphabet: "abcdefghijklmnopqrstuvwxyz"
 S      # Convert it to a character-list: ["a","b","c",...,"z"]
  ¢     # Count each in the (implicit) input-list
   ü    # For each overlapping pair of counts:
    Ê   #  Check that they are not equal to one another (1 if truthy; 0 if falsey)
     н  # Pop and only leave the first check (for letters 'a' and 'b')
        # (after which it is output implicitly as result)

If the amount of b and s/a are the same, it means the input only contains beans and no broccoli.

\$\endgroup\$
3
  • \$\begingroup\$ Wasn’t an input that includes broccoli, but other invalid salad ingredients supposed to be false? Or did I read that wrong? \$\endgroup\$ Commented May 14, 2020 at 17:49
  • \$\begingroup\$ @brandonscript You've indeed read that correct, but the challenge also states "Boolean or other convienient output allowing to distinguish if a salad contains broccoli or not." So in my top program I output 0 for truthy and 1 for falsey (which is probably why you're your questions is coming from?), and in my bottom answer I output 1 for truthy and 0 for falsey. So broccolieyerlaeensy for example (which contains broccoli as well as some other ingredients) would output 1 in my top program and 0 in my bottom program as falsey result. \$\endgroup\$ Commented May 14, 2020 at 18:23
  • \$\begingroup\$ Ah! Got it. Well done. \$\endgroup\$ Commented May 14, 2020 at 18:24
5
\$\begingroup\$

APL (Dyalog Classic), 19 12 bytes

>/+/↑'cl'=⊂⍞

Try it online!

Note that you have to add ⎕← to the beginning for it to output. Originally created with ngn/apl.

>/+/↑'cl'=⊂⍞
            ⍞ ⍝ get input
     'cl'=⊂   ⍝ make two packed vectors: characters equal to c and l
  +/↑         ⍝ turn into two row matrix and add (to get number of 'c's and 'l's
>/            ⍝ Are there more 'c's than 'l's?

returns broccoli: 1, no broccoli: 0

\$\endgroup\$
6
  • \$\begingroup\$ Turning this into a dfn yields the same bytecount... \$\endgroup\$
    – user92069
    Commented May 14, 2020 at 1:14
  • 1
    \$\begingroup\$ Can you do something like I am doing in terms of checking l and c equality and only summing once? \$\endgroup\$
    – mkst
    Commented May 14, 2020 at 10:06
  • \$\begingroup\$ @streetster I wish I knew how. APL is similar to K but using what you did would cause a length error. I tried to do it with something like ∊(is ⍺ in ⍵) but that can't find the number of times that ⍺ is in ⍵. \$\endgroup\$
    – Wezl
    Commented May 14, 2020 at 14:03
  • \$\begingroup\$ @Λ̸̸ that outputs, but what is it supposed to output? It outputs 1 for ''broccolieyerlaeensy' and 'broccoli'. \$\endgroup\$
    – Wezl
    Commented May 14, 2020 at 15:05
  • \$\begingroup\$ @streetster I managed (with the help of APL Orchard). I needed to add ⊂ but it worked and since I only use input once, I don't need to assign L. Saved 7 bytes. \$\endgroup\$
    – Wezl
    Commented May 14, 2020 at 18:08
5
\$\begingroup\$

JavaScript (ES6),  33  32 bytes

Saved 1 byte by not forcing a Boolean value, as suggested by @SteveBennett

Takes a string and returns undefined (falsy) for a broccoli-free salad (yummy!) or a string (truthy) otherwise (yuck!).

s=>s.split`b`[s.split`s`.length]

Try it online!

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Surely that succeeds for [l,c,b,r,r,o,r,c,i,i,c,o,c,b,o,c,c,b,i,o,l,o,l,o] by chance that this is a triple broccoli salad, and that wouldn't have worked for a double broccoli salad? \$\endgroup\$
    – Neil
    Commented May 13, 2020 at 16:12
  • \$\begingroup\$ @Neil Yes, I was just (slowly) figuring it out. :-( Now fixed. \$\endgroup\$
    – Arnauld
    Commented May 13, 2020 at 16:18
  • \$\begingroup\$ Is the ! really required? The problem isn't strict on the output, so you would just be returning truthy for broccoli, or falsy (undefined) without. \$\endgroup\$ Commented May 18, 2020 at 9:11
  • \$\begingroup\$ @SteveBennett I guess you're right. Thank you! \$\endgroup\$
    – Arnauld
    Commented May 18, 2020 at 9:17
  • \$\begingroup\$ Btw I really love this double split solution. So elegant. \$\endgroup\$ Commented May 19, 2020 at 1:07
4
\$\begingroup\$

Charcoal, 7 bytes

›№θb№θs

Try it online! Link is to verbose version of code. Outputs a Charcoal boolean; - for broccoli, nothing for none. Explanation:

 №θb    Number of `b`s in input
›       Exceeeds
    №θs Number of `s`s in input
        Implicitly print
\$\endgroup\$
4
\$\begingroup\$

JavaScript (SpiderMonkey), 32 bytes

s=>s.map(c=>++this[c],r=y=0)|r>y

Try it online!

JavaScript (Node.js), 37 bytes

s=>s.map(c=>n+=~~{r:1,y:-1}[c],n=0)|n

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ I think there might be a similar formula that works with < and > instead of ==, but I haven't checked \$\endgroup\$ Commented May 13, 2020 at 16:10
  • \$\begingroup\$ @mypronounismonicareinstate Yes it saves a byte, but should not be two \$\endgroup\$
    – l4m2
    Commented May 13, 2020 at 16:26
  • \$\begingroup\$ For anyone else mystified by this like I was: ++this[foo] is the same as ++foo but doesn't throw if foo isn't defined. r and y are just being set to zero in a convenient location - the fact that they're passed to map is conveniently irrelevant. Overall the code is just counting if there are more rs than ys \$\endgroup\$ Commented May 18, 2020 at 9:08
4
\$\begingroup\$

K (oK), 11 bytes

Solution:

</+/"sb"=/:

Try it online!

Explanation:

Shamelessly stolen "more s' than b's" logic from mathjunkie:

</+/"sb"=/: / the solution
    "sb"=/: / "sb" equal (=) each-right (/:)
  +/        / sum
</          / s less than b? (aka no brocoli?)
\$\endgroup\$
1
  • 1
    \$\begingroup\$ You beat me by one because you have each-right. Is that in APL? Also just realized that my new code is very similar to your code (I didn't try to copy). \$\endgroup\$
    – Wezl
    Commented May 14, 2020 at 18:16
4
\$\begingroup\$

Zsh, 22 characters

((${#1//a}==${#1//b}))

Expects the ingredients as a single command line parameter.
Sets the exit code to 1 for broccoli alert and 0 for no broccoli.

(Just to keep the exit code semantics of 0 = Ok / non-0 = error. Using < for comparison would save 1 character but reverse the result's encoding.)

Sample run:

manatwork@manatwork ~ % . ./broccoli-detector.zsh obnoiielnaornsbocc
manatwork@manatwork ~ % echo $?
1
manatwork@manatwork ~ % . ./broccoli-detector.zsh broccolieyerlaeensy
manatwork@manatwork ~ % echo $?                                      
0

Try it online! / Try all test cases online!

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

Retina 0.8.2, 18 bytes

+`[^bs]|bs|sb

1`b

Try it online! Link includes test cases. Explanation:

+`[^bs]|bs|sb

Delete everything that's not a b or an s, plus any remaining bs or sb pairs that result from bean salad.

1`b

Check whether there is any broccoli.

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

Jelly,  7  6 bytes

ċⱮ⁾abE

A monadic Link accepting a list of characters which yields 0 if the salad contains broccoli and 1 if not.

Try it online! Or see the test-suite.

How?

Tests whether the number of 'b's (in both 'broccoli' & 'beans') is equal to the number of 'a's (in only 'beans').

ċⱮ⁾abE - Link: list
 Ɱ     - map across...
  ⁾ab  - ...what: list of characters = ['a', 'b']
ċ      - ...applying: count
     E - all equal?
\$\endgroup\$
3
\$\begingroup\$

Java (JDK), 41 bytes

s->s.reduce(0,(a,c)->c<98?a-1:c<99?a+1:a)

Try it online!

Uses a chars()-Stream as input, returns any strictly positive value if it contains brocoli.

Credits

  • -5 bytes thanks to Elgirhath by comparing b to a instead of b to s, and by allowing any positive value instead of a strict boolean.
\$\endgroup\$
1
  • \$\begingroup\$ -3 bytes. Also you probably don't need last >0 if you specify what given output means ;) \$\endgroup\$
    – Elgirhath
    Commented May 14, 2020 at 13:15
3
\$\begingroup\$

asm2bf, 73 bytes

Try it online!

Takes input on stdin as a string; outputs either ASCII(0x00) or ASCII(0x01).

@l
in r1
ceqr1,.b
cadr2,1
ceqr1,.s
cadr3,1
jnzr1,1
gt r2,r3
outr2

Commented code:

; Essentially, our game plan is to compare amount of `b' and `s' occurences.
; Start a new label
@loop
; Read a character from stdin, put it in r1.
  in r1
; If r1 = 'b' (note the way of expressing a character constant), set
; the condition flag.
  ceq r1,.b
; If the condition flag is set, add 1 to r2
  cadd r2,1
; If r1 = 's', set the condition flag. Otherwise, clear it.
  ceq r1,.s
; If the condition flag is set, add 1 to r3
  cadd r3,1
; If r1 is bigger than zero, we didn't hit eof yet, so continue reading.
; Note: The golfed version is based on a certain property beyond explaining.
; It's related to the way how labels work under the hood.
  jnz r1,%l
; The loop finished.
; Compare r2 and r3 (the accumulators).
gt r2,r3
; Display the result
out r2
\$\endgroup\$
2
\$\begingroup\$

Japt, 6 bytes

Takes input as a string with reversed output.

èÕ¶Uèc

Try it - includes all test cases, footer negates the output for easier testing

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

C# (Visual C# Interactive Compiler), 39 bytes

i=>i.Count(x=>x==98)>i.Count(x=>x=='s')

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ -2 by comparing b and a Try it online! \$\endgroup\$
    – Elgirhath
    Commented May 14, 2020 at 11:25
  • \$\begingroup\$ 29 bytes Try it online!. Outputs 0 for no broccoli and positive integer otherwise \$\endgroup\$
    – Elgirhath
    Commented May 14, 2020 at 12:52
  • 1
    \$\begingroup\$ 27 bytes \$\endgroup\$
    – Elgirhath
    Commented May 14, 2020 at 13:05
1
\$\begingroup\$

C (gcc), 57 \$\cdots\$ 53 52 bytes

Saved 3 bytes thanks to l4m2!!!

Saved a byte thanks to Arnauld!!!

a;f(char*s){for(a=0;*s;++s)a+=*s-99?*s>120:-1;a=!a;}

Try it online!

Takes a string as input and returns a \$1\$ for edible and a \$0\$ for grossing me out!

\$\endgroup\$
6
  • \$\begingroup\$ You don't need to initalize a and b to zero so long as they are equal \$\endgroup\$
    – l4m2
    Commented May 13, 2020 at 16:48
  • \$\begingroup\$ but better is save a variable using ++ and -- \$\endgroup\$
    – l4m2
    Commented May 13, 2020 at 16:49
  • \$\begingroup\$ @l4m2 Have to init them or they'd be set to however they were left last run. But using one variable is better anyway - thanks! :-) \$\endgroup\$
    – Noodle9
    Commented May 13, 2020 at 17:13
  • \$\begingroup\$ @l4m2 Ah, could set one to the other! Clever except could overflow to a negative after many runs. \$\endgroup\$
    – Noodle9
    Commented May 13, 2020 at 17:22
  • \$\begingroup\$ 52 bytes by counting c vs y instead. The result is inverted. \$\endgroup\$
    – Arnauld
    Commented May 13, 2020 at 17:58
1
\$\begingroup\$

PHP, 44 42 bytes

-2 bytes thanks to @Elgirhath

$b=count_chars($a,1);echo+($b[98]>$b[97]);

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ great answer! I don't really know PHP but it seems that you can change != to < and 115 ('s') to 97 ('a') for -2 bytes ;) \$\endgroup\$
    – Elgirhath
    Commented May 14, 2020 at 21:00
1
\$\begingroup\$

Javascript, 46 characters

Shortening Yaraslav's answer:

s=>(q=z=>s.filter(e=>e==z).length)('b')>q('s')

Javascript, 62 characters

x=>([,a,b]=/(a*)(b*)/.exec(x.sort().join``),b.length>a.length)

Maybe I missed something? Just counts if there are more b than a.

\$\endgroup\$
1
  • \$\begingroup\$ Cool!!! Nice code! \$\endgroup\$ Commented May 18, 2020 at 21:36
1
\$\begingroup\$

Google Sheets, 34 33 bytes

Saved 1 byte thanks to Steve Bennett

=CountIf(A:A,"b")>CountIf(A:A,"s"

Input is in column A. When you exit the cell, Sheets will automatically add the trailing parentheses.

There's nothing really clever about this solution besides implementing the concept from others.

enter image description here

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can save a byte by replacing <> with >. It will never be less than. \$\endgroup\$ Commented May 20, 2020 at 1:09
0
\$\begingroup\$

JavaScript (Node.js), 62 bytes

s=>s.filter(e=>e=='b').map(Date)>s.filter(e=>e=='s').map(Date)

Try it online!

JavaScript (Node.js), 56 bytes

s=>s.filter(e=>e=='b').length>s.filter(e=>e=='s').length

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ How does this solution work..? \$\endgroup\$
    – RGS
    Commented May 16, 2020 at 10:59
  • \$\begingroup\$ Ah yes, I had the same idea, but yours is shorter. \$\endgroup\$ Commented May 18, 2020 at 8:16

Your Answer

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

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