28
\$\begingroup\$

Instructions

Given an unknown input string i with a value of either heads or tails, return 1 for heads or -1 for tails with the shortest code.

Sample not golfed code (55b):

if(i == "heads"){
    print(1);
}else{
    print(-1);
}

Sample golfed code (16b):

print("t">i||-1)


Javascript was used for the example but it's not a requirement. Sorry if it's too simple for most users, it can be improved.

\$\endgroup\$
9
  • 16
    \$\begingroup\$ Welcome to PPCG! This is too simple to be an interesting challenge. In the future, please consider posting challenges to the Sandbox, where they can get feedback before posting them live. \$\endgroup\$
    – Alex A.
    May 16, 2015 at 4:06
  • 1
    \$\begingroup\$ 6 answers, not so a bad challenge indeed. Try again \$\endgroup\$
    – edc65
    May 16, 2015 at 13:33
  • 5
    \$\begingroup\$ At 4 upvotes and 5 downvotes, your question wasn't really unpopular; it just got mixed reviews. While the task at hand is a little basic, it is well-defined and attracted 7 answers so far which feature several different approaches. Not that bad for a first attempt. \$\endgroup\$
    – Dennis
    May 16, 2015 at 16:31
  • 8
    \$\begingroup\$ I'm so confused right now, yesterday -4, now +4, this sure ain't stackoverflow :P \$\endgroup\$ May 17, 2015 at 7:26
  • 11
    \$\begingroup\$ I've been waiting for a short challenge like this for ages, most of the challenges are too long and complicated for a novice like me. \$\endgroup\$ May 18, 2015 at 11:52

59 Answers 59

18
\$\begingroup\$

C, 18 bytes

Pretty easy, but let's do it just for fun...

puts("-1"+*i/8%2);

Given the string char *i it prints 1 for heads and -1 for tails, with trailing newline.

Explanation

In C, "-1" + 1 points to 1 character forward, so it is the same as "1". Let's take a look at the first characters:

"heads"[0] = 'h' = 104 = 0b01101000
"tails"[0] = 't' = 116 = 0b01110100

If we count the bits from the rightmost one starting at zero, bit 3 is 1 in heads and 0 in tails: summing it to "-1" gives the right string. It looks like this:

"-1" + ((i[0] >> 3) & 1)

Now, substitute i[0] with *i and the right shift with the power-of-two division to save some bytes. Also remove useless parentheses:

"-1" + (*i / 8 & 1)

Now, & 1 can be substituted with % 2. The character count is the same, but the modulus has higher priority, allowing to drop the parentheses. Remove the whitespace:

"-1"+*i/8%2

Bonus

I think the shortest way to get an integer 1 or -1 (not a string) in C is:

18-*i/6

Explanation:

'h' = 104
't' = 116

('h' + 't') / 2 = 110
110 - 'h' =  6
110 - 't' = -6

(110 - 'h') / 6 =  1
(110 - 't') / 6 = -1

Apply distributive property (integer division):
18 - 'h' / 6 =  1
18 - 't' / 6 = -1
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Beautiful, love it \$\endgroup\$ May 16, 2015 at 15:07
12
\$\begingroup\$

Ruby, 8 (6 without output)

p ?t<=>i

Rocketship operator!

\$\endgroup\$
1
  • \$\begingroup\$ Clearly the right tool for the job. \$\endgroup\$
    – primo
    May 18, 2015 at 4:25
11
\$\begingroup\$

CJam, 4 bytes

I'e#

Assumes that the variable I holds the input, since i isn't a valid identifier in CJam.

Try it online.

This is equivalent to the JavaScript code I.indexOf('e').

\$\endgroup\$
5
  • \$\begingroup\$ Probably unbeatable for this challenge. \$\endgroup\$
    – Alex A.
    May 16, 2015 at 4:44
  • 1
    \$\begingroup\$ Sorry I didn't understand the requirements enough and made a fool of myself with this question. I'll go back and hide now \$\endgroup\$ May 16, 2015 at 9:36
  • \$\begingroup\$ Why do you not include the p in this? Is it standard in CJam not to? \$\endgroup\$
    – Tim
    May 16, 2015 at 10:56
  • \$\begingroup\$ @Tim CJam always prints the stack contents at the of the program automatically. \$\endgroup\$ May 16, 2015 at 11:47
  • 2
    \$\begingroup\$ @Tim: The question says to return 1 or -1, so I assumed leaving the number on the stack would be fine. I've edited the permalink to show that p is not needed. \$\endgroup\$
    – Dennis
    May 16, 2015 at 16:21
9
\$\begingroup\$

PHP - 11 Bytes

<?=1-$i^=F;

This works because 'tails' ^ 'F''2' and 'heads' ^ 'F''.', which when typed as an integer is 0.

You may test this solution (or any of the below) in the following way:

<?php foreach(['heads', 'tails'] as $i): ?>
 <?=1-$i^=F;
endforeach; ?>

Ideone Link


Alternatives

15: <?=1-md5($i)%3;
16: <?=md5($i)[5]-5;
16: <?=-crc32($i)%5;

\$\endgroup\$
3
  • \$\begingroup\$ With the short version I'm always getting a 1, care to explain what it does with the XOR? \$\endgroup\$ May 17, 2015 at 7:23
  • \$\begingroup\$ @JuanCortés I've added an explanation, and a link to Ideone. \$\endgroup\$
    – primo
    May 18, 2015 at 3:24
  • 2
    \$\begingroup\$ Now that's thinking outside the box! \$\endgroup\$
    – Dennis
    May 18, 2015 at 3:36
6
\$\begingroup\$

TI-BASIC, 9-10 bytes

cos(πʳinString(Ans,"t

Straightforward. "t" is in position 1 of "tails", but "t" is not in the string "heads", so inString( returns 1 for tails and 0 for heads.

If your calculator is in radian mode (as any mathematician's should be), it takes only nine bytes:

cos(πinString(Ans,"t

Note that TI calculators do not have named strings, so the input is in the calculator's answer variable. Also note that lowercase letters are two bytes each, so this solution actually takes less memory than than the word "heads".

\$\endgroup\$
3
  • \$\begingroup\$ This is awesome. Your byte count is off, though-- cos(, π and the radian symbol are all one byte, so it's actually 8-9 bytes. \$\endgroup\$
    – user39326
    May 20, 2015 at 16:08
  • 1
    \$\begingroup\$ The t and inString( are each two bytes. \$\endgroup\$
    – lirtosiast
    May 20, 2015 at 16:48
  • \$\begingroup\$ Oh, I'd forgotten about lowercase letters being two bytes. Never mind, then. \$\endgroup\$
    – user39326
    May 21, 2015 at 0:36
5
\$\begingroup\$

Fission, 26 21 Bytes

O/';'1
"S@]_"-
R? <tL

Martin (and his excellent answer here) convinced me to learn a new language, and what better place than a quick golf? This is almost certainly not optimal, but hey, it was fun! Once I feel good about it, I may provide some form of explanation if it is requested.

\$\endgroup\$
5
\$\begingroup\$

x86-16 machine code, 8 bytes

As a callable function, input string at DS:SI, output in AL.

80 3C 74    CMP  BYTE PTR[SI], 't'      ; if 'h': CF = 1, if 't': CF = 0 
1A C0       SBB  AL, AL                 ; AL = AL - AL - CF (AL = -CF) 
                                        ;  if 't': AL = 0 and CF = 0
                                        ;  if 'h': AL = -1 and CF = 1 
1C FF       SBB  AL, -1                 ; AL = AL - (-1) - CF 
                                        ;  if 't': AL = AL + 1 = 1
                                        ;  if 'h': AL = AL + 0 = -1
C3          RET

x86-16 machine code, IBM PC DOS, 17 bytes

Or as a standalone DOS COM executable. Input from command line, output to stdout.

00000000: b402 0826 8200 7a04 b22d cd21 b231 cd21  ...&..z..-.!.1.!
00000010: c3

Unassembled:

B4 02           MOV  AH, 02H        ; DOS API display char function     
08 26 0082      OR   DS:[82H], AH   ; set parity flag from input 
7A 04           JPE  HEADS          ; if even, heads - display just '1'
B2 2D           MOV  DL, '-'        ; otherwise first display a '-''
CD 21           INT  21H            ; output DL to console
            HEADS: 
B2 31           MOV  DL, '1'        ; display the '1'
CD 21           INT  21H            ; output DL to console
C3              RET

Explanation:

Use the CPU's parity flag to determine if first char is an 'h' (even number of binary 1's) or a 't' (odd number of binary 1's). This saves one byte over comparing the char in ASCII.

Input/Output:

enter image description here

\$\endgroup\$
4
\$\begingroup\$

Python 2, 16 bytes

print(i<'t')*2-1
\$\endgroup\$
4
\$\begingroup\$

Pyth - 4 bytes


 xz"e

Run with heads or tails. As i is int in Pyth, this uses z as the variable name, which contains any user input. It is equivalent to the Python print(z.find("e")), so uses @Dennis's method.

\$\endgroup\$
4
\$\begingroup\$

VBA (Excel), 12 bytes

Not a fantastic bit of golfing, but it's fun to try with VBA to get anywhere near to a proper programming language...

?13-asc(i)/6

i is the string, and it just exploits the ASCII value of the first character, divided by 6 and substracted from 13 to give 1 or -1. Very simple.

Example run in immediate window (10 extra bytes to set the input variable) :

i="Heads":?13-asc(i)/6
 1
\$\endgroup\$
4
\$\begingroup\$

C, 22 bytes

puts(*i>'h'?"-1":"1");

Credits goes to @TheE for telling me about this!

Explanation:

If the first character of the string is greater than 'h', the string "-1" is printed. Otherwise, the string "1" gets printed. Note that this approach comes with a trailing newline character.


Old version (25 bytes):

printf("%d",*i>'h'?-1:1);

Explanation:

If the first character of the string is greater than 'h', -1 is printed. Otherwise, 1 is printed.

\$\endgroup\$
8
  • \$\begingroup\$ i just said t before , use i as type char , the actual definition would exceed by 1byte like this return -(-1)**i/16 \$\endgroup\$
    – Abr001am
    May 16, 2015 at 11:40
  • \$\begingroup\$ @Agawa001 , But that returns 6 for h and 7 for t. \$\endgroup\$
    – Spikatrix
    May 16, 2015 at 11:42
  • \$\begingroup\$ oh i forgot , i must use power :p \$\endgroup\$
    – Abr001am
    May 16, 2015 at 11:43
  • \$\begingroup\$ Cool guy unfortunately C doesnt have such arithmetic operation thus u have to use -1*pow(-1,*i/16) which makes it waaay longer, in other hand, python and matlab use ** and ^ \$\endgroup\$
    – Abr001am
    May 16, 2015 at 11:56
  • 1
    \$\begingroup\$ @CoolGuy would using puts puts(*i>'h'?"-1":"1"); not be better? (22 bytes) \$\endgroup\$
    – euanjt
    May 20, 2015 at 12:45
4
\$\begingroup\$

Tr: 17 13 characters

(Or 14 10 if you count only the arguments…)

tr -s ta-s -1

Sample run:

bash-4.3$ tr -s ta-s -1 <<< heads
1

bash-4.3$ tr -s ta-s -1 <<< tails
-1

Brief explanation:

tr stands for transliterate, that means, replaces each character of the input found in the first argument with character at the same position in the second argument:

tr ta -1 <<< tails         # replaces t ⇢ -, a → 1
⇒ -1ils

If the first argument is longer, the characters without positional match in the second argument are replaced with second argument's last character:

tr tals -1 <<< tails       # replaces t ⇢ -, a → 1, l → 1, s → 1
⇒ -1i11

When -s (--squeeze-repeats) option is used, successive characters which would be replaced with the same character are replaced at once:

tr -s tals -1 <<< tails    # replaces t ⇢ -, a → 1, l+s → 1
⇒ -1i1

So if we enumerate all characters in “tails”, we get what we need:

tr -s tails -1 <<< tails    # replaces t ⇢ -, a+i+l+s → 1
⇒ -1

Same for “heads”, but wee need to keep the “t” in front to consume the minus (characters sorted alphabetically for creepiness):

tr -s taedhs -1 <<< heads   # replaces h+e+a+d+s → 1
⇒ 1

Merging all uniques characters of “tails” and “heads” in a single first argument, keeping “t” in front leads to final solution:

tr -s tadehils -1 <<< tails # replaces t → -, a+i+l+s → 1
⇒ -1

tr -s tadehils -1 <<< heads # replaces h+e+a+d+s → 1
⇒ 1

To avoid enumerating the characters, an interval in from-to format can be used instead.

\$\endgroup\$
2
  • \$\begingroup\$ Care to explain it? \$\endgroup\$ May 20, 2015 at 13:46
  • \$\begingroup\$ That assumes BSD/GNU tr. POSIXly: tr -s ta-s '-[1*]' \$\endgroup\$
    – sch
    Aug 19, 2019 at 7:47
4
\$\begingroup\$

Japt, 2 bytes

ae

Try it online

\$\endgroup\$
4
\$\begingroup\$

shell (portable/POSIX), 16 bytes

expr $i : he - 1

Try It Online!
Thanks to @StéphaneChazelas in unix.stackexchange.com

Other solutions tried:
echo $[30#$i%7-1] # 17 bytes but only in bash, zsh. Try It Online!
echo $((30#$i%7-1)) # 19 bytes but only bash,ksh,zsh. Try It Online!
he=2;echo $[${i%a*}-1] # 22 bytes But only in bash,zsh . Try It Online!
a=${i%h*};echo ${a:+-}1 # 23 . portable . Try It Online!
he=2;echo $((${i%a*}-1)) # 24 bytes . portable . Try It Online!
IFS=h;set $i;echo ${1:+-}1 # 26 (change IFS) . portable . Try It Online!
(IFS=h;set $i;echo ${1:+-}1) # 28 (subshell) . portable . Try It Online!
(IFS=h;set $i;echo $(($#*2-3))) # 31 bytes . portable . Try It Online!

Note: Using dash as a reasonable simile of a portable shell tester.

  • expr $i : he - 1 works by counting how many characters match he with $i : he. A heads match 2 and a tails match 0 (none).Then substracting 1 with - 1.

  • $[30#$i%7-1] works by converting the string to an integer. The base 30 and the mod by 7 were selected to obtain a difference of 2 between heads and tails. Then subtracting 1 converts the numbers to 1 and -1.
    Note that a $[...] is an archaic form of arithmetic expression $((...)) valid only in some shells.

  • he=2;echo $[${i%a*}-1] works by making a variable of some value and then using Arithmetic Expansion to expand that variable (from the text value). The ${i%a*} converts heads to he and tails to t (that, as a variable, has a value of 0).

  • IFS=h;set $i;echo ${1:+-}1 works in two steps. Setting IFS to h breaks the unquoted $i in set $i into parts divided by the character h, heads is divided to '' and 'eads', thus setting $1 to null. tail is not divided by h, thus making $1 equal to tails. Then, ${1:+-} generates a - if the value of $1 is non-null (as in tails) or nothing (as with a null $1). That sign (or nothing) is concatenated with 1.

  • (IFS=h;set $i;echo $(($#*2-3))) works in a similar way but use the number of parts ($#) that the string in $i got broken into.

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

Python, 20 bytes

print(('h'in i)*2-1)

This returns False if it isn't, and True if it is. In python False and 0 are the same, and True and 1 are as well.

So:

True (1) * 2 -1 = 2-1 = 1
False (0) * 2 - 1 = 0-1 = -1
\$\endgroup\$
3
\$\begingroup\$

Python 2, 17 bytes

print'-1'['t'>i:]

'heads' is less than 't', so it evaluates to True == 1, and prints the string after the first character. 'tails' is greater than 't', so it evaluates to False == 0 and the whole string is printed.

If we're doing this from the command line, with implicit printing, it just becomes:

'-1'['t'>i:]

...for 12 bytes, but it adds single quotes to the output.

\$\endgroup\$
3
\$\begingroup\$

QBasic, 11 bytes

This has got to be the shortest piece of QBasic I've ever written.

c=i>"t
?c^c

Explanation:

The above is some pretty heavily golfed QBasic. Once the autoformatter gets through with it, it'll look like this:

c = i > "t"
PRINT c ^ c

The first line compares the string i with "t". If i is "heads", i > "t" is false and c = 0. If i is "tails", i > "t" is true and c = -1. Yes, -1 is the default value for boolean true in QBasic!

The second line maps -1 to -1 and 0 to 1 via a math trick: (-1)^(-1) == 1/(-1) == -1, and 0^0, though technically mathematically undefined, returns 1.

This code requires that i be explicitly declared as a string variable; otherwise, it would have to be i$. Full test program (tested on QB64):

DIM i AS STRING
DATA heads, tails

FOR x = 1 TO 2
READ i

c=i>"t
?c^c

NEXT x
\$\endgroup\$
3
\$\begingroup\$

Gaia, 5 4 bytes

'eI(

Similar to Dennis' CJam answer, finds the index of e in the input string

Saved one byte since I didn't realise input was automatically used as an argument if there isn't enough stack values

How it works

'e  Push e
I   Index of e in the the input. 2 if heads, 0 if tails
(   Subtract One
Stack gets automatically outputted

Try it Online!

\$\endgroup\$
3
\$\begingroup\$

Bash, 22

echo $[0x${1:1:1}/2-6]

Takes the 2nd letter (e or a) and interprets it as a hex digit (14 or 10), then divide by 2 and subtract 6 to get the right answers.

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Awesome trick, I'm gonna borrow it :) \$\endgroup\$
    – roblogic
    Aug 14, 2019 at 13:13
  • 1
    \$\begingroup\$ For bash, use: echo $[30#$i%7-1] only 17 bytes. :-) \$\endgroup\$
    – user92894
    Aug 18, 2019 at 20:02
3
\$\begingroup\$

ed, 27 25 21 bytes

ed gave me a headache. Finally figured it out with help from @ed1conf on twitter and some peeps on unix.se. You can't just match things with s/re/newtext/, you have to prefix it with g otherwise ed packs a sad. It's like a grumpy 50 year old unix program saying "get off my lawn".

g/t/s//-
,s/\w\+/1
w

Try it online!

-2 bytes by dropping the final /s
-4 bytes thanks to @manatwork (& whose sed answer i plagiarised)
Old version:
g/t/s//- g/\w\+/s//1 wq .

\$\endgroup\$
2
  • 1
    \$\begingroup\$ But you need the address trick only for the 1st command, as the 2nd will never fail. And no need to explicitly q, it will quit by itself when nothing left to do. And you only need a newline after them, the “.” (or “roblogic”…) is unnecessary. Try it online! \$\endgroup\$
    – manatwork
    Aug 15, 2019 at 9:15
  • \$\begingroup\$ Ahh thanks I will try your suggestions when I get home. At the pub now 👍🏼 \$\endgroup\$
    – roblogic
    Aug 15, 2019 at 9:25
2
\$\begingroup\$

golflua 25 20 18

w(I.r():f'h'&1|-1)

Probably could be golfed some more by using some tricks that I'm not thinking about at the moment. (see history for old version) Saved 5 chars by moving input to write and ignoring the if statement there. Two more chars were saved by ignoring the optional parenthesis on find. It does not check for failed conditions (i.e., input that isn't heads or tails).

A Lua equivalent would be

io.write(io.read():find('h') and 1 or -1)
\$\endgroup\$
2
\$\begingroup\$

Haskell, 18 bytes

f('h':_)=1
f _= -1

Every string starting with the letter h is mapped to 1, all others to -1.

\$\endgroup\$
2
\$\begingroup\$

Sed: 16 characters

s/t/-/
s/\w\+/1/

Sample run:

bash-4.3$ sed 's/t/-/;s/\w\+/1/' <<< 'heads'
1

bash-4.3$ sed 's/t/-/;s/\w\+/1/' <<< 'tails'
-1
\$\endgroup\$
2
  • \$\begingroup\$ Nice, I used your regex for my ed solution, but it still took 23 bytes, because ed is old and grumpy! \$\endgroup\$
    – roblogic
    Aug 14, 2019 at 18:19
  • \$\begingroup\$ \w and \+ are GNU extensions though. \$\endgroup\$
    – sch
    Aug 19, 2019 at 7:48
2
\$\begingroup\$

APL (Dyalog Unicode), 5 bytes

3-3⊃⍋

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Stax, 3 bytes

'eI

Run and debug it

\$\endgroup\$
2
\$\begingroup\$

Stax, 4 bytes

└0Y.

Run and debug it

It's the codepoint of the first character mod 7 minus 5.

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

PowerShell, 15 bytes

($args[1]-99)/2

Try it online!

Takes input via splatting. Uses the e vs the a to do ASCII math

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

dc, 8 bytes

?z2*1r-p

dc can't do anything meaningful with strings other than read them in and attempt to evaluate them. Doing this, "heads" outputs some warnings about unimplemented commands and empty stack, which we ignore, but importantly the stack remains empty. "tails" does almost the same with the important exception that the final "ls" loads a value from the s register to the stack.

We then use "z" to get the stack length and arithmetically fiddle to get the right answers.

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Triangular, 10 bytes

F.~%.7/-_<

Try it online!

Divides the ASCII value of a character input by 7. Subtracts the quotient from 15. Execution stops when the IP runs out of the program space. This works because Triangular can only manage integer division. Conveniently, "h" has a value of 104, which is 14 when integer divided by 7; "t" is 116, which is 16 when integer divided by 7.

Ungolfed/Explanation:

   F
  . ~
 % . 7
/ - _ <
---------------------------------------------------------------
F                 - Push 15 to Top of Stack
 ~                - Read a character from input, push its value to ToS
   7              - Push 7 to ToS
     <_           - Change directions, then pop ToS-1 and ToS, push their integer quotient
        -         - Pop ToS-1 and ToS, push their difference
          %       - Print ToS as an integer

Previous version (14 bytes):

~\81|m/,!<.>i%

Read a character from input; if that character's ASCII value divided by 8 has a remainder, print -1, otherwise print 1.

\$\endgroup\$
2
\$\begingroup\$

Keg, 8 12 8 bytes

_d=2*1-.

Try it online!

Explanation (syntactically invalid)

_        Take input and discard the last item
 d=      If the top of the stack is d:
   2*    Re-set the top of the stack as 2
     1-  Decrement the top of the stack by 1
       . Explicitly output the top of the stack

-4 bytes thanks to manatwork

\$\endgroup\$
5
  • \$\begingroup\$ May there be some TIO interpreter version difference? Looks like it doesn't handle neither “heads” or “tails”. \$\endgroup\$
    – manatwork
    Aug 16, 2019 at 9:58
  • \$\begingroup\$ Now I fixed the program. \$\endgroup\$
    – user85052
    Aug 16, 2019 at 23:54
  • \$\begingroup\$ May there be some TIO interpreter version difference? Seems it takes input implicitly and reverses it on any attempt to process inexistent data, making it work without ^. \$\endgroup\$
    – manatwork
    Aug 17, 2019 at 12:41
  • \$\begingroup\$ BTW, you not need to discard 4 characters until “t” as the 2nd one “d” or “l” already identifies which input you got. Just have to explicitly output so can leave the unprocessed input on the stack: Try it online!. \$\endgroup\$
    – manatwork
    Aug 17, 2019 at 12:47
  • \$\begingroup\$ I think I can still -1 bytes by switching to "Reg": TIO! \$\endgroup\$
    – user85052
    Aug 18, 2019 at 2:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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