Kolejność zestawów Mia

9

Gra w kości Mia wprowadza bardzo nietrywialną kolejność zestawów rozmiaru drugiego:

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

Zasadniczo kolejność w krotce nie ma znaczenia {x,y}={y,x}, {1,2}jest większa niż cokolwiek innego, Pary są większe niż nie-pary, a wartość liczbowa decyduje w przypadku remisu.

Załóżmy teraz, że chcesz użyć nkości. Ponadto kości mają mtwarze.

Przykład:

  • {1,5,3,4} < {1,2,6,3} od 5431 <6321
  • {1,2,3,5} < {1,1,5,6} < {1,1,5,5}, {1,1,6,6} < {1,1,1,3} < {2,2,2,3} < {1,1,1,1} < {1,2,3,4}
  • {2,2,5} < {1,1,6} ponieważ oba zestawy mają każdą jedną parę i 611> 522

Krótko mówiąc, {1, ..., n}jest większy niż cokolwiek innego. Niech p > qzatem rzeczownik rodzaju jest większy niż rzeczownik rodzaju. W przypadku remisu wygrywa drugi (, trzeci, ...) - najdłuższy w swoim rodzaju. Wreszcie, jeśli nie można jeszcze podjąć żadnej decyzji, wygrywa największa wartość liczbowa. Wartość liczbowa zestawu jest największą liczbą całkowitą, jaką można zbudować z dostępnych liczb w zestawie, używając konkatenacji. Przykład:

  • {2,5,4,3} staje się 5432
  • {4,11,3,4} staje się B443 (dozwolone są kości o> 6 twarzach, B = 11)

Twoim zadaniem jest napisanie najmniejszego możliwego programu (tj. Funkcji) w wybranym języku, który, biorąc pod uwagę dwa kontenery (lista, tablica, zestaw, ...) zwraca, czy wygra pierwszy, czy drugi.

Uwaga: możesz założyć, że dwa pojemniki mają tę samą długość i zawierają tylko dodatnie liczby całkowite, ale nic więcej. Zwłaszcza nie można ich posortować. Zwracana wartość może być dowolna, np. {-1, 0, 1} dla {pierwsze wygrane, remis, drugie wygrane}.

pasbi
źródło
1
Który wygrywa z {1,1,6}, {2,2,5}? Czy porównujesz wartość liczbową największej kostki lub jakiejkolwiek kostki?
Martin Ender,
1
Pozwól, że sprawdzę, czy rozumiem porządek: Po pierwsze, {1, ..., n} jest najwyższy. Dla każdej listy wybierz najczęstszą wartość, a z równie wspólnych wartości najwyższą. Jeśli jedna lista zawiera więcej, wygrywa. Jeśli jednakowo powszechny, wygrywa ten, który jest większy. Jeśli są równe pod względem powszechności i wartości, usuń wszystkie z każdej listy i porównaj ponownie.
xnor
@Martin: Doskonałe pytanie. Myślę, że nie ma w tej sprawie „kanonicznej” decyzji, a ponieważ mój program Julii mówi, że {1,1,6} wygrywa z {2,2,5}, to po prostu tak.
pasbi
@xnor: Tak, jednak rozważ komentarz Martina i moją odpowiedź.
pasbi
@ oVooVo O tak, to ma sens biorąc pod uwagę twój przykład, w którym po prostu sortujesz je według wartości liczbowej po posortowaniu cyfr od największej do najmniejszej.
Martin Ender

Odpowiedzi:

2

Galaretka , 16 bajtów

ṢŒrUṢṚZ
Ṣ⁼J;ǵÐṀ

Pobiera listę list, z których każda reprezentuje rzut (w razie potrzeby może być więcej niż dwie) i zwraca listę zwycięzców.

Wypróbuj online! ... alternatywnie tutaj jest wersja, która zamiast tego sortuje rolki od najsłabszych do najsilniejszych.

W jaki sposób?

Ṣ⁼J;ǵÐṀ - Main link: list of list of dice rolls, L
     µÐṀ - filter keep maximal (i.e. sort L by the previous link as a key and keep maximums)
         -                                            e.g. [5,3,1,3]
Ṣ        -     sort roll                                   [1,3,3,5]
  J      -     range(length(roll))                         [1,2,3,4]
 ⁼       -     equal? [1,2,3,...n] beats everything        0
    Ç    -     call last link as a monad with input roll   [[2,1,1],[3,5,1]]
   ;     -     concatenate                                 [0,[2,1,1],[3,5,1]]

ṢŒrUṢṚZ - Link 1, rest of sort key: dice rolls        e.g. [5,3,1,3]
Ṣ       - sort the roll                                    [1,3,3,5]
 Œr     - run length encode                                [[1,1],[3,2],[5,1]]
   U    - upend (reverse each)                             [[1,1],[2,3],[1,5]]
    Ṣ   - sort                                             [[1,1],[1,5],[2,3]]
     Ṛ  - reverse                                          [[2,3],[1,5],[1,1]]
      Z - transpose                                        [[2,1,1],[3,5,1]]
        -     ...this is a list of: 1) the group sizes descending; and
                 2) the face values of each group, descending across equal group sizes
Jonathan Allan
źródło
@oVooVo Podczas gry w golfa zauważyłem to 1,1,2i 1,2,2są uważane za równe, ale specyfikacja ich obecnie nie rozróżnia.
Jonathan Allan
@oVooVo po dalszej kontroli przykład ma {1,1,5,6} < {1,1,5,5}gdzie 6 > 5. Czy możesz to wyjaśnić?
Jonathan Allan,
@oVooVo Może powinno być jak ten - ja zastąpiły „maksymalny wybór” ÐṀ, z pewnego rodzaju, Þdla celów testowych - wykorzystanie elementów z przykładu sortuje je w tej samej kolejności. Stosowana kolejność jest następująca: najpierw według „top-dog”, następnie według liczby równych twarzy malejących, a na koniec unikalnych twarzy malejących.
Jonathan Allan
{1,1,5,5} ma dwa „2 w swoim rodzaju”: (1,1) i (5,5). {1,1,5,6} ma tylko jeden „jedyny w swoim rodzaju”. Stąd wygrywa {1,1,5,5}. Wartość nie ma tutaj znaczenia. Podobnie {1,1,2,2}> {4,5,6,6}.
pasbi
{1,2,2}> {1,1,2}. Ponieważ oba mają jeden jedyny w swoim rodzaju, obowiązuje podział liczbowy. {1,2,2} => 221 i {1,1,2} => 211. Oczywiście 221 jest większe niż 211. Wyjaśnię to w specyfikacjach.
pasbi
2

JavaScript (ES6), 162 bajty

(a,b,g=a=>a.map(n=>e[n]=e[n]+1||1,e=[1])&&[[...e].every(n=>n==1),...e.filter(i=x=>x).sort(h=(a,b)=>b-a),...a.sort(h)],c=g(a),d=g(b))=>d.map((n,i)=>n-c[i]).find(i)

Objaśnienie: Pobiera dwie tablice jako parametry. gkonwertuje każdą tablicę na listę zliczeń. Lista jest następnie sprawdzana, aby sprawdzić, czy odpowiada zestawowi 1..n. Liczby są sortowane, a posortowane wartości są łączone. Oba wyniki są następnie porównywane. Zwracana wartość undefinedjest dodatnią liczbą całkowitą, jeśli wygrywa druga tablica, i ujemną liczbą całkowitą, jeśli wygrywa pierwsza tablica, w przeciwnym razie zwracana jest wartość falsy JavaScript .

Neil
źródło
Twój program mówi {1,1,6} <{2,2,5}, co jest błędne.
pasbi
@oVooVo Przepraszam, musiałem źle zrozumieć zasady (myślałem, że zerwałeś więzi w oparciu o wartość liczbową najdłuższego w swoim rodzaju).
Neil
0

PHP 333 bajtów

Zakładam, że jest mniej kości niż lic dla najwyższej wartości jako ulica zaczynająca się od 1

Zarabiam trochę więcej. Dane wejściowe to tablica z więcej niż dwiema wartościami. Dane wyjściowe to posortowana tablica.

<? $m=$_GET[m];foreach($m as$k=>$v){rsort($v);$m[$k]=$v;}function t($a,$b){if($a==$r=range($x=count($a),1))return 1;elseif($b==$r)return-1;$c=array_pad(array_values(array_count_values($a)),$x,0);$d=array_pad(array_values(array_count_values($b)),$x,0);rsort($c);rsort($d);if($e=$c<=>$d)return$e;return$a<=>$b;}usort($m,t);print_r($m);

Awaria

$m=$_GET["m"]; # Array as Input
foreach($m as$k=>$v){
    rsort($v); # reverse sort of an item
    $m[$k]=$v; # replace the sort item
}
function t($a,$b){ #sorting algorithm
    if($a==$r=range($x=count($a),1))return 1; # $a is highest value
    elseif($b==$r)return-1; # $b is highest value
    $c=array_pad(array_values(array_count_values($a)),$x,0); 
# prepare check multiple values for fist value
    $d=array_pad(array_values(array_count_values($b)),$x,0); 
# prepare check multiple values for second value
    rsort($c);
    rsort($d);
    if($e=$c<=>$d)return$e; # compare first and second multiples
    return$a<=>$b; # compare dices
}
usort($m,"t"); # start sort
print_r($m); #print sorted array from low to high
Jörg Hülsermann
źródło
0

Julia (489 bajtów)

function a(x,y)l=length;g=collect;s=sort;m=maximum;r=repmat;function b(z)w=sum(r(z,1,m(z)).==r(g(1:m(z))',l(z),1),1);u=zeros(m(w));map(i->if i>0 u[i]+=1;end,w);return u end;function c(x,y)if l(x)>l(y)return-1 elseif l(x)<l(y)return 1 else for i=l(x):-1:1 if x[i]>y[i] return-1 elseif x[i]<y[i] return 1 end end;return 0;end end;x=s(x);y=s(y);if x==y return 0;elseif x==g(1:l(x));return-1 elseif y==g(1:l(y))return 1 else d=c(b(x),b(y));if d==0 return c(x,y);else return d;end end end

Czytelny:

  1 function a(ds1, ds2)
  2     function countNOfAKind(ds)
  3         # return array. n-th value is number of occurences of n-of-a-kind.
  4         # e.g. findNOfAKind([1, 1, 1, 2, 2, 3, 3]) == [0, 2, 1]
  5         ps = sum(repmat(ds, 1, maximum(ds)) .== repmat(collect(1:maximum(ds))', length(ds), 1), 1);
  6         ls = zeros(maximum(ps));
  7         map(i -> if i>0 ls[i] += 1 end, ps);
  8         return ls
  9     end
 10 
 11     function cmpLex(ds1, ds2)
 12         # compare ds1, ds2 reverse-lexicographically, i.e. compare last distinct value.
 13         if length(ds1) > length(ds2)
 14             return -1
 15         elseif length(ds1) < length(ds2)
 16             return 1
 17         else
 18             for i = length(ds1):-1:1
 19                 if ds1[i] > ds2[i]
 20                     return -1
 21                 elseif ds1[i] < ds2[i]
 22                     return 1
 23                 end
 24             end
 25             return 0;
 26         end
 27     end
 28     
 29     ds1=sort(ds1);
 30     ds2=sort(ds2);
 31     if ds1 == ds2
 32         return 0;
 33     elseif ds1 == collect(1:length(ds1))
 34         return -1
 35     elseif ds2 == collect(1:length(ds2))
 36         return 1
 37     else
 38         d = cmpLex(countNOfAKind(ds1), countNOfAKind(ds2))
 39         if d == 0
 40             return cmpLex(ds1, ds2);
 41         else
 42             return d;
 43         end
 44     end
 45 end
pasbi
źródło
Dlaczego porównujesz długości? Instrukcje mówią „dwa pojemniki mają tę samą długość”. Czy coś brakuje?
DavidC
Usunąłem porównanie długości w wierszu 31. Nie było to konieczne, ale też nie bolało. Porównanie w linii 15 jest konieczne, ponieważ cmpLex jest używany nie tylko w linii 40 do porównania surowych danych wejściowych, ale także w linii 38 do porównania wyniku countNOfAKind. Ta funkcja może jednak generować wyjścia różnej wielkości dla wejść o jednakowej wielkości: countNOfAKind ([3,2]) = [2] (ponieważ istnieją dwie samotne liczby (3 i 2)), countNOfAKind ([2,2]) = [0, 1] (ponieważ nie ma samotnej liczby i jednej pary.
Pasbi