75
\$\begingroup\$

Write a program or function that takes in a string only containing the characters ^ and v (you can assume there will be no other characters). Read from left to right this string represents the sequence of mouse clicks a single user made while viewing a Stack Exchange question or answer for the first time.

Every ^ represents a click of the upvote button and every v represents a click of the downvote button. (For working examples look slightly left.)

Assume that no voting limitations are in effect so all the clicks are registered correctly.
Print or return:

  • 1 or +1 if the post ends up being upvoted.
  • 0 if the post ends up not being voted on. (-0 and +0 are not valid)
  • -1 if the post ends up being downvoted.

Posts start with zero net votes from the user and the buttons change the net votes as follows:

Net Votes Before    Button Pressed    Net Votes After
1                   ^                 0
1                   v                 -1
0                   ^                 1
0                   v                 -1
-1                  ^                 1
-1                  v                 0

The shortest code in bytes wins.

Test cases:

[empty string] -> 0
^^ -> 0
^v -> -1
^ -> 1
v -> -1
v^ -> 1
vv -> 0
^^^ -> 1
vvv -> -1
^^^^ -> 0
vvvv -> 0
^^^^^ -> 1
vvvvv -> -1
^^^^^^ -> 0
vvvvvv -> 0
^^v -> -1
^v^ -> 1
^vv -> 0
vv^ -> 1
v^v -> -1
v^^ -> 0
^vvv^^vv^vv^v^ -> 1
^vvv^^vv^vv^v^^ -> 0
^vvv^^vv^vv^v^^^ -> 1
^vvv^^vv^vv^v^^v -> -1
^vvv^^vv^vv^v^^vv -> 0
^vvv^^vv^vv^v^^vvv -> -1
^vvvvvvvvvvvv -> 0
^^vvvvvvvvvvvv -> 0
^^^vvvvvvvvvvvv -> 0
vvv^^^^^^^^^^^^ -> 0
vv^^^^^^^^^^^^ -> 0
v^^^^^^^^^^^^ -> 0
\$\endgroup\$
6
  • 15
    \$\begingroup\$ What? no side voting? Geoborts and Seadrus are sad \$\endgroup\$
    – Optimizer
    Nov 9, 2015 at 7:48
  • 30
    \$\begingroup\$ Dear Secret SE Developer: Congratulations on successfully duping your own community into making site improvements for you... ;) \$\endgroup\$
    – thanby
    Nov 10, 2015 at 9:58
  • 1
    \$\begingroup\$ I've been starring at the example table for a while now and I still don't get the test cases. a post with a score of 1 gets up-voted and it then has a score of 0. And a post with a score of 0 gets up-voted to have a score of 1. And post with a score of -1 gets up-voted to have a score of 1. So the ^ character can cause a -1, +1 or +2 score change? Am I dense where? What's going on? \$\endgroup\$
    – Brad
    Nov 11, 2015 at 18:18
  • 4
    \$\begingroup\$ @Brad I suggest you try the actions with some actual post (e.g. this question itself). Upvoting a post you already upvoted undoes the upvote. Same with downvoting. \$\endgroup\$ Nov 11, 2015 at 18:23
  • 8
    \$\begingroup\$ I wonder what the real-time votes on this question was. I'm willing to bet a lot of people used this question as a test case. \$\endgroup\$ Nov 11, 2015 at 18:46

39 Answers 39

35
\$\begingroup\$

Gol><> 0.3.11, 13 12 11 bytes

iEh`^=:@)+M

Try it online. Even though this will work fine in the next update, I've listed it as 0.3.11 just in case.

Explanation

i               Read char
 Eh             If EOF, halt and output top of stack as num
   `^=          Push 1 if char is ^, else 0
      :@        Dup and rotate, giving [is^ is^ votecount]
        )       Compare greater than, pushing 1 or 0 as appropriate
         +M     Add and subtract 1

Note that the first use of @ pulls a 0 from the bottom of the stack to initialise the vote count for the first iteration

To illustrate with a full table:

Votes before    Button    Is ^?    Compare <    Add     Subtract 1
     1            ^         1         0          1          0
     1            v         0         0          0         -1
     0            ^         1         1          2          1
     0            v         0         0          0         -1
    -1            ^         1         1          2          1
    -1            v         0         1          1          0
\$\endgroup\$
1
  • 1
    \$\begingroup\$ ....dang! Nice one! \$\endgroup\$ Nov 9, 2015 at 3:53
21
\$\begingroup\$

JavaScript (ES7), 47 46 44 43 37 36 bytes

Crossed out 44 is still regular 44 :(

s=>[for(x of s)s=x<"v"?s!=1:!~s-1]|s

Keeps a running total in s. Uses for of loop to iterate over each character in the string and updates s based on current character and previous value.

Edits: Golfed ~s&&-1 to !~s-1. This expression has to equal 0 if s equals -1 and -1 otherwise. Saved 6 bytes thanks to @nderscore.

How the expression works:

 ~s    // Bitwise inverse. ~s==0 only if s==-1
!      // Logical negate. Casts to boolean. Equivalent to s==-1
   -1  // Subtract. Casts to number so true-1 is 1-1 and false-1 is 0-1
\$\endgroup\$
4
  • 3
    \$\begingroup\$ I got it down to 37 bytes: v=>[for(x of v)v=x<"v"?~~v<1:!~v-1]|v \$\endgroup\$
    – nderscore
    Nov 9, 2015 at 22:01
  • \$\begingroup\$ @nderscore Hey, that's great. I thought the extra variable was clumsy, but didn't think I could eliminate it. \$\endgroup\$ Nov 9, 2015 at 22:21
  • 1
    \$\begingroup\$ Crossed out 44 is still regular 44... \$\endgroup\$
    – Riker
    Jan 8, 2016 at 23:27
  • \$\begingroup\$ Weren't array comprehensions removed from the spec? \$\endgroup\$
    – bren
    Apr 13, 2016 at 20:51
20
\$\begingroup\$

x86 machine code, 24 bytes

31 C0 8A 11 84 D2 75 07 C0 E0 02 C0 F8 06 C3 41 38 C2 74 EC 88 D0 EB EA

This is a function using the fastcall calling convention, which takes a string and returns an 8-bit integer.

I tested it with the following C program, which must be compiled for 32-bit mode.

#include <stdio.h>
#include <inttypes.h>

 __attribute__ ((aligned (16))) const unsigned char fun[] = {

    0x31,  //xor eax,eax
        0xC0,
    0x8A, //mov [ecx],dl
        1 | 2<<3,
    0x84, //test dl, dl
        0xC0 | 2<<3 | 2,
    0x75, // jnz
        7,
    0xC0, //shl al 2
        0xC0 | 4<<3,
        2,
    0xC0, //sar al 6
        0xC0 | 7<<3,
        6,
    0xC3, //ret
    0x41, //inc ecx
    0x38, //cmp al,dl
        0xC0 | 2,
    0x74, //je
        -20,
    0x88, //mov dl,al
        0xC0 | 2<<3,
    0xEB, //jmp
        -22,
};

int main()
{
    __fastcall int8_t (*votesimulator)(char*) = fun;
    char* s[] = {
        "",
        "^^",
        "^v",
        "^",
        "v",
        "v^",
        "vv",
        "^^^",
        "vvv",
        "^^^^",
        "vvvv",
        "^^^^^",
        "vvvvv",
        "^^^^^^",
        "vvvvvv",
        "^^v",
        "^v^",
        "^vv",
        "vv^",
        "v^v",
        "v^^",
        "^vvv^^vv^vv^v^",
        "^vvv^^vv^vv^v^^",
        "^vvv^^vv^vv^v^^^",
        "^vvv^^vv^vv^v^^v",
        "^vvv^^vv^vv^v^^vv",
        "^vvv^^vv^vv^v^^vvv",
        "^vvvvvvvvvvvv",
        "^^vvvvvvvvvvvv",
        "^^^vvvvvvvvvvvv",
        "vvv^^^^^^^^^^^^",
        "vv^^^^^^^^^^^^",
        "v^^^^^^^^^^^^",
    };

    for(int i = 0; i < sizeof(s)/sizeof(*s); i++)
        printf("%d\n", votesimulator(s[i]));

    printf("\n%d\n", sizeof(fun));
    for(int i = 0; i < sizeof(fun); i++)
        printf("%02X ", fun[i]);
    return 0;
}
\$\endgroup\$
2
  • \$\begingroup\$ Is this allowed? I mean I could also write the whole thing in C and just say the C code requires an empty file for performing the task while saying my code is the framework making my code becoming 0bytes. Why is that diferent from your solution? \$\endgroup\$
    – Zaibis
    Jul 12, 2016 at 9:29
  • \$\begingroup\$ @Zaibis Because my solution contains the code that solves the challenge? See meta.codegolf.stackexchange.com/a/1071/30688. \$\endgroup\$
    – feersum
    Jul 12, 2016 at 9:37
8
\$\begingroup\$

CJam, 18 14 bytes

Updated version with significant improvements contributed by Dennis:

0'jqf{-g_@=!*}

Try it online

Explanation:

0     Start value for running total.
'j    Push character between '^ and 'v for use in loop.
q     Get input.
f{    Apply block with argument to all input characters.
  -     Subtract character from 'j. This will give -12 for '^, 12 for 'v.
  g     Signum, to get 1 for '^, -1 for 'v, which is our increment value.
  _     Copy increment value.
  @     Bring running total to top.
  =     Compare. This will give 1 for the -1/-1 and 1/1 combinations where the new
        running total is 0. Otherwise, the new running total is the increment value.
  !     Negate to get 0 for the -1/-1 and 1/1 cases.
  *     Multiply result with increment value, to get new running total.
}     End block applied to input characters.
\$\endgroup\$
0
7
\$\begingroup\$

Befunge 93 - 55 bytes

vj#p01:>#<:1+|
>~:10g-|v:g25<
^p01"j"<1^   <
./*34-g0<@

52 characters and 3 new lines.

Tested on this interpreter.

The j is equidistant from ^ and v in ascii so it's used to make arithmetic conversions in the end, rather than space consuming conditionals.

\$\endgroup\$
7
\$\begingroup\$

brainfuck, 146 bytes

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

This program takes each byte of input and compares it against the last. If they're the same, it throws the input away and stores "0" as the "previous input", otherwise it saves it normally.

If the final result is v, it prints -. If the final result was non-zero, 1 is added to an empty cell. Finally, 48 is added to that cell and it is printed.

\$\endgroup\$
7
\$\begingroup\$

Javascript ES6, 91 48 chars

s=>~~{'^':1,v:-1}[s.replace(/(.)\1/g).slice(-1)]

Explanation: undefined ends by d.

Test:

` -> 0
^^ -> 0
^v -> -1
^ -> 1
v -> -1
v^ -> 1
vv -> 0
^^^ -> 1
vvv -> -1
^^^^ -> 0
vvvv -> 0
^^^^^ -> 1
vvvvv -> -1
^^^^^^ -> 0
vvvvvv -> 0
^^v -> -1
^v^ -> 1
^vv -> 0
vv^ -> 1
v^v -> -1
v^^ -> 0
^vvv^^vv^vv^v^ -> 1
^vvv^^vv^vv^v^^ -> 0
^vvv^^vv^vv^v^^^ -> 1
^vvv^^vv^vv^v^^v -> -1
^vvv^^vv^vv^v^^vv -> 0
^vvv^^vv^vv^v^^vvv -> -1
^vvvvvvvvvvvv -> 0
^^vvvvvvvvvvvv -> 0
^^^vvvvvvvvvvvv -> 0
vvv^^^^^^^^^^^^ -> 0
vv^^^^^^^^^^^^ -> 0
v^^^^^^^^^^^^ -> 0`
.split("\n").map(s => s.split(" -> "))
.every(([s,key]) => (s=>~~{'^':1,v:-1}[s.replace(/(.)\1/g).slice(-1)])(s)==key)

Answer history:

s=>({'':0,'^':1,v:-1}[s.replace(/^(.)\1(\1\1)*(?=.?$)|.*(.)(((?!\3).)\5)+/,"").substr(-1)])
s=>~~{'^':1,v:-1}[s.replace(/^(.)\1(\1\1)*(?=.?$)|.*(.)(((?!\3).)\5)+/,"").substr(-1)]
s=>~~{'^':1,v:-1}[s.replace(/^.*(.)(((?!\1).)\3)+|(.)\4(\4\4)*/,"").substr(-1)]
s=>~~{'^':1,v:-1}[s.replace(/^.*(.)(((?!\1).)\3)+|(.)\4(\4\4)*/,"").slice(-1)]
s=>~~{'^':1,v:-1}[s.replace(/.*(.)(((?!\1).)\3)+|(.)\4(\4\4)*/,"").slice(-1)]
s=>~~{'^':1,v:-1}[s.replace(/.*(.)(((?!\1).)\3)+|((.)\5)*/,"").slice(-1)]
s=>~~{'^':1,v:-1}[s.replace(/((.)\2)+/g,"!").slice(-1)]
s=>~~{'^':1,v:-1}[s.replace(/(.)\1/g,"!").slice(-1)]
s=>~~{'^':1,v:-1}[s.replace(/(.)\1/g,0).slice(-1)]
s=>~~{'^':1,v:-1}[s.replace(/(.)\1/g).slice(-1)]
\$\endgroup\$
7
\$\begingroup\$

Python 2, 49

lambda s:reduce(lambda x,c:cmp(cmp('u',c),x),s,0)

Iterates through with the update function

lambda x,c:cmp(cmp('u',c),x)

that takes the current vote count x and the new character c and outputs the new vote count.

The idea is to use Python 2's cmp function, which compares its two args and gives -1, 0, 1 for <, ==, > respectively. The inner one cmp('u',c) gives -1 for v and 1 for ^; any character between them suffices for 'u'. The outer one then compares that to x, which gives cmp(1,x) for ^ and cmp(-1,x) for v, which have the right values.

Direct iteration was 3 chars longer (52), though would be one char short (48) if taking an input() with quotes was allowed.

x=0
for c in raw_input():x=cmp(cmp('u',c),x)
print x

The best recursive function I found was one char longer (50)

f=lambda s:len(s)and cmp(cmp('u',s[-1]),f(s[:-1]))
\$\endgroup\$
5
\$\begingroup\$

Prolog, 159 152 bytes

Code:

v(1,^,0).
v(1,v,-1).
v(0,^,1).
v(0,v,-1).
v(-1,^,1).
v(-1,v,0).
r(X,[H|T]):-T=[],v(X,H,Z),write(Z);v(X,H,Z),r(Z,T).
p(S):-atom_chars(S,L),r(0,L).

Test it yourself:
Online Interpreter here

Example

>p("^vvv^^vv^vv^v^^vvv").
-1

>p("^vvv^^vv^vv^v^")
1

Edit: Saved 7 bytes by unifying r-clauses with OR.

\$\endgroup\$
2
  • \$\begingroup\$ Hmm. It seems like you could save quite a few bytes by redefining operators instead of defining functions (if that counts as a function under PPCG's rules?) \$\endgroup\$
    – ASCII-only
    May 29, 2018 at 12:20
  • \$\begingroup\$ @ASCII-only: Yeah. Hadn't learned that trick when I wrote this :) \$\endgroup\$
    – Emigna
    May 29, 2018 at 12:36
4
\$\begingroup\$

CJam, 16 bytes

0re`W=(2%*c'a--g

This will crash after printing 0, if applicable. The error can be suppressed with the Java interpreter. If you try this online, ignore everything but the last line of output.

How it works

0                e# Push a 0 on the stack.
 r               e# Read a whitespace-separated token from STDIN.
  e`             e# Perform run-length encoding.
    W=           e# Select the last [repetitions character] pair.
                 e# This will fail for the empty string, so the
                 e# interpreter will print the stack's only element (0).
      (          e# Shift out the number of repetitions.
       2%        e# Compute its parity.
         *       e# Create a string, repeating the character 1 or 0 times.
          c      e# Cast to character.
                 e# This will fail for a zero-length string, so the
                 e# interpreter will print the stack's only element (0).
           'a-   e# Subtract the character 'a' from '^' or 'v'.
              -  e# Subtract the difference (integer) from 0.
               g e# Apply the sign function.
\$\endgroup\$
4
\$\begingroup\$

Python 2, 177 159 72 bytes

Still kinda new to this code golf thing.

def v(s): 
 c=0 
 for i in s:c=((0,1)[c<1],(0,-1)[c>-1])[i=="^"] 
 return c

EDIT: Fixed the incorrect behavior.
EDIT 2: Thanks @MorganThrapp for shaving off lots of bytes.

\$\endgroup\$
5
  • \$\begingroup\$ You can shorten it to def v(s): c=0 for i in s:c=((0,1)[c<1],(0,-1)[c>-1])[i=="^"] return c. That's 72. \$\endgroup\$ Nov 10, 2015 at 14:33
  • \$\begingroup\$ @MorganThrapp Thanks, I didn't know about the (,)[] thing. \$\endgroup\$ Nov 10, 2015 at 14:45
  • \$\begingroup\$ Yeah, it's super helpful. If you haven't yet, read the tips for golfing in Python thread. \$\endgroup\$ Nov 10, 2015 at 14:46
  • 1
    \$\begingroup\$ That indentation isn't quite right, I just suggested an edit with the right indentation. You can't format code in comments, so it was wrong in mine. \$\endgroup\$ Nov 10, 2015 at 14:49
  • \$\begingroup\$ I believe this should be either i!="^" or i=="v". You can also use the fact that True/False corresponds to 1/0 for 60 bytes \$\endgroup\$
    – Jo King
    Jan 28, 2021 at 3:12
4
\$\begingroup\$

JavaScript (ES6), 64 59 58 52 bytes

f=v=>(t=/\^*$|v*$/.exec(v)[0]).length*(t<'v'?1:-1)%2

This is based on the observation that only the last stretch of the repetition (of either ^ or v) affects the result.

Thanks to Neil for golfing off 6 bytes.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Why do you need the captures? Seems to me f=v=>(t=/\^*$|v*$/.exec(v)[0]).length*(t<'v'?1:-1)%2 suffices. \$\endgroup\$
    – Neil
    Nov 10, 2015 at 12:57
  • \$\begingroup\$ @Neil: I'm not aware of array being coerced to the first element in > or < operator. Thanks for the tips \$\endgroup\$ Nov 11, 2015 at 2:45
  • \$\begingroup\$ No type coercion involved, I merely moved the [0] which may have confused you. \$\endgroup\$
    – Neil
    Nov 11, 2015 at 8:34
  • \$\begingroup\$ @Neil: Oh, I indeed am confused. I didn't realized that you have moved it inside, I thought it was f=v=>(t=/\^*$|v*$/.exec(v))[0].length*(t<'v'?1:-1)%2, which works due to type coercion with array. \$\endgroup\$ Nov 11, 2015 at 8:51
4
\$\begingroup\$

Haskell, 40 bytes

1%'^'=0
_%'^'=1
1%_=-1
_%_=0
v=foldl(%)0
\$\endgroup\$
5
  • \$\begingroup\$ You can cut all the spaces by defining f as an infix function %. Also, I think the v can be a _. \$\endgroup\$
    – xnor
    Nov 10, 2015 at 10:22
  • \$\begingroup\$ Actually, doesn't this give -1 for vv instead of 0? \$\endgroup\$
    – xnor
    Nov 10, 2015 at 10:28
  • \$\begingroup\$ Oh, I always forget about infixes. Thanks for the spot, missed the inner inversion. \$\endgroup\$ Nov 10, 2015 at 15:31
  • \$\begingroup\$ Save 3 characters by replacing the third line (15 characters) with 1%_=-1 _%_=0, 12 characters. \$\endgroup\$
    – Kevin Reid
    Nov 10, 2015 at 22:28
  • \$\begingroup\$ Okay right, now that's become shorter. \$\endgroup\$ Nov 11, 2015 at 10:38
4
\$\begingroup\$

Scala, 75 bytes

def d(s:String)=s./:(0){case(1,94)|(-1,'v')=>0;case(_,94)=> 1;case _=> -1}

Test for implemented function.

  object Util {
        def d(s: String) = s./:(0) { 
    case (1, '^') | (-1, 'v') => 0
    case (_, '^') => 1
    case (_, _) => -1
  }      
      def main(s: Array[String]): Unit = {
        println("1 == " + d("^vvv^^vv^vv^v^^^"))
        println("1 == " + d("^vvv^^vv^vv^v^"))
        println("-1 == " + d("^vvv^^vv^vv^v^^vvv"))
        println("0 == " + d("^^^vvvvvvvvvvvv"))
        println("0 == " + d("vvv^^^^^^^^^^^^"))
      }
    }
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Welcome to PPCG! Could you please add an explanation and/or an ungolfed version? \$\endgroup\$ Nov 12, 2015 at 11:57
3
\$\begingroup\$

APL, 17

(⊣×≠)/⌽0,2-'^ '⍳⍞

For interpreters without fork notation (like GNU APL), it would be {⍺×⍺≠⍵}/⌽0,2-'^ '⍳⍞ (19). This is probably the most boring of possible solutions because it works directly from the definition of the problem.

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

Ruby, 41 35 bytes

Regex. Only the last button pressed is interesting, so check the run-length of that. Then compare it to "a" (or any letter between ^ and v) to get 1 or -1.

->s{s[/(.?)\1*$/].size%2*(?a<=>$1)}
\$\endgroup\$
0
3
\$\begingroup\$

C# 6, 18 + 80 = 98 bytes

Requires:

using System.Linq;

Actual function:

int S(string v)=>v.Split(new[]{"^^","vv"},0).Last().Length<1?0:v.Last()<95?1:-1;

How it works: the code first removes everything before the last ^^ or vv. That content is not relevant because clicking the same button twice will always cancel your vote. It does this by splitting on ^^ and vv and taking the last item. If this item is an empty string (.Length<1), then the function returns 0 because all voting has been cancelled. If the string it not empty, then it just looks at the last char of the original string: it will override all previous votes. If the char code is smaller than 95, then it will be 94, ^, so it returns 1, otherwise -1.

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

Python 2.7, 79 75 88

s=input()
print (0,(1,-1)[s[-1]=='v'])[len(s[s.rfind(('v^','^v')[s[-1]=='v'])+1:])%2!=0]
\$\endgroup\$
10
  • \$\begingroup\$ This doesn't actually print anything. \$\endgroup\$ Nov 9, 2015 at 21:14
  • \$\begingroup\$ Running it in my interpreter, it shows the output of the last line \$\endgroup\$
    – wnnmaw
    Nov 9, 2015 at 21:18
  • \$\begingroup\$ That's because you're running it in the REPL. You need to provide a full program that will work outside the REPL. \$\endgroup\$ Nov 9, 2015 at 21:18
  • \$\begingroup\$ Also, you can shorten that ternary to (-1,(1,0)[n==0])[n>0] to save 10 bytes. Also, don't use a=str.count. It actually costs you 4 bytes. \$\endgroup\$ Nov 9, 2015 at 21:20
  • \$\begingroup\$ That produces -1 for n=0, but cool syntax \$\endgroup\$
    – wnnmaw
    Nov 9, 2015 at 21:21
3
\$\begingroup\$

Go, 179 bytes

An extremely naive solution.

package main
import(."fmt"."strings")
func main(){a:=""
i:=0
Scanln(&a)
b:=Split(a,"")
for _,e:=range b{switch i{case 1:i--
case 0:if e=="^"{i++}else{i--}
case-1:i++}}
Println(i)}

Ungolfed:

package main

import (
    ."fmt"
    ."strings"
)

func main() {
    a := ""
    i := 0
    Scanln(&a)
    b := Split(a, "")
    for _, e := range b {
        switch i {
        case 1:
            i--
        case 0:
            if e == "^" {
                i++
            } else {
                i--
            }
        case -1:
            i++
        }
    }
    Println(i)
}
\$\endgroup\$
3
\$\begingroup\$

05AB1E, 8 bytes

㤮öÓÆ.±

Try it online!

Alternative solutions with the same length: u㤮öÓÆ(, 㤮ögÓÆ(.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ This doesn't work. Neither your posted code nor the code in the TIO link (which is different) take into account votes like ^^ -> 0 \$\endgroup\$
    – Emigna
    May 8, 2019 at 14:40
  • \$\begingroup\$ @Emigna thanks for pointing it out! I fixed the code, it’s still 8 bytes. \$\endgroup\$
    – Grimmy
    May 8, 2019 at 22:52
2
\$\begingroup\$

Minkolang 0.11, 28 22 bytes

0$I2&N."j"o-34*:dr=,*!

Try it here.

Explanation

0                         Push a 0 (running total)
 $I                       Push length of input
   2&N.                   Output as integer and stop if this is 0
       "j"                Push 106
          o               Take character from input (94 for ^, 118 for v)
                          <<so ^ becomes +12 and v becomes -12>>
           -              Subtract
            34*:          Divide by 12
                d         Duplicate top of stack
                 r        Reverse stack
                  =,      Push 0 if equal, 1 otherwise
                    *     Multiply
                          <<this handles two of the same vote in a row>>
                     !    Unconditional trampoline (jumps the 0 at the beginning)

Note that there is no N. at the end. That's because I let it wrap around to the beginning. When the input is empty, the final tally is output as integer and the program stops.

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

Pyth, 13 bytes

ut+Jq\^H>JGzZ
\$\endgroup\$
2
\$\begingroup\$

Mathematica, 60 bytes

Mod[#,2]Sign@#&@Tr@Last@Split@StringCases[#,{"^"->1,_->-1}]&
\$\endgroup\$
1
  • \$\begingroup\$ @#&? That's useless (unless Sequences are involved, but Sequences are not involved. \$\endgroup\$ Apr 13, 2016 at 17:32
2
\$\begingroup\$

Shape Script, 26 bytes

"^"$"0>1@-"~"v"$"0<1-"~0@!

How it woks:

"^"$     split input on '^'
"
  0>         Check if the number is more than 0 (1 if true, 0 if false).
  1@-        subtract the answer from one.
"~       Join it back together, with this string in place of '^'
"v"$     Split on 'v'
"        
  0<         Check if 0 is more than the number (1 if true, 0 if false).
  1-         subtract one from the results
"~       Join it back together, with this string in place of 'v'
0@       add a zero to the stack and place it under the string just built. 
!        run the string as code
\$\endgroup\$
2
\$\begingroup\$

C# 6, 18 + 97 95 = 115 113 bytes, no string methods, excessive LINQ

int v(string s)=>(int)s.Reverse().TakeWhile((c,i)=>i<1||c==s[s.Length-i])?.Sum(x=>x<95?1:-1)%2;

Truly deserves to be preceded by

using System.Linq;

Got the idea of using x<95?1:-1 instead of x=='^'?1:-1 from ProgramFOX's answer

Coincidences:

  • The tweak I stole makes use of comparing to 95 – the byte count excluding the using statement, using said tweak
  • The sum of the digits of the total byte count equals the number of digits of the total byte count written as roman numeral
\$\endgroup\$
2
\$\begingroup\$

C: 67 66 Bytes

golfed:

void f(char *v){int i=0,c,s=0;for(;v[i]!=0;i++){v[i]>94?s--:s++;}}

ungolfed:

void f (char *v)
{
    int i = 0, c, s = 0;

    for (;v[i]!=0;i++)
    {
        v[i] > 94 ? s-- : s++;
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ This does not return a result. It does not pass all tests. \$\endgroup\$ Jul 3, 2017 at 10:33
2
\$\begingroup\$

Perl 5, 41 bytes

40 bytes, plus 1 for -p

/(.)\1*$/;$_=((length$&)%2)*($1=~v?-1:1)

/(.)\1*$/; compares the input string to the regex /(.)\1*$/, i.e. sees whether it ends with a single character repeated some number ≥1 of times.

If so, $& is the whole repetition string and $1 is the character; otherwise (i.e. the input string is empty), those two variables are the empty string.

$1=~v?-1:1 compares $1 to the regex v and returns −1 if it matches and 1 otherwise.

And multiply that ±1 by (length$&)%2, the length of $& modulo 2.

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

05AB1E, 14 12 11 bytes

Îvy'^QDŠ‹+<

Port of @Sp3000's Gol><> answer.

NOTE: @Grimy already posted a shorter 8 bytes alternative for 05AB1E, so make sure to upvote him!

Try it online or verify all test cases.

Explanation:

Î            # Push 0 (later mentioned as `r`) and the input-string
 v           # Loop over the characters of the input:
  y'^Q      '#  Does the current character equal "^"?
             #  (results in 1 for truthy; 0 for falsey - later mentioned as `b`)
      D      #  Duplicate this result `b`
       Š     #  Triple swap (`r`,`b`,`b`) to (`b`,`r`,`b`)
        ‹    #  Check if the boolean `b` is smaller than the result-integer `r`
             #  (again results in 1 for truthy; 0 for falsey)
         +   #  Add them together
          <  #  Decrease this by 1
             # (Implicitly output the result-integer `r` after the loop)
\$\endgroup\$
1
\$\begingroup\$

CJam, 27 24 bytes

'^_]r+e`W=(2%\(i99-g@*W*

Try it Online.

All I took from Dennis' answer is g (sign function) .

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

Ruby, 43

->s{a=0
s.bytes{|i|b=9-i/11;a=a!=b ?b:0}
a}

9-i/11 evaluates to 1 or -1 when given the ascii codes of ^ (94) or v (118)

In test program:

f=->s{a=0
s.bytes{|i|b=9-i/11;a=a!=b ?b:0}
a}

g=gets.chomp
puts f[g]
\$\endgroup\$

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.