title: Is it a Cyclops number? "Nobody" knows!

text:
# Question
Title: Is it a Cyclops number? "Nobody" knows!
**Task:**

Given an integer input, figure out whether or not it is a Cyclops Number.

What is a Cyclops number, you may ask? Well, it's a number whose binary representation only has one `0` in the center!

**Test Cases:**

```
Input | Output | Binary  | Explanation
--------------------------------------
0     | truthy | 0       | only one zero at "center"
1     | falsy  | 1       | contains no zeroes
5     | truthy | 101     | only one zero at center
9     | falsy  | 1001    | contains two zeroes (even though both are at the center)
10    | falsy  | 1010    | contains two zeroes
27    | truthy | 11011   | only one zero at center
85    | falsy  | 1010101 | contains three zeroes
101   | falsy  | 1100101 | contains three zeroes
111   | falsy  | 1101111 | only one zero, not at center
119   | truthy | 1110111 | only one zero at center

```

**Input:**

* An integer or equivalent types. (`int`, `long`, `decimal`, etc.)
* Assume that if evaluating the input results in an integer overflow or other undesirable problems, then that input doesn't have to be evaluated.

**Output:**

* Truthy or falsy.
* Truthy/falsy output must meet the used language's specifications for truthy/falsy. (e.g. C has `0` as false, non-zero as true)

**Challenge Rules:**

* Input that is less than 0 is assumed to be falsy and thus does not have to be evaluated.
* If the length of the binary representation of the number is even, then the number cannot be a Cyclops number.

**General Rules:**

---

This is my first **Programming Puzzles & Code Golf** challenge, so any feedback on how I should improve would be much appreciated!

# Answer
# Japt, 8 bytes

```
1¥¢q0 äè

```

Run it online

## Explanation:

```
1¥¢q0 äè
                                                              119
  ¢          // Convert the input into a binary string        "1110111"
   q0        // Split the string on "0"                       ["111","111"]
      ä      // Reduce each item by:                            a     b
       è     //   Seeing how many times a is found in b       [1]
 1¥          // == 1; See if the result equals 1              True

```

The idea is to split the binary string at `0`, which would yield two items if there is only one `0`. Then we see if the first item matches the second to ensure it is palindromic. If the binary string contains multiple `0`s, then the reduce would return a multi-item array and that would fail the `==1` condition. If the binary string does contain one `0`, but is not palindromic, `äè` will return `0` because `b` contains `0` matches of `a`.
> 11 votes

# Answer
# Python 2, 30 bytes

```
lambda n:(2*n^2*n+3)**2==8*n+9

```

Try it online!

Note that `2*n^2*n+3` is the bitwise xor of `2*n` and `2*n+3`, because that's Python's operator precedence.
> 24 votes

# Answer
# x86 Machine Code, 17 bytes

```
8D 47 01 31 F8 89 C2 F7 D2 0F AF C2 8D 44 78 02 C3

```

The above bytes define a function that accepts a 32-bit integer input value (in the `EDI` register for this example, following a common System V calling convention, but you could actually pick pretty much any input register you wanted without affecting the size of the resulting code), and returns a result (in the `EAX` register) indicating whether the input value is a Cyclops number.

The input is assumed to be an unsigned integer, since the challenge rules state that we can ignore negative values.

The decision logic is borrowed from Neil's answer: since a Cyclops number has the form \\$ n = (2 ^ k + 1) (2 ^ { k - 1 } - 1) \\$, we can use a series of bit-twiddling operations to check the input.

*Note:* The return value is truthy/falsy, but the semantics are reversed, such that the function will return falsy for a Cyclops number. I claim this is legal because machine code doesn't have "specifications for truthy/falsy", which is the requirement in the question. (See below for an alternative version if you think this is cheating.)

In assembly language mnemonics, this is:

```
; EDI = input value
; EAX = output value (0 == Cyclops number)
8D 47 01           lea    eax, [edi + 1]          ; \ EAX = ((EDI + 1) ^ EDI)
31 F8              xor    eax, edi                ; /
89 C2              mov    edx, eax                ; \ EDX = ~EAX
F7 D2              not    edx                     ; /
0F AF C2           imul   eax, edx                ; EAX *= EDX
8D 44 78 02        lea    eax, [eax + edi*2 + 2]  ; EAX  = (EAX + (EDI * 2) + 2)
C3                 ret                            ; return, with EAX == 0 for Cyclops number

```

**Try it online!**

---

As promised, if you think it's cheating to invert the semantics of truthy/falsy even in machine code where there are no real standards or conventions, then add three more bytes, for a total of **21 bytes**:

```
; EDI = input value
; AL  = output value (1 == Cyclops number)
8D 47 01           lea    eax, [edi + 1]          ; \ EAX = ((EDI + 1) ^ EDI)
31 F8              xor    eax, edi                ; /
89 C2              mov    edx, eax                ; \ EDX = ~EAX
F7 D2              not    edx                     ; /
0F AF C2           imul   eax, edx                ; EAX *= EDX
8D 44 78 01        lea    eax, [eax + edi*2 + 1]  ; EAX  = (EAX + (EDI * 2) + 1)
40                 inc    eax                     ; EAX += 1
0F 94 C0           setz   al                      ; AL = ((EAX == 0) ? 1 : 0)
C3                 ret                            ; return, with AL == 1 for Cyclops number

```

The first half of this code is the same as the original (down through the `imul` instruction). The `lea` is almost the same, but instead of adding a constant 2, it only adds a constant 1. That's because the following `inc` instruction increments the value in the `EAX` register by 1 in order to set the flags. If the "zero" flag is set, the `setz` instruction will set `AL` to 1; otherwise, `AL` will be set to 0. This is the standard way that a C compiler will generate machine code to return a `bool`.

Changing the constant added in the `lea` instruction obviously doesn't change the code size, and the `inc` instruction is very small (only 1 byte), but the `setz` instruction is a rather whopping 3 bytes. Unfortunately, I can't think of any shorter way of writing it.
> 19 votes

# Answer
# Regex (ECMAScript), ~~60~~ ~~58~~ ~~57~~ ~~60~~ 58 bytes

The input \\$n\\$ is in unary, as the length of a string of `x`s.

**SPOILER WARNING**: For the square root, this regex uses a variant of the generalized multiplication algorithm, which is non-obvious and could be a rewarding puzzle to work out on your own. For more information, see an explanation for this form of the algorithm in Find a Rocco number.

*-2 bytes by allowing backtracking in the search for \\$z\\$*
*-1 byte thanks to Grimmy, by searching for \\$z\\$ from smallest to largest instead of vice versa*
*+3 bytes to handle zero*
*-2 bytes by moving the square root capture outside the lookahead*

This works by finding \\$z\\$, a perfect square power of 2 for which \\$n=2(n-z)+\sqrt{z}+1\\$. Only the largest perfect square power of 2 not exceeding \\$n\\$ can satisfy this, but due to a golf optimization, the regex tries all of them starting with the smallest. Since each one corresponds to a cyclops number, only the largest one can result in a match.

```
^(x*)(?!(x(xx)+)\2*$)(x(x*))(?=(?=(\4*)\5+$)\4*$\6)x\1$|^$

```

Try it online!

```
^                 # N = tail
(x*)              # tail = Z, with the smallest value that satisfies the following
                  # assertions (which is no different from the largest value that
                  # would satisfy them, since no more than one value can do so);
                  # \1 = N - Z

(?!(x(xx)+)\2*$)  # Assert Z is a power of 2

# Assert Z is a perfect square, and take its square root
(x(x*))           # \4 = square root of Z; \5 = \4 - 1; tail = N - \1 - \4
(?=(\4*)\5+$)     # iff \4*\4 == Z, then the first match here must result in \6==0
(?=\4*$\6)        # test for divisibility by \4 and for \6==0 simultaneously

# Assert that N == \1*2 + \4 + 1. If this fails, then due to a golf optimization,
# the regex engine will backtrack into the capturing of \4, and try all smaller
# values to see if they are the square root of Z; all of these smaller values will
# fail, because the \4*\4==Z multiplication test only matches for one unique value
# of \4.
x\1$

|^$               # Match N==0, because the above algorithm does not

```
> 12 votes

# Answer
# JavaScript (Node.js), 20 bytes

```
p=>~p==(p^=p+1)*~p/2

```

Try it online!

Maybe this is correct, maybe.

Thanks Grimy, 1 byte saved.

---

# JavaScript (Node.js), 32 bytes

```
f=(p,q)=>p&1?f(p/2,q+q|2):!(p^q)

```

Try it online!

---

# JavaScript (Node.js), 34 bytes

```
p=>/^(1*)0\1$/.test(p.toString(2))

```

Try it online!
> 9 votes

# Answer
# Japt,  ~~25~~ ~~19~~ ~~10~~ 9 bytes

```
¢êÅ©1¶¢èT

```

*Thanks to @Shaggy for -1 byte*

Try it online!
> 7 votes

# Answer
# Perl 6, 23 bytes

```
{.base(2)~~/^(1*)0$0$/}

```

Try it online!

Regex based solution
> 7 votes

# Answer
# Mathematica (Wolfram language), ~~32~~ 31 bytes

*1 byte saved thanks to J42161217!*

```
OddQ@Log2[#+Floor@Sqrt[#/2]+2]&

```

Try it online!

Pure function taking an integer as input and returning `True` or `False`. Based on the fact (fun to prove!) that a number `n` is Cyclops if and only if `n` plus the square root of `n/2` plus `2` rounds down to an odd power of 2. (One can replace `Floor` by either `Ceiling` or `Round` as long as one also replaces `+2` by `+1`.) Returns `True` on input `0`.
> 7 votes

# Answer
# Ruby, 24 bytes

```
->x{x+x+2==(1+x^=x+1)*x}

```

Try it online!
> 6 votes

# Answer
# Japt, 8 bytes

```
¢ðT ¥¢Êz

```

Thanks to Luis felipe de Jesus Munoz for fixing my submission!

Try it Online!

# Old regex-based solution, 15 bytes

```
¤f/^(1*)0\1$/ l

```

Returns 1 for true, 0 for false.

Try it Online!
> 5 votes

# Answer
# Jelly,  ~~8~~  7 bytes

-1 thanks to Erik the Outgolfer (use isPalindrome built-in, `ŒḂ`, instead of `⁼Ṛ$`)

```
B¬ŒḂ⁼SƊ

```

A monadic Link accepting an integer which yields `1` (truthy) or `0` (falsey).

**Try it online!**

### How?

```
B¬ŒḂ⁼SƊ - Link: integer             e.g. 1    9          13         119
B       - to base 2                      [1]  [1,0,0,1]  [1,1,0,1]  [1,1,1,0,1,1,1]
 ¬      - logical NOT (vectorises)       [0]  [0,1,1,0]  [0,0,1,0]  [0,0,0,1,0,0,0]
      Ɗ - last three links as a monad:
  ŒḂ    -   is a palindrome?             1    1          0          1
     S  -   sum                          0    2          1          1
    ⁼   -   equal?                       0    0          0          1

```
> 5 votes

# Answer
# C (gcc), 26 bytes

```
f(n){n=~n==(n^=-~n)*~n/2;}

```

Try it online!

Port of Neil's answer. Relies on implementation-defined ordering of operations.

# C++ (clang), 38 bytes

```
int f(int n){return~n==(n^=-~n)*~n/2;}

```

Try it online!

Can't omit the types in C++, can’t omit the return in clang, otherwise identical.
> 5 votes

# Answer
# Brachylog, 8 bytes

```
ḃD↔Dḍ×ᵐ≠

```

This is a predicate that succeeds if its input is a Cyclops number and fails if its input is not a Cyclops number. Success/failure is the most fundamental truthy/falsey concept in Brachylog.

Try it online! Or, find all truthy outputs up to 10000.

### Explanation

```
          Input is an integer
ḃ         Get its binary representation, a list of 1's and 0's
 D        Call that list D
  ↔       When reversed...
   D      It's the same value D
    ḍ     Dichotomize: break the list into two halves
          One of these halves should be all 1's; the other should contain the 0
     ×ᵐ   Get the product of each half
       ≠  Verify that the two products are not equal

```

This succeeds only when given a Cyclops number, because:

* If the binary representation isn't a palindrome, `D↔D` will fail; in what follows, we can assume it's a palindrome.
* If there is more than one zero, both halves will contain at least one zero. So the products will both be zero, and `×ᵐ≠` will fail.
* If there is no zero, both halves will contain only ones. So the products will both be one, and `×ᵐ≠` will fail.
* That leaves the case where there is exactly one zero; since we already know we have a palindrome, this must be the central bit. It will appear in one half, causing that half's product to be zero; the other half will contain all ones, so its product will be one. Then we have 1 ≠ 0, `×ᵐ≠` succeeds, and the whole predicate succeeds.
> 5 votes

# Answer
# 05AB1E, 8 (or 9) bytes

```
bD0¢sÂQ*

```

Try it online or verify all test cases.

Returns `1` if truthy; `0` or any positive integer other than `1` as falsey. In 05AB1E only `1` is truthy and everything else is falsey, but I'm not sure if this is an allowed output, or if the output should be two consistent and unique values. If the second, a trailing `Θ` can be added so all outputs other than `1` become `0`:

Try it online or verify all test cases.

**Explanation:**

```
b     # Convert the (implicit) input-integer to a binary-string
 D    # Duplicate it
  0¢  # Count the amount of 0s
 s    # Swap to get the binary again
  ÂQ  # Check if it's a palindrome
 *    # Multiply both (and output implicitly)

  Θ   # Optionally: check if this is truthy (==1),
      # resulting in truthy (1) or falsey (0)

```

---

An arithmetic approach would be **10 bytes:**

```
LoD<s·>*Iå

```

Try it online or verify all test cases.

**Explanation:**

Creates a sequences using the algorithm \\$a(n) = (2^n-1)\*(2\*2^n+1)\\$, and then checks if the input-integer is in this sequence.

```
L        # Create a list in the range [1, (implicit) input-integer]
 o       # For each integer in the list, take 2 to the power this integer
  D<     # Create a copy, and decrease each value by 1
  s·     # Get the copied list again, and double each value
    >    # Then increase each value by 1
  *      # Multiply the numbers at the same indices in both lists
     Iå  # Check if the input-integer is in this list
         # (and output the result implicitly)

```
> 4 votes

# Answer
# Regex (ECMAScript), ~~53~~ 47 bytes

-6 bytes thanks to both Deadcode and Grimy

```
^((?=(x*?)(\2((x+)x(?=\5$))+x$))(?!\2{6})\3x)*$

```

Try it online!

*explanation by Deadcode*

This regex takes its input in unary, as a sequence of `x` characters in which the length represents the number. Properties of its binary representation are handled indirectly, by doing math on its unary representation.

It works by looping the following operation, which is a subtraction at every step:

* Trim the leftmost and rightmost `1` from the number's binary representation, if the `1` being trimmed from the left is immediately followed by another `1` or the full number is `101`

If and only if the initial input was a cyclops number, it will be the next smallest cyclops number at every step of the loop, e.g. `1110111``11011``101``0`. The regex matches if and only if the value is `0` at the end.

```
^                              # tail = N, the input number
(                              # While tail is odd and is >= 3, and has a leftmost "11"
                               # in its binary representation, trim off the leftmost and
                               # rightmost 1 from its binary representation. If it is a
                               # cyclops number, it will be the next smaller cyclops
                               # number on the next iteration.
    (?=
        (x*?)                  # Find the smallest \2 such that tail - 2*\2 satisfies the
                               # following assertion, i.e. that tail - 2*\2 = 2^k-1
                               # where k >= 2. In other words, assert tail is odd, and
                               # let \2 = (tail - 2^k + 1) / 2, where 2^k-1 has the
                               # largest value of k such that 2^k-1 <= tail. If tail is
                               # a cyclops number, then \2-1 will be the next smallest
                               # cyclops number;
                               # tail -= \2
        (                      # \3 = tool to make tail-1 = \2-1 (will be used later)
            \2                 # tail -= \2
            ((x+)x(?=\5$))+x$  # Assert tail = 2^k-1 where k >= 2
        )
    )
    (?!\2{6})                  # Assert that tail < 6*\2, which is a way of asserting
                               # that in tail's binary representation, the next 1 to the
                               # right of the one we'll be trimming is also 1. This
                               # prevents for example, trimming 10110111 -> 11011, which
                               # would give us a false positive. As a worst case example,
                               # let's say tail = 0b101111111111111111111111111111111111
                               # this would give us:
                               #             \2 = 0b001000000000000000000000000000000000
                               #           6*\2 = 0b110000000000000000000000000000000000
                               # So it's not quite exactly asserting that tail begins
                               # with "11" in its binary representation, and would
                               # continue looping in that case, but that doesn't matter
                               # because that number could never be trimmed into a
                               # cyclops number anyway. With any smaller value of tail
                               # that passes the other tests, we'd have:
                               #           tail = 0b101111111111111111111111111111111101
                               #             \2 = 0b000111111111111111111111111111111111
                               #           6*\2 = 0b101111111111111111111111111111111010
                               # and in this case tail >= 6*\2, so it stops the loop.
                               # On the other end of the scale is 0b101, which needs to
                               # be trimmed even though it doesn't have two leftmost 1
                               # bits in a row. And indeed, that works:
                               #           tail = 0b101
                               #             \2 = 0b001
                               #           6*\2 = 0b110
                               # In this case, it is just barely true that tail < 6*\2
                               # and the loop is allowed to continue one more step.
    \3x                        # tail = \2-1
)*
$                              # Assert that tail = 0 after the loop finished. This will
                               # be true iff N is a cyclops number. If it fails to match,
                               # backtracking cannot make it match, because everything in
                               # the loop is atomic.

```
> 4 votes

# Answer
# Haskell, 32 bytes

```
f n=or[2*4^k-2^k-1==n|k<-[0..n]]

```

Try it online!
> 4 votes

# Answer
# , ~~22~~ ~~19~~  ~~17~~  ~~15~~ 14 bytes

-3 bytes thanks to BolceBussiere !

-4 bytes thanks to ngn!

-1 byte thanks to Traws!

# , 14 bytes

```
1=1#.(*:|.)@#:

```

Try it online!
> 3 votes

# Answer
# Ruby, ~~27~~ 24 bytes

Convert to binary and check with a regex. Returns `0` if true, `nil` if false.

-3 bytes thanks to GB.

```
->n{"%b"%n=~/^(1*)0\1$/}

```

Try it online!

For two bytes more, there's a direct port of the Python solution:

```
->n{(2*n^2*n+3)**2==8*n+9}

```
> 3 votes

# Answer
## Batch, ~~39~~ 37 bytes

```
@cmd/cset/a"m=%1^-~%1,!(m/2*(m+2)-%1)

```

Explanation: A Cyclops number has the form \\$ n = (2 ^ k + 1) (2 ^ { k - 1 } - 1) \\$. The bitwise XOR then results in \\$ m = 2 ^ k - 1 \\$ from which we can recalculate \\$ n = \lfloor \frac m 2 \rfloor ( m + 2 ) \\$. This can then be used to test whether \\$ n \\$ was a Cyclops number.
> 3 votes

# Answer
# , ~~37~~ 33 bytes

```
(x=scan())%in%(2*4^(n=0:x)-2^n-1)

```

Try it online!

R doesn't have a built-in for converting to binary, so I simply used one of the formulae from OEIS to calculate a list of terms from the sequence.

`n<-0:x` generates a generous list of starting values. `2*4^(n<-0:x^2)-2^n-1)` is the formula from OEIS, and then it checks whether the input appears in that sequence using `%in%`.

-2 bytes by not having to handle negative inputs. -2 bytes by remembering I can change `<-` to `=`.
> 3 votes

# Answer
## Excel, ~~97~~ 63 Bytes

```
=A1=2*4^(ROUND(LOG(A1,4),0))-2^(ROUND(LOG(A1,4),0))-1

```

Calculates 2 numbers:

> Twice the nearest Power of 4
> `>Num|Binary|2*Power4|Binary`
> `> 1| 1| 2* 1= 2| 10`
> `> 2| 10| 2* 4= 8| 1000`
> `> 4| 100| 2* 4= 8| 1000`
> `> 20| 10100| 2*16=32|100000`

> 1 Plus the square root of the nearest Power of 4
> `>Num|Binary|1+√Power4|Binary`
> `> 1| 1|1+ √1= 2| 10`
> `> 2| 10|1+ √4= 3| 11`
> `> 4| 100|1+ √4= 3| 11`
> `> 20| 10100|1+ √16= 5| 101`

Then subtract the second number from the first:

> `>Num|Binary|2*Power4|Binary|1+√Power4|Binary|a-b|Binary`
> `> 1| 1| 2* 1= 2| 10|1+ √1= 2| 10| 0| 0`
> `> 2| 10| 2* 4= 8| 1000|1+ √4= 3| 11| 5| 101`
> `> 4| 100| 2* 4= 8| 1000|1+ √4= 3| 11| 5| 101`
> `> 20| 10100| 2*16=32|100000|1+ √16= 5| 101| 27| 11011`

And compare this result with the original number

**Old Method**

```
=DEC2BIN(A1)=REPLACE(REPT("1",1+2*INT(IFERROR(LOG(A1,2),0)/2)),1+IFERROR(LOG(A1,2),0)/2,1,"0")

```

Start with the Log-base-2 of A1 and round it down the nearest even number, then add 1.

Next create a string of that many `"1"`s, and replace the middle character with a `"0"` to create a Cyclops number with a binary length that is always odd, and the same as or 1 less than the binary length of A1

Then, compare it with the Binary representation of A1
> 3 votes

# Answer
# C (gcc),  ~~29 28~~  27 bytes

*Saved 1 byte thanks to @ceilingcat*

A port of the 21-byte JS answer by @tsh.

```
f(p){p=2*~p==~(p=-~p^p)*p;}

```

Try it online!
> 3 votes

# Answer
# Jelly, 9 bytes

```
BŒḂaB¬S=1

```

Try it online!
> 2 votes

# Answer
# Retina 0.8.2, ~~38~~ 37 bytes

```
.+
$*
+`^(1+)\1
$+0
10
1
^((1+)0\2)?$

```

Try it online! Link includes test cases. Edit: After clarification, previous solution didn't handle zero correctly. Explanation:

```
.+
$*

```

Convert from decimal to unary.

```
+`^(1+)\1
$+0
10
1

```

Convert from unary to binary, using the method from the Retina wiki.

```
^((1+)0\2)?$

```

Check for the same number of `1`s before and after the `0`, or an empty string (which is how the above conversion handles zero).
> 2 votes

# Answer
# Attache, 22 bytes

```
{Flip@_=_∧1=0~_}@Bin

```

Try it online!

## Alternatives

**27 bytes:** `{BitXor[2*_,2*_+3]^2=8*_+9}`

**27 bytes:** `{BitXor@@(2*_+0'3)^2=8*_+9}`

**27 bytes:** `{Palindromic@_∧1=0~_}@Bin`

**28 bytes:** `{BitXor[...2*_+0'3]^2=8*_+9}`

**28 bytes:** `{BitXor[…2*_+0'3]^2=8*_+9}`

**28 bytes:** `{Same@@Bisect@_∧1=0~_}@Bin`

**29 bytes:** `{_[#_/2|Floor]=0∧1=0~_}@Bin`

**30 bytes:** `Same@Bin@{_+2^Floor[Log2@_/2]}`

**30 bytes:** `{_[#_/2|Floor]=0and 1=0~_}@Bin`
> 2 votes

# Answer
# PHP, 74 bytes

```
function($x){return($c=strlen($a=decbin($x)))&1&&trim($a,1)===$a[$c/2|0];}

```

Try it online!

Or **61 bytes** using Arrow syntax:

```
fn($x)=>($c=strlen($a=decbin($x)))&1&trim($a,1)===$a[$c/2|0];

```

Try it online!

Totally naïve non-mathematical approach, just strings.

```
function cyclops( $x ) {
    $b = decbin( $x );     // convert to binary string (non-zero left padded)
    $l = strlen( $b );     // length of binary string
    $t = trim( $b, 1 );    // remove all 1's on either side
    $m = $b[ $l / 2 |0 ];  // get the middle "bit" of the binary string
    return
        $l & 1 &&          // is binary string an odd length?
        $t === $m;         // is the middle char of the binary string the same as
                           // string with left and right 1's removed? (can only be '0')
}

```

Or **60 bytes** based on @Chronocidal's algorithm above.

```
function($x){return decbin($x)==str_pad(0,log($x,2)|1,1,2);}

```

Try it online!
> 2 votes

# Answer
# Pyt, 17 bytes

```
ĐļƖĐ⁺2⇹^⇹ᵮ₂2⇹^-⁻=

```

Try it online!

No string manipulation required

```
ĐļƖĐ⁺2⇹^⇹₂2⇹^-⁻=

```

| Instruction | Stack | Note |
| --- | --- | --- |
| `Đ` | n,n | implicit input (n); duplicate onto stack |
| `ļƖ` | n,k | take base-2 log of n and cast to integer (k) |
| `Đ` | n,k,k | duplicate k on stack |
|  | n,k,k+1 | increment top of stack |
| `2⇹^` | n,k,2^(k+1) | raise 2 to the k+1 power |
|  | n,2^(k+1),k | swap the top two items on the stack |
| `ᵮ₂` | n,2^(k+1),k/2 | cast top of stack to float, then divide by 2 |
| `2⇹^` | n,2^(k+1),2^(k/2) | raise 2 to the k/2 power |
| `-⁻` | n,2^(k+1)-2^(k/2)-1 | subtract and decrement |
| `=` | True/False | check for equality; implicit print |
> 2 votes

# Answer
# Thunno, \\$ 8 \log\_{256}(96) \approx \\$ 6.58 bytes

```
bDZqs0c=

```

Attempt This Online!

Port of emirps's Vyxal answer.

## Thunno `P`, \\$ 9 \log\_{256}(96) \approx \\$ 7.41 bytes

```
bD0c1=sZq

```

Attempt This Online!

Port of Kevin Cruijssen's 05AB1E answer.

#### Explanation

```
bDZqs0c=  # Implicit input
bD        # Convert to binary and duplicate
  Zqs     # Check if it's a palindrome and swap
     0c=  # Is this equal to the count of 0s?
          # Implicit output

```

```
bD0c1=sZq  # Implicit input
bD         # Convert to binary and duplicate
  0c       # Count the number of "0"s in the string
    1=     # Is it equal to 1?
      sZq  # Swap and check if it's a palindrome
           # P flag multiplies them together
           # Implicit output

```
> 2 votes

# Answer
# GolfScript, ~~31~~ ~~35~~ 26 bytes

*-5 thanks to @DLosc*

```
.!5*+2base..-1%=\{0=},,1=&

```

Link includes test cases.

Try it online!

# Explanation

```
.!5*+2base..-1%=\{0=},,1=& | whole program
.!5*+                      | if the input is 0, make it 5 (smallest non-zero cyclops number)
     2base..               | push the binary version of the input
            -1%            | push the reversed version of the binary
               =           | is it equal to the non-reversed version?
                \{0=},,    | count the number of zeros
                       1=  | is it equal to 1?
                         & | are both of the above checks true?

```
> 2 votes

# Answer
# Vyxal, 8 bytes

```
Π:Ḃ=$0O=

```

Try it Online!

Different approach from the other Vyxal answer.

```
Π        # binary of input
  Ḃ=     # the equality of the reversed version of it to itself (0 for non palindrome, 1 for palindrome)
       = # is equal to
 :  $0O  # the count of 0s in itself

```

Could potentially be golfed
> 2 votes

# Answer
# Regex (ECMAScript), ~~65~~ ~~59~~ ~~57~~ 58 bytes

*+1 byte to handle 0 correctly*

```
^((((x*)xx)\3)x)?(?=(\1*)\2*(?=\4$)((x*)(?=\7$)x)*$)\1*$\5

```

Try it online!

Works by asserting the input is of the form \\$ (2^k - 1) (2^{k+1} + 1) \\$. Ties Deadcode's answer but with a completely different algorithm.
> 1 votes

# Answer
# APL(NARS), 57 char, 114 bytes

```
{⍵≤0:1⋄k=m←⌈k←2÷⍨≢v←{(2⍴⍨⌊1+2⍟⍵)⊤⍵}⍵:0⋄((,1)≡∪v∼⍦0)∧∼m⊃v}

```

test:

```
  f←{⍵≤0:1⋄k=m←⌈k←2÷⍨≢v←{(2⍴⍨⌊1+2⍟⍵)⊤⍵}⍵:0⋄((,1)≡∪v∼⍦0)∧∼m⊃v}
  ⎕fmt f¨0 1 5 12 27 85 101 119
┌8───────────────┐
│ 1 0 1 0 1 0 0 1│
└~───────────────┘

```

This below would be (modulus bugs) the function that would convert a positive integer number omega in one array of digits in base alpha:

```
{(⍺⍴⍨⌊1+⍺⍟⍵)⊤⍵}

```
> 1 votes

# Answer
# Excel, 101 ~~107~~ bytes

-6 bytes thanks to @Chronocidal.

```
=AND(ISEVEN(LOG(A1,2)),MID(DEC2BIN(A1),LEN(DEC2BIN(A1))/2+1,1)="0",LEN(SUBSTITUTE(DEC2BIN(A1),1,))=1)

```

Performs 3 checks:

* Odd length

```
ISEVEN(LOG(A1,2))
```
* Middle character is `0`

```
MID(DEC2BIN(A1),LEN(DEC2BIN(A1))/2+1,1)="0"
```
* There is a single `0`

```
LEN(SUBSTITUTE(DEC2BIN(A1),1,))=1
```
> 1 votes

# Answer
# C++ (gcc), ~~142~~ \\$\cdots\\$ ~~59~~ 55 bytes

Saved ~~10~~ a whopping ~~21~~ 23 bytes thanks to ceilingcat!!!

```
int f(int n){int c=__builtin_ctz(~n);n=(n>>c)+2==2<<c;}

```

Try it online!

### Ungolfed:

```
bool is_cyclops(int n)
{
    int ones = 1;
    while ((n & 1) == 1)
    {
        ++ones;
        n /= 2;
    }
    while (--ones, n /= 2, (n & 1) == 1)
    {
        // nothing to do
    }
    return n == 0 && ones == 0;
}

```
> 1 votes

# Answer
# C++ (clang), ~~72~~ ~~68~~ ~~67~~ 60 bytes

As with Neil's and Grimmy's solutions, this works by asserting that the input is of the form \\$(2^k-1)(2^{k+1}+1)\\$.

5 bytes were dropped thanks to Arnauld, by changing `((x)+1)` to `-~(x)` and `((x)-1)` to `~-(x)`, and then changing `n-a*-b` to `n+a*b`. An additional 7 bytes were dropped thanks to ceilingcat.

```
int f(int n){int z,k=1;while((z=n+~-k*~(k*=2))>0);return!z;}

```

Try it online!

Alternative 60 byter:

```
int f(int n){for(int o=n,k=1;n>0;)n=o+~-k*~(k*=2);return!n;}

```

Try it online!

Ungolfed:

```
bool is_cyclops_number(int n)
{
    for (int k=1;; k*=2)
    {
        int z = n - (k - 1) * (k*2 + 1);
        if (z == 0)
            return true;
        if (z < 0)
            return false;
    }
}

```

# C (gcc) - x86 & most others, ~~41~~ 34 bytes

Returns zero for true and nonzero for false.

```
k;f(n){for(k=1;n+~-k*~(k*=2)>0;);}

```

Try it online!

This demonstrates why I hate the implicit accumulator return value exploit that is commonly used in C submissions and less often in C++ submissions. It's fragile and very much architecture dependent. Here, it depends upon the comparison operator `>` not changing the value of the accumulator.

I did notice something quite curious regarding the ARM gcc assembly code. It appears that the return value hack is being explicitly supported, by copying the intermediate result `r3`, which wasn't stored into any variable, into the accumulator `r0` once the loop is done:

```
        cmp     r3, #0
        bgt     .L2
        nop
        mov     r0, r3

```

Similarly on PowerPC gcc, where register `3` carries the return value:

```
        cmpwi 7,9,0
        bgt 7,.L2
        mr 3,9

```

Similarly on RISC-V gcc, where `a0` carries the return value:

```
       add   a5,a5,a4
       bgtz  a5,10144 <f+0x12>
       nop
       mv    a0,a5

```

In fact, it appears the trick works on all but one of the architectures on godbolt. On MSP430 gcc 6.2.1, it yields the code with the equivalent of `return 0` (as the return value is passed through `R12`):

```
        MOV.B   #0, R12
        CMP.W   R13, R12 { JL .L2
        NOP

```
> 1 votes

# Answer
## VBA, ~~41~~ 36 Bytes

```
x=2^Int([Log(A1,4)]):?[A1]=2*x^2-x-1

```

Run in the Immediate window, with Explicit Declaration turned off. Input is cell `A1` of the active sheet. Outputs True/False to the immediate window.

Uses the same logic as my Excel Answer to find the Cyclops number of the same number of bits (or 1 bit shorter if there are an even number!) and then compares that with the input.

Saves some bytes when calculating Cyclops numbers by reducing them to the form `y = 2x^2 - x - 1` (where `x = n-1` for the *nth* Cyclops number, or `x = 2^Int(Log([A1])/Log(4))` to find the largest Cyclops number with a lesser-or-equal number of bits) and storing x in a variable

(-5 Bytes thanks to Taylor Scott!)
> 1 votes

# Answer
# Stax, ~~9~~ 7 bytes

```
ç8┤-½Θ■

```

Run and debug it
> 1 votes

# Answer
# Haskell, 82 bytes

```
import Text.Printf
(`all`[(==)<*>reverse,("0"==).filter(<'1')]).flip($).printf"%b"

```

And a port of xnor's Python solution:

# Haskell, 47 bytes

```
import Data.Bits
\n->(2*n`xor`(2*n+3))^2==8*n+9

```
> 1 votes

# Answer
# K (ngn/k), 19 bytes

```
{1=(~x)+/~a&|a:2\x}

```

Try it online!

`{` `}` function with argument `x`

`2\x` the bits of `x`

`a:` assign to `a`

`a&|a` *and* between `a` and its reverse (`|a`)

`~` *not*

`+/` sum

`(~x)` use "not `x`" as the initial value for the sum. this is to correct for `2\x` returning an empty list of bits when `x` is 0

`1=` compare with 1
> 1 votes

# Answer
# Gaia, ~~10~~ 9 bytes

```
b:ṭ¤0C1=∧

```

Try it online!

Verify All Test Cases

```
b:		% convert to binary and dup
  ṭ		% is it a palindrome?
        ∧	% and
   ¤0C		% is the count of zeros
      1=	% equal to 1?
		% implicit print top of stack

```
> 1 votes

# Answer
# dc, ~~62~~ 60 bytes

```
[2~rd0<B]dsBx1kz2/szsi[1r-si]sC[zlz=Cli*siz0<M]sMz1=Cz1<Mlip

```

Try it online!

`dc` has no native truthy/falsy values (conditionals either execute a macro or they don't); using 1 for truthy and 0 for falsy, I hope that's ok.

```
[2~rd0<B]dsBx          # Basic breakdown into binary. Every digit is a stack entry. Luckily this
                       # also leaves an extra 0 on the stack.
1k                     # Set precision to one - needed it at 0 for the binary-ifier.
z2/sz                  # Divide the stack depth by 2 and store it in 'z'. This is why we're lucky
                       # that the binary-ifier leaves an extra bit on the stack! Numbers with even
                       # numbers of binary digits will now have an odd number & this value will be
                       # (whatever).5 which... isn't a valid stack depth.
si                     # Seed 'i' which is our truthiness register w/ that extra 0
[1r-si]sC              # Macro 'C' toggles the top of stack between 0 and 1 by subtracting it from 1.
                       # It stores this in 'i'. This is the only way 'i' ever becomes 1.
[zlz=Cli*siz0<M]sM     # First we test if we're at the position of the stack that matches up with
                       # 'z', and run 'C' if so. Thus, if we're in the 'Cyclops' position (the
                       # middle), we'll flip that from a 0 to a 1 or vice versa. Next we load 'i'
                       # and multiply it by top of stack, putting that back in 'i'. For the first half
                       # this whole thing does nothing but multiply stuff by zero. In the middle
                       # position (if there is one) it sets 'i' to 1 if it's a zero. For the rest of
                       # the digits, it multiplies by '1' if things are ok, and '0' if there's another
                       # (Cyclops-invalidating) zero.
z1=Cz1<M               # 1 and 0 don't work w/o special treatment. Run 'C' if it's one of these,
                       # otherwise start 'M'
lip                    # Print 'i'

```

Golfed off two bytes because my brain was fried and I was using a wasteful, convoluted method of toggling between 1 and 0.
> 1 votes

# Answer
# Zsh `--extendedglob`, 30 bytes

```
>$[[##2]$1]
<`ls|rev`~*0*0*~1#
```

Attempt This Online!

Outputs via exit code (`0` = is a cyclops number, `1` = not a cyclops number).

* `>` \- create the file
    + `$[[##2]$1]` \- the input in base 2
* `<`ls|rev`~*0*0*~1#` \- try to find a file that matches this pattern:
    + ``ls|rev`` \- the file in reverse (i.e. palindromic)
    + `~` \- but not this pattern
        - `*0*0*` \- more than one 0
    + `~` \- and not this pattern either
        - `1#` \- one or more 1s

The exit code depends on whether or not the pattern matched and the file could be found.
> 1 votes

# Answer
# Burlesque, 21 bytes

```
b2JXXRA'0==j'0CN1==&&

```

Try it online!

```
b2   # As binary
J    # Duplicate
XX   # Split into chars (RA is supposed to work with strings but doesn't)
RA   # Get middle
'0== # Is 0
j    # Reorder stack
'0CN # Count of 0s
1==  # ==1
&&   # And

```

Shorter, but sadly doesn't work for zero case because `2dg` returns empty list

# Burlesque, 16 bytes

```
2dgJRAj0CN-.||n!

```

Try it online!

```
2dg # Base 2 as list of digits
J   # Duplicate
RA  # Get middle
j   # Reorder stack
0CN # Count 0s
-.  # Decrement (i.e 1 -> truthy, else falsy)
||n!# not or (Check both zero)

```
> 1 votes

# Answer
# Vyxal, 9 bytes

```
b0₌O€vL≈=

```

Try it Online!

Output 0 → False, 1 → True

```
b         # To binary array
 0        # Push 0
  ₌       # Parallel apply next two operators:
   O      #   Count how many "0" and
    €     #   Split at "0"
     vL   # Lengths of parts
       ≈  # If its equal return 1
        = # If its equal number of zeroes, return 1, else 0

```
> 1 votes

# Answer
# Swift 5.7, 60 bytes

```
{nil != (try?#/(1+)0\1/#.wholeMatch(in:String($0,radix:2)))}

```

SwiftFiddle link

Swift 5.7 introduced Regex literals, delimited by `#/`...`/#`. This code attempts to match the regex `(1+)0\1` against the string, and returns whether or not it succeeded. Input may be any `BinaryInteger`.

I'm not certain that this is shorter than bit manipulation, but this is shorter than the existing answer.
> 1 votes

# Answer
# Erlang 37 bytes

```
f(x)->Y=2*X bxor (2*X+3),Y*Y==8*X+9.

```
> 1 votes

# Answer
# Vyxal, 55 bitsv2, 6.875 bytes

```
b†Ḃ₍⁼∑≈

```

Try it Online!

Bitstring:

```
0111000000100000010011101011101001010010110100100111000

```

```
b†Ḃ₍⁼∑≈
b†       # Convert to binary, then invert each bit
  Ḃ      # Push the list of inverted bits and its reverse
   ₍  ≈  # is each item in the list equal?
    ⁼    # does the reverse of the inverted bits equal the inverted bits
     ∑   # sum of the bits

```

Created with the help of Luminespire.

7 byter (before encoding) with a completely different method.

Edit: Apparently this is a port of Jelly but I didn't realize

Since the equality check can only be 0 or 1, and the sum of the inverted bits is always at least 1 for any nonzero number, the values can only be equal if there is exactly one "1" in the inverted binary representation and that "1" is directly in the middle
> 1 votes

# Answer
# Factor, 69 bytes

```
: f ( n -- ? ) >bin [ dup reverse = ] [ [ 48 = ] count 1 = ] bi and ;

```

Try it online!
> 0 votes

# Answer
# Java (OpenJDK 8), 135 130 bytes

Uses the Formula described here: A129868

```
(n)->java.util.stream.IntStream.range(0,16).map(r->((Double)(Math.pow(2,2*r+1)-(Math.pow(2,r)-1)-2)).intValue()).anyMatch(c->c==n)

```

Try it online!
> 0 votes

# Answer
**Swift, 161 bytes**

```
func c(a:Int)->Int{
    let b=String(a,radix:2)
    let f=b.firstIndex(of:"0")
    return a>=0 && f==b.lastIndex(of:"0") && f?.encodedOffset==b.count/2 ? 1 : 0
}

```

Try it online!
> 0 votes

# Answer
# Perl 5 `-p`, 32 bytes

```
$_=(sprintf'%b',$_)=~/^(1*)0\1$/

```

Try it online!
> 0 votes

# Answer
# Java, 201 bytes (compilable)

Hmm, a different approach in java, runnable on commandline (so there is much to cut out).

```
class Z{public static void main(String[]a{a=Integer.toBinaryString(Integer.valueOf(a[0])).split("0");System.out.println(a.length==0?1:(a.length!=2?1:a[0].length()-a[1].length()+a.length-2)==0?1:0);}}

```

prints 0 for non cyclops and 1 for cyclops numbers.
> 0 votes

# Answer
# PHP

The shortest code should be this:

```
preg_match('`^(?<l>1*)0\k{l}$`', decbin($n));

```

Here the script to test it:

```
$inputs = [
    0,
    1,
    5,
    9,
    10,
    27,
    85,
    101,
    111,
    119,
];

function isCyclop($n) {
    return preg_match('`^(?<l>1*)0\k{l}$`', decbin($n));
}

foreach ($inputs as $input) {
    echo "$input : ".(isCyclop($input)?'truthy':'falsy').PHP_EOL;
}

```
> 0 votes

# Answer
# Java, 96 bytes

```
n->{String[]a=Integer.toBinaryString(n).split("0");return n==0||a.length==2&&a[0].equals(a[1]);}

```

Try it online!
> 0 votes

# Answer
## Perl 6 (26 bytes)

```
{so .base(2)~~/^(1*)0$0$/}

```
> 0 votes

# Answer
# Pip, 87 bytes

```
a:qTa<=1{((a%2)=0)?(x:"0".x)(x:"1".x)a//:2}1=a?x:"1".xsc:x^"0"x=0|#x%2=1&(c0)=(c1)&#c=2

```

Try it online!
> 0 votes

# Answer
# Pip, 15 bytes

```
YTBa^0 2=#y&$=y

```

Try it online!

A much shorter pip solution.

## Explanation

```
YTBa^0 2=#y&$=y a → input integer
YTBa^0         Yank binary representation of a into var y, split on 0's
       2=#y     Length of y = 2?
           &$=y and all items of y are equal?
                Implicit output of boolean

```
> 0 votes

# Answer
# \>\<\>, 45 bytes

```
!v:2%$2,:1%-:1(?!
1\~
*>l2=?vl3=?0${*
$0=*n;>

```

Try it online!
> 0 votes

# Answer
# Java 8, 66 ~~69~~ bytes

> -3 bytes thanks to @ceilingcat !

```
n->{int r=0,i=0;for(;i<16;)r+=n-~(1<<i)==1<<i+++i?1:0;return r>0;}

```

Try it online!

Don't hesitate to ask if this needs any explanation!

---

Alternative solution really close using Streams (**70 bytes**) :

```
n->"0123456789:;<=>?".chars().anyMatch(e->n-~(1<<e-48)==1<<2*(e-48)+1)

```
> 0 votes

# Answer
# Thunno 2, 8 bytes

```
ḃDḲ=s0c=

```

Attempt This Online!

Port of emirps's Vyxal answer.

#### Explanation

```
ḃDḲ=s0c=  # Implicit input
ḃD        # Convert to binary; duplicate
  Ḳ=s     # Check if palindrome; swap
     0c=  # Equals the count of 0s?
          # Implicit output

```
> 0 votes

# Answer
# Uiua, 17 characters (32 bytes UTF-8)

`↥↧≍⇌.∶=1/+¬.⋯∶=0.`

Explanation of ungolfed version:

```
↥⊃(↧⊃(≍⇌.)(=1/+¬)⋯)(=0)
↥⊃                   (=0)  # n is zero, or
                  ⋯       # the binary expansion of n
   ↧⊃      (=1/+¬)         # sums to 1 when all its bits are flipped
   ↧⊃(≍⇌.)                # and matches itself reversed

```
> 0 votes

# Answer
# Japt, 8 bytes

Adding to the collection of 8-byte Japt solutions; can't seem to come up with anything shorter.

```
¢¶¢Ôp¢èT

```

Try it (Includes all test cases)

```
¢¶¢Ôp¢èT     :Implicit input of integer U
¢            :Convert to binary
 ¶           :Check for equality with
  ¢Ô         :  Convert U to binary and reverse
    p        :  Repeated
     ¢è      :    Convert U to binary and count the occurrences of
       T     :      0

```
> 0 votes

---
Tags: code-golf, number, decision-problem, binary
---


title: Last Week Day Of The Month

text:
# Question
Title: Last Week Day Of The Month
# Introduction

This challenge was inspired by a seemingly simple task requested at work that couldn't easily be done in Microsoft Teams. At least not from what we could find!

## Task

Your task, if you choose to accept it, is to output the last week day of **any month** in **any year**.

## Input

You can input the desired month/year in whatever format you like, but it must take in an input. Having these hard-coded into the calculations **doesn't count!**

Input examples include but are not limited to:

* `08/2023`
* `October 1678`
* `1/2067`

## Output

Your output must be the last week day of the month in the below format:

***Tuesday 31st***

## Test cases

| Input | Output |
| --- | --- |
| `10/2023` | `Tuesday 31st` |
| `February 2017` | `Tuesday 28th` |
| `09/1674` | `Friday 28th` |
| `1/2043` | `Friday 30th` |

## Assumptions / Stipulations

* You can assume the inputs are always in a workable format and not null
* Calendar is the Gregorian Calendar
* Monday, Tuesday, Wednesday, Thursday and Friday are all week days. Saturday and Sunday are NOT valid week days for this task
* You can ignore public holidays

PS. I got the test cases from timeanddate.com

## Current Winner (28th November 2023)

> PHP - Kaddath \- 55 Bytes https://codegolf.stackexchange.com/a/266340/91342

# Answer
> 7 votes
# Bash and GNU Date, ~~84~~ 83 bytes

Thanks to gildux for shaving 1 byte.

```
s=(1 2)
m=1$1+month
date -d$m-$((s[`date -d$m +%w`]+1))day +%A\ %eth|sed s/1th/1st/

```

Input format is the month name and year as a single word, e.g. `October2023` or `sep2026`.

An English locale (such as the standard `C` locale) is required for the day names to be in English.

You might need to unset `TZ` environment variable to get proleptic Gregorian dates.

---

### How it works

1. **`m=1$1+month`**: Create a `date` input that is one month later than the start of the target month (ie. the first day of the following month). GNU Date allows us to omit all the spaces, which is helpful.
2. **`date -d$m +%w`**: Obtain the day of week of the first day of the following month.
3. **`$((s[…]+1))`**: We'll need to back up one day, plus an additional day if following month starts on Sunday (weekday 0) or an additional two days if it starts on Monday (weekday 1).

The array `s` is incomplete; the arithmetic works because empty string concatenates with `+1` to give the result we want.
4. **`date -d$m-$((…))day +%A\ %eth`**: Format that last working day, appending `th` to give a candidate ordinal.
5. **`|sed s/1th/1st/`**: Rewrite `31th` as `31st`. The last working day must be in the range 26th...31st, so there are no `nd`s or `rd`s to consider.

---

### Full demo

```
#!/bin/bash

last-working-day()
{
s=(1 2)
m=1$1+month
date -d$m-$((s[`date -d$m +%w`]+1))day +%A\ %eth|sed s/1th/1st/
}

test "$*" || set -- $(for i in {0..35}; do date -d 1jan00+${i}month +%b%Y; done)

for i
do
    printf '%s: %s\n' $i "$(last-working-day $i)"
done

```

Output (no args):

```
Jan2000: Monday 31st
Feb2000: Tuesday 29th
Mar2000: Friday 31st
Apr2000: Friday 28th
May2000: Wednesday 31st
Jun2000: Friday 30th
Jul2000: Monday 31st
Aug2000: Thursday 31st
Sep2000: Friday 29th
Oct2000: Tuesday 31st
Nov2000: Thursday 30th
Dec2000: Friday 29th
Jan2001: Wednesday 31st
Feb2001: Wednesday 28th
Mar2001: Friday 30th
Apr2001: Monday 30th
May2001: Thursday 31st
Jun2001: Friday 29th
Jul2001: Tuesday 31st
Aug2001: Friday 31st
Sep2001: Friday 28th
Oct2001: Wednesday 31st
Nov2001: Friday 30th
Dec2001: Monday 31st
Jan2002: Thursday 31st
Feb2002: Thursday 28th
Mar2002: Friday 29th
Apr2002: Tuesday 30th
May2002: Friday 31st
Jun2002: Friday 28th
Jul2002: Wednesday 31st
Aug2002: Friday 30th
Sep2002: Monday 30th
Oct2002: Thursday 31st
Nov2002: Friday 29th
Dec2002: Tuesday 31st

```

# Answer
> 6 votes
# PHP, -F 55 bytes

```
<?=date('l jS',strtotime("$argn+1month last weekday"));

```

Try it online!

Input is in "yyyy-mm" format in my example, but `strtotime` supports many formats

It's so rare that PHP is competitive! I knew one day would be the glory of this pile of unconsistent mess, that I came to like golfing with ;) I needed to add one month because using `strtotime` without a day number returns the first day, and `last` is actually a relative term (opposite of `next`).

Probably still golfable, still searching for edge cases where it could not work (relative month `+1 month` can be broken I think, `-1 month` is for sure)

NOTE: my first version was 4 bytes shorter `++$argn." last weekday"`, I liked it because it uses PHP's string increment, but even if it works with the tests cases, it will fail for December -\> "2023-12" would give "2023-13" and `strtotime` is not really clever

# Answer
> 5 votes
# JavaScript (ES6), 129 bytes

*-1 thanks to @l4m2*
*-2 thanks to @Shaggy*

Expects `([year, month])`, as integers.

```
f=(D,d=31,s="st")=>(q=new Date([...D,d])).getDate()>9&&q.getDay()%6?q.toLocaleString("EN",{weekday:"long"})+' '+d+s:f(D,d-1,"th")

```

Try it online!

Or **126 bytes** if we assume a default English locale.

### Commented

```
f = (                 // recursive function taking:
  D,                  //   D[] = [year, month]
  d = 31,             //   d = day, starting at 31
  s = "st"            //   s = suffix, initialized to "st"
) =>                  //
( q = new Date([      // build the date q for:
    ...D,             //   the year and month stored in D[]
    d                 //   the day d
  ])                  //
).getDate() > 9       // if the resulting day is greater than 9
&&                    // (i.e. we didn't overflow to the next month)
q.getDay()            // and the 0-based day-of-week index
% 6 ?                 // is neither 0 or 6 (Sunday / Saturday):
  q.toLocaleString(   //   return the name of the day
    "EN", {           //   obtained with toLocaleString()
      weekday: "long" //   set up to English
    }                 //
  ) +                 //
  ' ' +               //   followed by a space
  d +                 //   followed by the day
  s                   //   followed by the suffix
:                     // else:
  f(D, d - 1, "th")   //   recursive call with d - 1 and s = "th"

```

# Answer
> 5 votes
# Factor \+ `math.text.english`, 110 bytes

```
[ last-day-of-month dup weekend? [ friday< ] when
dup day-name swap day>> dup ordinal-suffix [I ${} ${}${}I] ]

```

Attempt This Online!

Takes a timestamp (date object) as input.

* `last-day-of-month` get the last day of the month
* `dup weekend?` is it a weekend?
* `[ friday< ] when` then change it to the Friday before
* `dup day-name` get the day name ("Monday", "Tuesday", etc.)
* `swap day>>` get the day number of the month
* `dup ordinal-suffix` get its ordinal suffix
* `[I ${} ${}${}I]` interpolate it all together and print

# Answer
> 5 votes
# Python, 129 bytes

```
from datetime import*
def f(y,m,d=31,s="st"):
 try:q=date(y,m,d);1/(q.weekday()<5);print(f'{q:%A %d}{s}')
 except:f(y,m,d-1,"th")

```

Attempt This Online!

# Answer
> 4 votes
# Ruby, ~~99 89~~ 102 bytes

```
->y,m{(1..4).find{|d|(A=Date.new y,m,-d).wday<5}
A.strftime"%A %d#{A.day>30?'st':'th'}"}
require'time'

```

Try it online!

**Explanation**

Anonymous function tacking year and month as numbers.

We find which of the last 4 days of month ( checking backwards using -d ) are wdays (week days 0-indexed) less than 5 saving each time date object in constant A for later use.

When it's found loop is stopped so A is the last weekday of the month.

Then we format the output, we can only have 31st or XXth.

# Answer
> 4 votes
# POSIX shell, 168 bytes

Not the shortest possible with the shell, but it doesn't use any bashism and is funny (see explanation bellow.)

```
cal $@|tail -2|awk 'NF>1{split("S Mon Tues Wednes Thurs Fri",d)
a=6;if(NF==1){b=$1-2}else if(NF==7){b=$6}else{a=NF;b=$NF}
print d[a]"day",(b==31)?b"st":b"th"}'|tail -1

```

With the following limitations:

* months are given as integer only, not strings (January or jan for example)
* separator is changed from slash to blanks (i.e. `1 2043` instead of `1/2043`) which is natural shell arguments separator

### Explanation

We can use the POSIX `cal` to visually catch the last weekday.

```
$ # for February 2017
$ cal 2 2017
   February 2017
Su Mo Tu We Th Fr Sa
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28

```

The last week is on the visually shown last line (but there's an extra blank line), so with POSIX `tail` (for golfing purpose, `tail -n -2` is shorten `tail -2`)

```
$ # last week of February 2017
$  cal 2 2017 | tail -n -2
26 27 28

```

Finally we should pick the last day… Because the column position vary, `awk` is a better candidate than `cut` here (But one can prefer `perl` or some other scripting langage, but I'm trying to use commands that should be always available), hence the following script:

```
BEGIN  { # on start, create array of days names
         split("Su Mo Tu We Th Fr Sa", d)
       }
NF > 1 { # on filled line, print last column name and value
         print d[NF],$NF
      }

```

If the script is put in file `LastDay.awk`, our chaining become:

```
$ # last day of February 2017
$  cal 2 2017 | tail -n -2 | awk -f LastDay.awk
Tu 28

```

However, note that the first column is Sunday, and we need to deal with boundaries. The modification is:

```
BEGIN  { # on start, create array of days names
         split("S Mo Tu We Th", d)
       }
NF > 1 { # check last column
         if (NF==7) {
           print "Fr",$6 # Saturday: we read the previous field
         } else if (NF==1) {
           print "Fr",($1-2) # Sunday: we count two days less
         } else {
           print d[NF],$NF # Week-Day: pick column name and value
         }
      }

```

For golfing purpose,

* I try to use ternary operator (which is an expression that expects three other expressions) without success
* Initial array creation is not done in `BEGIN` but each time, and rule is evaluate in any case…
* Replace `$1 $2` with `$@` (thanks Toby Speight for the comment) and remove extra spaces

But, in order to comply with the output requirements, we have to add more characters for days.

```
NF > 1 { split("S Mon Tues Wednes Thurs Fri", d)
         if (NF==7) { # sat
           print d[6] "day",$6
         } else if (NF==1) { # sun
           print d[6] "day",($1-2)
         } else { # non w-e
           print d[NF] "day",$NF
         }
      }

```

For compliance, we have to deal with ordinals too. To avoid repeating ourself many times, let's opt for assignments and put formatting at end.

```
NF > 1 { split("S Mon Tues Wednes Thurs Fri", d)
         if (NF==7) { # sat
           a=d[6]
           b=$6
         } else if (NF==1) { # sun
           a=d[6]
           b=($1-2)
         } else { # non w-e
           a=d[NF]
           b=$NF
         }
         print a "day", (b==31)?b"st":b"th"
      }

```

### Addendum

Well, `cal 12 2001` shows that there wasn't simply a blank line as I believed, the formatting is for six weeks… Then, before invoking AWK, our selection should be changed so:

```
- cal $1 $2 |                  tail -n -2
+ cal $1 $2 | grep -v '^ *$' | tail -n -1

```

Alternatively, the AWK output (`Friday 28th` and `Monday 31st`) must be filtered though `tail -n -1`. Either add 14 characters before (and save `NF > 1` condition), or add 10 characters after (and keep 4 characters condition). Fifty-fifty, so it's a matter of taste.

# Answer
> 3 votes
# Python3, 153 bytes

```
from datetime import*
T=timedelta(1)
def f(m,y):
 d=date(y+(m>11),m%12+1,1)-T
 while d.weekday()>4:d-=T
 return d.strftime('%A %d')+['th','st'][d.day>30]

```

Try it online!

# Answer
> 3 votes
# Charcoal, ~~137~~ 136 bytes

```
≔Ｉ⪪Ｓ/θ≔⁻⁺×¹²⊟θ⊟θ²θ≔ＥＥ²⁻θι﹪Σ⟦÷ι⁴⁸⁰⁰±÷ι¹²⁰⁰÷ι⁴⁸÷ι¹²÷×¹³⁺⁴﹪ι¹²¦⁵⟧⁷θ≔⊟θη≔⊟θθ≔⁻⁺²⁸﹪⁻θη⁷∨¬θ⊗¬⊖θθ§⪪”⟲1Ｕ↘α‹¬@²¦À≧≡FGv_Ｅ✂₂↘” ⁺θηday Ｉθ§⪪stth²‹θ³¹

```

Try it online! Link is to verbose version of code. Explanation: Uses my code for Zeller's congruence from my answer to ASCII Calendar Planner.

```
≔Ｉ⪪Ｓ/θ

```

Split the date on `/`.

```
≔⁻⁺×¹²⊟θ⊟θ²θ

```

Convert to months since March 1, 1 BC.

```
≔ＥＥ²⁻θι﹪Σ⟦÷ι⁴⁸⁰⁰±÷ι¹²⁰⁰÷ι⁴⁸÷ι¹²÷×¹³⁺⁴﹪ι¹²¦⁵⟧⁷θ

```

Use a modified Zeller's congruence to extract the day of the week of the first day of next month and this month as a list.

```
≔⊟θη≔⊟θθ

```

Extract the list entries into variables to save bytes.

```
≔⁻⁺²⁸﹪⁻θη⁷∨¬θ⊗¬⊖θθ

```

Calculate the last working day of the month.

```
§⪪”...” ⁺θηday

```

Output the day of the week.

```
Ｉθ

```

Output the day of the month.

```
§⪪stth²‹θ³¹

```

Output the ordinal suffix.

# Answer
> 3 votes
# Vyxal, 104 bytes

```
S½⌊Ḃ÷dN„4/?›13*5/⁰14=[¹›₁1"4*₁JḊ÷¬∧∨28:›"i|30⁰⇧5%₂+]:£Wf⌊∑7%:¥∇2<[›-6]⇩`°⋏ ß₀ †ƛ ßɖ »£`⌈ið„:31=«⟇'Ḋ«½iW∑

```

Try it Online! | All test cases

Takes the year and the month (one-based) seperately. January and February are considered the 13th and 14th months of the previous year.
Vyxal has no Date/Time built-ins, so this uses a variation of Zeller's Congruence.

```
S½⌊Ḃ÷dN„4/?›13*5/⁰14=[¹›₁1"4*₁JḊ÷¬∧∨28:›"i|30⁰⇧5%₂+]:£Wf⌊∑7%:¥∇2<[›-6]⇩`°⋏ ß₀ †ƛ ßɖ »£`⌈ið„:31=«⟇'Ḋ«½iW∑

S½⌊Ḃ÷dN„4/?›13*5/   ## First Part of Zeller's Congruence Formula
S½⌊                 # Split year into two halves [century, year of the century]
   Ḃ                # Bifurcate, push this and its reverse
    ÷dN             # Push each item to stack, multiply the year of the century by -2
       „            # Rotate stack ([century, year of the century] is on top)
        4/          # Divide both by 4
          ?›13*5/   # Multiply month + 1 with 13/5

⁰14=[¹›₁1"4*₁JḊ÷¬∧∨28:›"i|30⁰⇧5%₂+]  ## Calculate number of days in month
⁰14=[                             ]  # If month is 14 (February) ...
    [                    |             # Leap year calculation:
     ¹›       Ḋ                        # Does year + 1 divide ...
       ₁1"4*₁J                         # ... [400, 4, 100] (Pair [100, 1] * 4 and join 100)
               ÷¬∧∨                    # Split on stack, logical not, and, or
                ¬∧∨                    # [ (year + 1 divides 4 and not 100) or (year + 1 divides 400) ]
                   28:›"i              # Index into [28, 29]
                         |        ]  # Calculate days for other months:
                            ⁰⇧5%₂      # ((Year+2) % 5) % 2 == 0
                            ⁰⇧5%₂      # Maps [1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1] for months 3 to 13 (March=3, ..., January=13)
                          30     +     # Add result to 30

:£Wf⌊∑7%  ## Second Part of Zeller's Congruence Formula
:£        # Save a copy of number of days in month in register
  Wf⌊∑    # Wrap terms in list, take floor and sum all terms
      7%  # Result modulo 7 (Returns weekday as Saturday=0, Sunday=1, ...)

:¥∇2<[›-6]⇩`°⋏ ß₀ †ƛ ßɖ »£`⌈i  ## Calculate workday (as day of the week and month)
:¥∇                            # Push the number of days in the month (register), weekday, weekday
   2<[   ]                     # If weekday < 2 (Saturday or Sunday)
      ›-6                      # Subtract weekday+1 from number of days in month (last workday), Push 6 (Friday)
           `°⋏ ß₀ †ƛ ßɖ »£`    # Compressed string of workdays
          ⇩                ⌈i  # Index workday-2 into list (Monday=0, Tuesday=1, ...)

ð„:31=«⟇'Ḋ«½i  ## Day of the Month formatting
ð„             # Push space and rotate stack
  :31=         # Is the day of the month 31? (Returns 1 or 0)
      «⟇'Ḋ«½i  # Compressed string "thst", halve and index into string

W∑  # Join all values in the stack (workday as day of the week, space, workday as day of the month)

```

# Answer
> 3 votes
# PowerShell Core, 118 bytes

```
param($y,$m)for(;!((($k=Date "$y/$m/1"|% *hs 1|% *ys(--$d))|% d*k)%6)){}"{0:dddd} {0:dd}"-f$k+('st','th')[$k.Day-ne31]

```

Try it online!

Takes in two parameters, `$y`ear and `$m`onth, returns a `string`.

Less golfed:

```
param($y,$m)
for(;(($k=(Date "$y/$m/1").AddMonths(1).AddDays(--$d)).DayOfWeek-in"Saturday","Sunday")){}
"{0:dddd} {0:dd}"-f$k+('st','th')[$k.Day-ne31]

```

Finds the last day of the month, while it is a Saturday or a Sunday, check one day before Then formats the date

# Answer
> 3 votes
# C (gcc), 270 250 bytes

```
char*s[]={"Mon","Tues","Wednes","Thurs","Fri","sth"};l(y){return y/4-y/100+y/400;}
f(m,y){int d,p=l(y);y-=d=m<3;d=6+y+p+(31*(m+=12*d-2))/12;
d+=y=31-(12652612>>(m*2-2)&3)+(m>11&p-l(y));d%=7;y-=p=d&d/4*3;
printf("%sday %d%.2s\n",s[d-p],y,s[5]+(y<31));}

```

Try it online!

Doing it the hard way - a bunch of mod 7 math to count extra days since the first Monday of Year 0.

`p=l(y)` returns the number of leap years since 0.
`d=m<3` is true for Feb and March
`y-=d...m+=12*d-2` sets `m` to the month, where Mar is 1 and Jan and Feb are 11 and 12 of the prior year.
`d=6+y+p+31*m/12` sets d to the number of extra days between the first Monday in year 0 and the last day of the prior month. (the 31\*m/12 gives the correct pattern of +3s and +2s)
`(m>11&p-l(y)` is 1 if it's February of a leap year
`12652612` is "31-days" for each month encoded in 2 bits, so
`y=31-(12652612>>(m*2-2)&3)+...` sets y to the last day in the query month.
`d+=y...;d%=7` gets the day of the week (0==Mon) for the query.
`p=d&d/4*3` sets p to the days needed to truncates Sat/Sun to Fri (4)
`y-=p` fixes the last day of the month
`s[d-p]` is the day string,
2 characters from `s[5]+(y<31)` is "st" or "th"

# Answer
> 3 votes
# Google Sheets / Microsoft Excel, 76 bytes

`=let(d,workday(eomonth(A1,)+1,-1),text(d,"dddd d")&if(day(d)=31,"st","th"))`

Put the month and year in cell `A1` in one of the formats specified in the question (or any other valid date format), and the formula in `B1`.

The formula gets the first day of the *next* month and then finds the previous weekday before that, which is the same as the last weekday of the specified month.

The day number of the last weekday of a month will never end in `2` or `3`, so it is enough to add `st` when the day is `31` and use `th` with any other date.

The formula is for Google Sheets, but I tested it in the most recent version of Microsoft Excel for the web and it seems to work the fine there as well.

The Google Sheets epoch is 30 December 1899. The formula will work with dates from January 1900 to December 99999. In Microsoft Excel, the range of valid dates seems more limited, and formula will work from January 1900 to November 9999.

| input | expected | formula |
| --- | --- | --- |
| 10/2023 | Tuesday 31st | Tuesday 31st |
| February 2017 | Tuesday 28th | Tuesday 28th |
| 09/1674 | Friday 28th | #NUM! |
| 1/2043 | Friday 30th | Friday 30th |

# Answer
> 3 votes
# (Pure) Zsh, 126 bytes

```
zmodload zsh/datetime
s=strftime
for d ({31..9})$s -sT %A\ %dth `$s -r %F $1-$d`&&[[ $T = [^S]*$d\th ]]&&break
<<<${T/1th/1st}

```

Try it online!

Using the builtin `strftime` rather than any external programs.

```
zmodload zsh/datetime
# "strftime" is long enough that setting $s and using $s twice is shorter than "strftime" twice.
s=strftime

# start at the 31st of the month, count downward
for d ({31..9})
    # Get the timestamp of "YYYY-MM-DD" with strftime -r (reverse/strptime)
    # and find "Nameofday DDth" from timestamp. (-s)ave in $T
    $s -sT %A\ %dth `$s -r %F $1-$d` &&
    # if Nameofday begins with an S or we end up on a different day of month
    # (like 02-31 converted to 03-03), keep going.
    [[ $T = [^S]*$d\th ]] && break

# Fix suffix
<<<${T/1th/1st}

```

# Answer
> 2 votes
# APL(Dyalog Unicode), 66 bytes SBCS

```
{⊃'Dddd DDoo'(1200⌶)⊃⌽w/⍨0≠6|7|w←∊{0::⍬⋄,¯1 1 ⎕DT⊂⍵}¨(⊂⌽⍵),¨25+⍳6}

```

Try it on APLgolf!

woo-hoo. Shaggy waiting room. Takes date as `m y`.

# Answer
> 2 votes
# Go, 234 bytes

```
import(."fmt";."time")
func f(m,y int)string{M,e:=Month(m),"th"
t,W:=Date(y,M,31,0,0,0,0,UTC),(Time).Weekday
for w:=W(t);t.Month()!=M||w<1||w>5;{t=t.Add(Hour*-24);w=W(t)}
if t.Day()>30{e="st"}
return Sprintf("%s %d%s",W(t),t.Day(),e)}

```

Attempt This Online!

### Explanation

```
import(."fmt";."time")
func f(m,y int)string{M,e:=Month(m),"th"
// start the date off at the 31st of the month, regardless of the month
t,W:=Date(y,M,31,0,0,0,0,UTC),(Time).Weekday
// subtract 1 day while...
for w:=W(t);
// the months don't match, or
t.Month()!=M
// the day is not a weekday
||w<1||w>5;{t=t.Add(Hour*-24);w=W(t)}
// replace "31th" with "31st"
if t.Day()>30{e="st"}
return Sprintf("%s %d%s",W(t),t.Day(),e)}

```

# Answer
> 2 votes
# bash and BSD date, 96 bytes

As an alternative to Toby Speight's answer but using BSD implementation instead of GNU one

```
s=(1 2)
m="-v$2y -v$1 -v+1m -v1d"
date $m -v-$((s[`date $m +%w`]+1))d +%A\ %eth|sed s/1th/1st/

```

It has the following limitations:

* months can be integers only, not strings (`October` or `sep` for example)
* separator is changed from `/` to blanks which is natural shell arguments separator

There's certainly room for tweaking.

# Answer
> 2 votes
# Python, 152 bytes

Since there is already multiple python answers I've tried to use the calendar library since I never used it before. It just uses the fact that the object monthcalendar gives weeks of the month and days of those weeks as a 2d array -\>then just a check for highest number in the first 5 days of last week.

```
from calendar import *
def f(y,m,d=31,s="st"):
 if d in monthcalendar(y, m)[-1][:5]:
  print(day_name[weekday(y,m,d)],str(d)+s)
 else: f(y,m,d-1,s="th")

```

Attempt This Online!

# Answer
> 1 votes
# C#, 143 bytes

```
(y,m)=>new[]{DateTime.DaysInMonth(y,m)is{}z?z:z,z-1,z-2}.Select(x=>new DateTime(y,m,x).ToString("dddd dd")+(x>30?"st":"th")).First(x=>x[0]!=83)

```

Explanation

```
f = (y, m) =>                       // lambda that takes year and month
  new[] {                           // create new implicitly typed array
      DateTime.DaysInMonth(y, m)    // get number of days in month
          is {} z ? z : z,          // hack to set variable z to this value inline
      z-1, z-2                      // add the 2 days previous to z
  }                                 // array contains the last 3 days of the given month in descending order
  .Select(                          // transform the elements of the array
      x => new DateTime(y, m, x)    // create new datetime with the given year and month
      .ToString("dddd dd")          // convert to string and format
      + (x > 30 ? "st" : "th"))     // add "st" if is the 31st, "th" otherwise
  .First(                           // get first element that matches condition
      x => x[0] != 83)              // first character is not "S" (i.e not day isn't saturday or sunday)

```

Try it online!

---
Tags: code-golf, string, date
---