Machen Sie dieses Würfelspiel fair

8

Diese Herausforderung wurde von der britischen Informatikolympiade übernommen .


Würfelspiel

Zwei Spieler spielen ein Würfelspiel, bei dem sie jeweils ein Würfelpaar werfen und die höchste Summe gewinnt. Die Würfelpaare haben die gleiche Anzahl von Seiten, müssen jedoch nicht auf jeder Seite die gleichen Werte haben. Daher ist das Spiel fair, wenn für beide Würfelpaare alle möglichen Summen mit gleicher Wahrscheinlichkeit gemacht werden können.

Zum Beispiel, wenn Spieler 1 die folgenden Würfel hat:

{1,2,3,4,5,6} {1,2,3,4,5,6}

Dann können sie folgende Summen produzieren:

    1  2  3  4  5  6
 +------------------
1|  2  3  4  5  6  7 
2|  3  4  5  6  7  8
3|  4  5  6  7  8  9
4|  5  6  7  8  9  10
5|  6  7  8  9  10 11
6|  7  8  9  10 11 12

Wenn Spieler 2 hat:

{1,2,2,3,3,4} {1,3,4,5,6,8}

Sie können produzieren:

    1  2  2  3  3  4
 +------------------
1|  2  3  3  4  4  5 
3|  4  5  5  6  6  7
4|  5  6  6  7  7  8
5|  6  7  7  8  8  9
6|  7  8  8  9  9  10
8|  9  10 10 11 11 12

Dieses Spiel ist fair, da das Minimum für beide 2 ist, das Maximum 12 ist und jede Summe gleich oft auftritt, z. B. können 7 mit jedem Paar auf 6 Arten gemacht werden.


Herausforderung

Schreiben Sie ein Programm / eine Funktion, die zwei Würfel als Eingabe und optional eine Ganzzahl verwendet, die die Anzahl der Seiten darstellt, die jeder Würfel enthält, und druckt / gibt ein anderes Würfelpaar zurück, das verwendet werden kann, um ein faires Spiel mit den beiden Eingabewürfeln zu spielen, oder Jeder Falsey-Wert, wenn es keine andere Lösung als die Eingabe gibt.


Spezifikationen

  • Die Anzahl der Seiten auf beiden Würfeln muss gleich sein und der Anzahl der Seiten auf dem eingegebenen Würfelpaar entsprechen. Diese Zahl ist immer eine ganze Zahl größer oder gleich 1.

  • Die beiden zurückgegebenen Würfel können identisch sein, das Paar darf jedoch nicht mit dem Eingabepaar identisch sein.

  • Unterschiedliche Ordnungspaare sind nicht unterschiedlich. {1,2,3} {4,5,6} ist dasselbe wie {4,5,6} {1,2,3}.

  • Ihr Programm muss nicht schnell ein Ergebnis liefern, solange es schließlich die richtige Ausgabe liefert.

  • Die Werte auf dem eingegebenen Würfelpaar sind immer ganze Zahlen zwischen 1 und einschließlich 9, aber die zurückgegebenen Werte können beliebige ganze Zahlen ≥ 1 sein.

  • Wenn es mehr als eine mögliche Lösung gibt, muss nur eine zurückgegeben werden.

  • Eingabe / Ausgabe kann in jedem vernünftigen Format erfolgen.

Testfälle

6
1 2 2 3 3 4
8 6 5 4 3 1

1 2 3 4 5 6
1 2 3 4 5 6

4
1 1 1 1
1 4 5 8

1 1 4 4
1 1 5 5

3
1 3 5
2 4 6

False

8                    
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8

Any of the following:

1 2 2 3 3 4 4 5       |    1 2 2 3 5 6 6 7   |    1 2 3 3 4 4 5 6
1 3 5 5 7 7 9 11      |    1 3 3 5 5 7 7 9   |    1 2 5 5 6 6 9 10
Trelzevir
quelle
3
3-seitige Würfel sehen cool aus: images2.sw-cdn.net/product/picture/…
Magic Octopus Urn
Enthält der Würfel nur Ziffern oder kann er auch höher sein als 9? Ich sehe nur die Entscheidung über die Seiten >=1, aber gibt es ein Maximum? Wenn es höher als 9 sein kann, würde es Ihnen etwas ausmachen, einen Testfall dafür hinzuzufügen?
Kevin Cruijssen
@ KevinCruijssen Aktualisiert, Eingabe enthält nur Ziffern, Ausgabe kann eine beliebige Ganzzahl ≥1 enthalten.
Trelzevir

Antworten:

2

Gelee , 34 Bytes

+þµFṢ
ç©ṀRœċL}Œċµç/⁼®µÐf
,Ṣ€,Ṛ$ḟ@ç

Gibt eine Liste aller möglichen Würfelpaare bis zur Reihenfolge der Würfel und Gesichter * zurück (mit Ausnahme aller Würfel, die mit dem Eingabepaar identisch sind).

Probieren Sie es online aus!

Dies ist ein Brute-Forcer und nicht effizient (zu langsam, um den 6-Gesichter-Testfall bei TIO überhaupt auszuführen).

+þµFṢ - Link 1, sorted sums: dieA, dieB
 þ    - outer product with
+     -     addition (make a table of the sums, a list of lists)
  µ   - monadic chain separation
   F  - flatten into one list
    Ṣ - sort

ç©ṀRœċL}Œċµç/⁼®µÐf - Link 2, all possible fair dice pairs (including input): dieA, dieB
ç                  - call the last link (1) as a dyad
 ©                 - save the result to the register for later use too
  Ṁ                - maximum (the largest sum)
   R               - range [1,2,...,maxSum]
       }           - use right argument (dice B) to turn the monad into a dyad:
      L            -     length
    œċ             - all combinations with replacement (i.e. all dice with faces between 1 and maxSum inclusive [overkill, but golfier than less])
        Œċ         - all pairs of these dice
          µ        - monadic chain separation
               µÐf - filter keep:
            /      -     reduce with:
           ç       -         last link (1) as a dyad (the sorted sums of the current pair)
              ®    -     retrieve register value (the sorted sums of the input pair)
             ⁼     -     equal?

,Ṣ€,Ṛ$ḟ@ç - Main link: dieA, dieB
,         - pair - [dieA, dieB]
 Ṣ€       - sort €ach - [dieASorted, dieBSorted]
     $    - last two links as a monad:
    Ṛ     -     reverse - [dieBSorted, dieASorted]
   ,      -     pair - [[dieASorted, dieBSorted], [dieBSorted, dieASorted]]
        ç - call the last link (2) as a dyad (with dieA, dieB)
       @  - reversed @rguments:
      ḟ   -     filter out - removes any results that are equivalent to the input pair.

* dh wenn [[1,1,4,4],[1,1,5,5]]es eine Möglichkeit gibt (wie in einem der Beispiele), wird es kein [[1,1,5,5],[1,1,4,4]oder [[1,4,1,4],[1,1,5,5]]usw. geben.

Jonathan Allan
quelle
Hmm, ich habe tatsächlich angenommen, dass die Würfel in der richtigen Reihenfolge sind (entweder zuerst die Würfel), ist das in Ordnung oder nicht?
Jonathan Allan
... Ich habe festgestellt, dass ein Testfall einen Würfel hat, der nicht bestellt wurde, also habe ich die Annahme entfernt.
Jonathan Allan
1

C ++ 14, 130 Bytes

Als unbenanntes Lambda unter der Annahme M, dass es so ist std::vector<std::vector<int>>. Fair ist 0, alles andere ist unfair.

#include<map>
[](auto&M){auto g=[](auto&v){std::map<int,int>m;for(int x:v)for(int y:v)m[x+y]++;return m;};return g(M[0])-g(M[1]);}

Ungolfed:

#include<map>

auto f=
[](auto&M){
 auto g=[](auto&v){
  std::map<int,int>m;
  for(int x:v)
   for(int y:v)
    m[x+y]++;
  return m;
 };
 return g(M[0])==g(M[1]);
}
;
Karl Napf
quelle
1

Python, 228 Bytes

from itertools import*;s,C=lambda x,y:sorted(sum([[i+j for j in y]for i in x],[])),combinations_with_replacement;f=lambda k,l,m:([[*a]for a in C([*C([*range(1,s(l,m)[-1])],k)],2)if(s(l,m)==s(*a))*~-([*a]in[[l,m],[m,l]])]+[0])[0]

Dies war vor langer Zeit; Ich könnte das jetzt wahrscheinlich ein bisschen besser spielen.

0WJYxW9FMN
quelle