Reihenfolge der Mia-Sets

9

Das Würfelspiel Mia führt eine sehr nicht triviale Reihenfolge von Sätzen der Größe zwei ein:

{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}

Im Allgemeinen spielt die Reihenfolge innerhalb eines Tupels keine Rolle {x,y}={y,x}, {1,2}ist größer als alles andere, Paare sind größer als Nichtpaare und der numerische Wert entscheidet im Falle eines Gleichstands.

Angenommen, Sie möchten nWürfel verwenden. Auch die Würfel haben mGesichter.

Beispiel:

  • {1,5,3,4} < {1,2,6,3} seit 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} da beide Sätze jeweils ein Paar und 611> 522 haben

Kurz gesagt, {1, ..., n}ist größer als alles andere. Sei p > q, dann ist p-of-a-kind größer als q-of-a-kind. Bei einem Unentschieden gewinnt das zweite (, dritte, ...) - längste Unikat. Wenn noch keine Entscheidung getroffen werden konnte, gewinnt der größte Zahlenwert. Der numerische Wert einer Menge ist die größte Ganzzahl, die Sie mithilfe der Verkettung aus den verfügbaren Zahlen in der Menge erstellen können. Beispiel:

  • {2,5,4,3} wird 5432
  • {4,11,3,4} wird zu B443 (> 6-seitige Würfel sind erlaubt, B = 11)

Ihre Aufgabe ist es, das kleinstmögliche Programm (dh die kleinste Funktion) in der Sprache Ihrer Wahl zu schreiben, das bei zwei Containern (Liste, Array, Set, ...) zurückgibt, ob der erste oder der zweite gewinnt.

Hinweis: Sie können davon ausgehen, dass die beiden Container dieselbe Länge haben und nur positive Ganzzahlen enthalten, sonst nichts. Insbesondere können sie nicht sortiert werden. Der Rückgabewert kann ein beliebiger Wert sein, z. B. {-1, 0, 1} für {erste Siege, Unentschieden, zweite Siege}.

pasbi
quelle
1
Welche Siege {1,1,6}, {2,2,5}? Vergleichen Sie den numerischen Wert des größten p-of-a-kind oder eines Würfels?
Martin Ender
1
Lassen Sie mich überprüfen, ob mein Verständnis der Reihenfolge richtig ist: Erstens ist {1, ..., n} am höchsten. Nehmen Sie für jede Liste den gebräuchlichsten Wert und von gleich gemeinsamen Werten den größten. Wenn eine Liste mehr davon enthält, gewinnt sie. Wenn es gleich häufig ist, gewinnt das, was größer ist. Wenn sowohl die Gemeinsamkeit als auch der Wert gleich sind, entfernen Sie alle aus jeder Liste und vergleichen Sie sie erneut.
xnor
@ Martin: Ausgezeichnete Frage. Ich denke, es gibt keine "kanonische" Entscheidung darüber, und da mein Julia-Programm sagt, dass {1,1,6} über {2,2,5} gewinnt, ist es genau das.
Pasbi
@xnor: Ja, aber beachte Martins Kommentar und meine Antwort.
Pasbi
@oVooVo Oh ja, das macht tatsächlich Sinn, wenn man Ihr Beispiel betrachtet, in dem Sie sie einfach nach numerischen Werten sortieren, nachdem Sie die Ziffern vom größten zum kleinsten sortiert haben.
Martin Ender

Antworten:

2

Gelee , 16 Bytes

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

Nimmt eine Liste von Listen, von denen jede einen Wurf darstellt (kann also mehr als zwei sein, wenn gewünscht) und gibt eine Liste der Gewinner zurück.

Probieren Sie es online aus! ... alternativ ist hier eine Version, die stattdessen die Rollen von der schwächsten zur stärksten sortiert.

Wie?

Ṣ⁼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
quelle
@oVooVo Beim Versuch, dies mehr zu spielen, habe ich das bemerkt 1,1,2und werde 1,2,2als gleich angesehen, aber die Spezifikation unterscheidet sie derzeit auch nicht.
Jonathan Allan
@oVooVo bei weiterer Prüfung hat das Beispiel {1,1,5,6} < {1,1,5,5}wo 6 > 5. Könnten Sie das klarstellen?
Jonathan Allan
@oVooVo Vielleicht sollte es sein , diese - ich die „maximale Auswahl“ ersetzt habe, ÐṀmit einer Art, Þfür die Zwecke testen - die Elemente aus dem Beispiel unter Verwendung es sie in derselben Reihenfolge sortiert. Die verwendete Reihenfolge ist: zuerst nach "Top-Dog", dann nach Anzahl gleich absteigender Gesichter und schließlich nach absteigenden eindeutigen Gesichtern.
Jonathan Allan
{1,1,5,5} hat zwei "2-of-a-kind": (1,1) und (5,5). {1,1,5,6} hat nur ein "2-of-a-kind". Somit gewinnt {1,1,5,5}. Der Wert spielt hier keine Rolle. Ebenso {1,1,2,2}> {4,5,6,6}.
Pasbi
{1,2,2}> {1,1,2}. Da beide ein 2-Unikat haben, gilt das numerische Brechen. {1,2,2} => 221 und {1,1,2} => 211. Offensichtlich ist 221 größer als 211. Ich werde dies in den Spezifikationen klarstellen.
Pasbi
2

JavaScript (ES6), 162 Byte

(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)

Erläuterung: Nimmt zwei Arrays als Parameter. gkonvertiert jedes Array in eine Liste von Zählungen. Die Liste wird dann überprüft, um festzustellen, ob sie einem Satz entspricht 1..n. Die Zählungen werden sortiert und die sortierten Werte werden verkettet. Die beiden Ergebnisse werden dann verglichen. Der Rückgabewert ist eine positive Ganzzahl, wenn das zweite Array gewinnt, und eine negative Ganzzahl, wenn das erste Array gewinnt, andernfalls wird der falsche JavaScript-Wert undefinedzurückgegeben.

Neil
quelle
Ihr Programm sagt {1,1,6} <{2,2,5}, was falsch ist.
Pasbi
@oVooVo Entschuldigung, ich muss die Regeln falsch verstanden haben (ich dachte, Sie haben Verbindungen abgebrochen, basierend auf dem numerischen Wert des längsten Unikats).
Neil
0

PHP 333 Bytes

Ich gehe davon aus, dass es weniger Würfel gibt als Gesichter für den höchsten Wert als Straße, die mit 1 beginnt

Ich mache ein bisschen mehr. Die Eingabe ist ein Array mit mehr als zwei Werten. Die Ausgabe ist das sortierte Array.

<? $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);

Nervenzusammenbruch

$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
quelle
0

Julia (489 Bytes)

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

Lesbar:

  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
quelle
Warum vergleichst du Längen? Die Anweisungen sagen "die zwei Behälter haben die gleiche Länge". Vermisse ich etwas
DavidC
Ich habe den Längenvergleich in Zeile 31 entfernt. Es war nicht notwendig, tat aber auch nicht weh. Der Vergleich in Zeile 15 ist erforderlich, da cmpLex nicht nur in Zeile 40 zum Vergleichen der Roheingaben verwendet wird, sondern auch in Zeile 38, um das Ergebnis von countNOfAKind zu vergleichen. Diese Funktion kann jedoch unterschiedlich große Ausgänge für gleich große Eingänge erzeugen: countNOfAKind ([3,2]) = [2] (da es zwei einsame Zahlen gibt (3 und 2)), countNOfAKind ([2,2]) = [0, 1] (weil es keine einsame Nummer und ein Paar gibt.
Pasbi