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

1
\$\begingroup\$

SmileBASIC, 15 bytes

H=2?VAR(I[T])-1

Not the shortest possible solution, but I didn't want to post a boring program that's the same as all the others.

The VAR "function" converts a variable name into a variable. VAR("X") = 1 is equivalent to X = 1, for example.

The program sets H to 2, then uses VAR() on the first character in the input string.
(I[T] is the same as I[0], because T is 0. I had to include T here because VAR is not allowed to create new variables).

If the input is heads, VAR() returns the variable H, which has a value of 2.
If the input is tails, VAR() returns the variable T, which has a value of 0.

Then, it subtracts 1 from this and outputs either -1 or 1.

Because variable names in SmileBASIC are not case sensitive, this program works for any capitalization of the input string.

Note:
Normally, string variables must have names ending in $, but there are several ways to avoid this restriction. The simplest is to put the code inside a function, because function arguments are not type checked:

TEST "heads"
TEST "tails"

DEF TEST I
 H=2?VAR(I[T])-1
END
\$\endgroup\$
1
\$\begingroup\$

Homespring, 50 bytes

youth. fountain bear 1 pump heads    -1 pump tails

very simple, make the input salmon young, block him after he enters the right branch so he spawns early, then bear eats the downstream input salmon

\$\endgroup\$
  • 1
    \$\begingroup\$ What does make the input salmon young mean? \$\endgroup\$ – Embodiment of Ignorance Dec 31 '18 at 22:44
  • \$\begingroup\$ Could you add a tio link so others can easily verify the solution? \$\endgroup\$ – FrownyFrog Jan 1 '19 at 18:17
  • \$\begingroup\$ @EmbodimentofIgnorance, bears eat all mature salmon, so without making the input salmon young it would be eaten by the bear before it has a chance to spawn. This way it can slip past the bear, but matures again after spawning. \$\endgroup\$ – BadAtPerl Jan 2 '19 at 0:34
  • \$\begingroup\$ @FrownyFrog, tio doesn't appear to be entering the input properly. I tried a small sample program, bird, which should return the input, but didnt get any output. I doubt i'll use homespring again but maybe i'll throw up an online interpreter if i cant find one \$\endgroup\$ – BadAtPerl Jan 2 '19 at 0:39
1
\$\begingroup\$

APL (Dyalog Unicode), 5 bytes

3-3⊃⍋

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Perl 5 -p, 10 bytes

$_=o cmp$_

Try it online!

\$\endgroup\$
1
\$\begingroup\$

@, 16 bytes

I will expand it later.

?-ň*8+94{1}{-1}

Explanation

?               If statement
 -ň             Subtract input with
   *8+94        The ASCII code of h
        {1}     If true, return 1
           {-1} Otherwise, return -1
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 3 bytes

'ek

Try it online or verify both test cases.

Explanation:

'ek '# Get the 0-based index of "e" in the (implicit) input-string
     # (or -1 if no "e" is present)
     # (and output the result implicitly)
\$\endgroup\$
1
\$\begingroup\$

Commodore BASIC (PET, VIC-20, C64/128, C16/+4, TheC64Mini) 44 Tokenized and BASIC bytes

 0b$="heads":inputa$:?-1*(b$=a$)+1*(a$<>b$)

Commodore BASIC returns -1 as TRUE and 0 as FALSE, so a bit of simple maths is required to output the right required answer here.

Commodore VIC-20 Heads or Tails

\$\endgroup\$
1
\$\begingroup\$

Zsh, 25 19 bytes

-5 bytes using @Digital Trauma's bash solution; get the second letter, either e or a. Then 0xe and 0xa are interpreted as hex, i.e. decimal 14 and 10. Then we do a bit of arithmetic to output 1 or -1.

Try it Online!

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

24 bytes: <<<${1[1]:s/h//:s/t/-/}1

25 bytes: <<<${1[1]:s/h/1/:s/t/-1/}

\$\endgroup\$
  • 1
    \$\begingroup\$ I need to stop following you around... 13 bytes \$\endgroup\$ – GammaFunction Aug 18 '19 at 4:08
1
\$\begingroup\$

Gema, 7 characters

t=-
*=1

Generally the same thing as my Sed solution does, but there is a big difference: Sed executes all commands on the pattern space (so later commands act on previous command's result), while Gema handles each piece of input once and discards it.

So although in the 1st step Gema's t=- does the same as Sed's s/t/-/, in the 2nd step Gema's *=1 will act either on “ails” or “heads”, while Sed's s/\w\+/1/ has to handle either “-ails” or “heads”.

Sample run:

bash-5.0$ gema 't=-;*=1' <<< 'heads'
1

bash-5.0$ gema 't=-;*=1' <<< 'tails'
-1

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Zsh, 13 12 bytes

-1 from @Isaac

<<<$[#1%7-5]

Try it online! Try it online!

man zshmisc, under Arithmetic Evaluation:

An expression of the form ##x where x is any character sequence such as a, ^A, or \M-\C-x gives the value of this character and an expression of the form #name gives the value of the first character of the contents of the parameter name.

\$\endgroup\$
1
\$\begingroup\$

Java (JDK), 18 bytes

i->i=="heads"?1:-1

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Welcome! This is a well-golfed solution but when the input is heads it only works when i is interned because of the reference comparison (==). For this reason strings are usually compared in Java using String#equals. Your TIO works because your inputs are string literals, but this approach doesn't work in general. I don't think assuming strings are interned/literal is typical on here, so you should probably make sure your solution doesn't rely on that. \$\endgroup\$ – Jakob Aug 19 '19 at 18:58
  • \$\begingroup\$ @Jakob yeah, but it's 25 now... \$\endgroup\$ – CuttingChipset Aug 19 '19 at 19:40
  • \$\begingroup\$ True, but it works for any input, which is the most important thing. Now the question is can you find a shorter version? (I think you'll find there's a 17-byte solution). \$\endgroup\$ – Jakob Aug 20 '19 at 2:45
1
\$\begingroup\$

Brain-Flak, 52 34 bytes

({}[{}()()()])({<{{}}>[()()]}()<>)

Output is the top element of the stack

-18 bytes thanks to Jo King

Try it with heads!

Try it with tails!

\$\endgroup\$
  • \$\begingroup\$ 34 bytes. Try to combine consecutive pops and pushes, especially in that first section \$\endgroup\$ – Jo King Aug 19 '19 at 14:40
  • \$\begingroup\$ Oh wow, could you make an explanation, since I don't really understand the second part? \$\endgroup\$ – EdgyNerd Aug 19 '19 at 14:45
  • \$\begingroup\$ Explanation plus another byte saved in the loop \$\endgroup\$ – Jo King Aug 19 '19 at 15:01
1
\$\begingroup\$

C-INTERCAL, 177 bytes

This is my first, and hopefully last, INTERCAL program. INTERCAL is a truly remarkable language. Those who haven't heard of it should immediately investigate (here is the manual I used).

PLEASEDO,1<-#2PLEASEDOWRITEIN,1PLEASEDO.1<-',1SUB#1'~#4DO(2)NEXTDO,1SUB#1<-#76(1)DO,1SUB#2<-#40(2)DO(3)NEXTDO,1<-#1DO,1SUB#1<-#116DOCOMEFROM(1)DOREADOUT,1(3)DOFORGET.1DORESUME#1

The program reads from standard input and writes to standard output. After printing the appropriate string, the program crashes with one of two humorous error messages depending on the input.

Try It Online

Ungolfed

    PLEASE DO ,1 <- #2
    PLEASE DO WRITE IN ,1
    PLEASE DO .1 <- ',1 SUB #1' ~ #4
    DO (2) NEXT
    DO ,1 SUB #1 <- #76
(1) DO ,1 SUB #2 <- #40
(2) DO (3) NEXT
    DO ,1 <- #1
    DO ,1 SUB #1 <- #116
    DO COME FROM (1)
    DO READ OUT ,1
(3) DO FORGET .1
    DO RESUME #1

Well, that didn't help much...

In the first three lines, we read 2 (#2 in INTERCAL) characters from the input into array ,1 and store in variable .1 whether the first character read has bit 2 set (mask of 4); in ASCII h is 0b1101000 and t is 0b1110100, so this variable now indicates whether the input is tails. This uses the "select" operator ~, which in this case performs both masking and shifting to select bit 2 as 0 or 1.

The rest of the program is an if/else conditional and a print statement. Unfortunately, control flow is very limited in INTERCAL. The only mechanism is a call stack that's pushed to when the program executes DO (x) NEXT. DO RESUME #1 then operates like a return statement (but with no return value), popping the stack and jumping to the next statement after the most recent DO (x) NEXT. But the value passed to DO RESUME can be any number. DO RESUME #3 pops the call stack three times and jumps to the third-from-last DO NEXT.

A similar construct is DO FORGET, which only pops the stack the specified number of times but does not jump. DO RESUME always jumps, so passing it 0 is a run-time error. But the instruction DO FORGET #0 is valid, and doesn't do anything.

And so with the statements DO (2) NEXT and DO (3) NEXT I push two locations onto the call stack. At (3) I then discard .1 frames, which has the effect of "forgetting" the call at (2) if and only if the input was tails. As a result, we end up just after either DO (2) NEXT or DO (3) NEXT after the return on the last line, depending on the input.

Each branch then loads the appropriate character data into ,1 (see here for why the values don't make any sense), and COME FROM (1), an inverted goto, joins the two branches at the output statement DO READ OUT. Control then continues, but luckily in either case the program crashes before printing anything else.

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

Befunge, 28 bytes

28 bytes including whitespace and newlines:

<v"heads"
 >94+%v
,,"-1"_1.@

Assumes that either heads or tails is put into the string above (this is the equivalent of assuming the input is stored in i). Works by performing modulo 13 on the top character on the stack - h divides exactly, t does not.

I also made a 22 character version (excluding whitespace/newlines) but the input has to be backwards:

"sdaeh"v
       9
       4
       +
       %
@,,"-1"_1.
\$\endgroup\$
  • \$\begingroup\$ You can make this code shorted by using d instead of 94+ to get the number 13. \$\endgroup\$ – pppery Nov 28 '15 at 18:19
0
\$\begingroup\$

Unefunge 98, 15 or 16 bytes

'h-4j@.-1_1.@

The above code assumes input is stored on top os the stack in reverse order. There are two 16-byte solutions that don't make this assumption:

$'d-4j@.-1_1.@

Assuming input is on top of the stack in normal order.

~'h-4j@.-1_1.@

Reading input from stdin

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

Whitespace, 40 bytes

[S S S N
_Push_0][S N
S _Duplicate_0][T   N
T   S _Read_input_as_character][T   T   T   _Retrieve][S S S T  T   T   N
_Push_7][T  S T T   _Modulo][S S S T    S T N
_Push_5][T  S S T   _Subtract][T    N
S T _Print_as_integer]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Since Whitespace inputs one character at a time, I use that to my advantage here by only looking at the first character and porting @recursive's Stax answer (so make sure to upvote him as well!)

Try it online (with raw spaces, tabs and new-lines only).

Explanation in pseudo-code:

Integer c = STDIN as character code-point
c = c % 7
c = c - 5
Print c to STDOUT as integer
\$\endgroup\$
0
\$\begingroup\$

33, 12 bytes

P110mz6dzcmo

Try it online!

Requires heads or tails non-capitalised.

This only accepts the first character of the input. If it needs to accept all input, replace the P with Ij.

Explanation

P            | Get the first character of input as its ASCII value
             |              ( h | t )
 110mz       | Subtract 110 (-6 | 6 )
      6dz    | Divide by 6  (-1 | 1 )
         cm  | Flip sign    ( 1 |-1 )
           o | Print it
\$\endgroup\$
0
\$\begingroup\$

jq, 14 characters

index("e")//-1

That's searching character position in the string. Unfortunately on not found it returns null, so the // (alternative operator) has to be used. (Still shorter than an .[:1]<"i" check as that results boolean and there is no way to cast that to integer.)

Sample run:

bash-5.0$ jq -R 'index("e")//-1' <<< 'heads'
1

bash-5.0$ jq -R 'index("e")//-1' <<< 'tails'
-1

Try it online!

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

><>, 9 bytes

ab*i-6,n;

Try it online!

I'm honestly surprised that there wasn't a fish answer yet.

Subtracts the ASCII value of the first character input from 110 and divides by 6.

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

brainfuck, 42 bytes

,>,+++[-<->]<[-[->+++<]>.>]-[>+<-----]>--.

Try it online!

Checks if it is heads or tails by checking if the ordinal values of first two characters are only three away from each other.

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

MathGolf, 3 bytes

'e=

Try it online!

Basically identical to a lot of other solutions. Checks the index of 'e', and returns -1 if not found.

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

JavaScript (V8) - 19 Bytes

Since OPs solution returns 'true' and '-1' (see here), the following function:

f=i=>i[0]=='h'?1:-1

returns '1' and '-1' - see here. Just to be a smart-ass and so.

// Adaption of Java (SDK) version as a JS function.

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

Runic Enchantments, 10 bytes

1i3%1C=?Z@

Try it online! (heads)
Try it online! (tails)

Works by determining if the 4th character is a d (compare to number literal 100) and if not, multiplies a 1 by -1, then prints and terminates.

1              Push 1 (the output)
  i            Read input string
   3%          Get 4th character (0-indexed)
     1C=?      Compare with 100 (decimal value of d)
         Z     If false, multiply TOS with -1
          @    Output entire stack (the only thing left with be a 1 or -1) and terminate
\$\endgroup\$
0
\$\begingroup\$

R, 58 55 bytes

for(i in scan(,''))print(`if`(utf8ToInt(i)[1]%%8,-1,1))

Try it online!

Really poor attempt, but I the utf8ToInt values for "h","H","t","T" are 104, 72, 116, 84 respectively. As a result, "h" and "H" values are both evenly divisible by 8, while "t" and "T" are not. So a conversion and check for even divisibility yields the desired results.

This method compared to the following method takes different spellings of heads/Heads/HEADS/etc. and tails/Tails/TAILS/etc. As long as it starts with an h/H or t/T it will work properly.

EDIT: -3 bytes switching to a for loop. Prints each value on newline instead of a single array of 1's and -1's.

R, 49 bytes

for(i in scan(,''))print(ifelse(i=="heads",1,-1))

This method was suggested by @user5957401 and is much simpler. The difference here is that this method assumes that the user will input strictly "heads" or "tails" (technically anything but "heads").

Try it online!

\$\endgroup\$
  • \$\begingroup\$ ifelse(i=="heads",1,-1) seems like a quicker way to vectorize \$\endgroup\$ – user5957401 Aug 19 '19 at 20:11
  • \$\begingroup\$ That's pretty simple actually, I don't know why I didn't think of that. I'll add yours in. \$\endgroup\$ – Sumner18 Aug 19 '19 at 20:13

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.