26
\$\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\$
  • 14
    \$\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 '15 at 4:06
  • 1
    \$\begingroup\$ 6 answers, not so a bad challenge indeed. Try again \$\endgroup\$ – edc65 May 16 '15 at 13:33
  • 4
    \$\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 '15 at 16:31
  • 7
    \$\begingroup\$ I'm so confused right now, yesterday -4, now +4, this sure ain't stackoverflow :P \$\endgroup\$ – Juan Cortés May 17 '15 at 7:26
  • 10
    \$\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\$ – Sean Latham May 18 '15 at 11:52

54 Answers 54

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

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Probably unbeatable for this challenge. \$\endgroup\$ – Alex A. May 16 '15 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\$ – Juan Cortés May 16 '15 at 9:36
  • \$\begingroup\$ Why do you not include the p in this? Is it standard in CJam not to? \$\endgroup\$ – Tim May 16 '15 at 10:56
  • \$\begingroup\$ @Tim CJam always prints the stack contents at the of the program automatically. \$\endgroup\$ – Martin Ender May 16 '15 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 '15 at 16:21
17
\$\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
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Beautiful, love it \$\endgroup\$ – Juan Cortés May 16 '15 at 15:07
11
\$\begingroup\$

Ruby, 8 (6 without output)

p ?t<=>i

Rocketship operator!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Clearly the right tool for the job. \$\endgroup\$ – primo May 18 '15 at 4:25
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;

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ With the short version I'm always getting a 1, care to explain what it does with the XOR? \$\endgroup\$ – Juan Cortés May 17 '15 at 7:23
  • \$\begingroup\$ @JuanCortés I've added an explanation, and a link to Ideone. \$\endgroup\$ – primo May 18 '15 at 3:24
  • 2
    \$\begingroup\$ Now that's thinking outside the box! \$\endgroup\$ – Dennis May 18 '15 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".

| improve this answer | |
\$\endgroup\$
  • \$\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\$ – M. I. Wright May 20 '15 at 16:08
  • 1
    \$\begingroup\$ The t and inString( are each two bytes. \$\endgroup\$ – lirtosiast May 20 '15 at 16:48
  • \$\begingroup\$ Oh, I'd forgotten about lowercase letters being two bytes. Never mind, then. \$\endgroup\$ – M. I. Wright May 21 '15 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.

| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

Python 2, 16 bytes

print(i<'t')*2-1
| improve this answer | |
\$\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.

| improve this answer | |
\$\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
| improve this answer | |
\$\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.

| improve this answer | |
\$\endgroup\$
  • \$\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 '15 at 11:40
  • \$\begingroup\$ @Agawa001 , But that returns 6 for h and 7 for t. \$\endgroup\$ – Spikatrix May 16 '15 at 11:42
  • \$\begingroup\$ oh i forgot , i must use power :p \$\endgroup\$ – Abr001am May 16 '15 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 '15 at 11:56
  • 1
    \$\begingroup\$ @CoolGuy would using puts puts(*i>'h'?"-1":"1"); not be better? (22 bytes) \$\endgroup\$ – euanjt May 20 '15 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.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Care to explain it? \$\endgroup\$ – Juan Cortés May 20 '15 at 13:46
  • \$\begingroup\$ That assumes BSD/GNU tr. POSIXly: tr -s ta-s '-[1*]' \$\endgroup\$ – sch Aug 19 '19 at 7:47
4
\$\begingroup\$

8088 assembly, IBM PC DOS, 17 bytes

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 from command line, output to console.

Input/Output:

enter image description here

| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

Japt, 2 bytes

ae

Try it online

| improve this answer | |
\$\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.

| improve this answer | |
\$\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.

| improve this answer | |
\$\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
| improve this answer | |
\$\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!

| improve this answer | |
\$\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!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Awesome trick, I'm gonna borrow it :) \$\endgroup\$ – roblogic Aug 14 '19 at 13:13
  • 1
    \$\begingroup\$ For bash, use: echo $[30#$i%7-1] only 17 bytes. :-) \$\endgroup\$ – Isaac Aug 18 '19 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 .

| improve this answer | |
\$\endgroup\$
  • 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 '19 at 9:15
  • \$\begingroup\$ Ahh thanks I will try your suggestions when I get home. At the pub now 👍🏼 \$\endgroup\$ – roblogic Aug 15 '19 at 9:25
2
\$\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
| improve this answer | |
\$\endgroup\$
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)
| improve this answer | |
\$\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.

| improve this answer | |
\$\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
| improve this answer | |
\$\endgroup\$
  • \$\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 '19 at 18:19
  • \$\begingroup\$ \w and \+ are GNU extensions though. \$\endgroup\$ – sch Aug 19 '19 at 7:48
2
\$\begingroup\$

Stax, 3 bytes

'eI

Run and debug it

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Stax, 4 bytes

└0Y.

Run and debug it

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

| improve this answer | |
\$\endgroup\$
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

| improve this answer | |
\$\endgroup\$
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!

| improve this answer | |
\$\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.

| improve this answer | |
\$\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

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ May there be some TIO interpreter version difference? Looks like it doesn't handle neither “heads” or “tails”. \$\endgroup\$ – manatwork Aug 16 '19 at 9:58
  • \$\begingroup\$ Now I fixed the program. \$\endgroup\$ – user85052 Aug 16 '19 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 '19 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 '19 at 12:47
  • \$\begingroup\$ I think I can still -1 bytes by switching to "Reg": TIO! \$\endgroup\$ – user85052 Aug 18 '19 at 2:41
1
\$\begingroup\$

Vitsy, 13 bytes

So what, I'm late for the party. ¯\_(ツ)_/¯

zv&v'h'=)i1rN
z             Grab all input.
 v            Capture the top item (h or t) as a temp variable.
  &           Generate new stack, move to it.
   v'h'=      Test if the variable is h.
        )i    If it isn't, push -1.
          1   Push 1.
           r  Reverse the stack.
            N Print out the top item as a number.
| improve this answer | |
\$\endgroup\$

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.