Kto wygra wybory?

32

Jest to wyzwanie, w którym dwie osoby, 1 i 2, ubiegają się o urząd. Ludzie deterministycznie głosują w określony sposób w świecie 1 i 2, co może pozwolić kandydatom na zorientowanie się w wynikach przed wyborami.

UWAGA: nie dotyczy to żadnych wyborów zewnętrznych ani innych wydarzeń politycznych.

Dwie osoby biegną do biura. Zadzwonimy do tych osób 1 i 2. Ponieważ oboje chcą wiedzieć, czy wygrają wybory, decydują się wykorzystać swoją wiedzę o ludziach i trochę kodu, aby dowiedzieć się, jaki będzie wynik. Ze względu na chęć zminimalizowania wydatków rządowych kod musi być możliwie jak najkrótszy.

Twoje zadanie: Biorąc pod uwagę liczbę osób na podstawie tego, jak głosują, wyjdź, kto wygra wybory.

W zabawnym i ekscytującym świecie 1 i 2 jest pięć rodzajów ludzi:

  • A: osoby, które zdecydowanie zagłosują na 1.
  • B: osoby, które zdecydowanie zagłosują na 2.
  • X: osoby, które będą głosować na osobę po ich lewej, będą głosować na. Jeśli po ich lewej stronie nie ma żadnej osoby, wówczas głosują na każdego, kto będzie głosował po ich prawej stronie. Jeśli nie jest jasne, na kogo osoba po ich prawach głosuje, wówczas nie głosuje.
  • Y: ludzie będą głosować przeciwnie do osoby po lewej stronie. Jeśli po ich lewej stronie nie ma żadnej osoby, wówczas głosują przeciw temu, kto ma rację. Jeśli nie jest jasne, na kogo osoba po ich prawach głosuje, wówczas nie głosuje.
  • N: ludzie, którzy nie głosują.

Jest to oceniane od lewej do prawej.

Przykład:

Ktokolwiek jest „oceniany”, jest napisany małymi literami, dla jasności.

Input: `XXAYAN`
        xX      Votes for whoever their friend is voting for. Their friend has not decided yet, so it is unclear, so they do not vote.
        Xx      Person to left is voting "none" so votes "none."
          a     Votes for 1
          Ay    Since person on left is voting for 1, votes for 2.
            a   Votes for 1
             n  Does not vote

Ostatnia ankieta:

  • 2 osoby głosowały na 1

  • 1 osoba głosowała na 2

  • 3 osoby nie głosowały

1 ma najwięcej głosów, więc 1 wygrywa!

Przypadki testowe:

Możesz używać innych znaków lub wartości jako danych wejściowych i wyjściowych, o ile są one odrębne. (Na przykład: liczby zamiast liter, różne litery, małe litery, prawda / fałsz lub dodatnie / ujemne (na wyjściu) itp.)

Input -> Output

"AAAA" -> 1
"BBBB" -> 2
"BBAXY" -> 2
"BAXYBNXBAYXBN" -> 2
"XXAYAN" -> 1
"AAAABXXXX" -> 2
"AXNXXXXAYB" -> 1
"NANNY" -> 1
"XA" -> 1
"YAB" -> 2
"XY" -> anything (do not need to handle test cases with no victor)
"AB" -> anything (do not need to handle test cases with no victor)
Towarzyszu SparklePony
źródło
1
@EriktheOutgolfer ANNY jest taki sam jak tylko A NN. NX i NY stają się NN.
Towarzysz SparklePony,
5
Warto określić, że nonejest odwrotnie none, jeśli zachowanie NYw komentarzach jest prawidłowe.
Kamil Drakari
1
IMHO nie powinno być testami poczynając XA, XB, YAi YB.
Neil
1
Czy dane wejściowe mogą zawierać tylko 1 literę? np. „A”, „X”, „Y”, „N”.
tsh
2
Czy dane wyjściowe muszą być dwiema odrębnymi wartościami, czy możemy na przykład wypisać jakąkolwiek dodatnią liczbę całkowitą, jeśli wygrywa 1 i jakąkolwiek ujemną liczbę całkowitą, jeśli wygrywa 2?
Kevin Cruijssen

Odpowiedzi:

9

Perl 5, 56 80 72 65 53 bajtów

+26 bajtów do obsługi skrzynki X lub Y na pierwszej pozycji i A lub B na drugiej. wyjście jest, 1jeśli 1 wygrywa puste (fałszywa wartość w perlu) w przeciwnym razie.

s/^X(.)/$1$1/,s/A\KX|B\KY|^Y(?=B)/A/|s/B\KX|A\KY|^Y(?=A)/B/&&redo;$_=y/A//>y/B//

TIO

użycie Pi Szamiast Xoraz Yzezwolenie na użycie operacji xor na znakach, pozwoliłoby zaoszczędzić trochę więcej bajtów

s/(?|^(P|S)(?=(A|B))|(A|B)\K(P|S))/P^$1^$2/e&&redo;$_=y/A//>y/B//

używa grupy resetowania gałęzi (?|.. |.. ), dzięki czemu $1 $2odnosi się do odpowiedniej grupy w oddziale. Używanie \0i \3zamiast XiY

$_=s/^\W(?=(\w))|(\w)\K\W/$1.$2^$&/e?redo:y/A//>y/B//

72 bajty

65 bajtów

53 bajty

Nahuel Fouilleul
źródło
from my last understanding they are not counted any more
Nahuel Fouilleul
To nie obsługuje poprawnie Xi Yna początku łańcucha. Spróbuj XBAi YAB.
Grimmy
@Grimy, zaktualizowano
Nahuel Fouilleul
9

Java 8, 153 141 135 131 129 bajtów

a->{int l=a.length,t,r=0,i=-1;for(;++i<l;r+=(t=a[i]=a[i]>4?t<3?t^3:3:a[i]>3?t:a[i])>2?0:3-t*2)t=a[i>0?i-1:i<l-1?i+1:i];return r;}

Używa tablicy liczb całkowitych jako danych wejściowych A=1, B=2, N=3, X=4, Y=5i zwraca dodatnią liczbę całkowitą ( >= 1), jeśli wygrywa A, ujemną liczbę całkowitą ( <= -1), jeśli wygrywa B lub 0jeśli jest to remis.

-18 bajtów dzięki @ OlivierGrégoire .

Wypróbuj online.

Wyjaśnienie:

a->{                      // Method with int-array parameter and boolean return-type
  int l=a.length,         //  Length of the input-array
      t,                  //  Temp integer, uninitialized
      r=0,                //  Result-integer, starting at 0
  i=-1;for(;++i<l         //  Loop `i` in the range [0, l):
           ;              //    After every iteration:
            r+=           //     Increase the result by:
             (t=a[i]=     //       Change `i`'th item in the array to:
                 a[i]>4?  //        If the `i`'th item is a 5:
                  t<3?    //         If `t` is 1 or 2:
                   t^3    //          Use `t` Bitwise-XOR 3 to invert it
                          //          (1 becomes 2; 2 becomes 1)
                  :       //         Else (`t` is 3, 4, or 5 instead):
                   3      //          Set it to 3
                 :a[i]>3? //        Else-if the `i`'th item is a 4:
                  t       //         Set it to `t`
                 :        //        Else (the `i`'th item is a 1, 2 or 3):
                  a[i])   //         Leave it unchanged
             )>2?         //      And if this new `i`'th value is 3, 4, or 5:
              0           //       Leave the result the same by increasing it with 0
             :            //      Else (it's 1 or 2 instead):
              3-t*2;      //       Increase it by 3 minus two times the `i`'th value
                          //       (which is 1 for 1; and -1 for 2)
         t=               //   Set `t` to:
           a[i>0?         //    If `i` is not the first item:
              i-1         //     Set `t` to the previous (`i-1`'th) value
             :i<l-1?      //    Else-if `i` is not the last item:
              i+1         //     Set `t` to the next (`i+1`'th) value
             :            //    Else (`i` is the first or last item):
              i];         //     Set `t` to the current item itself
  return r;}              //  Return the result
                          //  (positive if A wins; negative if B wins; 0 if it's draw)
Kevin Cruijssen
źródło
i=0;for(int n:a)i+=n<2?1:n<3?-1:0;return i>0; saves a few bytes bytes.
Olivier Grégoire
1
Actually, i=0;for(int n:a)i+=n>2?0:3-n*2;return i>0; is even shorter.
Olivier Grégoire
@OlivierGrégoire Thanks! When I saw your first comment I was about to find something shorter, but you beat me to it with your second comment. ;)
Kevin Cruijssen
1
131 bytes by merging the second loop in the first one. It doesn't feel right, though, and some test cases might have to be added...
Olivier Grégoire
@OlivierGrégoire Thanks! Been able to golf 4 more bytes by merging it some more with the temp variable. And what feels wrong about it? If you add a System.out.println(java.util.Arrays.toString(a)); after the loop you can see it changed as you would expect (imo). What kind of test case would you think results in an incorrect result and due to what part of the code?
Kevin Cruijssen
8

Haskell, 60 50 48 59 bytes

l#(v:o)|v<2=v+v#o|n<-(3-v)*l=n+n#o
_#_=0
f x=rem(x!!1)2#x>0

Uses 1 for A, -1 for B, 0 for N, 2 for X and 4 for Y. Returns True if A wins, else False.

Try it online!

On the recursive way down the input list we add 1 for every vote for A, -1 for every vote for B and 0 for "no vote". l is the last vote, v the next. If v=1, -1 or 0 (or v<2) we just add it to the sum. If v is "vote same" (X in the challenge, 2 for my solution) we keep and add l ((3-2)*l = l). If v is "vote opposite" (Y in the challenge, 4 for my solution) we first negate l ((3-4)*l = -l) and then add it. Base case is the empty list which starts the sum with 0. Recursion is started with l set to rem s 2 where s is the second element of the input list (x!!1). rem s 2 maps 1 and -1 to itself, all other values to 0. Fix votes ignore l anyway [*] and X or Y get the right neighbor if it's a fix vote. If the overall sum is positive, A wins.

[*] this makes singleton lists with fix votes like [1] work, because due to Haskell's laziness access to the second element is never evaluated. Inputs like [2] fail with error, but don't have to be considered.

nimi
źródło
1
@Grimy: thanks for pointing out. Fixed.
nimi
6

JavaScript (ES6),  78 75  73 bytes

Takes input as an array of integers with: 0 = N, 1 = A, 2 = B, 4 = Y, 8 = X.

Returns false if the first candidate wins or true if the 2nd candidate wins.

a=>a.reduce((v,x,i)=>v+~~[,1,-1][p=x?x&3||~-x%7^(p&3||a[i+1]&3):0],p=0)<0

Try it online!

Arnauld
źródło
4

05AB1E, 34 33 32 30 bytes

gFÐNè©[email protected]èDÄ2‹*D(‚®èNǝ]O

Uses an integer-array as input with A=-1, B=1, N=0, X=2, Y=3 and outputs a negative integer (<= -1) if A wins, a positive integer (>= 1) if B wins, or 0 if it's a draw.

Try it online or verify all test cases.

Explanation:

g             # Take the length of the (implicit) input-list
              #  i.e. [3,1,3,3,2,0,1] → 7
 F            # Loop `N` in the range [0, length):
  Ð           #  Triplicate the list at the top of the stack
              #  (which is the implicit input-list in the first iteration)
   Nè         #  Get the `N`'th item of the list
              #   i.e. [3,1,3,3,2,0,1] and `N`=0 → 3
              #   i.e. [-1,1,-1,3,2,0,1] and `N`=3 → 3
     ©        #  Store it in the register (without popping)
   2@i        #  If it's larger than or equal to 2 (so either 2 or 3):
      Nx      #   Push `N` and `N` doubled both to the stack
              #    i.e. `N`=0 → 0 and 0
              #    i.e. `N`=3 → 3 and 6
        1.S   #   Compare the double integer with 1 (-1 if N*2<1; 0 if N*2==1; 1 if N*2>1)
              #   (So this will be -1 in the first iteration, otherwise it will be 1)
              #    i.e. 0 → -1
              #    i.e. 6 → 1
            #   Subtract that from the index, and index it into the list
              #    i.e. `N`=0 and -1 → 1 (first item, so get the next index)
              #     → [3,1,3,3,2,0,1] and 1 → 1
              #    i.e. `N`=3 and 1 → 2 (fourth item, so get the previous index)
              #     → [-1,1,-1,3,2,0,1] and 2 → -1
      D       #   Duplicate that value
       Ä2    #   Check if that value is -1, 0, or 1 (abs(i) < 2) (truthy=1; falsey=0)
          *   #   And multiply that with the value
              #   (remains the same if truthy; or becomes 0 if falsey)
      D(‚     #   Pair it with its negative (-1 becomes [-1,1]; 1 becomes [1,-1])
         ®è   #   And index the `N`'th value (from the register) into it (with wraparound)
              #   (if it was a 2, it uses the unchanged (first) value of the pair;
              #    if it was a 3, it uses the negative (second) value of the pair)
              #     i.e. [1,-1] and 3 → -1
              #     i.e. [-1,1] and 3 → 1
      Nǝ      #   And replace the `N`'th value with this
              #    i.e. [3,1,3,3,2,0,1], `N`=0 and -1 → [-1,1,3,3,2,0,1]
              #    i.e. [-1,1,-1,3,2,0,1], `N`=3 and 1 → [-1,1,-1,1,2,0,1]
 ]            # Close both the if-statement and loop
  O           # Sum the modified list (which now only contains -1, 0, or 1)
              #  i.e. [-1,1,-1,1,1,0,1] → 2
Kevin Cruijssen
źródło
3

Retina 0.8.2, 70 bytes

AY
AB
BY
BA
}`(A|B)X
$1$1
^X(A|B)|^Y[AB]
$1$1
+`N|X|Y|AB|BA

.+|(?<=B)

Try it online! Link includes test cases. Outputs 0 for a tie. Explanation:

AY
AB
BY
BA

Handle Y voters to the right of people with decided votes.

}`(A|B)X
$1$1

Handle X voters to the right of people with decided votes, and then loop back until all possible Y and X votes can be decided.

^X(A|B)|^Y[AB]
$1$1

Handle an initial X voter next to a decided vote, and also an initial Y voter next to a decided vote. As this voter will vote opposite to the decided vote, we can just delete both votes in this case.

+`N|X|Y|AB|BA

Delete any remaining no vote or undecided votes, and cancel out all pairs of opposing decided votes. Repeat until all possible votes are cancelled. In the case of a tie, nothing will be left, otherwise the remaining votes will all be of the same type.

.+|(?<=B)

Output 1 if there are any votes, but 2 if they are B votes.

Neil
źródło
3

JavaScript (Node.js), 42 bytes

s=>s.map(c=>x+=l=c%2|l*c/2,l=s[x=1]%2)|x>1

Try it online!

Save 1 bytes, thanks to Shaggy.


  • Input as integer array where N = 0, A = -1, B = 1, X = 2, Y = -2;
  • Output 1 = Falsy, 2 = Truthy
tsh
źródło
2
Your TIO seems to output 0, 1 and 3 instead of 1 and 2?
Kevin Cruijssen
1
@KevinCruijssen But OP allowed truthy vs. falsy as output if i understand correctly. Falsy means 1 won the game, and truthy means 2 won.
tsh
Ah ok, forgot 3 is truthy in JS as well. I always think of 0/1 as falsey/truthy. And since we no longer need distinct outputs, 0 = 1 wins and >= 1 = 2 wins is fine as well. So +1 from me.
Kevin Cruijssen
It looks like you could save a byte using bitwise OR, instead of logical OR.
Shaggy
@Shaggy So strange. It works.
tsh
2

Python 3 2, 125 121 117 bytes

(Thanks to Jonathan Frech)

def f(x):
    for i,v in enumerate(x):n=x[i-(i>0)];x[i]=(v>3)*n+abs(n-1)*(v<0)+x[i]*(0<v<4)
    print x.count(1)>x.count(0)

Using tab indentation

Input: list of ints where 'A'=1, 'B'=0, 'X'=4, 'N'=3, 'Y'=-1, so "AAAA" is [1, 1, 1, 1] and "XXAYAN" is [4, 4, 1, -1, 1, 3].

[{'A': 1, 'B': 0, 'X': 4, 'N': 3, 'Y': -1}[c] for c in s] will convert the strings to the needed input format.

You can Try it online! (Thanks to Jonathan Frech for the suggestion)

user24343
źródło
Hello and welcome to PPCG. I would recommend using TIO, as it nicely formats your code. Furthermore, I do not quite understand your input format. You may have to ask the OP about its validity.
Jonathan Frech
As a golfing tip, (i, i-1)[i>0] should be equivalent to i-(i>0).
Jonathan Frech
Furthermore, your ifs could probably become x[i]+=(v>3)*n+abs(n-1)*(v<0). You can then save on indentation by moving the now non-compound statement (using ;) on the same line as the for.
Jonathan Frech
@JonathanFrech Thank you very much; I hope I explained the input better
user24343
1

Perl 5, 54 bytes

s/^\W(?=(\w))|(\w)\K\W/$1^$2^$&/e&&redo;$_=y/A//>y/B//

Try it online!

Uses A for A, B for B, N for N, \0 for X and \3 for Y (the last two being literal control chars). The trick is that A bitwise-xor \3 equals B, and vice-versa.

Grimmy
źródło
it uses many ideas of my answer, i wasn't sure we can use non printable character as input and output, except i didn't realize the benfit of using backslash character classes
Nahuel Fouilleul
1

Javascript (ES6) - 133 bytes

a=>(i=($=_=>'AB'.search(_)+1)(a[1],o=0),[...a].map(v=>(r=['NAB','NBA']['XY'.search(x)],p=r?r[i]:v,i=$(p),o+='NA'.search(p))),o>0?1:2)

Takes in a string with the format given in the OP and returns 1 if candidate 1 won and 2 otherwise (I'll admit it, I'm even-biased).

M Dirr
źródło
1

Python 2, 95 73 bytes

lambda(v):sum([l for l in[2*int(v[1]/2)]for i in v for l in[i*l**(i%2)]])

Try it online!


  • Input as integer array where N = 0, A = -2, B = 2, X = 1, Y = -1;
  • Output negative = A, 0 = draw, positive = B
  • If first input is X or Y, then 2*int(v[1]/2) maps second to itself or 0

Bug fix was required that added extra bytes, but converting to lambda thanks to @Stephen reduced it back to 95

ABridgeTooFar
źródło
74 bytes by removing whitespace and changing the function to a lambda function
Stephen