[Question]
  [
Some versions of the standard Android calculator app allow you to press a key, like 'sin' and then the 'del' key to make it 'si'. Probably just a bug which they can't be bothered with removing.
[![Screenshot of Android calculator](https://i.stack.imgur.com/EyDGLl.jpg)](https://i.stack.imgur.com/EyDGLl.jpg)
The following letters/letter groupings are typable:
```
 
sin
si
s
cos
co
c
tan
ta
t
ln
l
log
lo
e
```
So, 'tasteless' is typable, because ta-s-t-e-l-e-s-s and so is 'clogs' because 'c-log-s'. However 'got' is not typable, neither is 'an' or 'xyz'.
Write a program that takes a single word (or sequence of letters, only a-z in input) as input and produces output to indicate if a word is typable or not.
Output may be a single character/letter/digit/etc. or it may be larger. All typable words should produce the same output. All non-typable words should also produce the same output.
P.S. Just out of curiosity, is 'tasteless' the longest dictionary word that is typable?
  
[Answer]
# Perl, ~~47~~ ~~43~~ 41 + 1 = 42 bytes
-4 bytes thanks to @Sunny Pun. -2 bytes thanks to @Brad Gilbert b2gills and @Downgoat
Run with the `-n` flag.
```
say!/^(s(in?)?|co?|t(an?)?|ln?|log?|e)+$/
```
It can definitely be golfed futher, but in the spirit of competition, I'm leaving the mostly-original regex I came up with at the beginning.
Returns nothing if true, `1` if false.
[Try it online!](https://tio.run/nexus/perl#@1@cWKmoH6dRrJGZZ69pX5Ocb19TopEIZufkAXF@un1Nqqa2iv7//yWJJSU5qSWJOanF/3Xz/uv6muoZGBoAAA "Perl – TIO Nexus")
I downloaded a dictionary file, and the longest word I found was 11 letters -- `tattletales`
[Answer]
# JavaScript (ES6), 44 bytes
```
s=>/^((si|ta|l)n?|co?|log?|[ste])+$/.test(s)
```
I *think* this is the shortest regex possible, but of course I may be wrong.
### Explanation
An obvious first place to start would be a regex that simply includes all options separately:
```
s=>/^(sin|si|s|cos|co|c|tan|ta|t|log|lo|l|ln|e)+$/.test(s)
```
First, we can observe that `cos` can be formed from `co` and `s`, making it unnecessary:
```
s=>/^(sin|si|s|co|c|tan|ta|t|log|lo|l|ln|e)+$/.test(s)
```
Some of these, such as `sin` and `si`, can be combined by making the last letter optional:
```
s=>/^(sin?|s|co?|tan?|t|log?|ln?|e)+$/.test(s)
```
This works because `sin?` matches `si` with or without an `n` on the end, thus covering both `sin` and `si`.
There seems to be a lot of `n?`s as well. What if we put them all together?
```
s=>/^((si|ta|l)n?|s|co?|t|log?|e)+$/.test(s)
```
One more way to golf this would be to combine the remaining single-char options into a character range, but this comes out at the same length:
```
s=>/^((si|ta|l)n?|co?|log?|[ste])+$/.test(s)
```
And that's how you golf a simple regex. I believe this is the shortest possible regex that matches every string correctly, but perhaps not. I will award a **+100 bounty** to anyone who manages to improve upon this regex.
[Answer]
# Pyth, ~~37~~ ~~33~~ ~~29~~ 28 bytes
The code contains an unprintable character, so here is an `xxd` hexdump.
```
00000000: 737d 5173 4d5e 733c 5252 6336 2e22 6174  s}QsM^s<RRc6."at
00000010: 14d0 69ba 76f1 ac59 6422 346c            ..i.v..Yd"4l
```
[Try it online.](https://pyth.herokuapp.com/?code=s%7DQsM%5Es%3CRRc6.%22at%14%C3%90i%C2%BAv%C3%B1%C2%ACYd%224l&input=%22clog%22&debug=1)
~~Extremely~~ Astronomically inefficient. The time and space complexity is ~~O(16n)~~ O(24n).
### Explanation
First, a `Q` is implicitly appended.
```
s}QsM^s<RRc6."…"4lQ     Implicit: Q = input
            ."…"        Generate "logsincostanlnee"
          c6            Split in 6 parts: ["log", "sin", "cos", "tan", "ln", "ee"]
         R      4       For each n from 0 to 3
       <R               Take the first n chars from each string
      s                 Flatten the results
                 lQ     Get length of input
     ^                  Take that Cartesian power of the list
   sM                   Join each resulting list
 }Q                     Check if the input is found
s                       Cast to integer
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~32~~ ~~31~~ ~~30~~ ~~28~~ 26 bytes
```
ŒṖw@€€“¡Ṡ[ẈKœịḲ-¢ȧ?-»’%3ḌẠ
```
Outputs **0** if the word is typeable, **1** if not. *Thanks to @JonathanAllan for golfing off 1 byte!*
[Try it online!](https://tio.run/nexus/jelly#AT8AwP//xZLhuZZ3QOKCrOKCrOKAnMKh4bmgW@G6iEvFk@G7i@G4si3CosinPy3Cu@KAmSUz4biM4bqg////Y2xvZ3M "Jelly – TIO Nexus")
### How it works
```
ŒṖw@€€“¡Ṡ[ẈKœịḲ-¢ȧ?-»’%3ḌẠ  Main link. Argument: s (string of lowercase letters)
ŒṖ                          Yield all partitions of s.
      “¡Ṡ[ẈKœịḲ-¢ȧ?-»       Yield "sine  logcostanln". Every third character
                            marks the start of a typeable word.
  w@€€                      Find the indices of all substrings in the partitions
                            in the string to the right (1-based, 0 if not found).
                     ’      Decrement. "Good" indices are now multiples of 3.
                      %3    Modulo 3. "Good" indices are mapped to 0, "bad"
                            indices are mapped to 1 or 2.
                        Ḍ   Convert from decimal to integer. A partition will
                            yield 0 iff all indices are "good".
                         Ạ  All; yield 0 if one or more integers are falsy (0), 1
                            if all integers are truthy (non-zero).
```
[Answer]
# [Brachylog](http://github.com/JCumin/Brachylog), 33 bytes
*Fixed a bug thanks to @Synoli.*
```
~c:1a
,"sincostanloglneeee"@6e@[?
```
[Try it online!](http://brachylog.tryitonline.net/#code=fmM6MWEKLCJzaW5jb3N0YW5sb2dsbmVlZWUiQDZlQFs_&input=ImNsb2dzIg)
Outputs `true.` if typeable or `false.` otherwise.
### Explanation
We try deconcatenations of the input until we find one for which all strings that we concatenate are a prefix of one of `["sin", "cos", "tan", "log", "lne", "eee]`.
```
~c                          A list of strings which when concatenated results in the Input
  :1a                       All strings of this list satisfy the predicate below:
  
,"sincostanloglneeee"@5           The list ["sin", "cos", "tan", "log", "lne", "eee"]
                       e          Take one element of that list
                        @[?       The input is a prefix of that element
```
[Answer]
# [Perl 6](https://perl6.org), ~~60 50~~ 44 bytes
first attempt (*60*)
```
put +?(get~~/^<{<sin cos tan ln log e>».&{|m:ex/^.+/}}>*$/)
```
translation of the Perl 5 answer (*50*)
```
put +?(get~~/^[s[in?]?|co?|t[an?]?|ln?|log?|e]*$/)
```
using `-n` switch (*43+1*)
```
put +?/^[s[in?]?|co?|t[an?]?|ln?|log?|e]*$/
```
The first `?` converts the result to Boolean, and the first `+` converts that to a number (`1` for `True`, `0` for `False`)
[Answer]
## Mathematica, 101 bytes
```
If[StringMatchQ[#,("sin"|"si"|"s"|"cos"|"co"|"c"|"tan"|"ta"|"t"|"ln"|"l"|"log"|"lo"|"e")..],"T","F"]&
```
It seems that the hard parts of this challenge are coming up with the shortest regex and choosing the most concise language to match the regex. I don't have anything to contribute to the former, and Mathematica isn't good candidate for the latter since you have to use `StringMatchQ` and `RegularExpression`. What I can do is answer your P.S.: is "tasteless" the longest word that you can type?
```
In[1]:= f=StringMatchQ[#,("sin"|"si"|"s"|"cos"|"co"|"c"|"tan"|"ta"|"t"|"ln"|"l"|"log"|"lo"|"e")..]&;
In[2]:= Select[EntityList@"Word",f@#[[2,1]]&][[All,2,1]]//SortBy[StringLength]//DeleteDuplicates
Out[2]= {c,e,l,s,t,cc,cl,el,et,lo,si,sl,ta,te,ccc,col,cos,cot,eel,ell,eta,etc,lee,let,log,lot,sec,see,set,sic,sin,sit,tae,tan,tat,tec,tee,cell,clog,clot,coco,cole,colt,coss,cost,cote,else,less,loco,loge,loll,lose,loss,lota,sect,seel,sell,sess,seta,sett,sill,silo,silt,sine,sise,siss,site,sloe,slog,slot,stet,taco,tact,tael,talc,tale,tall,tect,tell,test,cello,close,cosec,costa,cotan,eccle,elect,elsin,ettle,loess,lotte,secle,setee,since,sleet,stale,stall,state,steel,stele,tasse,taste,tatee,teest,telco,testa,tetel,tsine,cellco,closet,coleta,collet,coltan,cosine,cosset,costal,ecesis,estate,lessee,scelet,select,sellee,sestet,settee,settle,siesta,silole,stacte,stance,stasis,tallet,tallot,taslet,tassel,tasset,tattle,tectal,teetan,tellee,testee,tsetse,celesta,cessile,cocotte,collect,costate,ecolect,ectasis,electee,sessile,sinless,sitelet,statant,tassell,tastant,testate,coestate,colessee,colocolo,cosiness,costless,electant,lossless,sceletal,siletane,statelet,tactless,tallness,telltale,telocoel,coelostat,sissiness,stateless,tasteless,tattletale}
```
So "tattletale" seems to be the longest by one character.
[Answer]
# [Wonder](https://github.com/wonderlang/wonder), 41 bytes
```
!.(mstr"^(s|t|co?|(l|ta|si)n?|log?|e)+$")
```
Usage:
```
(!.(mstr"^(s|t|co?|(l|ta|si)n?|log?|e)+$")) "tasteless"
```
Totally misunderstood the question before, but now it's all fixed.
Outputs `F` for match and `T` for no match.
## Noncompeting, 35 bytes
```
!.`^(s|t|co?|(l|ta|si)n?|log?|e)+$`
```
Usage:
```
(!.`^(s|t|co?|(l|ta|si)n?|log?|e)+$`) "tasteless"
```
This makes use of applicable regexes, which was implemented after this challenge.
[Answer]
# Processing, 223 bytes
```
int d(String b){for(String p:"tan0log0sin0cos0ln0e".split("0"))if(p.startsWith(b))return 1;return 0;}
int l(String p){String b="";int t=1;for(char c:p.toCharArray()){b+=c;if(d(b)<1){b=c+"";t=d(b);}if(t<1)return t;}return t;}
```
Finally decided to do an answer without regex. To call the function, use `l("tasteless");`. Returns `0` for false and `1` for true.
### Expanded code with explanation
```
int d(String b){
  for(String p:"tan0log0sin0cos0ln0e".split("0"))
    if(p.startsWith(b))
      return 1;
  return 0;
}
//main function
int l(String p){
  String b="";
  int t=1;
  for(char c:p.toCharArray()){
    b+=c;
    if(d(b)<1){
      b=c+"";
      t=d(b);
    }
    if(t<1)return t;
  }
  return t;
}
```
Basically, we iterate over the given string, building up `b` char by char. We check using `d()` if any of the `tan`,`log`,... start with `b`. If it does, then it is valid. Else, we check if the char at that position is valid and we reset `b`. Now if it is invalid, `0` will be returned, or else it will still be valid. At the end, if the program hasn't already returned something, then return `1`.
[Answer]
# Scala, 49 bytes
```
s=>s.matches("(s(in?)?|co?|t(an?)?|ln?|log?|e)+")
```
Returns true if the given string matches the regex, false otherwise.
[Answer]
# [Python 3](https://docs.python.org/3/), 154 bytes
```
r=1;i=input()
while r:
 r=0
 for s in'sin,cos,tan,log,ln,co,lo,si,ta,s,c,t,l,e'.split(','):
  if i.startswith(s):r=i=i.replace(s,'',1);break
print(i=='')
```
[Try it online!](https://tio.run/nexus/python3#FY1BDsMgDATvvIKbQbKi5pqIx9CINFYtQLarPJ/Q284cZoekdadEtf8sRHdfxMXL5rykl/NnE6@eKihVPJqi5YrcPsh/nAuVpkPFAw0ZCyzamSwAQpwRT6enRS2L6U12BY2bpHm3SOmcjxIUAXCN@1tK/rouVC1QSgDRjWHMzVRsjAc "Python 3 – TIO Nexus")
[Answer]
# [Python 3](https://docs.python.org/3/), ~~149~~ 130 bytes
```
i=input()
for a in 'tan,sin,cos,log,si,co,ta,lo,lo,ln,s,c,t,l,e'.split(','):
    if a in i:
        i=i.replace(a,"")
print(not i)
```
edit #1: shaved 19 bytes using @Henke solution
[Answer]
## Python 2, 124 bytes
```
f=lambda w:any(f(w[len(s):])if w[:len(s)]==s else 0for s in'sin,cos,tan,log,ln,co,lo,si,ta,s,c,t,l,e'.split(','))if w else 1
```
[Answer]
# PHP, 60 bytes
```
<?=preg_match("#^((si|ta|l)n?|co?|log?|s|e|t)+$#",$argv[1]);
```
regex stolen from [ETHproductions](https://codegolf.stackexchange.com/a/102128#102128):  
takes input from command line argument; prints `1` for typable, `0` for not typeable.
**older versions, ~~75~~ ~~73~~ 69 bytes**
```
<?=!preg_replace("#co|log|ln|lo|sin|si|tan|ta|[celst]#","",$argv[1]);
```
replaces all possible words with empty string, returns the result, negates.
```
<?=!preg_split("#co|log|ln|lo|sin|si|tan|ta|[celst]#",$argv[1],-1,1);
```
splits input by regex matches. Flag `1` stands for `PREG_SPLIT_NO_EMPTY` and tells `preg_split` to only return non-empty results. If input is typable, `preg_split` will only have empty results, so it will return an empty array, which is falsy. `!` negates the result.
Both versions take input from command line argument  
and print `1` if result is empty (input is typable), else nothing.
Notes:  
Packing the regex using `?` does not work here; it renders the expressions ungreedy; probably due to backtracking. And the order of the alternatives is important: `ta` has to stand before `t` or the engine will stop matching when it finds `t`.
I found a [quantifier cheat sheet](http://www.rexegg.com/regex-quantifiers.html#cheat_sheet), thought `??` or `?+` might help; but they did not work for me.
[Answer]
# Java 8, 55 bytes
```
s->return s.matches("^((si|ta|l)n?|co?|log?|[ste])+$");
```
Disclamer: *I used [ETHproductions'](https://codegolf.stackexchange.com/a/102128/60199) regex because it was many bytes shorter than mine.* Full credit on the Regex to him. What I did was add 24 bytes to make it a Java function.
Returns `false` if the word did not fit into the Regex, else `true`.
]