8
\$\begingroup\$

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.

\$\endgroup\$
  • 5
    \$\begingroup\$ Can a positive integer begin with 0? \$\endgroup\$ – feersum Aug 10 '16 at 11:14
  • 1
    \$\begingroup\$ Are repeated zeros like 00 truthy, or are they even valid inputs? (I suppose they are not valid, but just checking) \$\endgroup\$ – Zgarb Aug 10 '16 at 13:02
  • 3
    \$\begingroup\$ What about FileNotFound? ;) \$\endgroup\$ – TRiG Aug 10 '16 at 14:26
  • \$\begingroup\$ @feersum a non-zero input will never have preceding zeros. \$\endgroup\$ – helloworld922 Aug 10 '16 at 16:04
  • \$\begingroup\$ @Zgarb they are not valid inputs \$\endgroup\$ – helloworld922 Aug 10 '16 at 16:05

10 Answers 10

17
\$\begingroup\$

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.

\$\endgroup\$
9
\$\begingroup\$

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!

\$\endgroup\$
  • \$\begingroup\$ The n?on is great, I'm going to use it. I think you don't need the first `\` \$\endgroup\$ – edc65 Aug 10 '16 at 13:00
  • \$\begingroup\$ @edc65: You're right, I don't, oddly enough. \$\endgroup\$ – Business Cat Aug 10 '16 at 13:04
  • \$\begingroup\$ Nice trick with n?on. \$\endgroup\$ – AdmBorkBork Aug 10 '16 at 13:09
8
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Answers like this make me want to write an automated script that posts questions on Code Review seeded with Code Golf content. wipes tear \$\endgroup\$ – corsiKa Aug 10 '16 at 19:48
  • \$\begingroup\$ This is amazing. Even if there might be shorter solutions, I don't care, this is the clear winner. \$\endgroup\$ – philomory Aug 10 '16 at 23:31
6
\$\begingroup\$

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)))

\$\endgroup\$
  • \$\begingroup\$ Does removing the \d from the regexp and changing to |v!=0 work? \$\endgroup\$ – Neil Aug 10 '16 at 12:25
  • \$\begingroup\$ How about swapping the \d for 1-9? Provided that feersum's question is accurate, ^([-1-9dsty]|on|fo|non) should suffice. \$\endgroup\$ – AdmBorkBork Aug 10 '16 at 12:54
4
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ @edc65 the first answer didn't, now checking for false and including ord('0') does \$\endgroup\$ – Karl Napf Aug 10 '16 at 11:24
  • \$\begingroup\$ 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. \$\endgroup\$ – DJMcMayhem Aug 10 '16 at 11:36
3
\$\begingroup\$

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)

\$\endgroup\$
  • \$\begingroup\$ Why the downvote? It seems to work, just true is false and false is true, that's allowed \$\endgroup\$ – edc65 Aug 10 '16 at 11:40
  • 2
    \$\begingroup\$ You can shorten the string array be writing ' 0 f failure false n nan nil no notfound not-found null nullptr off undefined'.split(' ') \$\endgroup\$ – KarlKastor Aug 10 '16 at 11:51
  • \$\begingroup\$ @KarlKastor You can actually use .split() instead, because the default separator for split is whitespace. \$\endgroup\$ – Skyler Aug 10 '16 at 18:18
  • \$\begingroup\$ @Skyler I know, but then there's the empty string missing somehow. \$\endgroup\$ – KarlKastor Aug 10 '16 at 18:45
2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ You don't need parentheses to use alternation in regex: '^[-1-9dsty]|fo|n?on' :) \$\endgroup\$ – briantist Aug 10 '16 at 15:40
  • \$\begingroup\$ @briantist Without the parens, it matches notfound and not-found because of the fo. \$\endgroup\$ – AdmBorkBork Aug 10 '16 at 15:55
  • \$\begingroup\$ D'oh, you're right. You could do ^[-1-9dsty]|^fo|^n?on but that's the same number of chars and less clear. \$\endgroup\$ – briantist Aug 10 '16 at 15:58
2
\$\begingroup\$

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.

\$\endgroup\$
  • 2
    \$\begingroup\$ Ah 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" :-) \$\endgroup\$ – corsiKa Aug 10 '16 at 19:50
1
\$\begingroup\$

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

\$\endgroup\$
0
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ Don´t the ins include non-empty? \$\endgroup\$ – Titus Aug 10 '16 at 16:37
  • \$\begingroup\$ @Titus I'm not sure what you mean. \$\endgroup\$ – atlasologist Aug 10 '16 at 16:55
  • \$\begingroup\$ 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 \$\endgroup\$ – Titus Aug 10 '16 at 17:57
  • \$\begingroup\$ @Titus, I see what you mean. I had the same thought at first, but ''[:1] in 'abc' evaluates to true. \$\endgroup\$ – atlasologist Aug 10 '16 at 18:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.