Orden de conjuntos de Mia

9

El juego de dados Mia presenta un orden muy trivial de conjuntos de tamaño dos:

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

En general, el orden dentro de una tupla no importa {x,y}={y,x}, {1,2}es mayor que cualquier otra cosa, los pares son mayores que los que no son pares y el valor numérico decide en caso de empate.

Ahora suponga que quiere usar ndados. Además, los dados tienen mcaras.

Ejemplo:

  • {1,5,3,4} < {1,2,6,3} desde 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} ya que ambos conjuntos tienen cada par y 611> 522

En pocas palabras, {1, ..., n}es mayor que cualquier otra cosa. Deje p > q, entonces p-de-uno-tipo es mayor que q-de-uno-bueno. En caso de empate, el segundo (, tercero, ...) - el más largo de su tipo gana. Finalmente, si aún no se puede tomar una decisión, gana el mayor valor numérico. El valor numérico de un conjunto es el número entero más grande que puede construir a partir de los números disponibles en el conjunto, utilizando la concatenación. Ejemplo:

  • {2,5,4,3} se convierte en 5432
  • {4,11,3,4} se convierte en B443 (> se permiten dados de 6 caras, B = 11)

Su tarea es escribir el programa más pequeño posible (es decir, función) en el idioma de su elección, que, dados dos contenedores (lista, matriz, conjunto, ...) devuelve si gana el primero o el segundo.

Nota: puede suponer que los dos contenedores tienen la misma longitud y contienen solo enteros positivos, pero nada más. Especialmente pueden no estar ordenados. El valor de retorno puede ser cualquier cosa, por ejemplo, {-1, 0, 1} para {primeras victorias, empate, segundas victorias}.

pasbi
fuente
1
La cual uno gana de {1,1,6}, {2,2,5}? ¿Compara el valor numérico del mayor p-of-a-kind o de cualquier dado?
Martin Ender
1
Permítame verificar si mi comprensión del orden es correcta: Primero, {1, ..., n} es el más alto. Para cada lista, tome el valor más común, y de valores igualmente comunes tome el más grande. Si una lista tiene más de eso, gana. Si es igualmente común, el que sea mayor gana. Si es igual tanto en lo común como en el valor, elimine todos los de cada lista y compare nuevamente.
xnor
@ Martin: Excelente pregunta. Supongo que no hay una decisión "canónica" sobre eso, y dado que mi programa de julia dice que {1,1,6} gana sobre {2,2,5}, entonces es solo eso.
pasbi
@xnor: Sí, sin embargo, considera el comentario de Martin y mi respuesta.
pasbi
@oVooVo Oh, sí, eso tiene sentido teniendo en cuenta su ejemplo en el que simplemente los ordena por valor numérico después de ordenar los dígitos de mayor a menor.
Martin Ender

Respuestas:

2

Jalea , 16 bytes

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

Toma una lista de listas, cada una de las cuales representa una tirada (por lo que puede ser más de dos si lo desea) y devuelve una lista de los ganadores.

Pruébalo en línea! ... alternativamente, aquí hay una versión que clasifica los rollos de más débil a más fuerte.

¿Cómo?

Ṣ⁼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
fuente
@oVooVo Mientras intentaba jugar más al golf, me di cuenta de eso 1,1,2y 1,2,2se consideran iguales, pero la especificación tampoco los distingue actualmente.
Jonathan Allan
@oVooVo después de una inspección adicional, el ejemplo tiene {1,1,5,6} < {1,1,5,5}dónde 6 > 5. ¿Podrías aclarar?
Jonathan Allan
@oVooVo Tal vez debería ser como este - He sustituido la "selección máxima", ÐṀcon una especie, Þpara propósitos de prueba - con ayuda de los elementos del ejemplo que los ordena en el mismo orden. El orden utilizado es: primero por si es "top-dog", luego por conteos de caras iguales descendentes y finalmente por caras únicas descendentes.
Jonathan Allan
{1,1,5,5} tiene dos "2 en su tipo": (1,1) y (5,5). {1,1,5,6} tiene solo un "2 en su tipo". Por lo tanto, {1,1,5,5} gana. El valor no importa aquí. Del mismo modo, {1,1,2,2}> {4,5,6,6}.
pasbi
{1,2,2}> {1,1,2}. Como ambos tienen un 2 en su tipo, se aplica el desempate numérico. {1,2,2} => 221 y {1,1,2} => 211. Obviamente 221 es mayor que 211. Aclararé esto en las especificaciones.
pasbi
2

JavaScript (ES6), 162 bytes

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

Explicación: Toma dos matrices como parámetros. gconvierte cada matriz en una lista de recuentos. Luego se verifica la lista para ver si corresponde a un conjunto 1..n. Los recuentos se ordenan y los valores ordenados se concatenan. Luego se comparan los dos resultados. El valor de retorno es un entero positivo si gana la segunda matriz y un entero negativo si gana la primera matriz; de lo contrario, se devuelve el valor falso de JavaScript undefined.

Neil
fuente
Su programa dice {1,1,6} <{2,2,5}, lo cual está mal.
pasbi
@oVooVo Lo siento, debo haber entendido mal las reglas (pensé que rompiste los lazos en función del valor numérico del más largo de su tipo).
Neil
0

PHP 333 Bytes

Supongo que hay menos dados que caras para el valor más alto como calle que comienza con 1

Yo hago un poco más. La entrada es una matriz con más de dos valores. La salida es la matriz ordenada.

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

Descompostura

$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
fuente
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

Legible:

  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
fuente
¿Por qué estás comparando longitudes? Las instrucciones dicen "los dos contenedores tienen la misma longitud". ¿Me estoy perdiendo de algo?
DavidC
Eliminé la comparación de longitud en la línea 31. No era necesario, pero tampoco dolía. La comparación en la línea 15 es necesaria, ya que cmpLex no solo se usa en la línea 40 para comparar las entradas sin procesar, sino también en la línea 38 para comparar el resultado de countNOfAKind. Sin embargo, esa función puede producir salidas de diferentes tamaños para entradas de igual tamaño: countNOfAKind ([3,2]) = [2] (porque hay dos números solitarios (3 y 2)), countNOfAKind ([2,2]) = [0, 1] (porque no hay un número solitario y un par.
pasbi