Is it truthy or falsy?

8

2

There are so many different ways to express whether something is true or not! The goal of this challenge is to produce a standardized output of truthy or falsy for various input truthy and falsy values.

For the purposes of this challenge, the following inputs are considered truthy:

  1. A string representing a signed integer with a non-zero value (contains only the digits [0-9], with an optional - at the beginning). Note that the string -0 will never be given as input. A non-zero integer will never be preceded by a 0 (i.e. 01 will never be given as input, similarly -01 will never be gien as input).
  2. The case-insensitive strings equivalent to one of defined, found, nonnil, non-nil, on, success, t, true, y, and yes

For the purposes of this challenge, the following inputs are considered falsy:

  1. The string 0. Repeated zeros (00, 00...) will never be given as input.
  2. An empty string
  3. The case-insensitive strings equivalent to one of f, failure, false, n, nan, nil, no, notfound, not-found, null, nullptr, off, and undefined

Input

The input is a string representing a truthy/falsy value. The string may come from any source desired (stdio, function parameter, etc.). There is no leading/trailing whitespace.

The input is guaranteed to match one of the allowed truthy/falsy values above (i.e. you do not need to provide any error handling).

Output

Your program/function must output a truthy/falsy value which represents the "truthy-ness" or "falsy-ness" of the input. You are only allowed to specify exactly 1 truthy and 1 falsy value which your output must convert the input to (these are your "standardized" truthy/falsy value). The output may be written to any sink desired (stdio, return value, output parameter, etc.).

Please specify what truthy and falsy value you chose in your answer.

Ex.: If you choose the string true as a truthy value, you cannot also have the integer 1 for truthy.

Test Cases

Test cases are formatted as the first line is the input, and the second line is the output.

-1
true

1
true

1234
true

-4321
true

defined
true

deFined
true

Found
true

nonnil
true

non-nil
true

ON
true

SuCCess
true

T
true

true
true

y
true

YeS
true

0
false

'' (empty string)
false

faLSE
false

f
false

Failure
false

n
false

NaN
false

nil
false

no
false

notfound
false

not-Found
false

NULL
false

nullptr
false

OFF
false

unDefined
false

Scoring

This is code-golf; shortest code in bytes wins. Standard loopholes apply. You may use any built-ins desired.

helloworld922

Posted 2016-08-10T10:19:35.920

Reputation: 2 503

5Can a positive integer begin with 0? – feersum – 2016-08-10T11:14:11.120

1Are repeated zeros like 00 truthy, or are they even valid inputs? (I suppose they are not valid, but just checking) – Zgarb – 2016-08-10T13:02:17.713

3

What about FileNotFound? ;)

– TRiG – 2016-08-10T14:26:39.413

@feersum a non-zero input will never have preceding zeros. – helloworld922 – 2016-08-10T16:04:37.473

@Zgarb they are not valid inputs – helloworld922 – 2016-08-10T16:05:21.430

@TRIG I would have added that if there were fewer answer already given for the current set of inputs. – helloworld922 – 2016-08-10T16:07:08.097

Answers

17

MATL, 20 bytes

U|sG36ZA13\[BID1]m+g

Input is a string enclosed in single quotes. Output is 1 for truthy or 0 for falsy.

Try it online! Or verify all test cases.

How it works

U|s      % Take input implicitly. Interpret as number, absolute value, sum
G36ZA    % Push input again. Convert from base-36
13\      % Modulo 13
[BID1]   % Push array [6 3 8 1]
m        % True if member: gives 1 iff the result from modulo 13 is in the array
+g       % Add, convert to logical. Display implicitly

This performs two tests on the input:

  1. Try to interpret the input as a number, and detect if it is nonzero. The function used to interpret a string as a number outputs an empty array if it's not possible; and the sum of the entries of an empty array is 0. So it suffices to try the conversion, take the absolute value, and sum. This gives a positive value if the input contains a nonzero number, and 0 otherwise.
  2. Assuming the input string doesn't represent a number, we need to classify it into one of the two given sets. To do this, the input is interpreted as the digits of a number expressed in base-36, using alphabet '01...9ab...z'. The base conversion function is case-insensitive and ignores digits not present in the alphabet (in our case, '-'). It turns out that the modulo 13 of the resulting number is 1, 3, 6 or 8 for the truthy strings, and doesn't give any of those values for the falsy strings. So it can be used as a signature. We thus perform modulo 13 and see if the result is any of those four values. This gives 1 if it is, or 0 otherwise.

The final result should be truthy if any of the two conditions is met, and falsy otherwise. So we add the two numbers resulting from 1 and 2 above and convert to logical, which gives 1 or 0 as standardized truthy/falsy values.

Luis Mendo

Posted 2016-08-10T10:19:35.920

Reputation: 87 464

9

Retina, 22 24 23 bytes

Saved 1 byte thanks to edc65

i`^([-1-9sdty]|fo|n?on)

The whole code is just a regex. The i` at the start makes the regex case insensitive.

Outputs 1 for truthy, 0 for falsey.

Try it online!

Business Cat

Posted 2016-08-10T10:19:35.920

Reputation: 8 927

The n?on is great, I'm going to use it. I think you don't need the first \\ – edc65 – 2016-08-10T13:00:33.863

@edc65: You're right, I don't, oddly enough. – Business Cat – 2016-08-10T13:04:39.487

Nice trick with n?on. – AdmBorkBork – 2016-08-10T13:09:33.620

8

Batch, 142 bytes

@goto l%1 2>nul
:l
:l0
:lfailure
:lfalse
:ln
:lnan
:lnil
:lno
:lnotfound
:lnot-found
:lnull
:lnullptr
:loff
:lundefined
@echo 1

Outputs 1 for falsy, nothing for truthy.

Neil

Posted 2016-08-10T10:19:35.920

Reputation: 95 035

Answers like this make me want to write an automated script that posts questions on Code Review seeded with Code Golf content. wipes tear – corsiKa – 2016-08-10T19:48:31.973

This is amazing. Even if there might be shorter solutions, I don't care, this is the clear winner. – philomory – 2016-08-10T23:31:04.547

6

JavaScript (ES6), 35 39

Edit using the n?on trick, stolen from BusinessCat's answer

Edit 2 OP clarified, no leading 0s, saved 4 bytes

v=>/^([-1-9dsty]|fo|n?on)/i.test(v)

Simply returns true or false

Test

f=v=>/^([-1-9dsty]|fo|n?on)/i.test(v)

trues=[-1,1,1234,-4321,'defined','deFined','Found',
'nonnil','non-nil','ON','SuCCess','T','true','y','YeS']
falses=[0,'','faLSE','f','Failure','n','NaN','nil',
'no','notfound','not-Found','NULL','nullptr','OFF','unDefined']

console.log('TRUE: '+trues.map(x=>f(x)))

console.log('FALSE:' +falses.map(x=>f(x)))

edc65

Posted 2016-08-10T10:19:35.920

Reputation: 31 086

Does removing the \d from the regexp and changing to |v!=0 work? – Neil – 2016-08-10T12:25:54.640

How about swapping the \d for 1-9? Provided that feersum's question is accurate, ^([-1-9dsty]|on|fo|non) should suffice. – AdmBorkBork – 2016-08-10T12:54:11.593

4

Python, 129 79 78 bytes

Gotta submit fast!

lambda n:n.lower()[:3]in" 0 f n no nil fai fal nan not nul off und".split(" ")

True is false and false is true; I have a nice rhyme for this, I really do (not)

Destructible Lemon

Posted 2016-08-10T10:19:35.920

Reputation: 5 908

Why the downvote? It seems to work, just true is false and false is true, that's allowed – edc65 – 2016-08-10T11:40:20.507

2You can shorten the string array be writing ' 0 f failure false n nan nil no notfound not-found null nullptr off undefined'.split(' ') – KarlKastor – 2016-08-10T11:51:55.147

@KarlKastor You can actually use .split() instead, because the default separator for split is whitespace. – Skyler – 2016-08-10T18:18:26.493

@Skyler I know, but then there's the empty string missing somehow. – KarlKastor – 2016-08-10T18:45:49.300

4

Python, 111 bytes

def b(s):s=s.lower();return s!='no'and not sum(map(ord,s))in[0,48,323,744,523,877,110,785,443,922,315,317,946]

Tests on sum of ASCII values, extra check for no since on has the same value.

  • Edit1: forgot to test on integer values. Now checking for false inputs

Karl Napf

Posted 2016-08-10T10:19:35.920

Reputation: 4 131

@edc65 the first answer didn't, now checking for false and including ord('0') does – Karl Napf – 2016-08-10T11:24:24.993

lambda s:s.lower()!='no'and sum(map(ord,s.lower()))in[0,48,323,744,523,877,110,785,443,922,315,317,946]>1 I haven't tested it though. – James – 2016-08-10T11:36:42.023

3

Python, 83 75 bytes

import re
def f(s):return re.search(r'^([-1-9dsty]|fo|n?on)',s.lower()).pos

Returns 0 on success, AttributeError on failure.

Now using edc85's regex to save 8 bytes.

Skyler

Posted 2016-08-10T10:19:35.920

Reputation: 897

2Ah yes, the good old "explode the program when it fails the test" approach. I love seeing comments like "we couldn't have reached here with invalid arguments" :-) – corsiKa – 2016-08-10T19:50:12.823

2

PowerShell v2+, 39 37 bytes

$args[0]-match'^([-1-9dsty]|fo|n?on)'

Presumes that the answer to @feersum's question is "No, truthy integers may not start with a 0."

Port of @edc65's regex JavaScript answer, with my own 1-9 substitution instead of \d. Uses @BusinessCat's n?on trick to golf further.

Outputs literal Boolean $true or $false values, which when left on the pipeline and sent through an implicit Write-Output at the end of execution results in True or False being printed to the console.


If the answer is "Yes, truthy integers can start with 0," then the following changes need to be made for 51 49 bytes

param($n)$n-ne0-and$n-match'^([-\ddsty]|fo|n?on)'

If you don't like regex, go for PowerShell v3+ and the following at 107 bytes

param($n)$n-and$n-notin-split'0 f failure false n nan nil no notfound not-found null nullptr off undefined'

This takes the string of falsey values, -splits them on whitespace, and uses the -notin operator to check the input $n against that array of strings (which is, by default, case-insensitive). Requires the $n-and to check against the empty string.

AdmBorkBork

Posted 2016-08-10T10:19:35.920

Reputation: 41 581

You don't need parentheses to use alternation in regex: '^[-1-9dsty]|fo|n?on' :) – briantist – 2016-08-10T15:40:28.860

@briantist Without the parens, it matches notfound and not-found because of the fo. – AdmBorkBork – 2016-08-10T15:55:55.027

D'oh, you're right. You could do ^[-1-9dsty]|^fo|^n?on but that's the same number of chars and less clear. – briantist – 2016-08-10T15:58:31.803

1

PHP, 50 bytes

<?=preg_match('%^([-1-9dsty]|fo|n?on)%i',$argv[1])

prints 1 for truthy, nothing for falsy

tried to come up with a different solution, but the shortest regex for falsy is 3 bytes longer than that for truthy: %^(0|fa|f?$|n(?!on)|of|u)%i

Titus

Posted 2016-08-10T10:19:35.920

Reputation: 13 814

0

Python, 83 bytes

lambda x:x.lower()[:3]in['fou','non','on']or x[:1].lower()in'dsty-123456789'and''<x

https://repl.it/ClgO/1

atlasologist

Posted 2016-08-10T10:19:35.920

Reputation: 2 945

Don´t the ins include non-empty? – Titus – 2016-08-10T16:37:30.870

@Titus I'm not sure what you mean. – atlasologist – 2016-08-10T16:55:21.883

What is x[:1] for an empty string? Does in return false in that case? If so, you should be able to drop the and''<x – Titus – 2016-08-10T17:57:22.080

@Titus, I see what you mean. I had the same thought at first, but ''[:1] in 'abc' evaluates to true. – atlasologist – 2016-08-10T18:51:24.247