Puntuación del juego olímpico [cerrado]


9

El desafío es escribir un programa de código de golf que, dados n números reales positivos del 0 al 10 (formato xy, y solo puede ser 0 o 5: 0, 0.5, 1, 1.5, 2, 2.5 ... 9.5 y 10), descarta los valores más bajos y más altos (solo uno, aunque se repitan) y muestra el promedio del resto, en formato xy (y puede ser 0 o 5, redondeado al más cercano), similar a la puntuación de algunos Juegos Olímpicos.

Ejemplos: Entrada -> Salida

6 -> 6

6.5, 9 -> 8

9, 7, 8 -> 8

6, 5, 7, 8, 9 -> 7

5, 6.5, 9, 8, 7 -> 7

6.5, 6.5, 9.5, 8, 7 -> 7

5, 6.5, 7.5, 8.5, 9.5 -> 7.5

Notas: Si la entrada es solo dos números, no descarte ninguno, solo promedie. Si la entrada es un número, la salida es la misma.

Aclarando la regla de redondeo (lo siento, poco confuso):

x.01 a x.25 redondeado a x.0

x.26 a x.75 redondeado a x.5

x.76 a x.99 redondeado a x + 1.0


2
¿Cómo es válido el segundo ejemplo (6.5, 9 => 8)? Si arroja lo alto y lo bajo, ¿no quedan valores para promediar?
Jeff Zeitlin

2
¡Bienvenido a Code Golf SE!
AdmBorkBork

66
Sugeriría que no manejemos datos no válidos, los Juegos Olímpicos tendrán un número fijo de jueces mayor que dos para tal evento. (El buceo elimina las cuatro extremidades de siete, por ejemplo)
Jonathan Allan el

77
Su ejemplo 6.5, 9no está de acuerdo con su especificación que indica que x.75 se redondea a x.5.
Nick Kennedy el

77
Hasta que se resuelva el redondeo, he votado para cerrar.
Nick Kennedy el

Respuestas:


5

Jalea , 12 bytes

ṢṖḊȯµÆmḤær0H

Pruébalo en línea!

    µ           Take
Ṣ               the input sorted,
 Ṗ              without its last
  Ḋ             or first element,
   ȯ            or the unchanged input if that's empty,
     Æm         then calculate the mean,
       Ḥ        double it,
        ær      round it to the nearest multiple of
          0     10^-0 (= 1),
           H    and halve it.

Una versión que redondea mitades hacia abajo, de acuerdo con la especificación a expensas del segundo caso de prueba:

Jalea , 12 bytes

ṢṖḊȯµÆmḤ_.ĊH

Pruébalo en línea!

El método de redondeo aquí es más cercano al de Jonathan Allan:

Ḥ        Double,
 _       subtract
  .      one half,
   Ċ     round up,
    H    and halve.

Resulta que cumple accidentalmente con la actualización de la especificación
Cadena no relacionada

@NickKennedy Si no redondeo , ese caso produce 6.8, que debería redondear hasta 7 de acuerdo con las especificaciones desde 6.75 <6.8 ≤ 7.
Cadena no relacionada

1
lo siento uno dos muchos 7s. Quise decir[1,10,6,7,7,7]
Nick Kennedy el

1
Oh, sí, eso sí hace mal.
Cadena no relacionada

4

Retina , 86 bytes

\.5
__
\d+
*4*__
O`_+
_+ (.+) _+
$1
O`.
^ *
$.&*__:
(_+):(\1{4})*(\1\1)?_*
$#2$#3*$(.5

Pruébalo en línea! El enlace incluye casos de prueba. Explicación:

\.5
__
\d+
*4*__

Dado que Retina no puede manejar fácilmente números fraccionales o cero, cada número se representa en unario como 1 más de 4 veces el valor. Por lo .5tanto, el se expande a 2 _s, mientras que el se *4*_aplica a la parte del número entero, y _se agrega un final .

O`_+

Ordenar los números en orden.

_+ (.+) _+
$1

Si hay al menos tres números, descarte el primero (el más pequeño) y el último (el más grande).

O`.

Ordena los espacios al inicio, sumando también los números.

^ *
$.&*__:

Cuente el número de espacios y agregue _y un separador. Esto representa el número por el que tenemos que dividir.

(_+):(\1{4})*(\1\1)?_*
$#2$#3*$(.5

Divida la suma entre el número de números, teniendo en cuenta el hecho de que estamos trabajando en múltiplos de 4 veces el número original, de modo que las partes enteras y decimales se puedan extraer directamente. Esta es una división truncada, pero afortunadamente porque agregamos un extra _a cada número, el resultado incluye efectivamente un extra de 0.25, lo que nos da el redondeo que queremos.


3

EDITAR: Esta respuesta ya no es válida. Fue válido durante aproximadamente medio minuto después de su publicación.

Jalea , 10 bytes

ṢḊṖȯƊÆmḤḞH

Pruébalo en línea!


parece producir el resultado incorrecto para [6.5,9].
Cadena no relacionada

1
@UnrelatedString En el momento en que publiqué esto, era la salida correcta. Parece que OP ha cambiado la regla ahora.
Erik the Outgolfer

1
Sí, hice un desastre, lo siento :(
JuanCa

1
Según mi comentario en la publicación de Arnauld, básicamente también tenía este algoritmo, así que, después de obtener una aclaración sobre las reglas, publiqué el mío :)
Jonathan Allan

1
@JonathanAllan, que es lo mismo que las cadenas no relacionadas. : P
Erik the Outgolfer

3

J , 36 35 bytes

[:(1r4<.@+&.+:+/%#)}:@}.^:(2<#)@/:~

Pruébalo en línea!

Pidió prestado el truco de doble / piso / reducir a la mitad para redondear a 0.5 incrementos de Cadena no relacionada.



3

JavaScript (V8) , 213 211 189 176 bytes

Editar: -2 bytes porque terminé ;\n}cuando podía terminar con un }error tonto.

Edición 2: -22 bytes más leyendo sobre consejos generales de golf JS. Logré sacar paréntesis de mis ternar anidados en la rfunción de redondeo, y utilicé operaciones matemáticas bit a bit para evitar usar Math.flooryMath.ceil

Edición 3: -13 bytes porque pude reemplazar la a.lengthfunción de acceso directo con solo llamadas directas a.lengthpara ahorrar 4 bytes. También moví la función g () directamente a la declaración de devolución, ya que solo se usó una vez, lo que eliminó el resto de los bytes.

a=>{s=i=>a.splice(i,1)
e=_=>a.reduce((t,i)=>t+=i)/a.length
r=n=>(m=n%1,m<0.75?m>0.25?~~(n)+0.5:~~(n):n%1?-~n:n)
return a.length>2?r((a.sort((x,y)=>x-y),s(0),s(-1),e())):r(e())}

Pruébalo en línea!

Estoy seguro de que se puede mejorar, ya que soy bastante nuevo, pero fue divertido resolverlo. Creo que las principales cosas que podrían mejorarse son mis métodos / lógica de redondeo y el hecho de que la función principal utiliza un cuerpo de función ( { }yreturn ).

Había una cosa en la pregunta que era inconsistente con los ejemplos y no estaba realmente seguro de cómo manejarlo. Lo implementé para que sea consistente con los ejemplos, pero no refleja exactamente las reglas de redondeo especificadas, aquí está el ejemplo que encontré que es inconsistente:

6.5, 9 -> 8

Dices que debería ser 8, aunque el promedio es 7.75. En las reglas de redondeo, usted dice que tiene que ser al menos .76 para ir a +1. Elegí reflejar los ejemplos en lugar de sus reglas de redondeo, por lo que> = 0.75 para ir a +1, y <= 0.25 para ir a -1, entre 0.25 y 0.75 (exclusivo) para .5. Si las especificaciones de redondeo cambian, mi código debería poder adaptarse sin cambiar el número de bytes, simplemente cambiando los números en la función de redondeor , y tal vez el orden de la declaración ternaria dependiendo de las reglas.

Ligeramente inexpresivo con la explicación (las operaciones matemáticas se cambiaron a operaciones bit a bit y g () está directamente en la declaración de devolución)

a => { // a is the input array
    s = i=>a.splice(i, 1); // shortcut to remove index i for 1 element
    e = _=>a.reduce((t, i) => t += i) / a.length; // get array avg
    g = _=>(a.sort((x,y)=>x-y), s(0), s(-1), e()); // what to execute when > 2: sort, remove 1st/last, get avg
    t = n=>Math.floor(n); // Math.floor shortcut

    // apply olympic rounding to number by checking the value of n%1
    r = n=>(m=n%1,m < 0.75 ? (m > 0.25 ? t(n) + 0.5 : t(n)) : Math.ceil(n));

    // if arr length > 2: round g(), otherwise round e()
    return a.length > 2 ? r(g()) : r(e());
}

1
He publicado un comentario sobre la pregunta sobre la discrepancia entre el ejemplo y las especificaciones.
Nick Kennedy el

1
por qué no usa l = a.length y cada vez que desea una longitud simplemente llame a l, aquí no sé por qué está usando la función aquí
Chau Giang

@chaugiang Eso ahorraría el valor, no una referencia a a.length, por lo que dado que lo estoy usando antes y después de las operaciones que modifican la matriz, lquedaría inválido tan pronto como se cambie la matriz. LMK si está mal. Resulta que en realidad me ahorraría 3 bytes ahora para reemplazar esto con a.lengthllamadas directas . Cuando lo escribí inicialmente, no sabía que JS le permitía usar números negativos para el empalme, por lo que inicialmente mi segundo empalme fue en s(l()-1)lugar de solo s(-1), y cuando tuve 3 llamadas de longitud, guardó bytes para tener este acceso directo. Ahora ya no vale la pena. Gracias, se actualizará!
Matsyir

2

Jalea , 12 bytes

ṢṖḊȯ⁸ÆmḤ+.ḞH

Un enlace monádico que acepta una lista de números que produce un número.

Pruébalo en línea!

¿Cómo?

ṢṖḊȯ⁸ÆmḤ+.ḞH - Link, list of numbers, X
Ṣ            - sort X
 Ṗ           - remove the right-most
  Ḋ          - remove the left-most
    ⁸        - chain's left argument, X
   ȯ         - logical OR (if we have nothing left use X instead)
     Æm      - arithmetic mean
       Ḥ     - double
         .   - literal half
        +    - add
          Ḟ  - floor
           H - halve

1
@NickKennedy 34/5> 6.75
Jonathan Allan el

1
Lo siento significaba 1,10,7,7,7,6donde 27/4 = 6.75
Nick Kennedy

1
No, el problema es el redondeo poco convencional en la especificación. De hecho, su respuesta también obtiene [1,10,7,6,6,6] incorrecta (debería ser 6, no 6.5), mientras que la versión original de @ UnrelatedString lo hace bien porque Python se redondea (12.5 se redondea a 12 ) Como he señalado en un comentario sobre la pregunta, uno de los ejemplos también viola las especificaciones de redondeo. También tenga en cuenta que las fracciones de potencias de 2 no deberían ser un problema para la inexactitud de coma flotante porque tienen una representación binaria exacta.
Nick Kennedy el

1
Siento que la especificación es incómoda y posiblemente involuntaria. (¿A qué se redondea x.251, etc., son los límites inclusivos, exclusivos o depende de nosotros?) ... y luego está el comentario "Me di cuenta de que es un poco confuso, redondeémoslos al más cercano , dependiendo de la plataforma ". Tal vez deberíamos VTC como poco claro?
Jonathan Allan

1
sí, de acuerdo con VTC por ahora
Nick Kennedy


2

Rápido , 203 bytes

func a(b:[Double])->Void{var r=0.0,h=0.0,l=11.0
b.forEach{(c)in h=c>h ?c:h;l=c<l ?c:l;r+=c}
var d=Double(b.count)
r=d>2 ?(r-h-l)/(d-2.0):r/d
d=Double(Int(r))
r=r-d<=0.25 ?d:r-d<=0.75 ?d+0.5:d+1
print(r)}

Pruébalo en línea!


2

PHP , 110 bytes

Parece que PHP tiene algunas buenas funciones integradas para esto. Simplemente array_sum todo, entonces si hay más de dos elementos, reste los valores min () y max () y divídalos entre 2 menos que la longitud de la matriz.

Para el redondeo, utilizo la función round () con el indicador PHP_ROUND_HALF_DOWN (que = 2) en el doble del promedio, y luego lo divido por 2 para que vaya en incrementos de 0.5

EDITAR: para el caso de [6.5, 9] estoy siguiendo la regla establecida de que 7.75 se redondea a 7.5 y no 8 como en el ejemplo original dado.

function s($s){$c=count($s);$t=array_sum($s);if($c>2){$c-=2;$t-=min($s)+max($s);}return round($t/$c*2,0,2)/2;}

Pruébalo en línea!


1
¡Bien hecho! ¡Quería publicar una respuesta de PHP, pero las reglas tenían muchos defectos o cambios que acabo de renunciar! Modifiqué un poco su código y guardé 10 bytes: ¡ Pruébelo en línea!
Noche2

2

Zsh , 141 136 bytes

Pruébalo en línea!   141bytes

setopt FORCE_FLOAT
m=$1 n=$1 a=$#
for x ((t+=x))&&m=$[x>m?x:m]&&n=$[x<n?x:n]
s=$[2*(a>2?(t-m-n)/(a-2):t/a)]
<<<$[(s^0+(s-s^0>.5?1:0))/2]

La solución sigue las últimas especificaciones. Guardado algunos bytes usando implícito($@) .

Implícitamente iteramos sobre los argumentos con for x, construimos un total acumulado ty también encontramos máximos, mínimos m, n. Si el número de argumentos aes mayor que 2, descartamos my ndel promedio. ses 2 veces el promedio resultante. Si la mantisa de ses mayor que 0.5, redondea shacia arriba, de lo contrario trunca con s^0. Finalmente, divide por 2 y salida.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.