Buat permainan dadu ini adil

8

Tantangan ini diadaptasi dari Olimpiade Informatika Inggris .


Game dadu

Dua pemain memainkan permainan dadu di mana mereka masing-masing melempar sepasang dadu, dan jumlah tertinggi menang. Pasangan dadu memiliki jumlah sisi yang sama, tetapi tidak harus memiliki nilai yang sama di setiap sisi. Oleh karena itu, permainan ini adil jika untuk kedua pasang dadu semua jumlah yang mungkin dapat dibuat dengan probabilitas yang sama.

Misalnya, jika Pemain 1 memiliki dadu berikut:

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

Kemudian mereka dapat menghasilkan jumlah berikut:

    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

Jika Player 2 memiliki:

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

Mereka dapat menghasilkan:

    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

Permainan ini adil karena minimum untuk keduanya adalah 2, maksimal 12, dan setiap jumlah terjadi jumlah yang sama, misalnya 7 dapat dibuat 6 cara dengan masing-masing pasangan.


Tantangan

Tulis program / fungsi yang mengambil dua dadu sebagai input, dan opsional bilangan bulat yang mewakili jumlah sisi yang berisi setiap dadu, dan cetak / kembalikan sepasang dadu yang berbeda yang dapat digunakan untuk memainkan permainan yang adil dengan dua dadu masukan, atau nilai falsey jika tidak ada solusi yang berbeda dari input.


Spesifikasi

  • Jumlah sisi pada kedua dadu harus sama, dan sama dengan jumlah sisi pada pasangan input dadu. Angka ini akan selalu berupa bilangan bulat yang lebih besar dari atau sama dengan 1.

  • Dua dadu yang dikembalikan bisa sama, tetapi pasangannya tidak boleh sama dengan pasangan masukan.

  • Pasangan pesanan yang berbeda tidak berbeda; {1,2,3} {4,5,6} sama dengan {4,5,6} {1,2,3}.

  • Program Anda tidak perlu menghasilkan hasil dengan cepat, asalkan pada akhirnya akan menghasilkan output yang benar.

  • Nilai pada pasangan input dadu akan selalu berupa bilangan bulat antara 1 dan 9 inklusif, tetapi nilai yang dikembalikan dapat berupa bilangan bulat ≥1.

  • Jika ada lebih dari satu solusi yang mungkin, hanya satu yang perlu dikembalikan.

  • Input / Output dapat dalam format yang masuk akal.

Uji Kasus

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
sumber
3
Dadu 3 sisi terlihat keren: images2.sw-cdn.net/product/picture/…
Magic Octopus Urn
Apakah mati hanya berisi angka, atau dapatkah itu lebih tinggi dari itu 9? Saya hanya melihat hukum tentang sisi-sisi yang ada >=1, tetapi apakah ada maks? Jika bisa lebih tinggi dari 9, maukah Anda menambahkan test case untuknya?
Kevin Cruijssen
@KevinCruijssen Diperbarui, input hanya akan berisi digit, output dapat mengandung bilangan bulat ≥1.
Trelzevir

Jawaban:

2

Jelly , 34 byte

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

Mengembalikan daftar semua pasangan dadu yang mungkin ke urutan dadu dan wajah * (tidak termasuk yang dadu sama dengan pasangan input).

Cobalah online!

Ini adalah brute-forcer, dan tidak efisien (terlalu lambat untuk menjalankan test case 6-face di TIO).

+þµ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.

* Yaitu jika [[1,1,4,4],[1,1,5,5]]kemungkinan (seperti dalam salah satu contoh) tidak akan ada seorang [[1,1,5,5],[1,1,4,4]atau [[1,4,1,4],[1,1,5,5]], dll

Jonathan Allan
sumber
Hmm, saya benar-benar mengira dadu akan dalam urutan muka (baik dadu pertama), apakah itu OK atau tidak?
Jonathan Allan
... Saya perhatikan test case memiliki cetakan yang tidak dipesan sehingga saya menghilangkan anggapan tersebut.
Jonathan Allan
1

C ++ 14, 130 byte

Sebagai lambda tanpa nama dengan asumsi Mseperti std::vector<std::vector<int>>. Adil 0, hal lain tidak adil.

#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]);}

Tidak Disatukan:

#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
sumber
1

Python, 228 byte

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]

Ini sudah lama sekali; Saya mungkin bisa bermain golf ini sedikit lebih baik sekarang.

0WJYxW9FMN
sumber