text:
A nasty little memory leak
Below Python code generates memory leak.
Challenge: Fix the memory leak with minimal changes to the code as measured by Levenshtein distance to the original code. You may only change the code before t is initialised. When the del t line is removed the modified program should print I'm still alive! every second.
PS: I already know the answer (found it after several hours of debugging). This is not the programming help question! Hopefully this would be interesting to folks.
import threading, time

# this class takes callback and calls it every 1 sec
class MyTimer:
    def __init__(self, callback):
        self.callback = callback
        self.th = threading.Thread(target=self.run,daemon=True)
        self.th.start()
    def run(self):
        while(True):
            self.callback()
            time.sleep(1)

class TestMyTimer:
    def __init__(self):
        self.timer = MyTimer(self.is_alive)
    def is_alive(self):
        print("I'm still alive")

# test code for MyTimer
t = TestMyTimer()
del t

# just to be sure to collect all dead objects
import gc
gc.collect()

# if you are still seeing messages then we have memory leak!
time.sleep(60)

Here's repl.it to play with this code online.

Ah, rereading this, I see that you're aware of the answer to your problem. However, on PPCG, the puzzles tend to be challenges for which we write code to solve the criteria, rather than solve a puzzle in a piece of code. The closest tag I can see for this is the rarely used [tag:programming-puzzle] (which is often mistagged), but you would still need an objective winning criterion (i.e. what makes one answer to your question better than a different answer) to make this challenge on-topic

In the future, it might be best to look through and answer some existing challenges, and make sure to post future challenges in the Sandbox to gauge community reactions before posting to main.

Unfortunately this was closed for the wrong reason. PPCG is a bit odd in that we require each challenge to have an objective way to compare answers against each other (and generally "first poster" is frowned upon). If I had to guess, the best way to get this information out would be to post a question on SO and self answer it. The "gotcha" is fairly elusive, and I wouldn't have guessed that it was wrong just from looking at the code.

I think this could be tagged as programming-puzzle with the winning criterion being minimal editing distance to get a solution without memory leak.

I'm not asking for help. I already know the answer. This is indeed programming challenge! I've modified the question to be clear on this. Also added the suggested tag.

I went ahead and voted to reopen just now in light of the change.  Just for future reference though you might want to ping me in a comment by @ing my username if you addressed my question, that way I can vote on it.  I had just assumed you were away and I hadn't noticed that you had fixed the issue.

An additional thought: you might want to enforce that the fixed code produce a particular output, otherwise the best solution is likely to be to comment out everything (distance 6).  This does prevent leaks but doesn't require any skill and probably is not what you were thinking.

I've added the [tag:code-challenge] as all challenges require a tag. I apologise for initially dismissing the challenge as a generic programming help question, but we get those quite often here. Voting to reopen.

So I'm having a bit of a problem understanding what your intent here is. Are you trying to stop the timer by deleting the reference to the test object?

Taking inspiration from the comments and from the question, just by adding 3 characters I "fixed" the memory leak.
Granted, I broke everything else at the same time
import threading, time

# this class takes callback and calls it every 1 sec
class MyTimer:
    def __init__(self, callback):
        self.callback = callback
        self.th = threading.Thread(target=self.run,daemon=True)
        self.th.start()
    def run(self):
        while(True):
            self.callback()
            time.sleep(1)

class TestMyTimer:
    def __init__(self):
        self.timer = MyTimer(self.is_alive)
    def is_alive(self):
        print("I'm still alive")

# test code for MyTimer
#t = TestMyTimer()
#del t

# just to be sure to collect all dead objects
import gc
#gc.collect()

# if you are still seeing messages then we have memory leak!
time.sleep(60)

Edit: The challenge has now been properly updated :)

LOL. Not quite there :)

import threading, time

# this class takes callback and calls it every 1 sec
class MyTimer:
    def __init__(self, callback):
        self.a = True
        self.callback = callback
        self.th = threading.Thread(target=self.run,daemon=True)
        self.th.start()
    def run(self):
        while(True):
            self.callback(self.a)
            time.sleep(1)

class TestMyTimer:
    def __init__(self):
        self.timer = MyTimer(self.is_alive)
    def is_alive(self, k):
        print("I'm still alive")
        if not k:
            raise SystemExit()

# test code for MyTimer
t = TestMyTimer()
t.timer.a = 0
del t.timer, t

# just to be sure to collect all dead objects
import gc
gc.collect()

# if you are still seeing messages then we have memory leak!
time.sleep(60)

Memory leak is still there. You can check this by using objgraph library and then doing objgraph.show_backrefs(objgraph.by_type('TestMyTimer'), refcounts=True). You just stopped the timer to print the messages.

Fair enough, I've edited my answer to raise the SystemExit.

Please add your score to your submission

Python 3, 2 bytes
import threading, time

# this class takes callback and calls it every 1 sec
class MyTimer:
    def __init__(self, callback):
        self.callback = callback
        self.th = threading.Thread(target=self.run,daemon=True)
        self.th.start()
    def run(self):
        while(True):
            self.callback()
            time.sleep(1);t

class TestMyTimer:
    def __init__(self):
        self.timer = MyTimer(self.is_alive)
    def is_alive(self):
        print("I'm still alive")

# test code for MyTimer
t = TestMyTimer()
del t

# just to be sure to collect all dead objects
import gc
gc.collect()

# if you are still seeing messages then we have memory leak!
time.sleep(6)

Try it online!
Maybe not intended but I don't know a just intended solution

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Square Root Distance from Integers
Given a decimal number k, find the smallest integer n such that the square root of n is within k of an integer. However, the distance should be nonzero - n cannot be a perfect square.
Given k, a decimal number or a fraction (whichever is easier for you), such that 0 < k < 1, output the smallest positive integer n such that the difference between the square root of n and the closest integer to the square root of n is less than or equal to k but nonzero.
If i is the closest integer to the square root of n, you are looking for the first n where 0 < |i - sqrt(n)| <= k.
Rules

You cannot use a language's insufficient implementation of non-integer numbers to trivialize the problem.
Otherwise, you can assume that k will not cause problems with, for example, floating point rounding.

Test Cases
.9         > 2
.5         > 2
.4         > 3
.3         > 3
.25        > 5
.2         > 8
.1         > 26
.05        > 101
.03        > 288
.01        > 2501
.005       > 10001
.003       > 27888
.001       > 250001
.0005      > 1000001
.0003      > 2778888
.0001      > 25000001
.0314159   > 255
.00314159  > 25599
.000314159 > 2534463

Comma separated test case inputs:
0.9, 0.5, 0.4, 0.3, 0.25, 0.2, 0.1, 0.05, 0.03, 0.01, 0.005, 0.003, 0.001, 0.0005, 0.0003, 0.0001, 0.0314159, 0.00314159, 0.000314159

This is code-golf, so shortest answer in bytes wins.

Wolfram Language (Mathematica), 34 bytes
Min[⌈.5/#+{-#,#}/2⌉^2+{1,-1}]&

Try it online!
Explanation
The result must be of the form \$m^2 \pm 1\$ for some \$m \in \mathbb{N}\$. Solving the inequations \$\sqrt{m^2+1} - m \le k\$ and \$m - \sqrt{m^2-1} \le k\$, we get \$m \ge \frac{1-k^2}{2k}\$ and \$m \ge \frac{1+k^2}{2k}\$ respectively. So the result is \$\operatorname{min}\left({\left\lceil \frac{1-k^2}{2k} \right\rceil}^2+1, {\left\lceil \frac{1+k^2}{2k} \right\rceil}^2-1\right)\$.

Python, 42 bytes
lambda k:((k-1/k)//2)**2+1-2*(k<1/k%2<2-k)

Try it online!
Based on alephalpha's formula, explicitly checking if we're in the \$m^2-1\$ or \$m^2+1\$ case via the condition k<1/k%2<2-k.
Python 3.8 can save a byte with an inline assignment.
Python 3.8, 41 bytes
lambda k:((a:=k-1/k)//2)**2-1+2*(a/2%1<k)

Try it online!
These beat my recursive solution:
50 bytes
f=lambda k,x=1:k>.5-abs(x**.5%1-.5)>0 or-~f(k,x+1)

Try it online!

05AB1E, 16 bytes
nD(‚>I·/înTS·<-ß

Port of @alephalpha's Mathematica answer, with inspiration from @Sok's Pyth answer, so make sure to upvote both of them!
Try it online or verify all test cases.
Explanation:
n                 # Take the square of the (implicit) input
                  #  i.e. 0.05 → 0.0025
 D(‚              # Pair it with its negative
                  #  i.e. 0.0025 → [0.0025,-0.0025]
    >             # Increment both by 1
                  #  i.e. [0.0025,-0.0025] → [1.0025,0.9975]
     I·           # Push the input doubled
                  #  i.e. 0.05 → 0.1
       /          # Divide both numbers with this doubled input
                  #  i.e. [1.0025,0.9975] / 0.1 → [10.025,9.975]
        î         # Round both up
                  #  i.e. [10.025,9.975] → [11.0,10.0]
         n        # Take the square of those
                  #  i.e. [11.0,10.0] → [121.0,100.0]
          TS      # Push [1,0]
            ·     # Double both to [2,0]
             <    # Decrease both by 1 to [1,-1]
              -   # Decrease the earlier numbers by this
                  #  i.e. [121.0,100.0] - [1,-1] → [120.0,101.0]
               ß  # Pop and push the minimum of the two
                  #  i.e. [120.0,101.0] → 101.0
                  # (which is output implicitly)

Neat, thanks for linking the answer that has the formula used. I was doing mental gymnastics trying to figure out the formula from 05AB1E's ever-odd syntax.

JavaScript (ES7),  51  50 bytes
f=(k,n)=>!(d=(s=n**.5)+~(s-.5))|d*d>k*k?f(k,-~n):n

Try it online!
(fails for the test cases that require too much recursion)

Non-recursive version,  57  56 bytes
k=>{for(n=1;!(d=(s=++n**.5)+~(s-.5))|d*d>k*k;);return n}

Try it online!
Or for 55 bytes:
k=>eval(`for(n=1;!(d=(s=++n**.5)+~(s-.5))|d*d>k*k;);n`)

Try it online!
(but this one is significantly slower)

Japt, 18 16 bytes
-2 bytes from Shaggy
_=¬u1)©U>½-½aZ}a

Try it online!

Might be shorter using Arnauld's solution

A little shuffling saves a byte.

Oh... of course i could have reversed that :|. Also that %1 && is nasty, not sure if using Arnauld's solution would be shorter (maybe not)

16 bytes by reassigning Z¬u1 to Z at the beginning of the function.

The other method appears to be 26: [1,-1]®*U²Ä /U/2 c ²-Z} rm

J, 39 29 bytes
[:<./_1 1++:*:@>.@%~1+(,-)@*:

NB. This shorter version simply uses @alephalpha's formula.
Try it online!
39 bytes, original, brute force
2(>:@])^:((<+.0=])(<.-.)@(-<.)@%:)^:_~]

Try it online!
Handles all test cases

Pyth, 22 21 bytes
hSm-^.Ech*d^Q2yQ2d_B1

Try it online here, or verify all the test cases at once here.
Another port of alephalpha's excellent answer, make sure to give them an upvote!
hSm-^.Ech*d^Q2yQ2d_B1   Implicit: Q=eval(input())
                  _B1   [1,-1]
  m                     Map each element of the above, as d, using:
           ^Q2            Q^2
         *d               Multiply by d
        h                 Increment
       c      yQ          Divide by (2 * Q)
     .E                   Round up
    ^           2         Square
   -             d        Subtract d
 S                      Sort
h                       Take first element, implicit print

Edit: Saved a byte, thanks to Kevin Cruijssen

I don't know Pyth, but is it possible to create [-1,1] in 3 bytes as well, or do you need an additional reverse so it becomes 4 bytes? If it's possible in 3 bytes, you could do that, and then change the *_d to *d and the +d to -d. Also, does Pyth not have a Minimum builtin, instead of sort & take first?

@KevinCruijssen The order of the two elements isn't important as we're taking the minimum, though I can't think of a way of creating the pair in 3 bytes. A good catch on changing it to - ... d though, that saves me a byte! Thanks

@KevinCruijssen Also there isn't a single byte minimum or maximum function unfortunately :o(

Ah, of course. You map over the values, so it doesn't matter if it's [1,-1] or [-1,1]. I was comparing the *d and -d with my 05AB1E answer, where I don't use a map, but can subtract/multiply a 2D array from/with another 2D array, so I don't need a map. Glad I could help to save a byte in that case. :) And thanks for the inspiration for my 05AB1E answer.

Perl 6, 34 33 29 bytes
-1 byte thanks to Grimy
{+(1...$_>*.sqrt*(1|-1)%1>0)}

Try it online!

-1 byte by replacing >= with >. Square roots of integers are either integer or irrational, so the equality case provably cannot happen.

@Grimy Thanks, this seems to be allowed according to the challenge rules. (Though floating-point numbers are always rational, of course.)

Java (JDK), 73 70 bytes
k->{double i=1,j;for(;(j=Math.sqrt(++i)%1)==0|j>=k&1-j>=k;);return i;}

Try it online!
-3 bytes thanks to @ceilingcat

C# (Visual C# Interactive Compiler), 89 85 71 bytes
k=>{double n=2,p;for(;!((p=Math.Sqrt(n)%1)>0&p<k|1-p<k);n++);return n;}

Try it online!
-4 bytes thanks to Kevin Cruijssen!

You can save a byte by putting the n++ in the loop, so the -1 can be removed from the return: k=>{double n=1,p;for(;Math.Abs(Math.Round(p=Math.Sqrt(0d+n))-p)>k|p%1==0;n++);return n;}

Also, the 0d+ can be removed, can it not?

@KevinCruijssen Yes it can, I just forgot the n was already a double

APL (Dyalog Unicode), 27 bytesSBCS
⌊/0~⍨¯1 1+2*⍨∘⌈+⍨÷⍨1(+,-)×⍨

Try it online!
Monadic train taking one argument. This is a port of alephalpha's answer.
How:
⌊/0~⍨¯1 1+2*⍨∘⌈+⍨÷⍨1(+,-)×⍨ ⍝ Monadic train

                         ×⍨ ⍝ Square of the argument
                   1(+,-)   ⍝ 1 ± that (returns 1+k^2, 1-k^2)
                 ÷⍨         ⍝ divided by
               +⍨           ⍝ twice the argument
             ∘⌈             ⍝ Ceiling
          2*⍨               ⍝ Squared
     ¯1 1+                  ⍝ -1 to the first, +1 to the second
  0~⍨                       ⍝ Removing the zeroes
⌊/                          ⍝ Return the smallest

Jelly, 13 bytes
I have not managed to get anything terser than the same approach as alephalpha
- go upvote his Mathematica answer!
²;N$‘÷ḤĊ²_Ø+Ṃ

Try it online!
How?
²;N$‘÷ḤĊ²_Ø+Ṃ - Link: number, n (in (0,1))
²             - square n        -> n²
   $          - last two links as a monad:
  N           -   negate        -> -(n²)
 ;            -   concatenate   -> [n², -(n²)]
    ‘         - increment       -> [1+n², 1-(n²)]
      Ḥ       - double n        -> 2n
     ÷        - divide          -> [(1+n²)/n/2, (1-(n²))/n/2]
       Ċ      - ceiling         -> [⌈(1+n²)/n/2⌉, ⌈(1-(n²))/n/2⌉]
        ²     - square          -> [⌈(1+n²)/n/2⌉², ⌈(1-(n²))/n/2⌉²]
          Ø+  - literal         -> [1,-1]
         _    - subtract        -> [⌈(1+n²)/n/2⌉²-1, ⌈(1-(n²))/n/2⌉²+1]
            Ṃ - minimum         -> min(⌈(1+n²)/n/2⌉²-1, ⌈(1-(n²))/n/2⌉²+1)

Java 8, 85 bytes
n->{double i=1,p;for(;Math.abs(Math.round(p=Math.sqrt(i))-p)>n|p%1==0;i++);return i;}

Port of EmbodimentOfIgnorance's C# .NET answer.
Try it online.
The Math.round can alternatively be this, but unfortunately it's the same byte-count:
n->{double i=1,p;for(;Math.abs((int)((p=Math.sqrt(i))+.5)-p)>n|p%1==0;i++);return i;}

Try it online.

MathGolf, 16 bytes
²_b*α)½╠ü²1bαm,╓

Try it online!
Not a huge fan of this solution. It is a port of the 05AB1E solution, which is based on the same formula most answers are using.
Explanation
²                  pop a : push(a*a)
 _                 duplicate TOS
  b                push -1
   *               pop a, b : push(a*b)
    α              wrap last two elements in array
     )             increment
      ½            halve
       ╠           pop a, b, push b/a
        ü          ceiling with implicit map
         ²         pop a : push(a*a)
          1        push 1
           b       push -1
            α      wrap last two elements in array
             m     explicit map
              ,    pop a, b, push b-a
               ╓   min of list

Is every symbol considered a byte in code golfing? Because some of your characters require more than a single byte. I don't mean to nit-pick, I'm genuinely wondering :)

Good question! A "byte" in golfing relates to the minimum file size required to store a program. The text used to visualize those bytes can be any bytes. I have chosen Code Page 437 to visualize my scripts, but the important part is the actual bytes that define the source code.

A good example of the number of characters and number of bytes being different is this answer. Here, the 'ԓ' character is actually 2 bytes, but the rest are 1 byte characters.

Forth (gforth), 76 bytes
: f 1 begin 1+ dup s>f fsqrt fdup fround f- fabs fdup f0> fover f< * until ;

Try it online!
Explanation
Starts a counter at 1 and Increments it in a loop. Each iteration it checks if the absolute value of the counter's square root - the closest integer is less than k
Code Explanation
: f                   \ start a new word definition
  1                   \ place a counter on the stack, start it at 1
  begin               \ start and indefinite loop
    1+                \ add 1 to the counter
    dup s>f           \ convert a copy of the counter to a float
    fsqrt             \ get the square root of the counter
    fdup fround f-    \ get the difference between the square root and the next closes integer
    fabs fdup         \ get the absolute value of the result and duplicate
    f0>               \ check if the result is greater than 0 (not perfect square)
    fover f<          \ bring k to the top of the float stack and check if the sqrt is less than k
    *                 \ multiply the two results (shorter "and" in this case)
  until               \ end loop if result ("and" of both conditions) is true
;                     \ end word definition

Japt, 14 bytes
_=¬aZ¬r¹©U¨Z}a

Try it
_=¬aZ¬r¹©U¨Z}a     :Implicit input of integer U
_                  :Function taking an integer Z as an argument
 =                 :  Reassign to Z
  ¬                :    Square root of Z
   a               :    Absolute difference with
    Z¬             :      Square root of Z
      r            :      Round to the nearest integer
       ¹           :  End reassignment
        ©          :  Logical AND with
         U¨Z       :  U greater than or equal to Z
            }      :End function
             a     :Return the first integer that returns true when passed through that function

Perl 5 -p, 42 bytes
$t=sqrt++$\while($p=abs$t-int$t)>$_||!$p}{

Try it online!

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Floating over the integers
As you may know, the typical binary floating point numbers in a computer language are quite different than the typical integer numbers in a computer language. Floating point numbers can represent a much larger range, and can represent fractional amounts, however there is a trade-off that is frequently elided.
The distance between integers is constant, and in fact the value of that constant is one. The distance between floating point numbers, however, is variable, and increases the further one travels down the number line, away from the origin at 0. At some point, that distance is so large that the floating point numbers start skipping over integers, and many integers that are technically less than the maximum value of the floating point numbers, cannot actually be represented by floating point numbers.
The challenge:
Write a program that when given the number n, will print out the first n positive integers that cannot be represented by a floating point number in your language of choice.

"First n positive integers" means, lowest in value, closest to the origin, and distinct from each other.
Infinite precision floating point numbers are not allowed.
It doesn't matter whether you choose 32 bit floats, 64 bits floats, or some other type of float, as long as it is a non-infinite precision floating point number in your language of choice, on your machine of choice.
Order of numbers does not matter
This is Code Goﬂ. Smallest number of characters wins.
Good luck and have fun

Example:
In Rust, using 32 bit floating point builtin type 'f32':
n=4, result = [16777217,16777219,16777221,16777223]

(updated - 1 order doesnt matter - 2 Golf->Goﬂ)

Smallest number of characters wins I think you mean bytes. If not, is there a reason you're using characters?

i just love unicode?

Do we use single precision floating point or double?

Could you please remind us how a positive integer is represented as a float? I know I can look it up, but challenges specifications should be self-contained and it would save readers the time.

@xnor I don't think it should include this just because most language use IEEE754 floating point numbers. Other form of floating point numbers should be allowed although I don't know one.

@donbright I recommend scoring in bytes. The reason is that, otherwise, the full code in ASCII-only golfing languages (such as CJam or Pyth) can be compressed in a unicode string that will unpack to the ASCII-only code, therefore saving characters, but not bytes. Furthermore, the byte is the actual unit of digital data storage, while "character" is a term that depends on the encoding the solution uses, and one character can even take up 6 bytes, for example. This is how the "packing" mentioned before worked before we changed the default scoring method for [tag:code-golf] to the byte count.

Do the numbers have to be output in order? Or would your example be valid if it output, for example,  [16777223,16777221,16777219,16777217]?

@Sara-J order does not matter. Updated, thanks.

@EriktheOutgolfer sorry, Jo King already used this in their perl answer so I am kind of stuck... . For now i changed it to "Code Goﬂ" to indicate its not technically Code Golf.

@donbright Alright, your call. BTW it's not that code golf is strictly scored in bytes, it was in characters for a long time many years ago, it's just that I recommended scoring in bytes based on my personal experience.

@EriktheOutgolfer yeah i see what you mean... next time ill probably do bytes

I don't mind switching my code to score in bytes if you want

cQuents, 9 bytes
&#N_=N+.0

Try it online!
& is broken on TIO right now, so TIO link will not work, but it would time out anyway, as the only way to start at 2^53 is modifing the interpreter.
Explanation
           Implicit input n
&          Output first n terms of the sequence
 #         Only include an integer N in the sequence if:
  N        N
   _=        is not equal to
     N+.0                    N converted to float

how can i run this on my machine? i cloned github and typed python cquents.py , pasted the program and got an error

@donbright put the code in the source.cq file

python cquents.py  \n 5 \n cquents_core.CQSyntaxError: Unknown factor : EOF
.... cquents_core.CQSyntaxError: Unknown factor : &

@donbright uh you might have a trailing newline in your source.cq file? That would cause that error. If you want to test it without waiting change line 169 in cquents_core.py to self.n = 2 ** 53.

congratulations, fascinating language

Perl 6, 28 characters
{grep({.Num+|0-$_},^∞)[^$_]}

Try it online!
This is actually 30 bytes, but the challenge is scored in characters.
This should work theoretically. This creates a lazy list of numbers that compares the default number type (with arbitrary precision) against the same number converted to a Num datatype, which is a 64-bit floating point number, and returns the first \$n\$ elements of the list
Here's a version starting at \$2^{53}-5\$

i like the infinity literal.

C (gcc), 58 bytes
f(n,i){for(i=9;n;i++)i-(int)(i+.0f)&&printf("%d ",i,n--);}

Try it online!
Works with 32-bit float.

JavaScript, 46 bytes
n=>{for(x=1n;n;)+[++x]!=x&&console.log(x)&n--}

This will certainly timeout on TIO. So, here is a TIO link which initialize x with 253.

Save 7 10 bytes, thanks to Neil.
Save 2 bytes, thanks to Arnauld

So sad SpiderMonkey do not support bigint yet. Otherwise we can save many bytes by switching to SpiderMonkey and use print.

Number(++x)!=x saves 5 bytes.

@Neil I remembered that one cannot mix number with bigint. But I didn't know they can check equality without explicit type convertion.+(++x+'') would be shorter than Number(++x).

Would something like this work?

@Oliver It should work for small n. Try to pass n = 1000 and initial x as 2**54, you will find out the difference.

+[++x]!=x saves another 3 bytes.

Ruby 2.6, 42 bytes
->n{(1..).lazy.select{|i|i!=i*1.0}.take n}

Works with 64-bit floats, returns an enumerator.
Ruby 2.5 and below, 43 bytes
->n{1.step.lazy.select{|i|i!=i*1.0}.take n}

And finally, the one that actually finishes in reasonable time:
->n{(2**53).step.lazy.select{|i|i!=i*1.0}.take n}

Try it online!

cool, i didnt realize ruby could do that

Java 8, 68 67 bytes
n->{for(int i=9;;)if(++i!=(int)(i+0f))System.out.println(i*n/n--);}

Uses the 32-bit float, but by changing 0f to 0d and int to long it can also be tested with the 64-bit double.
Try it online with int and 0f.
Try it online with long and 0d.
Explanation:
n->{                       // Method with integer parameter and no return-type
  for(int i=9;;)           //  Loop `i` from 9 upwards indefinitely:
    if(++i                 //   Increase `i` by 1 first
          !=               //   And if it does not equal:
            (int)(i+0f))   //   Itself as float, and casted back to integer:
      System.out.println(i //    Print the current `i`
        *n/n--);}          //    And decrease `n` by 1
                           //    (and due to the `n/n`, the infinite loop will stop as soon
                           //     as `n` becomes 0, with a division by zero error)

05AB1E (legacy), 10 bytes
µ¾ÐtnïÊi,¼

No TIO, because it will time out way before it reaches the first number 9007199254740993.. I'm using the legacy, since it is run in Python, so will output the same numbers as the Python answer. I'll see if I can determine the first few numbers for the new version of 05AB1E as well, which is run in Elixir (but that will be a separated answer in that case).
As alternative for the TIO, here a prove that tnï for input 9007199254740993 does not result in 9007199254740993, but in 9007199254740994 instead: Try it online.
Explanation:
µ           # Loop until the counter_variable is equal to the (implicit) input
            # (the counter_variable is 0 by default)
 ¾Ð         #  Push the counter_variable three times
   t        #  Take its square-root
    n       #  And then the square of that
     ï      #  And cast it back from a decimal to an integer
      Êi    #  If they are NOT equal:
        ,   #   Print the counter_variable
         ¼  #   And increase the counter_variable by 1

05AB1E has no builtin to set the counter_variable manually unfortunately, otherwise I would have set it to about 9007199254740000 at the start.

how can i run o5ab1e legacy version on my own machine?

@donbright I'm not entirely sure, but if I look back at the commit history, this commit from July 9th, 2018 was the last commit made in the Python legacy 05AB1E. The commit after that was the start of the Elixir rewrite. So I think you can check out the code from that commit, and then run it with Python with the instructions given in the README of that version.

@donbright If you need any help, I suggest pinging @Adnan on the 05AB1E chat, since he's the one who made and manages the 05AB1E code (PS: If he doesn't respond, Emigna or Don't be a x-triple dot would probably know as well. I personally primarily use 05AB1E on TIO tbh.)

thanks. however cquents was one byte shorter.

Python 2, 57 bytes
n=1
exec"while n==int(.0+n):n+=1\nprint n;n+=1\n"*input()

Starting from 1 takes a very long time. For testing purposes, starting at \$2^{53}\$ gives the same results but much quicker: Try it online!
We count up values of n (an integer) until we find one for which converting to a float (by adding .0) and back to an int doesn't result in the same number. We then print that value and go to the next n. An exec loop lets us do this a fixed number of times according to the input.

C# (Visual C# Interactive Compiler), 54 bytes
n=>{for(int i=1;;)if(++i!=(int)(i+0f))Print(i*n/n--);}

Port of Kevin Cruijssen's Java answer
Try it online!


text:
Check type of an integer
You will receive an integer less than 2000000000 and bigger than -2000000000 and you have to test what type(s) of number this is out of:
Factorial
Square
Cube
Prime
Composite
Triangular
Positive
Negative

Here is a definition  of all the different types of numbers:
Factorial - A number That is equal to the product of all positive integers less than the a certain positive integer - 5×4×3×2×1 = 120
Square - A number that is the product of two identical integers - 5×5 = 25
Cube - A number that is the product of three identical integers - −5×−5×−5 = -125
Prime - A number that has only two divisors (1 and 0 are not) - 3
Composite - A number that has more than two divisors (also not 1 or 0) - 4
Triangular - A number that is equal the sum of all positive integers less than the a certain positive integer - 5+4+3+2+1 = 15
Positive - A number larger than 0 (not 0) - 7
Negative - A number less than 0 (not 0) - −7
Test Cases
-8 = ["Cube","Negative"]
-2 = ["Negative"]
-1 = ["Cube","Negative"]
 0 = ["Cube", "Square", "Triangular"]
 1 = ["Cube","Factorial","Positive","Square","Triangular"]
 2 = ["Factorial","Positive","Prime"]
 3 = ["Positive","Prime","Triangular"]
 4 = ["Composite","Positive","Square"]
 5 = ["Positive","Prime"]
 6 = ["Composite","Factorial","Positive","Triangular"]
 7 = ["Positive","Prime"]
 8 = ["Composite","Cube","Positive"]
 9 = ["Composite","Positive","Square"]
10 = ["Composite","Positive","Triangular"]
11 = ["Positive","Prime"]
12 = ["Composite","Positive"]

Note: The Order of the Result Does Not Matter and it can be expressed with words (Does Not Have To Be A List)
Remember, this is a code golf so the smallest answer in bytes is what I'm looking for

Welcome to PPCG. Nice first challenge. You may want harmonise the casing and/or explicitly state that any casing is acceptable. Does the result have to be a list of strings or is any indication using those words OK? Could we substitute "codes" or bit or synonyms, etc.?

Some more test cases would be nice too.

Is -1 a triangular number? Is -4 a composite number? Please define your types to make the challenge self contained and add some examples.

I really like this challenge idea, it would be nice if you could specify this a bit better.

I've taken the freedom to fix your definitions. Feel free to correct me if I'm wrong.

You should still clarify whether casing is important (as yours is inconsistent) and whether answering by other means than with English words is acceptable.

Do we actually have to be able to handle ±2×10⁹ or is it enough that the algorithm in principle works. Some solutions may want to calculate impractically large factorials or have practical issues with finding primality of large numbers. You may want to allow limiting to what's representable.

The test cases leave out the fact that they are posivite

@ASCII-only Fixed.

Is 0 not a square and cube?

0 is also a triangular number, right?

It says that the result can be expressed with words, but not that it has to. Should this be interpreted as allowing alternate formats for results, including integer instead of string, etc?

Zero is a square, a cube, and a triangular number. As you haven't as of yet replied to the relevant questions of the commenters above regarding whether a 0 input is a special case (test cases on their own aren't enough to specify the challenge), or edited this challenge to clarify them, I've voted to close it as unclear.

@EriktheOutgolfer 0 x 0 = 0, therefore it is square, 0 is a triangular number, 0 is a cube. 0 is not positive or negative

A number that has only two divisors (1 and 0 are not) - 3. But 3 has only 1 divisor (which is 3).

APL (Dyalog Extended), 130 119 bytesSBCS
Anonymous tacit prefix function.
((∊∘⎕A⊂⊢)'FactorialSquareTriangularCubePositiveNegativePrimeComposite')/⍨{⍵∊¨(⊂∘!,×⍨⍮+\)⍳|⍵},(|∊⍳∘|*3⍨),<,>,1∘⍭,0∘⍭∧1∘<

Try it online!
(…)/⍨ filters the list of strings on the left by the bit mask on the right:
 (…)'Fac…ite' apply the following tacit function to the long string:
  ∊∘⎕A element-wise membership of the uppercase alphabet
  ⊂ partitions (i.e. True begins a new partition)
  ⊢ the unmodified argument
The last 46 bytes return a bit vector indicating [Factorial, Square, Triangular, Cube, Positive, Negative, Prime, Composite]:
{⍵∊¨(⊂∘!,×⍨⍮+\)⍳|⍵},(|∊⍳∘|*3⍨),<,>,1∘⍭,0∘⍭∧1∘<

Try it online!
{…} the first three bits (factorial, square, triangular) come from this anonymous lambda:
 ⍵∊¨(…)… is the argument a member of each of the following three lists?
  ⊂∘! the enclosed factorials
  , followed by
  ×⍨ the squares (lit. the multiplication selfies)
  ⍮ juxtaposed with
  +\ the running sum
 ⍳ of the integers one through
 |⍵ the absolute value of the argument
(…) the next bit (cube) comes from the following tacit function:
 | is the absolute value of the argument
 ∊ a member of
 ⍳∘| the integers 1 through the absolute value of the argument
 * raised to the power of
 3⍨ three
< the next bit is simply whether it is positive (zero is less than)
> the next bit is simply whether it is negative (zero is more than)
1∘⍭ the next bit is whether it is prime
0∘⍭ the final bit is whether it is non-prime
∧
1∘< one is less than it

JavaScript (ES7),  244 238  236 bytes
Returns an array of strings.
n=>'negative/positive/triangular/cube/square/factorial/prime/composite'.split`/`.filter((s,i)=>(k=!i)?n<0:i-1?i<5?(g=n=>(x=k++**(2+i%2))<n?g(n):x==n)(i-2?i&n<0?-n:n:8*n+1):(g=i-5?k=>n>1?n%--k?g(k):k<2^i>6:0:n=>n>1?g(n/++k):n==1)(n):n>0)

Try it online!
or See a formatted version
How?
We filter an array of number properties, keeping track of our current position in the index \$i\$:
 i | Property   | OEIS    | Test
---+------------+---------+---------------------------------------------------------
 0 | negative   | A001478 | n < 0
 1 | positive   | A000027 | n > 0
 2 | triangular | A000217 | look for k >= 0 such that k**2 = 8n+1
 3 | cube       | A000578 | look for k >= 0 such that k**3 = |n|
 4 | square     | A000290 | look for k >= 0 such that k**2 = n
 5 | factorial  | A000142 | divide n by 1, 2, 3, etc. until it's either 1 or < 1
 6 | prime      | A000040 | n > 1 and its largest proper divisor is equal to 1
 7 | composite  | A002808 | n > 1 and its largest proper divisor is greater than 1
Case \$i=0\$ (negative)
We test whether \$n < 0\$.
Case \$i=1\$ (positive)
We test whether \$n > 0\$.
Case \$2\le i \le 4\$ (triangular, cube, square)
We use the following function, starting with \$k=0\$:
g = n =>                   // n = input
  (x = k++ ** (2 + i % 2)) // x = either k**3 if i = 3, or k**2 otherwise; increment k
  < n ?                    // if the above result is less than n:
    g(n)                   //   do a recursive call
  :                        // else:
    x == n                 //   test whether x is equal to n

If \$i=2\$ (triangular test), \$g\$ is called with \$8n+1\$ (i.e. we test whether \$8n+1\$ is a perfect square).
If \$i=3\$ (cube test), \$g\$ is called with \$|n|\$ (i.e. we test whether \$|n|\$ is a perfect cube).
If \$i=4\$ (square test), \$g\$ is called with \$n\$ (i.e. we test whether \$n\$ is a perfect square).
Case \$i=5\$ (factorial)
We use the following function, starting with \$k=0\$:
g = n =>                   // n = input
  n > 1 ?                  // if n is greater than 1:
    g(n / ++k)             //   increment k and do a recursive call with n / k
  :                        // else:
    n == 1                 //   test whether n is equal to 1

Case \$i>5\$ (prime, composite)
We use the following function:
g = k =>                   // k = current divisor, initialized to n
  n > 1 ?                  // if n is greater than 1:
    n % --k ?              //   decrement k; if k is not a divisor of n:
      g(k)                 //     do a recursive call
    :                      //   else:
      k < 2 ^              //     test whether k = 1 (n is prime)
      i > 6                //     invert the result if i = 7
  :                        // else:
    0                      //   always return 0 (n is neither prime nor composite)

"its smallest proper divisor", maybe you mean "largest".

Japt, 101 96 88 bytes
-5 bytes thanks to Oliver
-8 bytes thanks to Shaggy
`t„gÔ³dÖ%oÐÒdpoÐÓv‚šg…iv‚cu¼çyÜ)Ã$quÂÂpÎX`qd g[U*8Ä ¬v1 Uk ÅÊU¬U<0Uõ³øU UõÊøU U¬v1 Uj]ð

Try it online!

Damn, beat me to doing it :) I need to be faster and online more if I'm ever going to answer anything :P

You could always try using a different approach :P

96 bytes

You've been posting some nice Japt answers recently. I have sort of relied on the Japt interpreter the few times I've posted a solution. That's pretty good if you are able to do it w/ TIO.

@dana I do use the interpreter every time, just because the quick reference is handy :P it's just that I move it to TIO so it's more consistent with other posts

@dana Oh, also Shaggy's compressors come in really when you have strings

There's a lot of space + U here, but join + eval might be too costly

90 bytes

I'm working on a new tip on string compression at the moment ;)

88 bytes

Stax, 79 71 bytes
ë∙☺H▓»░g▬äεê▄ú▓▒º₧Σ↓i∟I∩├▼┬√&A4¼╔uë[Ü▼╒π←=Å♥\aâ╬°Æ■v⌂♂δ┴▄·╠.ë¶<→`┬╪½¥6X

Run and debug it
Unpacked, ungolfed, and commented, it looks like this.
|c      peek input and terminate if falsey
12{|Fm  first 12 factorials
#       (1) is the input found in the array?
x       push original input from x register and
G       (2) execute program at trailing curly brace which tests for square-ness
x       push original input from x register
|n      get exponents of prime factorization
|g      gcd of array
3%!     (3) is not a multiple of 3
x1|M    push max(1, x) where x is the original input
c       copy value on the stack
|p      (4) is prime?
s       swap top two stack entries
|fD     (5) drop first element from prime factorization
x8*^    push 8x+1 where x is the original input
G       (6) execute program at trailing curly brace which tests for square-ness
x0>     (7) is original input greater than zero?
c!      (8) logically negate the value at (7)
`?|yL843smg!O5&;RVPC3&g9W!ISjvJN'n`
        compressed literal for "negative positive triangular composite prime cube square factorial"
        - these are the names in reverse order of the test results pushed at (1)-(8)
:.j     title case and split on spaces
f       filter list of names and implicitly output using the rest of the program as a predicate
  d     drop the name revealing the corresponding test result on top of the stack
        terminate program
}       `G` target from above; when done, resume execution
  c|qJ= copy, floor square-root, square, then test equality; this is a test for squareness

Run this one

How does this work?

@lirtosiast: added an explanation

Jelly, 67 65 60 59 bytes
“R!i“Æ²“ŒR*3i“Ẓ“<2oẒ¬“ŻÄi“R“<0”vTị“*Ṙœȯ#Ḅṙ×¬`ɲṇṭY¤²nxẊ2ı»Ḳ¤

Try it online!
A monadic link that accepts an integer and returns a list of strings.
Explanation
“R!i“Æ²“ŒR*3i“Ẓ“<2oẒ¬“ŻÄi“R“<0”   First part of main link
“                                 Begin list of strings separated by “
 R                                  Range: [1..n]
  !                                 Factorial [each]
   i                                Find index of argument
    “                             ,
     Æ²                             Is square?
       “                          ,
        ŒR                          Balanced range: [-n..n]
          *3                        Cube [each]
            i                       Find index of argument
             “                    ,
              Ẓ                     Is prime?
               “                  ,
                <2                  Is less than 2?
                  o                 Or
                   Ẓ                Is prime?
                    ¬               Negate
                     “            ,
                      Ż             Range with zero: [0..n]
                       Ä            Prefix sums
                        i           Find index of argument
                         “        ,
                          R         Range [used to test for positive]
                           “      ,
                            <0      Is less than 0?
                              ”   End list of strings

vTị“*Ṙœȯ#Ḅṙ×¬`ɲṇṭY¤²nxẊ2ı»Ḳ¤   Second part of main link
v                              Evaluate each with the argument
 T                             Indices of truthy elements
  ị                            Index into
                           ¤   (
   “*Ṙœȯ#Ḅṙ×¬`ɲṇṭY¤²nxẊ2ı»       Compressed string "Factorial Square Cube Prime Composite Triangular Positive Negative"
                          Ḳ      Split on spaces
                           ¤   )

Thanks to caird for 60->59

-1 byte (+\ -> Ä)

@cairdcoinheringaahing Thanks! I changed this part so many times that I totally forgot about this.

05AB1E, 76 75 bytes
_i¯ë.±D(IÅ²IÄ©3zmDïQIpIÑg3@Id*®LηPIå®ÅTIå)”îË¢…ï©×Ä›ˆÉíšâialÓª”¨¨"ular"«#sÏ

Try it online or verify all test cases.
Explanation:
_i               # If the (implicit) input is 0:
  ¯              #  Push an empty list
 ë               # Else:
  .±             #  Push the signum of the (implicit) input (-1 if <0; 0 if 0; 1 if >0)
                 #   i.e. -8 → -1
  D(             #  Duplicate and take it's negative
                 #   i.e. -1 → 1
  IÅ²            #  Push the input, and check if it's a square
                 #  (negative values will result in the negative numbers themselves)
                 #   i.e. -8 → -8
  IÄ             #  Push the absolute value of the input
                 #   i.e. -8 → 8
    ©            #  Store it in the register (without popping) to reuse later
     3z          #  Push 1/3
       m         #  Take the absolute input to the power of 1/3
                 #  (NOTE: a^(1/3) is the same as ³√a)
                 #   i.e. 8 → 2.0
        DïQ      #  Check if this is an integer without decimal digits
                 #   i.e. 2.0 → 1 (truthy)
  Ip             #  Push the input, and check if it's a prime
                 #   i.e. -8 → 0 (falsey)
  IÑ             #  Push the input, and get a list of its divisors
                 #   i.e. -8 → [1,2,4,8]
    g            #  Take the length of that list
                 #   i.e. [1,2,4,8] → 4
     3@          #  And check if it's larger than or equal to 3
                 #  (the list includes 1, hence the check for >=3 instead of >=2)
                 #   i.e. 4 >= 3 → 1 (truthy)
       Id        #  Push the input again, and check if it's non-negative
                 #   i.e. -8 → 0 (falsey)
         *       #  Check if both are truthy
                 #   i.e. 1 and 0 → 0 (falsey)
  ®L             #  Create a list in the range [1, absolute value of the input]
                 #   i.e. 8 → [1,2,3,4,5,6,7,8]
    η            #  Get a list of prefixes of this list
                 #   → [[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5],[1,2,3,4,5,6],[1,2,3,4,5,6,7],[1,2,3,4,5,6,7,8]]
     P           #  Get the product for each prefix-list
                 #   → [1,2,6,24,120,720,5040,40320]
      Iå         #  Check if the input is in this list
                 #   i.e. [1,2,6,24,120,720,5040,40320] and -8 → 0 (falsey)
  ®ÅT            #  Create a list of all triangular numbers below or equal to
                 #  the absolute value of the input
                 #   i.e. 8 → [0,1,3,6]
     Iå          #  Check if the input is in this list
                 #   i.e. [0,1,3,6] and -8 → 0 (falsey)
  )              #  Wrap all values on the stack into a single list
                 #   → [-1,1,-8,1,0,0,0,0]
  ”îË¢…ï©×Ä›ˆÉíšâialÓª”
                 #  Push dictionary string "Positive Negative Square Cube Prime Composite Factorial Triangle"
   ¨¨            #  Remove the last two characters (the "le" of "Triangle")
     "ular"«     #  Append "ular"
            #    #  Split this string by spaces
             s   #  Swap to take the earlier created list again
              Ï  #  And only leave the strings at the truthy indices
                 #  (NOTE: Only 1 is truthy in 05AB1E)
                 #   i.e. [-1,1,-8,1,0,0,0,0] → ["Negative","Cube"]
                 # (and output the result implicitly)

See this 05AB1E tip of mine (section How to use the dictionary?) to understand why ”îË¢…ï©×Ä›ˆÉíšâialÓª” is "Positive Negative Square Cube Prime Composite Factorial Triangle".

Husk, 60 65 61 59 bytes
Edit: +5 bytes to fix zero as a square, cube & triangular, and to fix zero, one and negative numbers as non-composites (in line with test cases)...
...but then -4 bytes thanks to Razetime, by changing all the forks (§: and §e) to a mapping over a bigger list of functions
f+m€⁰mëmΠm□m^3mΣΘḣ⁰mëṗȯ>2LḊ>0<0⁰w¨◄Γq□ṡ_ẏĊ8ζŀ⁸→PṘβ□θpż√₁□Ġë

Try it online!
How?
f                               # select each element if input satisfies:
 +                              # combine 2 lists of 4 together:
  m€⁰§:mΠ§:m□§em^3mΣΘḣ⁰         # first list:
  m€⁰                           # check whether input is
     §:  §:  §e                 # among
       mΠ                       # factorials of
           m□                   # or squares of
               m^3              # or cubes of
                  mΣ            # or triangular numbers of
                    Θḣ⁰         # series from 0..input
  mëṗȯ>2LḊ>0<0⁰                 # second list:
  m             ⁰               # map functions over input:
   ë                            # list of 4 functions
    ṗ                           # is prime?
     ȯ>2LḊ                      # is composite (more than 2 divisors)?
          >0                    # is positive?
            <0                  # is negative?

                                # elements to select:
w                               # split on spaces
 ¨◄Γq□ṡ_ẏĊ8ζŀ⁸→PṘβ□θpż√₁□Ġë     # compressed string
                                # "Factorial Square Cube Triangular Prime Composite Positive Negative"

55(mapping list of functions twice)

Incorrectly classifies all negative numbers, 0 and 1 as composite and doesn't classify 0 as a square, cube and triangular.

@xigoi - well spotted!  Fixed now (with negatives as non-composite in line with test-cases).

@Razetime - thanks!  The mapping is really nice!  Swapping mΣ for ∫ unfortunately seems to result in negative numbers being classified as triangular: I don't understand why, so I had to stick with mΣ (and so annoyingly still be 2 bytes longer than Jelly...)

@DominicvanEssen happens sometimes lol

Python 3, 405 259 bytes
Thanks to @ASCII-only
def z(n):
	x=y=1
	while x<n:x*=y;y+=1
	return"Factorial "*(x==n)+"Square "*(n>=0and n**.5%1==0)+"Cube "*(abs(n)**(1/3)%1==0)+"Negative "*(n<0)+"Positive "*(n>0)+"Triangular "*(n>0and(8*n+1)**.5%1==0)+["Composite ","Prime "][all(n%x for x in range(2,n))]*(n>1)

Try it online!
Old Code
Generates the squares, cubes, and factorials into lists to check against, has a function to check for primality (and consequently compositeness), uses a simple equality to check for positivity/negativity, and checks if 8n+1 is a perfect square to determine if n is a triangular number. Hardcoded the limits for the square, cube, and factorial lists. Returns the answer in a set, which I assume is acceptable (adding elements to a list requires more bytes).
p=lambda n:all(n%x!=0 for x in range(2,n))
def z(n):
	f,a,x,y,s,c=[],set(),1,1,[i*i for i in range(44721)],[i**3 for i in range(-1259,1259)]
	while x<2*10**9:f.append(x);x*=y;y+=1
	if n in f:a.add("Factorial")
	if n in s:a.add("Square")
	if n in c:a.add("Cube")
	if n>0:
		a.add("Positive")
		if 8*n+1 in s:a.add("Triangular")
	if n>1:a.add(("Composite","Prime")[p(n)])
	if n<0:a.add("Negative")
	return a

Try it online!

jZNfa6swGMav66fIhIHaDIztztpuDsb@wIExBufciRepjV3ARpfEzXbss/ck0Wqxx8NBLzS/53neNy9JsZVvOZvs90WY4c1yhQFb4Cxz2Hl1FvogzTmoAGWAY7YmTgCZ61orkoKdw9yFNUohhhXcQgGTMIqhepF6IupRY6WddTq9CpAba@ZN@hAFl3M3tkafbzQjoLoJPOR73nyRjsOoiq8rL9xeb8chskY0BUz70gVWzH7Cicw5xZkdd0zU7Nd7iTlpAF4K1bGCSQ3vy@UBsVtf7WRkll9zQSX9MEizmcfG6Cjzt6rF1mWGeWtGhjj2fb4ptJvY0H7ldENsNypUzbgR3vh1xAtZ40MJTmTJGcB7SYRMsCAChCCynIsZBF91j7AzfLtQoUCj3hoalPuaNJOAoNYYcGzppgi7CcDWdrxr4zUtDJjqrRvZRMtO0Gnc1LRyPL6THozu8q95Bv3oRwx01y99NRw560c2w2rVRjX/z96R/w9hvyuEhttCwWCQ5rFlmbvFilJCgJn4JPoPtAdMHfWCUyadRrKrP9S11qdUEOm0K@AsbBL0/ahd9tPdz@fHBwhIVZBEkpV9qOLu/wA

381, add https://tio.run/## to start

394 bytes.

358

@ASCII-only 341 bytes.

263

259

C# (Visual C# Interactive Compiler), 286 bytes
n=>{int k=0;return(n>0?"Positive":n<0?"Negative":"")+(Math.Sqrt(8*n+1)%1==0?"Triangular":"")+(new int[n].Where((a,b)=>n%++b<1).Count()>2?"Composite":n<3?"":"Prime")+(Math.Pow(n,1/3d)%1>0?"":"Cube")+(Math.Sqrt(n)%1>0?"":"Square")+(g(k)?"Factorial":""));bool g(int i)=>i>1?g(i/++k):1==i;}

Try it online!

05AB1E, 63 bytes
ÅTIL3mILÄ!)IQO`Î‹Î›IÅ²IpD≠$‹*)“×ÄšâialîË¢…ï©›ˆÉí“#.•’α`ë\Ä•šsÏ™

Try it online! or Verify all test cases!
Commented:
ÅT                   # push the triangular numbers up to the input
  IL                 # push the range [1..input]
    3m               # take each number to the third power
      IL             # push the range [1..input]
        Ä            # take absolute values
         !           # take the factorial of each number
          )          # collect the three list in a list of lists
           IQ        # for each element chack if it is equal to the input
             O       # sum the sublists
              `      # and push all three values to the stack

Î‹                   # is 0 < input? (Î pushes 0 and the input)
  Î›                 # is 0 > input?
    IÅ²              # is the input a square number?
       Ip            # is the input prime?
         D≠          # duplicate this value and invert the copy
           $         # push 1 and the input
            ‹        # is 1 < input
             *       # is the input composite? (not prime & > 1)
              )      # collect all these values in a list

“×ÄšâialîË¢…ï©›ˆÉí“  # push compressed string "cube factorial positive negative square prime composite"
 #                   # split on spaces
  .•’α`ë\Ä•          # push compressed string "triangular"
           š         # and prepend it to the word list
            s        # swap the integer back to the top
             Ï       # keep all words where 1's are in the integer list
              ™      # titlecase all words


text:
Play Zip, Zap, Zop
There's a little improv warm up game where you arrange yourselves in a circle and send zips, zaps, and zops around by pointing to a person and saying the next word in the sequence, then they do the same until all of you are warmed up or whatever.
Your task is to create a program that gives the next word in sequence given an input word. (Zip --> Zap --> Zop --> Zip) Since there's a lot of different ways to say these three words and flairs that can be added to them, your program should imitate case and letter duplication and carry suffixes.
To elaborate, your input will be one or more Zs, then one or more Is, As, or Os (all the same letter), then one or more Ps, (all letters up to this point may be in mixed case) followed by some arbitrary suffix (which may be empty). You should leave the runs of Zs and Ps, as well as the suffix exactly as received, but then change the Is to As, As to Os, or Os to Is, preserving case at each step.
Example Test Cases
zip         ==> zap
zAp         ==> zOp
ZOP         ==> ZIP
ZiiP        ==> ZaaP
ZZaapp      ==> ZZoopp
zzzzOoOPppP ==> zzzzIiIPppP
Zipperoni   ==> Zapperoni
ZAPsky      ==> ZOPsky
ZoPtOn      ==> ZiPtOn
zipzip      ==> zapzip
zapzopzip   ==> zopzopzip
zoopzaap    ==> ziipzaap

Rules and Notes

You may use any convenient character encoding for input and output, provided that it supports all ASCII letters and that it was created prior to this challenge.
You may assume the input word is some variant of Zip, Zap, or Zop. All other inputs result in undefined behavior.

Valid inputs will full-match the regex Z+(I+|A+|O+)P+.* (in mixed case)

Happy Golfing!

ziop -> what does this do?

@Joshua This is invalid according to the description (see "all the same letter").

@Arnauld: And the test case for zoopzaap disagrees with the description.

@Joshua Why? This only applies to the vowels between the leading z's and the first p. The suffix may contain anything.

JavaScript (Node.js),  69 63 57  54 bytes
s=>Buffer(s).map(c=>s|c%4<1?s=c:c+c*90%320%34%24-8)+''

Try it online!
How?
We process the input string \$s\$ character by character.
We reuse \$s\$ as a flag: as soon as a numeric value is stored in it, we know that we must not update anything else.
To identify "p" (112) and "P" (80), we use the fact that their ASCII codes are multiples of \$4\$ and the ASCII codes of the other letters at the beginning of the string ("z", "Z" and vowels) are not.
To turn a vowel with ASCII code \$c\$ into its counterpart \$n\$ while leaving z and Z unchanged, we use the following function:
$$n=c+((((90\times c) \bmod 320)\bmod 34)\bmod 24)-8$$
 letter | ASCII code |  * 90 | % 320 | % 34 | % 24 | - 8 | new letter
--------+------------+-------+-------+------+------+-----+-----------------------
   'i'  |     105    |  9450 |  170  |   0  |   0  |  -8 | 105 -  8 =  97 -> 'a'
   'a'  |      97    |  8730 |   90  |  22  |  22  |  14 |  97 + 14 = 111 -> 'o'
   'o'  |     111    |  9990 |   70  |   2  |   2  |  -6 | 111 -  6 = 105 -> 'i'
   'z'  |     122    | 10980 |  100  |  32  |   8  |   0 | 122 +  0 = 122 -> 'z'
   'I'  |      73    |  6570 |  170  |   0  |   0  |  -8 |  73 -  8 =  65 -> 'A'
   'A'  |      65    |  5850 |   90  |  22  |  22  |  14 |  65 + 14 =  79 -> 'O'
   'O'  |      79    |  7110 |   70  |   2  |   2  |  -6 |  79 -  6 =  73 -> 'I'
   'Z'  |      90    |  8100 |  100  |  32  |   8  |   0 |  90 +  0 =  90 -> 'Z'

Commented
s =>                  // s = input string
  Buffer(s)           // convert it to a Buffer of ASCII codes
  .map(c =>           // for each ASCII code c in s:
    s |               //   if s is numeric
    c % 4 < 1 ?       //   or c is either 'p' or 'P':
      s = c           //     turn s into a numeric value and yield c
    :                 //   else:
      c +             //     update c
        c * 90 % 320  //     by applying the transformation function
        % 34 % 24     //     (see above)
        - 8           //
  ) + ''              // end of map(); coerce the Buffer back to a string

How did you come up with that function?

@ThomasHirsch It was found with a brute-force search function. The first step (multiplication + 1st modulo) makes sure that the parameters give identical result for both lowercase and uppercase. The 2nd step (the next 2 modulos and the subtraction) checks whether the correct delta values can be obtained from there.

C (gcc),  81 ... 61 48  46 bytes
Saved 2 bytes thanks to @Grimy
Port of my JS answer. Outputs by modifying the input string.
f(char*s){for(;*++s%4;*s+=*s*90%320%34%24-8);}

Try it online!
Commented
f(char * s) {       // f = function taking the input string s
  for(;             //   for each character *s in s:
    *++s % 4;       //     advance the pointer; exit if *s is either 'p' or 'P' (it's safe
                    //     to skip the 1st character, as it's guaranteed to be 'z' or 'Z')
    *s +=           //     update the current character:
      *s * 90 % 320 //       apply a transformation formula that turns
      % 34 % 24     //       a vowel into the next vowel in the sequence
      - 8           //       while leaving 'z' and 'Z' unchanged
  );                //   end of for()
}                   // end of function

-2 bytes

@Grimy Nice catch, thanks! (I did try *++s%4 at some point but overlooked the resulting optimization...)

Further -3 bytes. This one should also be applicable to your JS answer.

@Grimy It's different enough from mine, so you may want to post this as a separate answer.

Stax, 19 bytes
Ç╛√êΣ%,╖FP╚`=Lh←⌡·ƒ

Run and debug it

Retina 0.8.2, 21 bytes
iT`Io`A\OIia\oi`^.+?p

Try it online! Transliterates letters up to and including the first p, although the z and p aren't in the transliteration section so aren't affected. The first O is quoted because it normally expands to 13567 and the second o is quoted because it too is magic; in the first part of the transliteration it expands to the other string. The resulting transliteration is therefore from IAOIiaoi to AOIiaoi then removing the duplicate source letters results in IAOiao to AOIaoi.

C, 43 bytes
f(char*s){for(;*++s%4;*s^=*s%16*36%98%22);}

Try it online!
Based on Arnauld's answer. I did a brute-force search to find the shortest formula that turns a => o, o => i, i => a, z => z.

Japt, 22 20 bytes
-2 bytes thanks to Oliver
r"%v+"_d`i¬iao¯`pu}"

Try it online!

R, 110 76 bytes
-36 bytes thanks to Krill
This function takes an input of one string.
function(a)sub(s<-sub('z+(.+?)p.*','\\1',a,T),chartr('aioAIO','oaiOAI',s),a)

Try it online!

Collecting the string from pieces in R tends to be very long... But you save a lot of bytes by first extracting a substring s that we'll be translating, and then replacing it with a translated copy: 76 bytes

@KirillL., Ah that's the clever trick I was trying to find.

Perl 6, 41 33 bytes
{S:i{.+?p}=$/~~tr/iaoIAO/aoiAOI/}

Try it online!
Simple case-insensitive substitution to shift the vowel section.

Python 3.8 (pre-release), 81 78 bytes
lambda s,p='iaoIAO':''.join(('aoiAOI'+c)[(p:=p*(ord(c)%4)).find(c)]for c in s)

Try it online!
Python 2, 98 bytes
lambda s:''.join(('aoiAOI'+c)[(-~-('p'in s[:i].lower())*'iaoIAO').find(c)]for i,c in enumerate(s))

Try it online!

Java (JDK), 52 bytes
s->{for(int i=0;s[++i]%4>0;)s[i]^=s[i]%16*36%98%22;}

Try it online!

Port of Grimy's C answer. Make sure to upvote his answer!

-3 bytes by using a port of Grimy's C answer instead: s->{for(int i=0;s[++i]%4>0;)s[i]^=s[i]%16*36%98%22;} 52 bytes.

C# (Visual C# Interactive Compiler), 60 bytes
n=>{for(int i=0;n[i]%4>0;)n[i]^=(char)(n[i++]%16*36%98%22);}

Based off of Grimy's C answer.
Try it online!

This unfortunately doesn't work as it replaces the vowels in the suffix as well.

As @Emigna states above, this replaces all aoi-vowels, instead of just the ones before the first p/P. One thing to golf however: ("iao".IndexOf((char)(c|32))+1)%4 can be -~"iao".IndexOf((char)(c|32))%4

Perl 5, 31 bytes
s/.+?p/$&=~y,iaoIAO,aoiAOI,r/ei

TIO

SNOBOL4 (CSNOBOL4), 183 bytes
	INPUT (BREAK('Pp') SPAN('Pp')) . P REM . S
A	P 'a' ='o'	:S(A)
Z	P 'A' ='O'	:S(Z)F(P)
I	P 'i' ='a'	:S(I)
K	P 'I' ='A'	:S(K)F(P)
O	P 'o' ='i'	:S(O)
L	P 'O' ='I'	:S(L)
P	OUTPUT =P S
END

Try it online!

Python 2, 84 bytes
f=lambda s,r='':s[0]in'pP'and r+s or f(s[1:],r+('aoiAOI'+s[0])['iaoIAO'.find(s[0])])

Try it online!

C/C++ (VC++ compiler) 192bytes
this is a rather naive try but anyway
void f(char*I){int c[]={-8,14,6},B=1,v[]={105,97,111},j=0;for(*I;*I>0&B;I++){if(*I==80|*I==112){B=0;break;}if(*I==90|*I==122){}else{for(j;j<3;j++){if(*I==v[j]|*I==v[j]-32){*I+=c[j];break;}}}}}

some slightly more readable Version is this
#include "stdafx.h"

void f(char * theString)
{
    signed int change[] = {'a'-'i','o'-'a','o'-'i'}; // add this to the vowel to get the next one
    char theVowels[] = {'i','a','o'};
    int breaker = 1;
    printf("Input %s\n",theString);
    for (int i = 0;(theString[i] != '\0') && breaker; i++)
    {
        switch (theString[i])
        {
            case 'Z': /*fall through*/
            case 'z': break;
            case 'P': /*fall through*/
            case 'p': breaker = 0;
                      break;
            default:
            {
                for (int j = 0; j < 3; j++)
                {
                    if ((theString[i] == theVowels[j]) || (theString[i]==(theVowels[j]-'a'+'A')))
                    {
                        theString[i] += change[j];
                        break;
                    }
                }
            }
            break;
        }

    }
    printf("Output %s\n",theString);
}
int main()
{
    char theString[]= "zzzzIIIIp0815-4711"; // a test string
    f(theString);
    return 0;
}

tio: https://tio.run/##fVLBTsMwDD0nX2GKIO3G2CZAIEoPHDmBhMQB6CG0aZsx0qlJAcH67cPJ2pVKiBxi2c9@8XOcTPIk2Wz2pUqWdSrA0yaV5XHhUfpeyhQyPyl4BSMwhbg3lVR5QL8p0TJXIgWpDCCucvEUQwTfjLMJk@yIlWh5ayVrQphOgacpskgNprRs8F5@iKV1cmFcQIlPA6USlLg3MfRgU3TLbXm3nE1IiX36pRL8VVSIzjGywu5M5ns3alUbONDPyjvqu8aErKzAt3USK2ahvwOfZAx7EbDnGQvg8LDjDUGOxwElqJfoD2mSAgY1CDmMJFwLYI/sEqajjC9RVFGVdV6Mpj36hajjDfvY3b8Vq67CKZy5OkKgZQHrpiLj9dJcOse10otcuCI0V3CCxinZZRGZgT8cQBT9mvgiDmC9HsqNIv93gv3gMbtmQbAl7pjJgHUcdQuyiFsFpB8DIQ3d3e7aYQ2lNtJ96m1t/v7Vhlqxb1wq321mtzptC3EE3heeGzyr2cX8bHJ6Pp9724UEI7QB7TJxPfzBtlTC1JWyc8dWNpsf

tio golfed : https://tio.run/##dU@7csIwEKytr9A4k4wfcpB4BDNCFHSuUxIKR5axHCIzsnAR4293JAYySZFt7vZ2b@eOJwfOxwep@PFcCLhuTSGb52ozdo0sYBnwKtdRFvZSGch3e9YnKSJz9DKgLSOocxOCF2i1RISQAdUM07LRQZTRKNvgpy3N4thul3bCWIovrhAyDfutdb5rkX/Q4aauburUqoM4tqJ3STWt1zNa/0rpdvX@cm@SmXVHWcy4JfdAh9Fd/JlLFYSgB577A5pKvBot1cGeDf0vi8zihFOySOZLQnwKJxOYQyNaA9urE3gnW0wZ@I/tm/LRT0RIgVcGf@j/TmjhaWHOWkFMwQDA@A0

151 bytes

Ruby, 40 bytes
$_[$&]=$&.tr"IAOiao","AOIaoi"if/z+.+?p/i

Try it online!

05AB1E (legacy), 22 bytes
l'pkIg‚£ć…iaoDÀ‚Du+`‡ì

Try it online or verify all test cases.
Can definitely be golfed a bit more..
Uses the legacy version of 05AB1E instead of the Elixir rewrite, because + merges fields in same-length lists, whereas the new version would need a pair-zip-join ‚øJ instead.
Explanation:
l                       # Lowercase the (implicit) input-string
                        #  i.e. "ZipPeroni" → "zipperoni"
 'pk                   '# Get the index of the first "p"
                        #  i.e. "zipperoni" → 2
    Ig‚                 # Pair it with the length of the entire input-string
                        #  i.e. 2 and "zipperoni" → [2,9]
       £                # Split the (implicit) input-string into parts of that size
                        #  i.e. "ZipPeroni" and [2,9] → ["Zi","pPeroni"]
        ć               # Extract head: push the head and remainder separately to the stack
                        #  i.e. ["Zi","pPeroni"] → ["pPeroni"] and "Zi"
         …iao           # Push string "iao"
             DÀ         # Duplicate, and rotate it once towards the left: "aoi"
               ‚        # Pair them up: ["iao","aoi"]
                Du      # Duplicate and transform it to uppercase: ["IAO","AOI"]
                  +     # Python-style merge them together: ["iaoIAO","aoiAOI"]
                   `    # Push both strings to the stack
                    ‡   # Transliterate; replacing all characters at the same indices
                        #  i.e. "Zi", "iaoIAO" and "aoiAOI" → "Za"
                     ì  # Prepend it to the remainder (and output implicitly)
                        #  i.e. ["pPeroni"] and "Za" → ["ZapPeroni"]

PHP, 30 bytes
too simple for a TiO:
<?=strtr($argn,oiaOIA,iaoIAO);

Run as pipe with -nF. For PHP 7.2, put the string literals in quotes.

This transliterates all oia vowels instead of only the ones before the first p/P, doesn't it?


text:
Generate a Baseball Pitch String
Goal
Write a program or function that takes a positive integer n and randomly generate a legal series of pitches (henceforth called a Pitch string) of length n.
Input
A non-zero, positive integer n <= 100
Output
Return a random string, or list of characters, that represent a possible, valid pitch string of length n. The characters used will be:

B - Ball. If you accumulate 4 of these, the batter is walked and finished batting.
S - Strike. If you accumulate 3 of these, the batter is out and finished batting.
F - Foul. Will also increase the Strike count but cannot get the batter out. I.e., you cannot have a Foul be the last pitch in a valid string. Any fouls past two strikes/fouls will not increase the Strike count (the batter already has 2 strikes at that point and a 3rd would get him out).
H - Hit. The batter has hit a ball into play and is finished batting.

(This is simplified slightly but don't you worry about that)
Valid pitch strings are those that end in a strike-out, a walk, or a hit.
I.e., an invalid pitch string has either

additional pitches after the 4th Ball, 3rd Strike, or Hit
terminated before generating a 4th ball, 3rd strike, or Hit.

Rules

Your program must be able to produce all possible results for a given input.
Your program does not have to be uniformly random but still must follow the previous rule.
This is code-golf.

Examples
Input => Possible Outputs
1 => [H] #Can only end with a hit
2 => [S,H], [B,H], [F,H] #Can only end with a hit
3 => [S,S,S], [F,F,S], [B,B,H], ... #Can now strike-out, otherwise must end with a hit
4 => [B,B,B,B], [S,B,S,S], [B,F,S,S], [B,B,B,H], ... #Can now be walked, struck-out, or get a hit
6 => [S,B,S,B,B,H], [F,F,F,F,F,S], ... #Can now have a full-count (3 balls, 2 strikes) before finishing

Input => Invalid Outputs
1 => [S], [B]    #Not enough for a strike-out/walk
2 => [S,S]       #Not enough for a strike-out/walk
2 => [H,H]       #Batter has already scored a hit
3 => [S,S,F]     #Fouls will not cause a strike-out
4 => [S,S,S,H]   #Batter has already struck out
5 => [B,B,B,B,B] #Batter has already walked

So we have to be able to produce anywhere from 1 to infinity F's?

The string will be at most 100 characters long. Fouls are what allows such long pitching strings, e.g. 99 Fs and a S is a strike-out

Oh, got it, missed that

@Quintec Reworded it to be a bit more explicit just in case

Python 2, 128 bytes
from random import*
def g(n):
 x=i=S=0;r=''
 while(S>2)+x<3>=i-S:x=randint(0,3);r+='BFSH'[x];S+=x>0;i+=1
 return(i==n)*r or g(n)

Try it online!
Randomly generate the pitch string until the batter is done, output it if it turns out the right length, and otherwise try again from scratch.

Python 2, 136 bytes
from random import*
def g(n):
 B=H=F=S=0;r=''
 while(F+S<3or'S'>x)>B/4+H:x=choice('BHFS');r+=x;exec x+"+=1"
 return(len(r)==n)*r or g(n)

Try it online!

Kevin's port of this made me realize this breaks down for higher numbers. n=8 can generate a chain of Fs at the end

@Veskah Nice catch. I hadn't accounted for the strike count (counting fouls) possibly going up to 6, and changing S/3 to (S>2) fixes it.

05AB1E,  44  50 44 bytes
Crossed out  44  is no longer 44 :)
[õ0U.µ["BFSH"3ÝΩ©è«®ĀX+U¼X2›®+3@¾X-3›~#}I¾Q#

Port of @xnor's Python 2 answer, so make sure to upvote him as well if you like this answer!
+6 bytes due to a bug-fix, and after that -6 bytes again thanks to @xnor by porting his way more efficient fix in comparison to my temporary work-around, as I was expecting. ;)
Try it online or verify some more random outputs.
Explanation:
[                # Start an infinite loop:
 õ               #  (Re)set the result-string to an empty string ""
 0U              #  (Re)set variable `X` to 0
 .µ              #  Reset the counter_variable to 0
   [             #  Start an inner infinite loop:
    "BFSH"       #   Push string "BFSH"
          3ÝΩ    #   Push a random integer in the range [0,3]
             ©   #   Store this random integer in variable `r` (without popping)
              è  #   Index it into the string "BFSH"
               « #   Append it to the result-string
    ®Ā           #   If `r` is NOT 0:
      X+U        #    Increase `X` by 1
    ¼            #   Increase the counter_variable by 1
    X2›®+        #   Calculate `X`>2 (1 if truthy; 0 if falsey) + `r`
         3@      #   Check if this is larger than or equal to 3
    ¾X-          #   Calculate counter_variable - `X`
       3›        #   Check if this is larger than 3
    ~            #   If either of the two checks above is truhy:
     #           #    Stop the inner infinite loop
   }             #  After the inner infinite loop:
    I¾Q          #  If the input and counter_variable are equal:
       #         #   Stop the outer infinite loop
                 # (and output the result-string at the top of the stack implicitly)

@Veskah I've done a straight-forward fix for now. I have the feeling xnor is able to do a shorter fix, so I'll probably port his fix to save some bytes later on. :)

You can fix it like I did by changing X/3 to X>2.

@xnor Thanks, back to 44 bytes again. I knew you'd find something shorter. ;p

R, 148 bytes
function(n){`~`=paste0
`*`=sample
o=""
while(nchar(o)<n-1){a=c("B"[T<4],"F","S"[F<2])*1
F=F+(a>"E")
T=T+(a<"F")
o=o~a}
o~c("B"[T>3],"H","S"[F>1])*1}

Try it online!
Generates the string, using conditional inclusion in the sampling datasets to ensure that the result is a possible pitch sequence.
Possibly doing rejection sampling (as xnor's python answer does) is shorter.
function(n){`~`=paste0		# alias
`*`=sample			# alias
o=""				# empty string for output
while(nchar(o)<n-1){		# do n-1 times:
a=c("B"[T<4],"F","S"[F<2])*1	# sample 1 from the string "BFS", conditionally including B or S if the ball/strike count is 3/2
F=F+(a>"E")			# increment F (strike count) if sampled character is F or S
T=T+(a<"F")			# increment T (ball count) if sampled character is B
o=o~a}				# append a to output

o~c("B"[T>3],"H","S"[F>1])*1}	# append the sampled "BHS", conditionally including B or S if the ball/strike count is 3/2.

Random "F and S" reference that kept playing in my head every time I typed one of those letters...

JavaScript (SpiderMonkey), 137 bytes
f=(n,o='',i=Math.random()*4|0,r=/^(?!.*((B.*){4}|([SF].*){2}S|H).)/)=>r.test(o)?n?f(n-1,o+'BSFH'[i%4])||i<8&&f(n,o,i+1):!r.test(o+1)&&o:0

Try it online!

Pyth, 53 bytes
u+GO?H+W<K/G\B3+W<Jl@"SF"G2\F\S\B+WqK3+WgJ2\H\S\B_UQ[

Try it online here.
This feels way too long, I think another approach may be required.
u+GO?H+W<K/G\B3+W<Jl@"SF"G2\F\S\B+WqK3+WgJ2\H\S\B_UQ[   Implicit: Q=eval(input())
                                                 _UQ    Reversed range from Q-1 to 0
u                                                   [   Reduce the above, with initial value G=[], next value as H:
                    @"SF"G                                Keep elements of G which are in "SF"
                   l                                      Length of the above
                  J                                       Store in J - this is the number of strikes and fouls so far
          /G\B                                            Count number of "B"s in G
         K                                                Store in K - this is the number of balls so far
    ?H                                                    If H is not 0 (i.e. not final pitch):
                           \F                               Start with "F" (foul is always available in non-final pitch)
                W<J       2                                 If J<2...
               +             \S                             ... append "S"
       W<K    3                                             If K<3...
      +                        \B                           ... append "B"
                                                          Else:
                                           \H               Start with "H" (hit is always available in final pitch)
                                       WgJ2                 If J >= 2...
                                      +      \S             ... append "S"
                                  WqK3                      If K == 3...
                                 +             \B           ... append "B"
   O                                                      Choose one element at random from the available options
 +G                                                       Append the above to G
                                                        Implicit print the result of the reduce operation

JavaScript (ES6),  107 106  99 bytes
f=(n,k=p=s=0,o='')=>p&&p>2|k-s>3|s>2&p<2?k-n?f(n):o:f(n,k+1,o+'FSBH'[p=Math.random()*4|0,s+=p<2,p])

Try it online!
Commented
f = (                       // f = recursive function taking:
  n,                        //   n = requested length
  k =                       //   k = pitch counter, initialized to 0
  p =                       //   p = last pitch
  s = 0,                    //   s = sum of strikes and fouls
  o = ''                    //   o = output string
) =>                        //
  p &&                      // if the last pitch was not a foul
  p > 2 |                   // AND the last pitch was a hit
  k - s > 3 |               //     OR we have 4 balls (or 3 balls + 1 hit)
  s > 2 & p < 2 ?           //     OR more than 2 strikes or fouls, ending with a strike:
    k - n ?                 //   if k is not equal to n:
      f(n)                  //     valid series but bad timing: try again from scratch
    :                       //   else:
      o                     //     success: return o
  :                         // else:
    f(                      //   do a recursive call:
      n,                    //     n is unchanged
      k + 1,                //     increment k
      o + 'FSBH'            //     append the pitch letter to o
        [ p = Math.random() //     pick a new random pitch
              * 4 | 0,      //     in [0..3]
          s += p < 2,       //     increment s if the pitch is a foul or a strike
          p ]               //     actual index in 'FSBH'
    )                       //   end of recursive call

Ink, 120 119 116 117 bytes
=f(n)
->g(n,3,2)
=g(n,b,s)
~n--
{n:{~{b:b->g(n,b-1,s)}|{s:s->g(n,b,s-1)}|}f->g(n,b,s-(s>0))|{~{b:h|b}|{s:h|s}|h}}->->

Try it online!
Probably still golfable.
Ungolfed (mildly reformatted)
=f(length) // Define a stitch f, with one parameter which specifies the length of the created string. This is the intended entry point.
->g(length,3,2) // Instantly divert to g, defined below, with some extra parameters

=g(length,balls_left,strikes_left) // Define a stitch g, with three parameters.
~ length--                         // Decrement remaining length
{
    - length: // If this is not to be the last character in the string
              // randomly do one of the following:
              // 1. If balls_left is nonzero, print a b and recurse
              // 2. If strikes_left is nonzero, print an s and recurse
              // 3. Do nothing
              // If we did not divert earlier, print an f and recurse.
        {~{balls_left:b->g(length,balls_left-1,strikes_left)}|{strikes_left:s->g(length,balls_left,strikes_left-1)}|}f->g(length,balls_left,strikes_left-(strikes_left>0))
    - else: // Randomly do one of the following
            // 1. If a ball would result in a walk, print a b, otherwise an h.
            // 2. If a strike would result in a strikeout, print an s, otherwise an h.
            // 3. Just print an h.
            // And finally, halt.
        {~{balls_left:h|b}|{strikes_left:h|s}|h}}->->

Edits

Saved a byte by finishing with ->-> instead of ->END.
Saved three bytes by decrementing n earlier.
Fixed a bug that caused strikeouts in incorrect places, thanks to @veskah for spotting it (+1 byte)

Based on the write-up and outputs, it looks like it doesn't factor in fouls incrementing the strike-count correctly

@veskah Well spotted, should be fixed now, thanks

APL (Dyalog Unicode), 77 bytesSBCS
{'HBSF'[{⍺←⍬⋄∨/((⊃⌽⍺)=⍳3)∧1,4 3≤(⊃s),+/1↓s←⍺∘(+/=)¨1+⍳3:⍺⋄∇⍨⍺,?4}⍣{i=≢⍺}i←⍵]}

Try it online!

Charcoal, 57 bytes
≔⁰η≔⁰ζＦ⊖Ｎ«≔‽⁺²‹ζ³ι¿›ι¹≦⊕ζ≦⊕η§SFB∨ι›η²»⊞υHＦ›η¹⊞υSＦ›ζ²⊞υB‽υ

Try it online! Link is to verbose version of code. Explanation:
≔⁰η≔⁰ζ

Start with 0 balls and 0 strikes.
Ｆ⊖Ｎ«

Loop over all of the deliveries except the last.
≔‽⁺²‹ζ³ι

If the have been fewer than three balls, then generate a random number from 0 to 2, otherwise just coinflip between 0 and 1.
¿›ι¹≦⊕ζ≦⊕η

A random value of 2 is a ball otherwise it increases the strike count.
§SFB∨ι›η²»

The values 0 to 2 map to strike, foul and ball, except that if there would be three strikes then foul is printed instead. (Four balls are excluded above.)
⊞υHＦ›η¹⊞υSＦ›ζ²⊞υB‽υ

Determine whether a strike or ball would get the batter out and choose from those or a hit as appropriate.

C (GCC) 164 145 142 bytes
-3 bytes ceilingcat
#define A(a)!i&&!r--?puts(#a),++a,--n:0;
b,s,f,h,i,r;p(n){srand(time(0));for(i=n;i--;){for(n=1;n;){r=rand()&3;b>2^!A(b)s+f>1^!A(s)!A(f)A(h)}}}

Try it online

Suggest &n instead of time(0)

Perl 5, 122 bytes
map{$B=$S=$H=0;while($B<4&&$S<3&&!$H&&/./g){${$&}++;$S+=$&eq F&&$S<2}y///c>pos||push@a,$_}glob"{B,F,H,S}"x<>;say$a[rand@a]

Try it online!

@Veskah  I missed that part.  Fixed it.


text:
Am I a Rude Number?
For a while now, I've been running into a problem when counting on my fingers, specifically, that I can only count to ten.  My solution to that problem has been to count in binary on my fingers, putting up my thumb for one, my forefinger for two, both thumb and forefinger for three, etc.  However, we run into a bit of a problem when we get to the number four.  Specifically, it requires us to put up our middle finger, which results in a rather unfortunate gesture, which is not typically accepted in society.  This type of number is a rude number.  We come to the next rude number at 36, when we raise the thumb on our second hand and the middle finger of our first hand.  The definition of a rude number is any number that, under this system of counting, results in us putting up only the middle finger of any hand.  Once we pass 1023 (the maximum number reachable on one person, with two hands of five fingers each), assume we continue with a third hand, with additional hands added as required.
Your Task:
Write a program or function that receives an input and outputs a truthy/falsy value based on whether the input is a rude number.
Input:
An integer between 0 and 109 (inclusive).
Output:
A truthy/falsy value that indicates whether the input is a rude number.
Test Cases:
Input:    Output:
0   --->  falsy
3   --->  falsy
4   --->  truthy
25  --->  falsy
36  --->  truthy
127 --->  falsy
131 --->  truthy

Scoring:
This is code-golf, so the lowest score in bytes wins.

assume we continue with a third hand, When it comes to being rude, teamwork makes the dream work.

@Veskah turns out that for the bounds of the question, you only need 3 people to make any given number.  Sure beats the old kind of counting on fingers.

Also, I don't have the time at the moment, but if anyone could figure out an equation for this sequence, that'd be great.

It's worse if you're British - 6 is rude too then!

Is it OK to take input in a different base than 10?

5 seems fairly rude too. Not sure anyone would say "Oh she had her thumb out, that's perfectly polite"

@Matthew 6 is a lot worse than 4 ... (upvoted your comment so it wouldn't be considered rude in the uk)

and 18 means 'cuckold'....

I wouldn't have even thought to convert to base 32. These answers are clever.

Is there an OEIS for this?

@MickyT No. At least currently no.

APL (dzaima/APL), 5 bytes
4∊32⊤

Try it online!
4∊ is 4 a member of
32⊤ to-base-32?

s/bytes/characters though?

@tripleee Thanks, added.

Regex (ECMAScript), 37 bytes
Input is in unary, as the length of a string of xs.
^((?=(x+)(\2{31}x*))\3)*(x{32})*x{4}$

Try it online!
^
(
    (?=(x+)(\2{31}x*))    # \2 = floor(tail / 32); \3 = tool to make tail = \2
    \3                    # tail = \2
)*                        # Loop the above as many times as necessary to make
                          # the below match
(x{32})*x{4}$             # Assert that tail % 32 == 4

I thought I knew regex, but apparently not.

JavaScript (SpiderMonkey), 23 bytes
f=x=>x&&x%32==4|f(x>>5)

Try it online!
This is a trivial solution, you just want to convert to base 32 and check if there is a 4 in it.

JavaScript (SpiderMonkey), 26 bytes
x=>x.toString(32).match(4)

Try it online!
It's interesting that /4/.test(...) cost one more byte than ....match(4).

Ruby, 36 19 bytes
->n{n.to_s(32)[?4]}

Try it online!
Saved 17 bytes with @tsh's method.

This returns true for 2207, which has a binary representation of 100010011111

@EmbodimentofIgnorance That is the correct result, is it not? The second hand is 00100.

I don't speak Ruby. But why not ->n{n.to_s(32)=~/4/}?

@tsh because I'm not as clever as you :)

Forgive me if I'm not understanding the question, but isn't the first hand of 2207 10001, the second 00111, and the third 11?  None of them have their middle finger only up

@EmbodimentofIgnorance No, you do it from right to left. 2207 → 100010011111 → first hand 11111, second hand 00100, third hand 00010.

Ah, I see. Disregard my above comments.

The question states that the maximum value is 1024 (2^10) anyways.

Japt, 5 bytes
sH ø4

Try it online!
Explanation
      // Implicit input
sH    // To a base-H (=32) string
   ø  // Contains
    4 // 4 (JavaScript interprets this as a string)

APL+WIN, 10 bytes
Prompts for input of integer
4∊(6⍴32)⊤⎕

Noting six hands are required to represent 10^9 converts to vector of 6 elements of the base 32 representation and checks if a 4 exists in any element.

Python 2, 34 32 bytes
f=lambda a:a%32==4or a>0<f(a/32)

Try it online!
2 bytes thanks to tsh

:| you can edit posts, you know that right

Yes; I know. It was an accident! An accident, I tell ya!

@tsh Oh nice, forgot that shortcircuits

Perl 6, 16 bytes
{.base(32)~~/4/}

Try it online!
Checks if there is a 4 in the base 32 representation of the number. Returns either Nil as false or a Match containing a 4.
You can prove this by the fact that \$2^5 = 32\$ so each digit is the state of each hand.

x86 Machine Code, 17 bytes
6A 20 59 85 C0 74 09 99 F7 F9 83 FA 04 75 F4 91 C3

The above bytes define a function that takes the number as input in the EAX register, and returns the result as a Boolean value in the EAX register (EAX == 0 if the input is not a rude number; EAX != 0 if the input is a rude number).
In human-readable assembly mnemonics:
; Determines whether the specified number is a "rude" number.
; Input:    The number to check, in EAX
; Output:   The Boolean result, in EAX (non-zero if rude; zero otherwise)
; Clobbers: ECX, EDX
IsRudeNumber:
    push    32           ; \ standard golfing way to enregister a constant value
    pop     ecx          ; /  (in this case: ECX <= 32)
CheckNext:
    test    eax, eax     ; \ if EAX == 0, jump to the end and return EAX (== 0)
    jz      TheEnd       ; /  otherwise, fall through and keep executing
    cdq                  ; zero-out EDX because EAX is unsigned (shorter than XOR)
    idiv    ecx          ; EAX <= (EAX / 32)
                         ; EDX <= (EAX % 32)
    cmp     edx, 4       ; \ if EDX != 4, jump back to the start of the loop
    jne     CheckNext    ; /  otherwise, fall through and keep executing
    xchg    eax, ecx     ; store ECX (== 32, a non-zero value) in EAX
TheEnd:
    ret                  ; return, with result in EAX

Try it online!

Interesting idea to use idiv, though.  I don't see any incremental improvements to this.  But see my answer : 14 bytes for a shift loop that uses MOV/AND/SUB/JZ to check the low 5 bits for rudeness.

C# (Visual C# Interactive Compiler), 31 bytes
n=>{for(;n>0;n/=n%32==4?0:32);}

Outputs by throwing an exception. The way you convert one number from decimal to another base is to divide the decimal number by that base repeatedly and take the remainder as a digit. That is what we do, and we check if any of the digits have a value of 4 in base-32;
Try it online!

27? as a bonus it doesn't output in a weird way

also what is tplig

@ASCII-only n>31 -> n>0

25 bytes

@Kevin Cruijssen @ASCII-only Recursive functions must have their declarations, so it would have to have a void f(...)..., massively increasing the byte count

yeah :/ (also... lambda is shorter than function here. byte count is still massive though, yes). Disappointingly, C# doesn't have a short builtin base conversion function

Your first "Try it online!" tells me "4 isn't a rude number.". Your 2nd "Try it online." fails to compile.

@Tvde1 fixed now, I messed the code on the footer for the second one. I deleted the first one since it was longer anyways

Whether or not a program halts is not an allowed output method. Output via exception is allowed.

J, 12 bytes
4 e.32#.inv]

Try it online!

Julia 1.0, 25 bytes
f(n)=n%32==4||n>0<f(n>>5)

Try it online!
Julia 1.0, 26 bytes
Alternative that is 1 character shorter, but 1 byte longer, too bad that ∈ takes 3 bytes in unicode.

n->'4'∈string(n,base=32)

Try it online!

could you use n->n%32... for your first answer for 2 bytes shorter?

@Giuseppe, unfortunately no, that function is recursive.

05AB1E, 5 bytes
32B4å

Port of @Adám's APL (dzaima/APL) answer.
Try it online or verify all test cases.
Explanation:
32B    # Convert the (implicit) input to Base-32
   4å  # And check if it contains a 4
       # (output the result implicitly)

Too bad ₆ is 36, not 32.

Catholicon, 4 bytes
ǔ?QǑ

Takes a number as a base-256 string.
Try it online!
Test suite

Hm, if this is allowed, then is it allowed to accept numbers in base 32 instead?

@recursive You can surround the numbers in << and >> and it allows for numbers greater than 255 in those, as shown in the test suite.

It was intended as a question about the challenge but it wasn't very clear.

R, 50 48 bytes
any(2^(0:4)%*%matrix(scan()%/%2^(0:34)%%2,5)==4)

Try it online!
Uses a neat matrix-based approach now (courtesy of @Giueseppe). It generates a 5x7 matrix of bits, converts this to a series of base 32 integers, and checks for any 4s.

@Giuseppe Oops, completely missed that. Should work now, though disappointingly 19 bytes longer. I don't think there's an inverse function to strtoi other than for hexadecimal and octal in base R

48 bytes with some matrix magic. I believe the bit conversion is longer than intToBits but then we can work with ints instead of raw which ends up saving a byte -- see for instance this with intToBits

@Giuseppe it's a completely different (and neat) solution to mine - do you want me to update mine or you post your own?

you're free to take it. :-)

of course, porting one of the many answers that tests for the presence of a digit 4 in a base-32 number is, oh, 29 bytes.

ES6, 31 30 26 bytes
b=>b.toString(32).match`4`

Feel free to say ideas on how to reduce this further, if any.

Welcome to PPCG!

You don't need to count the name of your function, and although I think you can save a byte by using test, you can actually save two bytes by matching against 4 as a number and letting match convert that into a string and then a RegExp for you.

Python 3, 43 bytes
Checks every 5-bit chunk to see if it is rude (equal to 4).

lambda n:any(n>>5*i&31==4for i in range(n))

Try it online!

*5-bit chunk...

C (gcc), 34 bytes
f(i){return i?i&31^4?f(i/32):1:0;}

Try it online!

32 bytes by rearranging the expression.

or 25 bytes by abusing the way gcc is compiling this.

Charcoal, 6 bytes
№⍘Ｎ³²4

Try it online! Link is to verbose version of code. Outputs -s according to how rude the number is. Explanation:
  Ｎ     Input as a number
 ⍘      Convert to base as a string
   ³²   Literal 32
№       Count occurrences of
     4  Literal string `4`

I use string base conversion to avoid having to separate the numeric literals for 32 and 4.

Tidy, 18 bytes
{x:4∈base(32,x)}

Try it online! Checks if 4 is an element of base(32,x) (base conversion).

Haskell, 31 bytes
elem 9.(mapM(:[6..36])[0..5]!!)

Try it online!

MATL, 8 bytes
32YA52=a

Try it online!

@Luis I can definitely drop the G (not sure why I included it in the first place) but that's only one byte (thanks for spotting that!). Changing 32YA52 to 32_YA4 is the same number of bytes right?

Ah, yes, I can't count

@Luis Count? Who needs to count when you can '32_YA4'n'32YA52'n-

Cubix, 26 bytes
u!@-W14;OIS%/\;;,p;?wO@u/s

Try it online!
Wraps onto a cube with edge length 3 as follows
      u ! @
      - W 1
      4 ; O
I S % / \ ; ; , p ; ? w
O @ u / s . . . . . . .
. . . . . . . . . . . .
      . . .
      . . .
      . . .

Watch it run
A fairly basic implementation, without all the redirects it does :

IS initiates the program by pushing the input and 32 to the stack
%4-! gets the remainder and checks if it is 4 by subtraction
1O@ output 1 if it was 4 and halt
;;, clean up the stack and do integer divide
p;? clean up bottom of the stack and check div result for 0
O@ if div result zero output and halt
s swap the top of stack and start back at step 2 above

Batch, 77 45 bytes
@cmd/cset/a"m=34636833,n=%1^m*4,(n-m)&~n&m*16

Based on these bit twiddling hacks. Explanation: Only 6 hands need to be checked due to the limited range (30 bits) of the input that's required to be supported. The magic number m is equivalent to 111111 in base 32, so that the first operation toggles the rude bits in the input number. It then remains to find which of the 6 hands is now zero.

x86 machine code, 14 bytes
(same machine code works in 16-bit, 32-bit, and 64-bit.  In 16-bit mode, it uses AX and DI instead of EAX and EDI in 32 and 64-bit mode.)
Algorithm: check low 5 bits with x & 31 == 4, then right-shift by 5 bits, and repeat if the shift result is non-zero.
Callable from C with char isrude(unsigned n); according to the x86-64 System V calling convention.  0 is truthy, non-0 is falsy (this is asm, not C1).
 line   addr    code bytes
  num
     1                             ; input:  number in EDI
     2                             ; output: integer result in AL: 0 -> rude, non-zero non-rude
     3                             ; clobbers: RDI
     4                         isrude:
     5                         .check_low_bitgroup:
     6 00000000 89F8               mov    eax, edi
     7 00000002 241F               and    al, 31          ; isolate low 5 bits
     8 00000004 2C04               sub    al, 4           ; like cmp but leaves AL 0 or non-zero
     9 00000006 7405               jz    .rude            ; if (al & 31 == 4) return 0;
    10
    11 00000008 C1EF05             shr    edi, 5
    12 0000000B 75F3               jnz   .check_low_bitgroup
    13                             ;; fall through to here is only possible if AL is non-zero
    14                         .rude:
    15 0000000D C3                 ret

    16          0E             size:  db $ - isrude

This takes advantage of the short-form op  al, imm8 encoding for AND and SUB.  I could have used XOR al,4 to produce 0 on equality, but SUB is faster because it can macro-fuse with JZ into a single sub-and-branch uop on Sandybridge-family.
Fun fact: using the flag-result of a shift by more than 1 will be slow on P6-family (front-end stalls until the shift retires), but that's fine.

Footnote 1:   This is an assembly language function, and x86 asm has both jz and jnz, so as per meta I can choose either way.  I'm not intending this to match C truthy/falsy.
It happened to be convenient to return in AL instead of EFLAGS, so we can describe the function to a C compiler without a wrapper, but my choice of truthy/falsy isn't constrained by using a C caller to test it.

Nibbles, 4.5 bytes
?`@32$4

Attempt This Online!
?`@32$4
?        Find the first index of
      4  4
 `@32    in the base 32 representation of
     $   input

Wolfram Language (Mathematica), 37 bytes 36 bytes 29 bytes
-2 bytes by Jonathan Frech
#~IntegerDigits~32~MemberQ~4&

Try it online!
31-byte solution:
MemberQ[IntegerDigits[#,32],4]&

Try it online!

Hello and welcome to PPCG. As it stands, your expression is a single Boolean value. Please fix your answer to either be a full program or a function (...#...& is often used in Mathematica).

Hello. Is this what you mean?

pls use https://tio.run/#mathematica instead of W|A to make sure it's valid mathematica code :P and you don't need the [n] at the end, just the &. Also since posts have edit history, it's fine to leave out previous entries, and the convention for old scores is <s>40</s> <s>36</s>

Yes. This is what I meant. 29 bytes.

I guess I have to get used to the functional programming style.

Java 8, 40 33 bytes
n->n.toString(n,32).contains("4")

Port of @Adám's APL (dzaima/APL) answer.
Try it online.
Explanation:
n->                 // Method with Integer parameter and boolean return-type
  n.toString(n,32)  //  Convert the input to a base-32 String
   .contains("4")   //  And check if it contains a "4"

Retina 0.8.2, 31 bytes
.+
$*
+`(1+)\1{31}
$1;
\b1111\b

Try it online! Link includes test cases. Outputs zero unless the number is rude. Works by converting the input to unary and then to unary-encoded base 32 and counting the number of 4s in the result.

><>, 28 bytes
Outputs 4 for rude numbers throws an exception for non-rude numbers.
:1(?^:" ":\
,&-v?=4:%&/
 ;n<

Try it online!

An exception is acceptable, the C# answer does it

Java 8, 28 22 21 bytes
n->n%32==4|n>>5%32==4

Inspired by @kevin-cruijssen's answer. Only works for 2 hands.
Try it online!
Explanation:
n->                 // Method with int parameter and boolean return-type
  n%32              // Only consider right 5 bytes (fingers)
  ==4               // Middle finger
  | ... n>>5       // Repeat with shifted bits for other hand

I'm pretty sure answers have to work with both hands

Jelly, 6 bytes
ḃ32=4Ẹ

Try it online!
Returns 1 if the number is rude, 0 otherwise
ḃ32=4Ẹ
ḃ32      # convert to base 32
   =4    # For each entry, is it equal to 4?
     Ẹ   # Are any equal to 4??

Why not ḃ32i4?

Scala, 44 bytes
Try it online!
def f(a:Int):Boolean=a%32==4||(a>0&&f(a/32))

This appears to have a typo. With it fixed it works. I curious how this could happen, when you're actually giving a TIO link that has the typo in it as well.

sorry for my typo.

Vyxal G, 36 bits1, 4.5 bytes
32τ4=

Try it Online! (link is to bitstring)
Suggested by @lyxal
Vyxal, 37 bits1, 4.625 bytes
32τ4c

Try it Online! (link is to bitstring) or see all the rude numbers up to 200
Explanation
32τ4=  # Implicit input
32τ    # Input in base 32
   4=  # Equals 4 (vectorised)?
       # Implicit output of maximum

32τ4c  # Implicit input
32τ    # Input in base 32
   4c  # Contains 4?
       # Implicit output

Try it Online! for 4.5 bytes

Thunno 2, 5 bytes
32B4Ƈ

Try it online! or see all the rude numbers up to 200
Does the base-32 (32B) version of the input contain 4 (4Ƈ)?

Perl 5, 43 bytes
sub f{sprintf("%099b",@_)=~/00100(.{5})*$/}

Try it online!

Ink, 38 36 bytes
=r(n)
{n:{n%32-4:->r(n/32)|1}|0}->->

Try it online!
Edit: Saved 2 bytes by simplifying the first conditional to "if n" rather than "if n>0".

K   8 Bytes
|/4=32\:

True if any digit of 32-base is 4

32\: converts its argument to 32-base
4=32\: compares 4 with each of the digits of 32: (generates a boolean list)
|/ is max-over the boolean list (any)

NOTES:

Use example: for argument 131 |/4=32\:131 returns 1b (1b for true 0b for false)
For all the case tests: (|/4=32\:)'0 3 4 25 36 127 131 returns 0010101b
If a function is needed, use {|/4=32\:x} (lambda, 11 Bytes) or with name r:{|/4=32\:x}. For all case tests {|/4=32\:x}'0 3 4 25 36 127 131 or r'0 3 4 25 36 127 131
4 in 32\: is easier to read than |/4=32\:, but it's longer (9 bytes)

Java 1, 42 40 bytes
r(int n){return n>0&&(4==n%32|r(n>>5));}

Edit: Replaced ternary operator with && to save 1 char, thanks to @Dillon Davis, which works due to short-circuit; inspiring me to change || to | to save another character
Try it online.
Explanation:
r(int n)        // Method with int parameter and boolean return-type
  n>0           // Stop recursion if no more bits
  &&            // Short-circuit stops recursion
  n%32=4        // Rude
  | r(n>>5)     // Recurse with shifted bits

Saves 1 byte r(int n){return n>0&&(4==n%32||r(n>>5));}

@DillonDavis Thanks! And that inspired me to save another byte changing || to |

Kotlin, 24 bytes
Simple base-32 conversion approach.
{'4' in it.toString(32)}

{  // lambda implicitly takes an int and returns a boolean
 '4' in  // 4 is within...
        it.toString(32)  // arg written in base-32
}

Try it online!

05AB1E, 5 bytes
32в4¢

Try it online!
Returns a truthy value (> 1) if the input is a rude number, and 0 otherwise. Uses a conversion to base 32 (to group by 5 bits) and tests for a 4 (00100 in binary, a rude number)

lol, there's already a 5-byter

That is a different language.

Perl 6, 16 bytes
{.base(32)~~/4/}

Returns ｢4｣ (truthy) when given a rude number and Nil (falsy) otherwise.

GolfScript, 10 bytes
Empty list is false, a list with something is true. (Seems like cheating. But it isn't.)
~32base 4&

Try it online!
Explanation
~           # Evaluate the input
 32base     # Convert to base-32
            # Copy
        4&  # Setwise and: does this list have 4?