21
\$\begingroup\$

Disclaimer: the content of this post is not medical information and should not be used for any medical purpose, as it is deliberately oversimplified for the purpose of the challenge.

There are several different strains of Neisseria meningitidis, the bacterium that causes meningococcal meningitis. Vaccines are available for strains A, B, C, W, and Y. They are available in three combinations.

The first is the quadrivalent meningococcal ACWY vaccine. As the name implies, this protects against strains A, C, W, and Y, but not B.

The second is the meningococcal B vaccine, which protects only against strain B.

The third is the pentavalent meningococcal ABCWY vaccine, which combines ACWY and B to protect against all five strains. Receiving the ABCWY vaccine is equivalent to receiving ACWY and B simultaneously.

However, while only one dose of ACWY is needed for full vaccination (we're ignoring boosters), two doses of B are needed. ABCWY counts as one dose of ACWY and one dose of B.

Write a program or function that accepts either an array of strings, or several strings delimited by a string of your choice. (The empty string is an acceptable delimiter; i.e., you may accept the strings run together.) These strings will be from the set ACWY, B, and ABCWY. Return or print ACWY if at least one dose of ACWY has been given but zero or one doses of B have been given, B if at least two doses of B but no doses of ACWY have been given, and ABCWY if at least one dose of ACWY and at least two doses of B have been given. If neither vaccine has been fully received, output the empty string. "Overvaccination" is allowed; ABCWY ABCWY ACWY should become ABCWY. You do not have to support invalid inputs.

Input Output
ABCWY B ABCWY
ABCWY ACWY
B [empty string]
B B B
ACWY B B ABCWY
ACWY B ACWY
\$\endgroup\$
8
  • 13
    \$\begingroup\$ Thank you for reminding me to schedule my second Men B dose :p \$\endgroup\$ Dec 18, 2023 at 19:14
  • \$\begingroup\$ Can we take a single string with no delimiters? \$\endgroup\$ Dec 18, 2023 at 19:33
  • 1
    \$\begingroup\$ Am I correct to assume that we don't have to care about "improper" inputs such as AWY B (missing C in ACWY)? \$\endgroup\$
    – Stef
    Dec 19, 2023 at 12:48
  • 1
    \$\begingroup\$ You've reminded me that I got my first B dose 5 years ago and never went back for the second... maybe I'll go schedule one too \$\endgroup\$
    – Esther
    Dec 20, 2023 at 18:32
  • 1
    \$\begingroup\$ I did not expect this site to send me to a Google search for this vaccine in France. Apparently it is not recommended here for adults (it is only in specific situations). It looks like that it elsewhere though - interesting. \$\endgroup\$
    – WoJ
    Dec 21, 2023 at 17:50

18 Answers 18

7
\$\begingroup\$

Perl 5 -p, 28 bytes

$_=A x/A/.B x/B.*B/.CWY x/A/

Try it online!

\$\endgroup\$
7
\$\begingroup\$

Google Sheets, 64 bytes

=join(,ifna(filter({"A","B","CWY"},search({"A","B*B","A"},A1))))

Put the input in cell A1 and the formula in cell B1.

Uses the search() with * wildcard method of JvdV's Excel answer.

The same can be done without arrays using simple string concatenation and regexes (81 bytes):

=let(a,regexmatch(A1,"A"),if(a,"A",)&if(regexmatch(A1,"B.*B"),"B",)&if(a,"CWY",)

Implementation of the same in JavaScript (62 bytes):

t=>(a=/A/.test(t)?'A':'')+(/B.*B/.test(t)?'B':'')+(a?'CWY':'')

(-4 bytes thanks to noodle man)

\$\endgroup\$
6
  • \$\begingroup\$ the JS can be 62 bytes t=>(a=/A/.test(t)?'A':_='')+(/B.*B/.test(t)?'B':_)+(a?'CWY':_) \$\endgroup\$
    – noodle man
    Dec 18, 2023 at 18:45
  • \$\begingroup\$ @noodleman thanks. \$\endgroup\$ Dec 18, 2023 at 21:54
  • \$\begingroup\$ Port of my Excel answer for 70 bytes: =INDEX(JOIN(,REPT({"A","B","CWY"},COUNTIF(A1,{"*A*","*B*B*","*A*"})))). This can probably be shortened a bit? \$\endgroup\$
    – JvdV
    Dec 20, 2023 at 14:50
  • 1
    \$\begingroup\$ @JvdV thanks. Your mid() works out shorter still. \$\endgroup\$ Dec 20, 2023 at 22:06
  • 1
    \$\begingroup\$ @JvdV thanks. The arrays can be horizontal which is easier on the eye. \$\endgroup\$ Dec 21, 2023 at 8:07
6
\$\begingroup\$

Jelly, 6 bytes

œ-”BQṢ

Try it online!

A monadic link taking a string with no delimiter and returning a string.

Explanation

œ-”B   | Set difference with "B"
    Q  | Uniquify
     Ṣ | Sort
\$\endgroup\$
2
  • 1
    \$\begingroup\$ I see that you beat me to thinking of using the multiset difference atom, I have noted that in mine now linking here :) \$\endgroup\$ Dec 18, 2023 at 19:49
  • \$\begingroup\$ @JonathanAllan thanks! Our original posts were only three minutes apart I think \$\endgroup\$ Dec 18, 2023 at 20:35
4
\$\begingroup\$

Python 3.8 (pre-release), 54 bytes

lambda s:"A"*(x:="C"in s)+"B"*(s.count("B")>1)+"CWY"*x

Try it online!

Python 3, 59 bytes

def f(s):x="C"in s;return"A"*x+"B"*(s.count("B")>1)+"CWY"*x

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Why specify "pre-release" for the 3.8 version? 3.8 has been out for years. Also, just writing out ("C"in s) longhand and using otherwise the same lambda works in older Python 3 (and at least 2.7, probably much earlier) and is also 59 bytes. \$\endgroup\$ Dec 20, 2023 at 22:44
  • \$\begingroup\$ The walrus operator in 3.8+ makes it a little shorter, but not backwards compatible, plus the formatting is just copied from TIO which specifies 3.8 as a pre-release. And yeah the lambda written out is the same length, but I like that it's the concept in both of my entries... I'm sure someone on here can do better tho \$\endgroup\$ Dec 22, 2023 at 0:19
4
\$\begingroup\$

Nekomata, 6 bytes

"B"∕uo

Attempt This Online!

A port of @Nick Kennedy's Jelly answer.

"B"∕uo
"B"∕    Set difference with "B"
    u   Uniquify
     o  Sort
\$\endgroup\$
4
\$\begingroup\$

JavaScript (ES6), 55 / 48 / 41 bytes

Expects a space-separated string.

s=>[...new Set(s.replace("B",""))].sort().join``.trim()

Try it online!

Or 48 bytes if we take a string with no delimiter.

Or 41 bytes if we return an array.

Method

Given the input string, e.g. "ABCWY ACWY B":

  • remove the first "B" → "ACWY ACWY B"
  • turn the string into a set → Set { 'A','C','W','Y',' ','B' }
  • turn the set into an array → [ 'A','C','W','Y',' ','B' ]
  • sort it in lexicographical order → [ ' ','A','B','C','W','Y' ]
  • turn it back into a string → " ABCWY"
  • remove the leading space, if any → "ABCWY"
\$\endgroup\$
2
  • \$\begingroup\$ You can save 7 bytes, if you take the input delimited by the empty string and remove the .trim() \$\endgroup\$ Dec 20, 2023 at 7:23
  • \$\begingroup\$ @JeanotZubler Thank you for pointing that out. I didn't notice the empty delimiter was allowed. \$\endgroup\$
    – Arnauld
    Dec 20, 2023 at 8:14
3
\$\begingroup\$

Retina 0.8.2, 16 bytes

\W

1`B

O`.
D`.

Try it online! Link includes test cases. Accepts any non-\w characters as a delimiter. Explanation:

\W

Join the words together.

1`B

Delete the first B, if any.

O`.

Sort the letters.

D`.

Deduplicate the letters.

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

Bash + core utilities, 37 bytes

sed s/B//|grep -o .|sort -u|tr -d \\n

Explanation

sed s/B// | # remove the first occurrence of B
grep -o . | # insert a newline after every character
sort -u   | # sort lines and remove duplicates
tr -d \\n | # remove newlines inserted for sorting
\$\endgroup\$
2
\$\begingroup\$

Jelly,  8  7 bytes

Note while I did eventually think of using œ- to avoid a byte, I now see that Nick Kennedy actually got there first!

Fœ-”BQṢ

A monadic Link that accepts a list of lists of characters (the vaccines) and yields a list of characters (the fully vaccinated).

Try it online! Or see the test-suite.

How?

Fœ-”BQṢ - Link: list of strings (from "B", "ACWY", "ABCWY"), Vaccinations
F       - flatten
 œ-”B   - multiset difference with 'B'
     Q  - deduplicate
      Ṣ - sort

Alternative TIO:

Taking a non [A-Z] separating string (like " " or ", ", etc):

œ-”BØAf
œ-”B     - multiset difference with 'B'
    ØAf  - "ABC...XYZ" filter keep
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 6 bytes

'Bõ.;ê

Port of @NickKennedy's Jelly answer.

Try it online or verify all test cases.

Explanation:

   .;   # In the (implicit) input-string, replace the first
'B     '# "B"
  õ     # with an empty string ""
     ê  # Then sort and uniquify the characters of the string
        # (which is output implicitly)
\$\endgroup\$
2
\$\begingroup\$

Excel ms365, 6463 bytes

New:

=CONCAT(IFERROR(MID(A1,SEARCH({"A","B*B","C"},A1),{1,1,3}),""))

Old:

=CONCAT(REPT({"A","B","CWY"},COUNTIF(A1,{"*A*","*B*B*","*A*"})))
\$\endgroup\$
2
\$\begingroup\$

Python, 50 bytes

lambda s:''.join(sorted(set(s.replace('B','',1))))

Another port of @NickKennedy's answer, approximately. Python doesn't have a built-in multiset or corresponding set-difference operator; it does have collections.Counter, but that takes way too much setup. Instead, I just remove up to one B from the input before uniquifying and sorting (and producing a string from the resulting list). This works in both Python 2 and Python 3. The count argument for the replace method of strings is not commonly discussed, but it's clearly documented.

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

Ruby, 26 bytes

->s{s.sub(?B,'').chars|[]}

Try it online!

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

JavaScript (Node.js), 44 bytes

s=>s.sort().filter(x=>!~(s[x]=~-s[x]),s.B=1)

Try it online!

JavaScript (Node.js), 49 bytes

s=>[...'ABCWY'].filter(x=>s.split(x)[x=='B'?2:1])

Try it online!

+4 bytes if a trailing delimited is not allowed.

Worse than Arnauld's solution (41, if it use no delimit and output array)

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

Charcoal, 9 bytes

Φα›№θι⁼κ¹

Try it online! Link is to verbose version of code. Accepts any character that's not an uppercase letter as a delimiter (some characters may need extra quoting). Explanation:

 α          Predefined variable uppercase alphabet
Φ           Filtered where
   №        Count of
     ι      Current letter
    θ       In input string
  ›         Is greater than
       κ    Current index
      ⁼     Equals
        ¹   Literal integer `1`
            Implicitly print
\$\endgroup\$
1
\$\begingroup\$

APL(Dyalog Unicode), 1715 bytes SBCS

⎕A∩⊢(/⍨)≠⍲'B'=⊢

Try it on APLgolf!

A tacit function which takes a string on the right using no delimiter or any delimiter that is not a capital letter. The test cases use spaces. (The test case B is written as (⍬,'B') because single characters in quotes are not treated as strings in APL)

⎕A∩⊢(/⍨)≠⍲'B'=⊢­⁡​‎‎⁡⁠⁣⁣‏⁠‎⁡⁠⁣⁤‏⁠‎⁡⁠⁤⁡‏⁠‎⁡⁠⁤⁢‏⁠‎⁡⁠⁤⁣‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁣⁢‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁣⁡‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁤‏⁠‎⁡⁠⁢⁡‏⁠‎⁡⁠⁢⁢‏⁠‎⁡⁠⁢⁣‏⁠‎⁡⁠⁢⁤‏‏​⁡⁠⁡‌⁢⁡​‎‎⁡⁠⁣‏‏​⁡⁠⁡‌⁢⁢​‎‎⁡⁠⁡‏⁠‎⁡⁠⁢‏‏​⁡⁠⁡‌­
          'B'=⊢  # ‎⁡Boolean mask for all Bs
         ⍲       # ‎⁢NAND
        ≠        # ‎⁣Boolean mask for all first instances
   ⊢(/⍨)         # ‎⁤apply Boolean mask (removes first B)
  ∩              # ‎⁢⁡intersection
⎕A               # ‎⁢⁢capital letter alphabet
💎

Created with the help of Luminespire.

Taking the intersection with the alphabet helpfully removes any delimiters and sorts alphabetically.

This solution doesn't work on any of the APL versions on TIO, as @att describes.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ as unique mask was added in 18.0, which postdates the 17.1 on tio \$\endgroup\$
    – att
    Dec 19, 2023 at 9:28
1
\$\begingroup\$

Uiua 0.8.0, 13 bytes SBCS

⊏⍏.⊝▽≠⇡⧻,⊗@B.

Try on Uiua Pad!

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

Scala, 115 bytes

A Port of @spooky_simon's Python answer in Scala.


Golfed version. Attempt This Online!

def g(x:Boolean)=if(x)1 else 0
def f(s:String)={val x=s.contains("C");"A"*g(x)+"B"*g(s.count(_=='B')>1)+"CWY"*g(x)}

Ungolfed version. Attempt This Online!

object Main {
  def main(args: Array[String]): Unit = {
    def f(s: String): String = {
      val hasC = s.contains("C")
      val bCount = s.count(_ == 'B') > 1

      ("A" * (if (hasC) 1 else 0)) +
      ("B" * (if (bCount) 1 else 0)) +
      ("CWY" * (if (hasC) 1 else 0))
    }

    println(f("ABCWY B"))
    println(f("ABCWY"))
    println(f("B"))
    println(f("B B"))
    println(f("ACWY B B"))
    println(f("ACWY B"))
  }
}
\$\endgroup\$

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.