Encolhendo números


10

A entrada é uma matriz de (pelo menos 3, no máximo 20) números inteiros diferentes. Cada número inteiro é maior que -1000 e menor que 1000.

Sua tarefa é reduzir os números "mapeando-os linearmente" de 0.0para 1.0. Isso significa que o menor número da matriz será mapeado para 0,0, o maior para 1,0.

Você obtém a matriz como um parâmetro (dentro de uma função) ou argumentos stdin / program (você pode escolher). Imprima o resultado no formato double1;double2;double3;.... A saída deve ter a mesma ordem que a entrada .

Se desejar, você pode arredondar a saída para 2 dígitos após o ponto decimal. Deve haver pelo menos 1 dígito após o ponto decimal.

O uso de funções internas (funções que diminuem os números para você, como mathematicas Rescale) não é permitido .

Exemplos:

Input              Output
[5,-20,30]         0.5;0.0;1.0
[1,2,3,4,5]        0.0;0.25;0.5;0.75;1.0
[0,5,100,400]      0.0;0.01;0.25;1.0

(A última saída é arredondada, caso contrário, seria 0.0;0.0125;0.25;1.0)


2
Então, mesmo que escrevamos uma função, o resultado deve ser impresso? (Ao contrário de retornar uma matriz correspondente de duplas.)
Martin Enders

@ MartinBüttner Sim, eles precisam ser impressos. Funções internas não são permitidas.
precisa saber é o seguinte

"o uso de funções internas (como o mathematicas Rescale) não é permitido." - isso é muito vago. Quais funções são proibidas? Apenas aqueles que resolvem o problema completo (o que seria uma brecha padrão) são?
John Dvorak

Espere, então, a entrada pode ser um argumento de função, mas a saída deve estar na tela ???
John Dvorak #

11
@Dennis O formato deve corresponder ao mostrado na pergunta. Isso significa que os números são separados por ponto e vírgula.
CommonGuy

Respostas:


5

CJam, 18 bytes

q~_$0=f-_$W=df/';*

Observe que o intérprete online representa erroneamente 0dcomo em 0vez de 0.0.

Exemplo de execução

$ cjam shrink.cjam <<< '[5 -20 30]'; echo
0.5;0.0;1.0
$ cjam shrink.cjam <<< '[1 2 3 4 5]'; echo
0.0;0.25;0.5;0.75;1.0
$ cjam shrink.cjam <<< '[0 5 100 400]'; echo
0.0;0.0125;0.25;1.0

Como funciona

q~                    " P := eval(input())         ";
  _$0=                " S := sorted(P)[0]          ";
      f-              " Q := { X - S : X ∊ P }     ";
        _$W=d         " D := double(sorted(Q)[-1]) ";
             f/       " R := { X / D : X ∊ Q }     ";
               ';*    " print(join(R, ';'))        ";

Minha reação a isso, como uma fonte CJam: Wtf? Explicação necessária ...
edc65 01/10

2
Ótima maneira de obter min e max usando o índice de matriz em vez de popping e, em seguida, trocando as coisas ao redor
Optimizer

Provavelmente é a minha fala fria, mas por que você classifica duas vezes? Uma matriz classificada não deve permanecer classificada se uma constante for subtraída de cada elemento?
Ingo Bürk

@ IngoBürk A matriz classificada não sobrevive ao acesso à matriz, eu acho. O que faz sentido, porque o resultado final não deve ser classificado.
Martin Ender

@ MartinBüttner D'oh. Claro. Precisamos manter a ordem para o resultado. Obrigado!
Ingo Bürk

4

JavaScript, ES6, 81 bytes

Obrigado a @ edc65 pelo toFixedtruque

F=a=>a.map(v=>((v-n)/d).toFixed(2),n=Math.min(...a),d=Math.max(...a)-n).join(';')

Execute-o no Firefox Console mais recente.

Isso cria uma função fque você pode chamar como

F([5,-20,30])

1) por que eval (prompt) quando uma função é permitida? 2) Deve haver pelo menos 1 dígito após o ponto decimal. 3) não há necessidade para armazenar H, apenas de d = Mm
edc65

Atualizada. Embora, recebendo pelo menos 1 dígito após decimal é difícil
Optimizer

If you want, you can round the output to 2 digits after the decimal pointessa é a maneira mais simples eu acho
edc65

@ edc65 Mas não há como converter 1para, 1.0exceto o que eu fiz.
Optimizer

Não. Posso sugerir?
Edc65

4

Python 2, 72 68 63 56 55

Obviamente não é tão conciso quanto as outras respostas, mas de qualquer maneira:

x=input()
m=min(x)
print[(i*1.-m)/(max(x)-m)for i in x]

Exemplo de execução:

[1,100,25,8,0]                  #input
[0.01, 1.0, 0.25, 0.08, 0.0]    #output

Antigo (68 caracteres, escrito em Python 3):

x=eval(input())
y=sorted(x)
print([(i-y[0])/(y[-1]-y[0])for i in x])

Você pode salvar mais um caracter definindo m=min(x).
FryAmTheEggman 01/10/14

4

CJam, 24 23 bytes

l~_$)\(:M\;-\Mf-\df/';*

A entrada deve ser como:

[5 -20 30]

Experimente online aqui Note-se que em linha impressões compilador Double 0como 0única. Execute o interpretador java que imprime corretamente.

Como funciona:

l~                      "Evaluate input and convert each element to double";
  _$                    "Copy the array and sort the copied array";
    )                   "Pop the last element out of the array. This is Max";
     \                  "Swap last two stack elements, bring sorted array on top";
      (:M               "Pop the first element of array and store it in M. This is Min";
         \;             "Bring the remaining of sorted array on top and remove it from stack";
           -\           "Subtract Max and Min and bring the original array to top of stack"
             Mf-        "Push min to stack and subtract it from each array element";
                \df/    "Bring (Double)(Max-Min) to top and divide each array element by it";
                   ';*  "Push the character ; to stack and join the array with it";

11
Ah, é uma ideia muito melhor obter o mínimo e o máximo.
Martin Ender

Isso imprime em 0;0.5;1vez de 0.0;0.5;1.0.
precisa saber é o seguinte

@ Manu - Sim, tentando consertar isso. E quase todas as respostas fazem isso apenas.
Optimizer

2
Você não precisa da correção. O interpretador Java representa o duplo 0 como 0.0.
Dennis

3

C # 92

Executando dentro do LinqPad

void F(int[]a)
{
   double n=a.Min(),d=a.Max()-n;
   a.Select(x=>((x-n)/d).ToString("0.00")).Dump();
}

Teste no LinqPad

void Main()
{
    F(new int[]{5,-20,30});
}
void F(int[]a){double n=a.Min(),d=a.Max()-n;a.Select(x=> ((x-n)/d).ToString("0.00")).Dump();}

Resultado

IEnumerable<String> (3 items)
0,50 
0,00 
1,00 

3

APL (15)

(2⍕+÷⌈/)(+-⌊/)⎕

(ou, sem trens, também 15 caracteres :)

2⍕V÷⌈/V←V-⌊/V←⎕

Isso lê o argumento do teclado e imprime o resultado na tela.

Explicação:

  • : leia uma linha do teclado e avalie-a
  • +-⌊/: subtraia o item mais baixo da matriz de todos os itens da matriz
  • +÷⌈/: divida cada item na matriz pelo item mais alto da matriz
  • 2⍕: formato com duas casas decimais

Teste:

      (2⍕+÷⌈/)(+-⌊/)⎕
⎕:
     5 ¯20 30
 0.50 0.00 1.00
      (2⍕+÷⌈/)(+-⌊/)⎕
⎕:
      1 2 3 4 5
 0.00 0.25 0.50 0.75 1.00
      (2⍕+÷⌈/)(+-⌊/)⎕
⎕:
      0 5 100 400
 0.00 0.01 0.25 1.00

Deve adicionar a contagem de bytes ...
Otimizador

Qual é apenas 24 bytes.
Optimizer

2
@ Otimizador: A menos que a pergunta indique o contrário, todas as respostas são pontuadas usando a codificação que gera a menor contagem de bytes. Há uma página de código APL que representa cada caractere APL por um byte.
Dennis

Corrija-me se estiver fazendo algo errado aqui, mas, por padrão, o code-golf é contado em bytes e mothereff.in/byte-counter#%282%E2%8D%95+%C3%B7%E2%8C%88/ … Página diz seus 24 bytes. Perdi algo ?
Optimizer

11
A saída deve ser separada por ponto e vírgula, não por espaços.
precisa saber é o seguinte

3

Pyth , 18

Agora com a formatação correta!

j\;mc-dhSQ-eSQhSQQ

Teste:

$ pyth -c 'j\;mc-dhSQ-eSQhSQQ' <<< '[0,5,100,400]'
0.0;0.0125;0.25;1.0

Explicação:

(implicit)              Q = eval(input())
j\;                     ';'.join(
   m                             map(lambda d:
    c                                         float_div(
     -dhSQ                                              d-sorted(Q)[0],
     -eSQhSQ                                            sorted(Q)[-1]-sorted(Q)[0]),
    Q                                         Q))

A saída não está formatada corretamente.
precisa saber é o seguinte

@ Manu Desculpe, eu consertei.
Isaacg #

Criar seu próprio idioma, que você muda ao longo do tempo, estende um pouco as regras? Obviamente, você pode adicionar um novo recurso para tornar o programa mais curto?
Chris Jefferson

3
@ ChrisJefferson Eu sempre uso a versão mais recente do idioma que foi lançada antes que o problema fosse solucionado. Como tudo foi enviado ao Github, pode-se verificar que não adiciono nada depois que o problema for postado. Essa é a regra padrão do CG.SE - o idioma deve ser mais antigo que a pergunta e eu a cumpro.
Isaacg #

2

Oitava 25

b=min(l);(l-b)/(max(l)-b)

Assume que a entrada está inserida le, como é um shell interativo, o resultado é impresso automaticamente (isso é permitido?)


2
O Octave / Matlab ainda precisa inputobter informações do usuário e imitar STDIN. Você também pode escrever uma função. Além disso, isso imprime o resultado no formato correto?
Martin Ender

E não, apenas retornar e imprimir o shell geralmente não conta. Golfscript e similares são diferentes porque o idioma especifica que a pilha é impressa no final. Mas esse não é o caso, por exemplo, do Javascript. E também não penso no Matlab / Octave.
Ingo Bürk

2

APL, 31 caracteres / 55 bytes

{b←⌊/⍵⋄c←(⌈/⍵)-b⋄{2⍕(⍵-b)÷c}¨⍵}

Código antigo sem dígitos após o ponto decimal:

{b←⌊/⍵⋄c←(⌈/⍵)-b⋄{(⍵-b)÷c}¨⍵}

Tome o mínimo de vetor, faça a diferença entre o máximo e o mínimo de vetor, subtraia o mínimo de cada elemento e divida pela diferença entre min e max.

Código editado para imprimir dois dígitos após o ponto decimal:


2

CJam, 30 29 bytes

l~:d_{e>}*\_{e<}*:Mf-\M-f/';*

Espera a entrada em STDIN como [5 -20 30].

Teste aqui. (Isso imprimirá inteiro 0e 1sem ponto decimal, mas o interpretador Java imprime 0.0e 1.0.)

Devido a um erro que não pode reduzir {e>}*a :e>apesar de que deve ser possível de acordo com a especificação (o que permitiria poupar 4 bytes quando aplicado a ambos MIN e MAX).

Explicação ligeiramente desatualizada: (será alterada mais tarde)

l~:d_{e<}*_@_{e>}*@-\@f-\f/';* "Read and eval the input leaving an array of strings on the stack";
l~                             "Read and eval the input leaving an array of strings on the stack";
  :d                           "Convert all elements to double";
    _                          "Duplicate the array";
     {e<}*                     "Wrap the MIN function in a black and fold it onto the array";
          _                    "Duplicate the minimum";
           @                   "Rotate the stack, pulling the array to the top";
            _                  "Duplicate the array";
             {e>}*             "Same as before, now with MAX";
                  @            "Rotate the stack, pulling the minimum to the top";
                   -           "Subtract to give the total range";
                    \          "Swap range and array";
                     @         "Rotate the stack, pulling the other minimum to the top";
                      f-       "Subtract the minimum from each element in the array";
                        \      "Swap range and array";
                         f/    "Divide each element in the array by the range";
                           ';  "Push a semicolon character";
                             * "Riffle the semicolon into the array";

No final do programa, o conteúdo da pilha é impresso por padrão.

Tenho certeza de que existe uma maneira de salvar metade da pilha reorganizada, mas ainda não estou tão confortável com o CJam.


Isso imprime em 0;0.5;1vez de 0.0;0.5;1.0.
precisa saber é o seguinte

@Manu Veja o comentário de Dennis na resposta do Optimizer. Funciona bem no interpretador Java.
Martin Ender

2

Xojo, 179 bytes

dim x,n as double,k,z as int16,s() as string
n=1e3
x=-n
for each k in a
x=max(x,k)
n=min(n,k)
next
for k=0 to ubound(a)
s.append str((a(k)-n)/(x-n),"0.0#")
next
msgbox join(s,";")

2

R, 60 bytes

m=min(x<-scan());cat(sprintf("%f",(x-m)/(max(x)-m)),sep=";")    

A formatação consome muitos bytes devido 0e, 1por padrão, é aparada para exibir nada além da parte inteira.


1

Clojure 63

(fn[v](let[l(apply min v)](map #(/(- % l)(-(apply max v)l))v))) 

Não segue as regras, pois retorna frações em vez de duplas. Se isso não for aceitável, adicione 7 bytes

Ungolfed:

(fn [values]
    (let [low (apply min values)]
         (map #(/ (- % low)
                  (- (apply max values) low))
              values)))

Chamadas assim:

((fn[v](let[l(apply min v)](map #(/(- % l)(-(apply max v)l))v))) [5 -20 30])

Resultado: (1/2 0 1)


1

Ruby, 49

f=->a{$><<a.map{|x|(x-l=a.min).fdiv(a.max-l)}*?;}

Explicação:

f=->a{}     # Define a lambda that takes one argument a
$><<        # Print the following to STDOUT
a.map{|x|}  # For each element x
(x-l=a.min) # Find the lowest element of a, assign it to l, and subtract it from x
.fdiv       # Float division (/ truncates)
(a.max - l) # Divide by the maximum minus the minimum
*?;         # Convert the resulting array into a string joined by the ';' character


0

Q (31) FORMATO DE SAÍDA INADEQUADO

{(%/)(x;max x)-min x}(.:)(0::)0

entrada

1 2 3

resultado

0 .5 1

0

Perl - 60

my@a=sort@ARGV;print map{($_-$a[0])/($a[-1]-$a[0])." "}@ARGV

0

Java 7, 149 bytes

float[]c(int[]x){int b=1<<31,a=b-1,j=0,l=x.length;for(int i:x){a=i<a?i:a;b=i>b?i:b;}float[]r=new float[l];for(;j<l;r[j]=x[j++]-a)*1f/(b-a);return r;}

Ungolfed & código de teste:

Experimente aqui.

import java.util.Arrays;
class M{
  static float[] c(int[] x){
    int b = Integer.MIN_VALUE,
        a = b-1, // In Java, Integer.MIN_VALUE - 1 = Integer.MAX_VALUE (and vice-versa)
        j = 0,
        l = x.length;
    for(int i : x){
      a = i < a ? i : a; // Determine min value of array
      b = i > b ? i : b; // Determine max value of array
    }
    float[] r = new float[l];
    for(; j < l; r[j] = (x[j++] - a) * 1f / (b-a));
    return r;
  }

  public static void main(String[] a){
    System.out.println(Arrays.toString(c(new int[]{ 5, -20, 30 })));
    System.out.println(Arrays.toString(c(new int[]{ 1, 2, 3, 4, 5 })));
    System.out.println(Arrays.toString(c(new int[]{ 0, 5, 100, 400 })));
  }
}

Resultado:

[0.5, 0.0, 1.0]
[0.0, 0.25, 0.5, 0.75, 1.0]
[0.0, 0.0125, 0.25, 1.0]
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.