15
\$\begingroup\$

I don't know about you all but I'm not preparing for Halloween––never did never will––but, my neighbor is, so we'll help her out.

She needs help figuring out which brand of candy she has, but she has so much candy she would not be able to finish before Halloween.

She has:

  • Snickers
  • KitKat
  • Starburst
  • GummyBears
  • Twix

Input

A multiline string (or any other reasonable form) containing only letters and spaces.

Output

A falsy value if it is not a valid candy, or which candy it is if it is a candy.

How to decide which candy it is

A candy is valid if it says one of the above brands on it. However, it's not that simple, because this is a valid candy:

K i t
       K a
           t

A valid candy is one where:

  • the letters are in order from left to right
  • the letters are capitalized correctly
  • the letters, going from left to right, do not both ascend and descend
  • the letters with whitespace removed form one of the above brands

This is , so shortest code in byte wins!

Examples

Truthys:

1.
              kers
           c
        i
       n
    S    

2.
  Kit K a t

3. 
St a
    r b u
         r st 

4.
         Bear s
G ummy

5.
T w i
                          x

Falsys:

1.
SNICKERS

2.
 C   n

   a   d y

3. 
xiwT

4.
S C I
       ss o
              r       s

5.
Kit
Kat
\$\endgroup\$
11
  • \$\begingroup\$ Can the input be padded with spaces? \$\endgroup\$
    – xenia
    Commented Oct 22, 2016 at 20:19
  • \$\begingroup\$ Also, does throwing an error count as returning a falsely value? \$\endgroup\$
    – xenia
    Commented Oct 22, 2016 at 20:27
  • \$\begingroup\$ @Loovjo, yes and yes \$\endgroup\$
    – Daniel
    Commented Oct 22, 2016 at 20:27
  • \$\begingroup\$ Can we assume no blank lines? \$\endgroup\$
    – anonymous2
    Commented Oct 23, 2016 at 3:03
  • \$\begingroup\$ @anonymous2, the input will not be empty \$\endgroup\$
    – Daniel
    Commented Oct 23, 2016 at 3:03

6 Answers 6

1
\$\begingroup\$

JavaScript (ES6), 221 218 216 212 208 205 201 bytes

f=a=>(c=d=L=0,e=1,s=[],[...a].map(a=>a=='\n'?c=L=0:c++-(a!=' '&&(s[c]?e=0:(!L&&(d?d-1?e&=c>Q>d-3:d=c>Q>2:d=1),L=s[Q=c]=a)))),e&&'Snickers0KitKat0Starburst0GummyBears0Twix'.split(0).indexOf(s.join``)+1)

Try it here.

\$\endgroup\$
7
  • \$\begingroup\$ Welcome to PPCG, and great first answer! Unfortunately, I don't believe this is valid; it returns a truthy value for Snick, ears|T, etc. I think you can fix this by adding .split('|') before .indexOf. \$\endgroup\$ Commented Oct 23, 2016 at 0:17
  • \$\begingroup\$ This is valid now. \$\endgroup\$
    – Oliver Ni
    Commented Oct 23, 2016 at 0:29
  • \$\begingroup\$ @ETHproductions. The ears|T is not the problem because only letters are allowed in test cases. However, you are right, for Snick. \$\endgroup\$
    – sbisit
    Commented Oct 23, 2016 at 0:29
  • \$\begingroup\$ Use this for -2 \$\endgroup\$
    – jrich
    Commented Oct 23, 2016 at 1:44
  • \$\begingroup\$ You can also use this trick to save several bytes. \$\endgroup\$ Commented Oct 23, 2016 at 2:09
1
\$\begingroup\$

Racket 446 bytes

(let((lr list-ref)(ls list-set)(sl string-length)(ss substring)(l(string-split s "\n")))(let loop((changed #f))(for((i(sub1(length l))))
(let*((s(lr l i))(r(lr l(add1 i)))(n(sl s))(m(sl r)))(when(> n m)(set! l(ls l i(ss s 0 m)))(set! l(ls l(add1 i)
(string-append r(ss s m n))))(set! changed #t))))(if changed(loop #f)(begin(let*((l(for/list((i l))(string-trim i)))(l(string-join l))
(l(string-replace l " " "")))(ormap(λ(x)(equal? x l))cl))))))

Ungolfed:

(define (f s cl)
  (let ((lr list-ref)
        (ls list-set)
        (sl string-length)
        (ss substring)
        (l (string-split s "\n")))
    (let loop ((changed #f))
      (for ((i (sub1 (length l))))
        (let* ((s (lr l i))
               (r (lr l (add1 i)))
               (n (sl s))
               (m (sl r)))
               (when (> n m)
                 (set! l (ls l i (ss s 0 m)))
                 (set! l (ls l (add1 i)(string-append r (ss s m n))))
                 (set! changed #t))))
        (if changed (loop #f)
            (begin
              (let* ((l (for/list ((i l))
                          (string-trim i)))
                     (l (string-join l))
                     (l (string-replace l " " "")))
                (ormap (λ(x) (equal? x l)) cl)))
            ))))

Testing:

(f "
              kers
           c
        i
       n
    S"
   (list "Snickers""KitKat""Starburst""GummyBears""Twix"))


(f "  Kit K a t"
   (list "Snickers""KitKat""Starburst""GummyBears""Twix"))

(f "St a
    r b u
         r st "
   (list "Snickers""KitKat""Starburst""GummyBears""Twix"))

(f "         Bear s
G ummy"
   (list "Snickers""KitKat""Starburst""GummyBears""Twix"))

(f "T w i
                          x"
   (list "Snickers""KitKat""Starburst""GummyBears""Twix"))

(f "SNICKERS"
   (list "Snickers""KitKat""Starburst""GummyBears""Twix"))
(f " C   n
          y
   a   d"
   (list "Snickers""KitKat""Starburst""GummyBears""Twix"))

(f "xiwT"
   (list "Snickers""KitKat""Starburst""GummyBears""Twix"))

(f "S C I
       ss o
              r       s"
   (list "Snickers""KitKat""Starburst""GummyBears""Twix"))

(f "Kit
Kat"
   (list "Snickers""KitKat""Starburst""GummyBears""Twix"))

Output:

#t
#t
#t
#t
#t
#f
#f
#f
#f
#t
\$\endgroup\$
2
  • \$\begingroup\$ I think you named your output "Ungolfed" \$\endgroup\$ Commented Oct 23, 2016 at 7:09
  • \$\begingroup\$ Yes. I have corrected the mistake. Thanks. \$\endgroup\$
    – rnso
    Commented Oct 23, 2016 at 7:15
1
\$\begingroup\$

JavaScript (ES6), 139 bytes

a=>/^(Snickers|KitKat|Starburst|GummyBears|Twix)$/.test(a.reduce((s,t)=>s.replace(/./g,(c,i)=>c<'!'?t[i]:t[i]<'!'?c:'!')).replace(/ /g,''))

Accepts input as an array of space-padded strings.

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

Pyth - 72 bytes

I hope I caught all the edge cases. Will base compress candy list.

&sSIM_Bmxdh-d;fnd{TK.tQd}-sKdc"Snickers KitKat Starburst GummyBears Twix

Test Suite.

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

R, 199 chars

function(M){if(any(outer(z<-diff(apply(M,1,function(r)which.min(r==" ")))),z<0))return(F);C=c("Twix","KitKat","Starburst","Snickers","GummyBears");C[match(paste0(gsub(" ","",c(t(M))),collapse=""),C)}

Input is in the form of a character matrix.

match takes care of which candy it is (it checks capitalisation too).

To check that the letters are an "ascending" or "descending" sequence, we just need to check that the locations of the first non-space character (if there) in each row is increasing or decreasing. To do, this we

  • take the first location of a nonspace character in each row, using apply
  • take the diff. This might have some zero in it, otherwise should either be all positive or all negative
  • name the diff z, and take the outer product with itself. If the diff had mixed positive and negative entries, there will be a negative entry somewhere in its outer product. If so, return FALSE.

Note that cases like

"    i "
"   w x"
"  T   "

will return an empty character vector (in particular not "Twix"), since match will be trying to match "Twxi".

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

Python 2.7, 254 bytes

I'm sure this can be golfed more. Input is an array of lines s.

x=len
p=lambda a:x(a)-x(a.lstrip())
g=sorted
a=map(p,l)
j=''.join
z=[i.replace(' ','')for i in l]
if g(a)==a:q=j(z)
elif g(a)==a[::-1]:q=j(z[::-1])
else:q=''
if x(set(a))<x(a):q=''
print 1if q in('Snickers','KitKat','Starburst','GummyBears','Twix')else 0

Try it here!

\$\endgroup\$
1
  • \$\begingroup\$ You can take the input as a string array/list, so there is no need to split it in the first line of your code. \$\endgroup\$
    – Daniel
    Commented Oct 24, 2016 at 11:41

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.