title: Parse a nested parentheses

text:
# Question
Title: Parse a nested parentheses
# Objective

Mimic Haskell's `reads :: ReadS ()`.

Or in other words, parse nested parentheses. Since the target type is `()` (the type with one possible value), "parsing" means discarding a leading nested parentheses.

# Valid Input

"Nested parentheses" means `()`, `(())`, `((()))`, and so on. That is, leading nonzero `(`s and trailing `)`s of the same number.

But there's a twist. The parser must munch also leading or intercalated whitespaces. So for example, the following strings are valid to be munched:

* `( )`
* `()`
* `( () )`

Note that trailing whitespaces are not to be munched.

# Whitespaces

The following ASCII characters are always considered a whitespace:

* `\t` U+0009; Horizontal Tab
* `\n` U+000A; Line Feed
* `\v` U+000B; Vertical Tab
* `\f` U+000C; Form Feed
* `\r` U+000D; Carriage Return
* U+0020; Space

For each of the following Unicode characters, it is implementation-defined to consider it a whitespace:

* U+0085; Next Line
* U+00A0; No-Break Space
* U+1680; Ogham Space Mark
* U+2000; En Quad
* U+2001; Em Quad
* U+2002; En Space
* U+2003; Em Space
* U+2004; Three-Per-Em Space
* U+2005; Four-Per-Em Space
* U+2006; Six-Per-Em Space
* U+2007; Figure Space
* U+2008; Punctuation Space
* U+2009; Thin Space
* U+200A; Hair Space
* U+2028; Line Separator
* U+2029; Paragraph Separator
* U+202F; Narrow No-Break Space
* U+205F; Medium Mathematical Space
* U+3000; Ideographic Space

All other characters are never considered a whitespace.

# Error

If the string doesn't start with a nested parentheses, the parser shall fall in an erroneous state. Ways that indicates an error include:

* Monadic failing
* Returning an erroneous value
* Raising/Throwing an error

# Output

When the parser successfully munched a nested parentheses, the parser shall output the unmunched part of string.

# Examples

## Valid example

* When given `()`, the output is an empty string.
* When given  `( ) Hello`, the output is  `Hello`. Note the leading whitespace of the output.
* when given `((()))))`, the output is `))`.

## Erroneous example

* Empty string
* `((()`
* `(()())`
* `(H)`
* `Hello, world!`

# Ungolfed solution

## C

Returns a null pointer for an error.

```
#include <stdbool.h>
#include <stdlib.h>

char *readMaybeUnit(char *str) {
    bool p = false;
    unsigned c = 0;
    while (*str != '\0') {
        switch (*str) {
        case '(':
            p = true;
            ++c;
            // FALLTHRU
        case '\t': case '\n': case '\v': case '\f': case '\r': case ' ':
            break;
        default:
            goto parseRightParentheses;
        }
        ++str;
    }
    parseRightParentheses: while (*str != '\0') {
        switch (*str) {
        case ')':
            if (1 >= c) {
                if (1 == c)
                    ++str;
                c = 0;
                goto returnReadMaybeUnit;
            }
            --c;
            // FALLTHRU
        case '\t': case '\n': case '\v': case '\f': case '\r': case ' ':
            break;
        default:
            goto returnReadMaybeUnit;
        }
        ++str;
    }
    returnReadMaybeUnit: return p && 0 == c ? str : NULL;
}

```

# Answer
> 6 votes
# Python 3.8 (pre-release), 112 bytes

```
f=lambda s,c=0,p='(':[f(s[1:],c+"()".find(a)%-3+1,max(a,p))if(a:=s[:1])in{p,*"	\n`0b``0c`\r )"}else 0,s][c<1and')'==p]

```

Try it online!

An attempt without using regular expressions. Returns `0` on error.

* Thanks to @movatica for saving 4 bytes!

###### Python 3, 116 bytes

```
f=lambda s,c=0,p='(':[f(s[1:],c+"()".find(s[:1])%-3+1,max(s[:1],p))if s[:1]in{p,*"	\n`0b``0c`\r )"}else 0,s][c<1and')'==p]

```

Try it online!

###### Python 2, 119 bytes

```
f=lambda s,c=0,p='(':[f(s[1:],c+"()".find(s[:1])%-3+1,max(s[:1],p))if s[:1]in{p}|set("	\n`0b``0c`\r )")else 0,s][`c`+p=="0)"]

```

Try it online!

---

###### Python 2 (non-recursive), 153 bytes

```
def p(s):c=i=a=0;t="""
while i<len(s):
 if~-s[i].isspace():
	if%r!=s[i]:break
	c+=%s
 i+=1""";exec t%('(','1')+t%(')',"-1\n\tif c==0:a=s[i+1:]");return a

```

Try it online!

* Thanks to @ovs for saving 4 bytes!

---

We could probably save a few more bytes if we returned the original string on error, but then inputs `'()'` and `''` would give the same output `''`.

# Answer
> 6 votes
# Haskell, ~~83~~ 76 bytes

```
c?(a:b)|elem a" \t\n\r\v\r"=c?b|a==c=[b]
_?_=[]
f x='('?x>>=(:)<*>f>>=(')'?)

```

Try it online!

Since this question to imitate Haskell's parsing I thought it would be nice to give this a try using Monadic parsing in Haskell. The result is actually really short. I use `[]` as my monad because it is just way shorter than `Maybe` or `Either`.

---

### What is monadic parsing?

Put simply monadic parsing is a type of parsing in which a parser is a function from a string to some optional type of a the remaining string and some data

```
type Parser a = String -> Option (a, String)

```

Here our `Option` type is a list, and we are just validating rather than producing any data, so our parser looks like:

```
type Parser a = String -> [ String ]

```

Where our parser takes some string and returns all possible suffixes of valid parses. The empty string represents a failure to parse because no suffixes means that no valid parse was found.

This way of structuring things makes it super easy to combine parsers. For example if we have a parser `p` which parses the regex `\s*(` and a parser `q` which parses the regex `\s*)` then we can make a parser that parses the expression `\s*(\s*)` using the Kleisli arrow

```
(>=>) :: (a -> m b) -> (b -> m c) -> (a -> m c)

```

Meaning the result is `p >=> q`. We can also do other combinators.

---

So here's how I use it in my answer.

The first thing we do is implement `?`, which takes a character `c` returns a parser the regex `\s*c` (where `c` is the character). Essentially this consumes a prefix made of any amount of whitespace followed by a single character. This is only ever called on `(` and `)`.

With this we implement `f` which is the parser that the challenge asks for. We don't actually have the Kleisli arrow in Prelude but I will write it as if we did for clarity and then show how we remove Kleisli arrows.

```
f = ('('?) >=> (:)<*>f >=> (')'?)

```

So we have three parsers first, it must start with some whitespace followed by a `(` then some gobbledygook parser and then it must end with some whitespace followed by a `)`.

The gobbledygook `(:)<*>f` can be expressed more clearly as

```
\ x -> x : f x

```

Which is to say it is it matches everything the `f` parser does but also matches the empty string.

So our `f` parser matches:

> Parentheses enclosing, either the empty string or another f.

Now to remove our Kleisli arrows we use `>>=` which has the similar type signature:

```
(>>=) :: m a -> (a -> m b) -> m b

```

So we take an argument from f, pass it to the first parser and change all of our `(>=>)`s to `(>>=)`s.

# Answer
> 4 votes
# Retina 0.8.2, ~~32~~ 31 bytes

```
^(\s*\()+(?<-1>\s*\))+(?(1)$.)

```

Try it online! Link includes test cases. Returns the original string on error. Considers the given control characters as white space, plus any Unicode characters (such as space) in the Separator group, plus U+0085. If only the minimal white space is desired, this can be achieved by prefixing `e``. Explanation:

```
^(\s*\()+

```

Match some open parentheses at the start of the string.

```
(?<-1>\s*\))+

```

Match some close parentheses.

```
(?(1)$.)

```

Check that the same number of open and close parentheses were matched.

```

```

Delete the matched parentheses.

Alternative solution, also 31 bytes:

```
r`^(?<-1>\s*\()+(\s*\))+(.*)
$2

```

Try it online! Link includes test cases. If only the minimal white space is desired, this can be achieved by prefixing `e`. Explanation:

```
r`

```

Start matching at the end of the string and work backwards (like a lookbehind would).

```
(.*)

```

Match as much result as possible.

```
(\s*\))+

```

Match some close parentheses.

```
^(?<-1>\s*\()+

```

Match the open parentheses at the start of the string. The number of close parentheses must be at least as many as the number of open parentheses for the balancing group to succeed, but it can't be more because the `(.*)` ensures that as few close parentheses are matched as possible.

```
$2

```

Keep everything except the matched parentheses.

Previous 32-byte solution that returns the empty string on error:

```
1!`(?<=^(?<-1>\s*\()+(\s*\))+).*

```

Try it online! Link includes test cases. If only the minimal white space is desired, this can be achieved by prefixing `e`. Explanation:

```
1!`

```

Output the matched part of the first match.

```
(?<=^(?<-1>\s*\()+(\s*\))+)

```

Ensure that the match starts after balanced parentheses. Note that this is a lookbehind, so the match is processed right-to-left - the `)`s are matched first, then a `(` can be matched for each `)`. There can't be too many `)`s because the lookbehind would have matched earlier, meaning that this is no longer the first match.

```
.*

```

Match the rest of the string. This actually counts as part of the match, and therefore becomes the resulting output.

# Answer
> 3 votes
# Perl 5, (-p) 22 bytes

```
s/^(\s*\((?1)?\s*\))//

```

Try it online!

Using recursive regex. The shorter `\s*\((?0)?\s*\)` didn't work because of start anchor missing.

The error case is given by the result of substitution operation :

* 1 - success
* "" - failed

# Answer
> 3 votes
# Haskell \+ hgl \+ TypeApplications, 16 bytes

```
st<gj<uP(ν @())

```

Attempt This Online!

### Explanation

`ν` is the general purpose read parser, so when given the `()` type it basically does exactly the desired task. However, there are two issues

1. The question wants the remainder, and parsers are generally set up to get the value not the remainder.
2. The question actually wants what is considered the lowest priority parse, i.e. the parse that trims the least whitespace. Parsers generally like to get higher priority parses

To solve this we just dump the most verbose parser output using `uP`. `gj` gets the lowest priority pair and `st` grabs the result from the pair.

## 16 bytes

```
gk$Sw$ivP$ν @()

```

Attempt This Online!

This version has no post processing after the parse, i.e. the top level function performs a parse.

### Explanation

This solves the two issues in a different way. It uses `ivP` to invert the parse priorities on `ν`. We use `Sw` to "swap" the result with the remainder.

At the top level we use `gk` to get the highest priority parse.

# Haskell \+ hgl, 17 bytes

```
st<gj<uP(mp()<ν)

```

Attempt This Online!

### Explanation

This is basically the same as the last one, except without type application we can't tell it what type to parse directly. Instead we want to map a function across the parser with the type `() -> a` where `a` is any type. This will force a type of `()` onto the output. Taking `()` as an input is pretty uncommon. The shortest I could find is `mp()`, which uses the semigroup action to combine two `()`s.

## 17 bytes

```
gk$Sw$mp()<ivP ν

```

Attempt This Online!

This version has no post processing after the parse, i.e. the top level function performs a parse.

# Haskell \+ hgl (no `ν`), 28 bytes

```
g=p__<*enP(g?<>p__)

```

```
gk$g*>h'

```

Attempt This Online!

# Reflection

I think these do decently, but I have a lot of notes on how to improve.

* There should be a version of `gk` to get the lowest priority parse.
* There should be some parse runners that return the remainder rather than the result.
* While I did have fun trying to find the shortest way to coerce the type of `ν`, extremely polymorphic `ν` should come with built-in ways to do this. The way to do this would be to make a version of `ν` which a witness value as input, and always returns something of the same type. If this were 3 bytes it would actually save bytes over using a type application in this case.
* You might notice `uP<ν` is really just an expensive way to do `reads`. I don't actually export any version of `reads`. This sort of makes sense, I haven't really invested the time into making `Read` related functions, but if `ν` exists, `reads` should probably exist.
* `(p__*>)` and `(<*p__)` to trim leading and trailing whitespace respectively are both way too expensive, there should be built in shortcuts.
* There should be a flip of `mpY`.
* `lSo` and `lMy` should return a specific type, probably `Nat`.
* I noticed there's no version of `py` which counts the number of results. It wouldn't be helpful in any way here, but I feel like that should exist.
* The recursive regex in the perl answer is sort of interesting. The option for this right now seems like:
```
gk$Sw$rX"/w*/(/r?/w*/)"

```
which are shorter than the answer without `ν` but longer than the other ones.
* Looking at the regex, there should be a version of `gk` for regexes.

---
Tags: code-golf, string, parsing, balanced-string
---


title: Detect MS Windows

text:
# Question
Title: Detect MS Windows
### Challenge

Create a program that returns a truthy value when run on Microsoft Windows (for simplicity we'll stick with Windows 7, 8.1 and 10) and a falsey value when run on any other operating system (OSX, FreeBSD, Linux).

### Rules

* Code that fails to run/compile on a platform doesn't count as a falsey value.

### Winning criteria

I'm labelling this as , so lowest score wins, but I'm also very interested in seeing creative solutions to this problem.

# Answer
> 84 votes
# Vim, 2 bytes

```
<C-a>1

```

On Windows, `<C-a>` (ctrl+a) is mapped by default to `Select All`. If you type a `1` in select mode in Windows, it replaces the selection with what you typed (1) leaving a 1 in the buffer.

On other operating systems, `<C-a>` by default is mapped to `Increment number`. Because there's no number to increment, it's a no-op, and then the 1 increases the count but in terms of the buffer is a no-op.

1 is truthy in Vim, and an empty string is falsy

# Answer
> 108 votes
# MATLAB, 4 bytes

```
ispc

```

From the documentation:

> `tf = ispc` returns logical 1 (true) if the version of MATLAB® software is for the Microsoft® Windows® platform. Otherwise, it returns logical 0 (false).

There are also the functions `ismac` and `isunix`. ~~I'll leave it to the reader to figure out what those functions do.~~ Mego kindly asked for diagrams explaining `ismac` and `isunix` so I've tried to illustrate it here:

It was not asked for a diagram of `ispc` but I can reveal that the behaviour is pretty similar, except substitute `OSX` and `Unix` with `Windows`.

---

**Second approach:**

Here's a second approach with `getenv` using 23 bytes that should be bullet proof, unless there's another operating system starting with `W`:

```
x=getenv('OS');x(1)==87

```

> `getenv 'name'` searches the *underlying operating system environment list* for text of the form `name=value`, where `name` is the input character vector. If found, MATLAB® returns the character vector value. If the specified name cannot be found, an empty matrix is returned.

# Answer
> 56 votes
# Python 2.7.10, 24 bytes

```
import os
0/('['>os.sep)

```

Thanks to FlipTack for 3 bytes

This program takes advantage of the fact that Windows is the only OS to use `\` as a path separator. Normally this is frustrating and bad, but for once it is actually an advantage. On Windows, `'['>os.sep` is false, and thus `0/0` is computed, causing a `ZeroDivisionError` and exiting with a non-zero exit code. On non-Windows platforms, `'['>os.sep` is true, making the expression `0/1`, which does nothing, and the program exits with exit code 0.

# Answer
> 47 votes
## ~~x86 Assembly, 7 bytes~~ (Inspired by Runemoro's answer)

```
31 DB 89 D8 40 CD 80

```

Or

```
xor ebx, ebx
mov eax, ebx
inc eax
int 0x80

```

## Description

First of all, we'll set `eax` to `1` (the system call number for `exit(int val)` for `Linux`, `FreeBSD` and `OSX`). Then, we'll call the interrupt gate `0x80` which is the system call gate for `Linux`, `FreeBSD` and `OSX`. That would cause the program to exit with status of `ebx` which is `0` (`false`).

On Windows `int 0x80` is an invalid gate (It uses `2e` as a syscall gate) and would crash the program, causing it to end with a positive exit code (`true`).

**Edit:** Would not work on `OSX` since it has a different argument-passing convention on 32 bit (by the stack).

## References and further reading

# Answer
> 29 votes
# PHP, 22 bytes

```
`<?=PATH_SEPARATOR>":";`

```

prints `1` if the path separator is semicolon (colon or empty for all other OSs except for DOS and OS/2), else nothing.

**also 22 bytes**, but not that safe:

```
<?=strpos(__FILE__,92);

```

prints a positive integer if the file path contains a backslash; else nothing.
A safe alternative with **27 bytes**: `<?=DIRECTORY_SEPARATOR>"/";` prints `1` or nothing.

**A strange find**: `<?=__FILE__[1]==":";` (**20 bytes**) should be, not safe either, but ok. But although `__FILE__` pretends to be a string (I tried `var_dump` and `gettype`), indexing it throws an error, unless you copy it somewhere else (concatenation also works) or use it as a function parameter.

Edit:
`<?=(__FILE__)[1]==":";` (also **22 bytes**) works in PHP 7; but that´s because the parentheses copy the constant´s value to a temporary variable.

**27 bytes**: `<?=stripos(PHP_OS,win)===0;`
tests if predefined `PHP_OS` constant starts with `win` (case insensitive; Windows,WIN32,WINNT, but not CYGWIN or Darwin); prints `1` for Windows, else nothing.

**17/18 bytes**:

```
<?=strlen("
")-1;

```

prints `1` if it was stored with Windows linebreak (also on DOS, OS/2 and Atari TOS - although I doubt that anyone ever compiled PHP for TOS), else `0`.

You could also check the constant `PHP_EOL`.

**more options:**

`PHP_SHLIB_SUFFIX` is `dll` on Windows, but not necessarily only there.
`php_uname()` returns info on the operating system and more; starts with `Windows` for Windows.
`$_SERVER['HTTP_USER_AGENT']` will contain `Windows` when called in a browser on Windows.
`<?=defined(PHP_WINDOWS_VERSION_BUILD);` (38 bytes) works in PHP\>=5.3

**conclusion**

The only failsafe way to tell if it´s really Windows, not anything looking like it, seems to be a check on the OS name. For PHP: `php_os()` may be disabled for security reasons; but `PHP_OS` will probably always contain the desired info.

# Answer
> 28 votes
# C, ~~44~~ ~~43~~ ~~38~~ 36 bytes

*Thanks to @Downgoat for a byte! crossed out 44 is still regular 44*
*Thanks to @Neil for two bytes!*

```
f(){return
#ifdef WIN32
!
#endif
0;}

```

# Answer
> 16 votes
# Befunge-98, 7 bytes

```
6y2%!.@

```

Try it online!

This works by querying the system path separator, which is `\` on Windows and `/` on other operating systems.

```
6y            System information query: #6 returns the path separator.
  2%          Test the low bit - this will be 1 for '/' and 0 for '\'.
    !         Not the value, so it becomes 0 for '/' and 1 for '\'.
     .@       Output the result and exit.

```

# Answer
> 15 votes
# Mathematica, 28 bytes

```
$OperatingSystem=="Windows"&

```

# Answer
> 13 votes
# Java 8, 33 bytes

*Special thanks to Olivier Grégoire for suggesting `separatorChar`, and Kritixi Lithos for -1 byte!*

This is a lambda expression which returns a boolean. This can be assigned to `Supplier<Boolean> f = ...;` and called with `f.get()`.

```
()->java.io.File.separatorChar>90

```

**Try it online!** \- the server isn't windows, so this prints `false`. However, in my windows machine, the same code prints `true`.

What this code does is get the System's file seperator, and check whether its codepoint is larger than the character `[`. This true for Windows, as it uses `\` as the seperator - but every other OS uses `/`, which has a lower code in the ASCII table.

# Answer
> 12 votes
# R, 15 bytes

```
.Platform$O>"v"

```

Thanks to plannapus for the suggestion to use partial matching for list element extraction.

.Platform is a list with some details of the platform under which R was built. There is an element `OS.type` (the only element with name starting with "O") which is character string, giving the Operating System (family) of the computer. One of `"unix"` or `"windows"`.

So `"unix"` is less then `"v"`, but `"windows"` is greater then `"v"`. Other valid 15 bytes answers are

```
.Platform$O>"V"
.Platform$O>"w"
.Platform$O>"W"

```

R is being developed for the Unix-like, Windows and Mac families of operating systems. Other OS families are not supported.

# Answer
> 11 votes
# J, 7 bytes

```
6=9!:12

```

This is a verb (similar to a function) that uses the builtin foreign conjunction `9!:12` to acquire the system type where 5 is Unix and 6 is Windows32.

# Answer
> 10 votes
## Perl, 11 bytes

```
print$^O=~MS

```

`^O` should be replaced by a literal Control-O.

Outputs `1` on windows, nothing on another OS.

Note that I'm not using `say` as it adds a trailing newline, which is truthy in Perl.

*-2 bytes thanks to primo. (and fixed potential issues)*
*-1 bytes thanks to ais523.*

# Answer
> 10 votes
## x86 machine code, 9 bytes

```
40 39 04 24 75 02 CD 80 C3

```

Compiled from:

```
inc eax        ; set eax to 1
cmp [esp], eax ; check if [esp] == 1 (linux)
jne windows    ; jump over "int 0x80" if on windows
int 0x80       ; exit with exit code 0 (ebx)
windows:
ret            ; exit with exit code 1 (eax)

```

# Answer
> 9 votes
# julia, 10 bytes

```
is_windows

```

A function that returns true for windows

# Answer
> 9 votes
# C#, ~~61~~ 48 bytes

```
()=>(int)System.Environment.OSVersion.Platform<4

```

Saved 13 bytes thanks to TheLethalCoder

Or a full program at 83 bytes:

```
class P{static int Main(){return(int)System.Environment.OSVersion.Platform<4?1:0;}}

```

Various Windows variants use enum values 0 to 3 in the Microsoft .NET implementation. 4 is Unix, 5 is Xbox \[360\] (which I won't consider "Windows"), 6 is MacOSX. Mono uses the same values, adding 128 for Unix/Linux in earlier versions.

Therefore, anything \< 4 is Windows, and everything else is not Windows.

# Answer
> 8 votes
# JavaScript, ~~42~~ ~~30~~ ~~26~~ 25 bytes

```
console.log((
//Begin
_=>navigator.oscpu[0]>'V'
//End
)())
```

Tested with Firefox. (Chrome doesn't have the `oscpu` property.) Since lowercase letters have a higher character code than uppercase letters, this depends on the first letter of `navigator.oscpu` being uppercase and not being *W*, *X*, *Y* or *Z* on any platform that Firefox supports (other than Windows, of course). According to this post, that is the case.

### Edits

1. Saved 12 bytes thanks to Neil.
2. Saved another four bytes
3. Saved another byte thanks to Blender.

# Answer
> 7 votes
## Batch, 50 bytes

```
@if %OS%==Windows_NT if not exist Z:\bin\sh echo 1

```

Edit: Fixed to ignore DOS instead of claiming that it's Windows.

The ~~only~~ other way I know of running Batch outside of Windows is to use WINE which by default will map `Z:` to `/`. Therefore if `Z:\bin\sh` exists, chances are that it's `/bin/sh`, so not MS Windows.

I don't know what WINE sets %OS% to, but if it's not `Windows_NT` then I could save 23 bytes.

# Answer
> 7 votes
# Node.js, ~~27~~ ~~16~~ ~~15~~ 13 bytes

Thanks to **@Patrick**, who shaved 12 bytes off my solution using Node's REPL:

```
_=>os.EOL>`
`

```

Original solution:

```
_=>require('path').sep!='/'

```

# Answer
> 7 votes
# Excel VBA, ~~41~~ ~~40~~ ~~30~~ ~~29~~ ~~26~~ 24 Bytes

Immediate windows function that returns `true` if the system's OS code starts is longer than length 3, because the info is restricted to output either else `mac` or `pcdos` this returns `true` only on windows pcs

```
?[Len(Info("SYSTEM"))>3]

```

**Previous Versions**

```
''# Ignore the second `"` that follows every `\` - its only there for highlighting

?Left(Environ("OS"),1)="W"                 # 24 Bytes

?InStr(ThisWorkbook.Path,"\"")             # 29 Bytes

?Mid(ThisWorkbook.Path,3,1)="\""           # 30 Bytes, Restricted to local Files

?Application.PathSeparator="\""            # 30 Bytes

?Left(Application.OperatingSystem,1)="W"   # 40 Bytes

```

**Changes**

-1 Thanks to Neil for using `Left(...,1)` over `Mid(...,1,1)`

-10 Thanks to ChrisH for pointing out @Mego's Path Separator Trick

-1 For Checking the `WorkbookPath` for `"\"` rather than using `Application.Path Separator`

-4 For switching to `Environ()`

-2 For switching to `[Len(Info(...`

**Novel Solution, 51 bytes**

Novel `sub`routine that outputs, to the VBE immediates window, a `1 (truthy)` under windows and `0 (falsey)` under mac by method of conditional compilation.

```
Sub a
i=1
#If Mac Then
i=0
#End If
Debug.?i
End Sub

```

# Answer
> 7 votes
# QBasic, 31 bytes

```
?INSTR(ENVIRON$("COMSPEC"),"W")

```

Prints non-zero under Windows, 0 under everything else.

`COMSPEC` is an environment variable unique to Microsoft OSs. It points to the command interpreter, typically `command.com` or `cmd.exe`. Under Windows, the command interpreter sits somewhere in the Windows directory; under MS-DOS, it sits in the DOS directory or on the root of the disk, and under any other OS, it doesn't exist.

By checking to see if the value of `COMSPEC` contains a "W", we can tell the difference between Windows and not-Windows.

# Answer
> 6 votes
# Perl 6,  ~~19~~  18 bytes

```
put $*DISTRO.is-win

```

```
put ?($*CWD~~/\\/)

```

Both output `True␤` or `False␤` depending on the system it is run on.

# Answer
> 6 votes
# bash + coreutils, 5 bytes

```
rm $0

```

Also works in most other POSIXy shells. (Note that Windows ports of `bash` and `rm` exist; even though they're only normally used with more heavily POSIXy operating systems, this isn't an entirely vacuous entry.) Outputs via exit code (0 = false, 1 = true). Can be counted as 4 bytes if you're allowed to assume a filename (e.g. `rm a`). Note that this can potentially fail in the case of very weird filenames (which `rm` will interpret as arguments due to the lack of quoting, and possibly delete files you care about, so I'd advise against running this program from a file with a weird name).

Note: deletes the program from disk as a side effect, or at least tries to. In the case where we're running on Windows, the OS will fail to delete the running file (an operation that Windows disallows either by default or full stop), and thus `rm` will error out. `bash` catches the error and converts it into an exit code (thus the program as a whole terminates normally). Most of the other entries here are using 0 for falsey and 1 for truthy in exit codes, so this does the same; note that `bash`'s `if` statement doesn't accept integers at all (rather, it accepts *commands* and branches based on whether they run successfully, and arithmetic tests are done via the means of programs like `test` that intentionally report a "crash" on a failed comparison), so this is on shakier ground in terms of legality than programs that output via exit code in languages where 0 is valid in an `if` statement test and sends the program to the `else` branch.

# Answer
> 5 votes
# APL (Dyalog), 21 bytes

```
'W'∊∊#⎕WG'APLVersion'

```

Try it online!

`#⎕WG'APLVersion'` Root (**#**) **W**indow **G**et property **APL Version**

enlist (flatten)

`'W'∊` is **W** a member? (no non-Windows return values contain a capital W)

# Answer
> 5 votes
# TrumpScript, 17 bytes

```
America is great.

```

Try it online!

---

This program, if run on windows, will print:

```
The big problem this country has is being PC

```

This is considered a truthy value.

---

Empty output and the following value are falsy:

```
Boycott all Apple products  until such time as Apple gives cellphone info to authorities regarding radical Islamic terrorist couple from Cal

```

The empty output will occur on any linux system (for this program), the long apple response obviously occurs on Mac (for any program). On TIO, the backend (I'm assuming) is a Unix operating system, so you can only get the falsy value; on my computer I get the PC message.

---

Not 100% sure if this counts as an error message (which would invalidate the answer), but if you didn't know about this it was probably worth a laugh for you.

# Answer
> 4 votes
# Haskell, ~~39~~ 31 bytes

```
import System.Info
f=os!!0=='m'

```

I check for the first letter output of "m", which should be "mingw" for windows. As far as I could tell, there is no other OS which starts with M. The information comes from https://github.com/ghc/ghc/blob/master/compiler/utils/Platform.hs

# Answer
> 4 votes
# tcl, 38 bytes

```
 expr [lsearch $tcl_platform windows]>0

```

# Answer
> 4 votes
# PHP 17 Bytes

The following will output 1 if windows and nothing if anything else. Ignoring notices of string convertion.

`<?=PHP_OS==WINNT;`

Try online Online tests for linux because the sandbox is linux for PoC.

# Answer
> 4 votes
# 8th, 11 bytes

```

os 1- not .

```

Prints `true` on Windows, `false` on Linux and macOS. Other platforms supported by 8th are Android, iOS and Raspberry Pi, but I am not able to test on them.

Ungolfed version (with comments)

```

G:os  \ Return a number n indicating the operating system
      \ 0 for Linux
      \ 1 for Windows
      \ 2 for macOS
      \ 3 for Android
      \ 4 for iOS
      \ 5 for Raspberry Pi
n:1-  \ Subtract 1
G:not \ If Windows --> true, otherwise --> false
.     \ Print result

```

# Answer
> 4 votes
# Java 8, 49 bytes

```
()->System.getenv().get("OS").contains("Windows")

```

Longer than the other Java answer, but takes a different approach.

This lambda fits in a `Supplier<Boolean>` and can be tested with the following program:

```
public class DetectMSWindows {

  public static void main(String[] args) {
    System.out.println(f(() -> System.getenv().get("OS").contains("Windows")));
  }

  private static boolean f(java.util.function.Supplier<Boolean> s) {
    return s.get();
  }

}

```

# Answer
> 4 votes
# Python 3 (13 bytes)

```
import winreg

```

Returns with exit code zero (generally true in shells) if on windows, and with a non-zero exit code otherwise.

If you prefer it the other way round, there is a 12 bytes solution: `import posix`.

# Answer
> 4 votes
# Powershell 6, 10 bytes

```
$isWindows

```

`Powershell 6` intoduce 3 predefined variables: `$isWindows`, `$isLinux` and `$IsMacOs`.

# Answer
> 3 votes
## FPC, 61 chars

```
begin{$ifdef win32}write('f');{$else}write('nf');{$endif}end;

```

# Answer
> 3 votes
# IBM/Lotus Notes Formula Language, ~~22~~ 21 bytes

```
@Like(@Platform;"W%")

```

Previous versions:

```
@Left(@Platform;1)="W"

```

or

```
@Begins(@Platform;"W")

```

Computed field formula on a Notes form. @Platform returns 1 of:

```
AIX/64
Linux/64
Macintosh
OS/400®
UNIX
Windows/32
Windows/64

```

So the formula returns 1 (@True) if the platform starts with "W" and 0 (@False) if not.

# Answer
> 3 votes
## Lua, 21 Bytes

```
os.execute"dir c:\\"

```

It will error if not on windows and list the C:\ directory if on windows.

# Answer
> 3 votes
# LibreOffice Calc / OpenOffice Calc, 21 bytes

**Code:**

```
=INFO("system")="WNT"

```

# Microsoft Excel, 23 bytes

**Code:**

```
=INFO("system")="pcdos"

```

**Result:**

Returns **TRUE** if Windows; **FALSE** otherwise.

# Answer
> 3 votes
# C (gcc), x64 only, 37 bytes

```
asm("m:_m:.int 50066");f(){m(2,1,0);}

```

Try it online!

Function called `f()`. Returns `1` for Windows, `0` for non-Windows.

You wanted a "creative solution"? Here you go. Unfortunately, it isn't as short or portable as the other C solution. (TODO: x86, ARM, and ARM64 polyglot /s)

Expanded:

```
// ASM
// We need both m and _m because macOS uses leading underscores for
// C symbols, while Windows and Linux do not.
m:
_m:
        // We manually encode these in the golfed code to save space.
        // eax = edx
        xchg    eax, edx // 0x92
        ret              // 0xC3
// C
int m(int, int, int);
int f()
{
    // The first parameter can be anything, I use 2 for ease of explanation.
    return m(2, 1, 0);
}

```

What does it do? It uses the fact that Windows and Linux (and Mac, BSD, etc) use different calling conventions on x64.

So, when GCC tries to call `m(2, 1, 0)`, on Windows it will use the Microsoft x64 calling convention (`rcx`, `rdx`, `r8`, `r9`):

```
    mov     ecx, 2
    **mov     edx, 1**
    mov     r8d, 0
    call    m
```

However, on Linux, Mac, BSD, etc, it will use the System V calling convention (`rdi`, `rsi`, `rdx`, `rcx`, `r8`, `r9`):

```
    mov     edi, 2
    mov     esi, 1
    **mov     edx, 0**
    call    m
```

As I have bolded, `edx` is used on both platforms, but since they represent different parameters in the calling conventions, Windows and non-Windows will get different values.

With some inline assembly, we can get GCC to return the value of `edx` instead of the third parameter.

To test how it would function on Windows, simply uncomment the prototype at the top, which uses an attribute to force GCC to use the Microsoft ABI.

# Answer
> 2 votes
~~tcl, 51
```
puts [string match windows $tcl_platform(platform)]

```
I don't have a Windows machine online, but on http://rextester.com/live/OVTY1488 replace `windows` by `unix` to see it output 1 instead of 0.
2nd attempt:
tcl, 40
```
puts [string match W* $tcl_platform(os)]

```~~

~~assuming Windows is the only system the name begins on a W.~~

3rd attempt:

# tcl, 26

```
puts [info exists env(OS)]

```

assuming Windows is the only system the `OS` environment variable is defined.

# Answer
> 2 votes
# Ruby, 38 bytes

Stealing the code from here:

```
exit (RUBY_PLATFORM=~/(?<!r)win/)!=nil

```

Return 0 on OK, to keep with shell conventions. We need the funny `(?<!r)` negative look-behind to avoid matching `darwin`, although if Microsoft device to make a `vrwin` Windows version for virtual reality the code will fail... On JRuby, though, this doesn't work so well, so instead:

# Ruby including JRuby, 52 bytes

```
exit (RbConfig::CONFIG['host_os']=~/(?<!r)win/)!=nil

```

I don't have raw Windows, just Cygwin, but if the `host_os` is `windows` then we need to distinguish `nil` and `0`.

# Ruby plus gem install os, 25 (+9?)

This needs an extra gem, so we might have to add an extra 9 bytes for `gem i os` at the command line:

```
require 'os'
exit OS.windows?

```

This also avoids the `darwin` problem completely!

# Answer
> 2 votes
# PHP, 18 bytes

```
<?=!(PHP_EOL^'=');

```

## Explanation

`PHP_EOL`, as its name might suggest, returns the line separator on a given system. On Windows, this is CRLF, and on other platforms, this is LF.

`^` is binary XOR. `'='` XOR `"\r"` is `'0'`, and PHP's string bitwise operations truncate to the length of the shortest string, so `"\r\n"` XOR `'='` is also `'0'`.

`!` is boolean NOT. In PHP, `"0"` is considered falsy. So, when we're on Windows, PHP will negate this to `true`. When we're not on Windows, we get a truthy value (`'7'`) which PHP negates to `false`.

`<?=` is the short opening tag for `echo`.

# Answer
> 2 votes
# Ruby 2, ~~17~~ 14 bytes

17 byte solution: `Gem.win_platform?` This only works on the newer versions of ruby, as in the older versions you would have to require `rubygems`.

---

### 14 byte solution:

`system 'del a'` This command outputs true if on windows, because there is a command called `del` in Windows, but outputs `nil` (falsey) on Linux and Mac because there is no such command as `del` in Unix. Oh, and if you are on windows it will delete a file called a in your current directory, that's an unintended side effect :P

# Answer
> 2 votes
# Python 3, 29 bytes

```
import os;exit(os.name!='nt')

```

Probably should have tryed that first....

## Previous answer (41 bytes)

Two answers I found that are the same size

```
import os;exit(-hasattr(os,"P_DETACH")+1)

```

and

```
import sys;exit(-hasattr(sys,"winver")+1)

```

also -+1 is a neat way to negate the output, gonna keep that one noted

# Answer
> 1 votes
# Elixir, 19 bytes

```
{:win32,_}=:os.type

```

Exit code 0 for Windows, 1 for others.

# Answer
> 1 votes
## Scala, 71 bytes

```
object W extends App{print(sys.env.get("OS").get.contains("Windows"))}

```

# Answer
> 1 votes
# Dartlang, 43 bytes

```
import'dart:io';main()=>Platform.isWindows;

```

First answer one here, so I hope this is okay :)

# Answer
> 1 votes
# , 43 bytes

```
int f(){version(Windows)return 0;return 1;}

```

D ... is horrible at golfing. But it **does** have a `version` construct, so I thought I'd post an answer in D.

And ... there's really no point in putting a TIO link, since TIO is ran on only one type of OS.

# Answer
> 1 votes
# SQL 2017, 61 bytes

```
SELECT IIF(host_platform='Linux',0,1)FROM sys.dm_os_host_info

```

SQL 2017 is the first MS SQL version that can run on a platform other than Windows. The system view `sys.dm_os_host_info` returns either `Linux` or `Windows`, so (at least in this version) anything that isn't on Linux is on Windows.

# Answer
> 1 votes
# Rust, 14 bytes

```
||!cfg!(unix);

```

The `target_family` attribute is `windows` on Windows and (most) others have `unix`.

# Answer
> 1 votes
# 05AB1E, ~~26~~ 19 bytes

```
'ª¬7£’ÿ :ï´.ƒª’.E2å

```

Try it online!

```
'ª¬7£’...’.E2å  # trimmed program
             å  # is...
            2   # literal...
             å  # in...
          .E    # result of running...
     ’...’      # "ÿ :os.type"...
                # (implicit) with ÿ replaced by...
    £           # first...
   7            # literal...
    £           # characters of...
'ª¬             # "inspection"...
          .E    # as Elixir code...
             å  # ?
                # implicit output

=================================================

inspect :os.type  # full program
        :os.type  # return tuple of OS family and OS name...
inspect           # as a string

```

`:os.type` return values:

| Family | Names |
| --- | --- |
| `unix` | A result from running `uname -s`. No Unix kernels have `2` in their name, so if the machine is running Unix, the program will return `0`. |
| `win32` | `nt` or `windows` |

# 05AB1E (legacy), 21 bytes

```
’__£Ø__('ï´').ˆ³’.EÇÈ

```

Try it online!

```
’...’.EÇÈ  # trimmed program
        È  # push 1 minus...
       Ç   # codepoint of...
     .E    # result of running...
’...’      # "__import__('os').sep"...
     .E    # as python code...
        È  # modulo 2
           # implicit output

=================================================

__import__('os').sep  # full program
__import__(    )      # return...
           'os'       # operating system...
                .sep  # file path separator

```

# Answer
> 1 votes
# Julia 0.6, 8 bytes

```
!is_unix

```

Try it online!

# Julia 1.0, 11 bytes

```
!Sys.isunix

```

Try it online!

# Answer
> 1 votes
# Factor, 11 bytes

```
os windows?

```

Try it online!

# Answer
> 1 votes
# Nim, 20 bytes

```
echo defined windows

```

Try it online!

# Answer
> 1 votes
# Lua (LuaJIT), 17 bytes

```
print(jit.os>"V")

```

Try it online!

# Answer
> 1 votes
# Thunno 2, 28 bytes

```
‘\_\_Ʋ¡\_\_('Ỵġ').ẓ÷()‘E`ż³=

```

Uses `platform.system()`, as suggested in this SO answer.

#### Explanation

```
‘...‘E`ż³=  # Full program
‘...‘       # Push compressed string "__import__('platform').system()"
     E      # Evaluate as Python code (returns "Linux"/"Darwin"/"Windows")
      `ż³   # Push compressed string "Windows"
         =  # Are they equal?
            # Implicit output

```

# Answer
> 1 votes
# Swift, ~~33~~ 39 bytes

```
var f={#if os(Windows)
1#else
0#endif
}

```

Simply performs a compile-time check on the OS family and returns `1` if it's on Windows, or `0` otherwise. (I'm not gonna lie, I'm a little surprised you can put compiler directives on non-new lines like that...)

# Answer
> 0 votes
# Racket, ~~26~~ 17 bytes

Shameless plug for the TCL answer I saw that used the OS environment variable.

```
(and(getenv"OS"))

```

---

(Old answer)

Pretty straight forward. `system-type` with no argument returns a symbol indicating the system operating system type.

```
(eq?'windows(system-type))

```

# Answer
> 0 votes
**Nim, 37 bytes**

```
quit when defined(windows): 0 else: 1

```

Returns exit code `0` for Windows, `1` for all other operating systems. Uses conditional compilation with `when`.

# Answer
> 0 votes
# PowerShell, 17

```
gdr|? P* -like *y

```

Abusing the fact that there's no Registry PSProvider on non-Windows systems.

# Answer
> 0 votes
# Node.js, 23 bytes

```
_=>os.platform=="win32"

```

# Answer
> 0 votes
# GNU AWK, ~~45~~ 37 bytes

```
BEGIN{print PROCINFO["platform"]~/w/}

```

Try it online!

Evaluates the `PROCINFO["platform"]` built-in variable, and returns `1` if it matches any `w` character; returns `0` otherwise. Why, you ask? According to the GNU AWK manual, only `mingw` option has a letter `w`:

```
PROCINFO["platform"]

    This element gives a string indicating the platform for which
    gawk was compiled. The value will be one of the following:

    "mingw"
        Microsoft Windows, using MinGW.

    "os390"
        OS/390.

    "posix"
        GNU/Linux, Cygwin, Mac OS X, and legacy Unix systems.

    "vms"
        OpenVMS or Vax/VMS.

```

# Answer
> 0 votes
# Python 3, 78 bytes

Raises a `KeyError` exception if it can't determine if running on Windows. On not-Windows it can return either None or 0 (both are falsy), on Windows it returns 1.

```
def f():
 try:open(':','x')
 except Exception as e:return{17:0,22:1}[e.errno]

```

`:` is a forbidden character on Windows (also on DOS, etc.)

# Answer
> 0 votes
# PowerShell, 18 bytes

```
$env:OS-like"Win*"

```

Try it online!

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