Pontuação dos Jogos Olímpicos [fechado]


9

O desafio é escrever um programa de código de golfe que, considerando n números reais positivos de 0 a 10 (formato xy, y possa ser apenas 0 ou 5: 0, 0,5, 1, 1,5, 2, 2,5 ... 9,5 e 10), descarte os valores mais altos e mais baixos (apenas um, mesmo que sejam repetidos) e mostra a média dos demais, no formato xy (y pode ser 0 ou 5, arredondado para o mais próximo), semelhante a algumas pontuações nos Jogos Olímpicos.

Exemplos: Entrada -> Saída

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: Se a entrada tiver apenas dois números, não descarte nenhum, apenas faça a média deles. Se a entrada for um número, a saída será a mesma.

Esclarecendo a regra de arredondamento (desculpe, pouco confuso):

x.01 a x.25 arredondam para x.0

x.26 a x.75 arredondado a x.5

x.76 a x.99 arredondado para x + 1.0


2
Como o segundo exemplo (6.5, 9 => 8) é válido? Se você jogar fora o alto e o baixo, não há valores para a média?
Jeff Zeitlin

2
Bem-vindo ao Code Golf SE!
AdmBorkBork 13/09/19

6
Eu sugiro que não lidemos com informações inválidas, a Olimpíada terá um número fixo de juízes maior que dois para esse evento. (Mergulho remove as quatro extremidades de sete por exemplo)
Jonathan Allan

7
Seu exemplo 6.5, 9não concorda com suas especificações, o que indica que x.75 arredonda para x.5.
Nick Kennedy

7
Até que o arredondamento seja classificado, votei para fechar.
Nick Kennedy

Respostas:


5

Jelly , 12 bytes

ṢṖḊȯµÆmḤær0H

Experimente online!

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

Uma versão que arredonda pela metade para baixo, de acordo com as especificações às custas do segundo caso de teste:

Jelly , 12 bytes

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

Experimente online!

O método de arredondamento aqui é mais próximo do de Jonathan Allan:

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

Só acontece a acidentalmente cumprir com a atualização para a especificação
Alheios Cordas

@NickKennedy Se eu não arredondar , esse caso produz 6,8, que deve arredondar para 7 de acordo com as especificações desde 6,75 <6,8 ≤ 7.
String não relacionada

1
desculpe um dois muitos 7s. Eu quis dizer[1,10,6,7,7,7]
Nick Kennedy

1
Ah, sim, isso faz errado.
String não relacionada

4

Retina , 86 bytes

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

Experimente online! O link inclui casos de teste. Explicação:

\.5
__
\d+
*4*__

Como a Retina não pode lidar facilmente com números fracionários ou zero, cada número é representado em unário como 1 mais que 4 vezes o valor. O .5expande, portanto, a 2 _s, enquanto que o *4*_aplica-se a todo o número da peça, e uma final _é sufixo.

O`_+

Classifique os números em ordem.

_+ (.+) _+
$1

Se houver pelo menos três números, descarte o primeiro (menor) e o último (maior).

O`.

Ordene os espaços para o início, somando também os números.

^ *
$.&*__:

Conte o número de espaços e adicione _e um separador. Isso então representa o número pelo qual devemos dividir.

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

Divida a soma pelo número de números, permitindo o fato de estarmos trabalhando em múltiplos de 4 vezes o número original, para que as partes inteiras e decimais possam ser extraídas diretamente. Esta é uma divisão truncante, mas, felizmente, porque adicionamos um extra _a cada número, o resultado inclui efetivamente 0,25 extra, dando-nos o arredondamento que queremos.


3

EDIT: Esta resposta tornou-se inválida. Foi válido por cerca de meio minuto após a publicação.

Gelatina , 10 bytes

ṢḊṖȯƊÆmḤḞH

Experimente online!


parece produzir o resultado errado para [6.5,9].
String não relacionada

1
@UnrelatedString No momento em que publiquei isso, era a saída correta. Parece que o OP mudou a regra agora.
Erik the Outgolfer

1
Sim, eu fiz uma bagunça, desculpe :(
JuanCa 13/09/19

1
De acordo com o meu comentário no post de Arnauld, basicamente eu também tinha esse algoritmo, então, depois de obter esclarecimentos sobre as regras, publiquei o meu :)
Jonathan Allan

1
@ JonathanAllan O mesmo que o de String não relacionada. : P
Erik, o Outgolfer

3

J , 36 35 bytes

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

Experimente online!

Emprestado o truque duplo / piso / metade para arredondar para incrementos de 0,5 a partir de String não relacionada.



3

JavaScript (V8) , 213 211 189 176 bytes

Edit: -2 bytes, porque eu terminei com ;\n}quando eu poderia terminar com um} erro bobo.

Edite 2: -22 mais bytes lendo sobre dicas gerais de golfe em JS. Consegui tirar parênteses de meus ternários aninhados na rfunção de arredondamento e usei operações matemáticas bit a bit para evitar o uso Math.flooreMath.ceil

Edite 3: -13 bytes porque consegui substituir a a.lengthfunção de atalho por apenas chamadas diretas a.lengthpara economizar 4 bytes. Também movi a função g () diretamente para a declaração de retorno, pois ela foi usada apenas uma vez, o que removeu o restante dos 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())}

Experimente online!

Tenho certeza de que pode ser melhorado, pois sou bastante novo, mas foi divertido resolver este. Acredito que as principais coisas que poderiam ser melhoradas são minha lógica / métodos de arredondamento e o fato de a função principal usar um corpo de função ({ } ereturn ).

Havia uma coisa na pergunta que era inconsistente com os exemplos e eu não tinha muita certeza de como lidar com isso. Eu o implementei para que seja consistente com os exemplos, mas não reflete exatamente as regras de arredondamento especificadas. Aqui está o exemplo que achei inconsistente:

6,5, 9 -> 8

Você diz que deve ser 8, embora a média seja 7,75. Nas regras de arredondamento, você diz que deve ter pelo menos 0,76 para ir +1. Eu escolhi refletir os exemplos em vez de suas regras de arredondamento, então> = 0,75 para ir +1 e <= 0,25 para -1, entre 0,25 e 0,75 (exclusivo) para 0,5. Se as especificações de arredondamento forem alteradas, meu código poderá adaptar-se sem alterar o número de bytes, apenas alterando os números na função de arredondamentor e, talvez, a ordem da declaração ternária, dependendo das regras.

Um pouco sem explicação com explicação (as operações matemáticas foram alteradas para operações bit a bit eg () está diretamente na declaração de retorno)

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
Publiquei um comentário sobre a pergunta sobre a discrepância entre o exemplo e as especificações.
Nick Kennedy

1
por que você não usa l = a.length e toda vez que você quer um comprimento simplesmente chame l, aqui não sei por que você está usando a função aqui
Chau Giang

@chaugiang Isso salvaria o valor, não uma referência a a.length , portanto, como o estou usando antes e depois das operações que modificam a matriz, lficará inválido assim que a matriz for alterada. LMK se estiver errado. Acontece que na verdade me economizaria 3 bytes agora para substituir isso por a.lengthchamadas diretas . Quando o escrevi inicialmente, eu não sabia que o JS permitia que você usasse números negativos para emenda, então, inicialmente, minha segunda emenda foi em s(l()-1)vez de apenas s(-1), e quando eu tinha três chamadas de comprimento, ele salvou bytes para ter esse atalho. Agora não vale mais a pena. Obrigado, irá atualizar!
Matsyir 14/09/19

2

Gelatina , 12 bytes

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

Um link monádico que aceita uma lista de números que gera um número.

Experimente online!

Quão?

ṢṖḊȯ⁸Æ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

1
Desculpe significava 1,10,7,7,7,6onde 27/4 = 6,75
Nick Kennedy

1
Não, o problema é o arredondamento levemente não convencional nas especificações. De fato, sua resposta também [1,10,7,6,6,6] está errada (deve ser 6 e não 6,5), enquanto a versão original do @ UnrelatedString acerta essa porque o Python arredonda para par (então 12,5 arredonda para 12 ) Como já assinalei em um comentário sobre a pergunta, um dos exemplos também viola a especificação de arredondamento. Observe também que frações de potências de 2 não devem ser um problema para imprecisão de ponto flutuante, porque elas têm uma representação binária exata.
Nick Kennedy

1
Eu sinto que a especificação é estranha e possivelmente não intencional. (O que x.251 arredonda para, etc; os limites são inclusivos, exclusivos ou depende de nós?) ... e depois há o comentário "Eu percebi que é um pouco confuso, vamos arredondá-los para o mais próximo , dependendo da plataforma ". Talvez devêssemos VTC tão claro?
Jonathan Allan

1
sim, concorde com o VTC por enquanto
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)}

Experimente online!


2

PHP , 110 bytes

Parece que o PHP tem algumas boas funções internas para isso. Eu apenas array_sum a coisa toda, então se houver mais de dois elementos, subtraia os valores min () e max () e divida por 2 menos que o comprimento da matriz.

Para o arredondamento, uso a função round () com o sinalizador PHP_ROUND_HALF_DOWN (que = 2) no dobro da média e, em seguida, divido-o por 2, para incrementos de 0,5

EDIT: no caso de [6.5, 9], estou seguindo a regra declarada de que 7,75 arredonda para 7,5 e não 8, como no exemplo 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;}

Experimente online!


1
Bem feito! Eu queria postar uma resposta PHP, mas as regras tinham muitas falhas ou alterações que acabei de desistir! Ajustei um pouco o seu código e salvei 10 bytes: Experimente online!
precisa saber é

2

Zsh , 141 136 bytes

experimente online!   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]

A solução segue as especificações mais recentes. Salvou alguns bytes usando implícito($@) .

Nós iteramos implicitamente sobre os argumentos com for xe construímos um total corrente te também encontramos máximos, mínimos m, n. Se o número de argumentos afor maior que 2, descartamos me nda média. sé 2x a média resultante. Se a mantissa de sfor maior que 0,5, arredondar para scima, caso contrário truncar com s^0. Finalmente, divida por 2 e faça a saída.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.