Números reducidos

10

La entrada es una matriz de (al menos 3, máximo 20) enteros diferentes. Cada entero es mayor que -1000 y menor que 1000.

Su tarea es reducir los números "mapeándolos linealmente" de 0.0a 1.0. Esto significa que el número más pequeño de la matriz se asignará a 0.0, el más grande a 1.0.

Obtiene la matriz como un parámetro (dentro de una función) o argumentos stdin / program (puede elegir). Imprima el resultado en el formato double1;double2;double3;.... La salida debe tener el mismo orden que la entrada .

Si lo desea, puede redondear la salida a 2 dígitos después del punto decimal. Debe haber al menos 1 dígito después del punto decimal.

El uso de funciones incorporadas (funciones que reducen los números para usted, como Mathicas Rescale) no está permitido .

Ejemplos:

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

(La última salida es redondeada, de lo contrario sería 0.0;0.0125;0.25;1.0)

CommonGuy
fuente
2
Entonces, incluso si escribimos una función, ¿el resultado tiene que imprimirse? (En lugar de devolver una serie correspondiente de dobles.)
Martin Ender
@ MartinBüttner Sí, tienen que imprimirse. Las funciones incorporadas no están permitidas.
CommonGuy
"no se permite el uso de funciones integradas (tales como Mathicas Rescale)". Eso es muy vago. ¿Qué funciones están prohibidas? ¿Solo aquellos que resuelven el problema completo (que sería una escapatoria estándar)?
John Dvorak
Espera, entonces, ¿la entrada puede ser un argumento de función, pero la salida debe estar en la pantalla?
John Dvorak
1
@Dennis El formato debe coincidir con el que se muestra en la pregunta. Esto significa que los números están separados por punto y coma.
CommonGuy

Respuestas:

5

CJam, 18 bytes

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

Tenga en cuenta que el intérprete en línea representa erróneamente 0dcomo en 0lugar de 0.0.

Ejecución de ejemplo

$ 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

Cómo 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, ';'))        ";
Dennis
fuente
Mi reacción a esto, como fuente de CJam: ¿Qué? explicación necesaria ...
edc65
2
Buena manera de obtener el mínimo y el máximo usando el índice de matriz en lugar de hacer estallar y luego intercambiar cosas
Optimizer el
Probablemente es mi hablar en frío, pero ¿por qué clasificas dos veces? ¿No debería una matriz ordenada permanecer ordenada si se sustrae una constante de cada elemento?
Ingo Bürk
@ IngoBürk Creo que la matriz ordenada no sobrevive al acceso a la matriz. Lo cual tiene sentido, porque el resultado final no debe ser ordenado.
Martin Ender
@ MartinBüttner D'oh. Por supuesto. Necesitamos mantener el orden para el resultado. ¡Gracias!
Ingo Bürk
4

JavaScript, ES6, 81 bytes

Gracias a @ edc65 por el toFixedtruco

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

Ejecútelo en la última consola de Firefox.

Esto crea una función fque puede invocar como

F([5,-20,30])
Optimizador
fuente
1) ¿por qué eval (prompt) cuando se permite una función? 2) Debe haber al menos 1 dígito después del punto decimal. 3) no es necesario almacenar M, solo d = Mm
edc65
Actualizado. Sin embargo, obtener al menos 1 dígito después del decimal es difícil
Optimizer
If you want, you can round the output to 2 digits after the decimal pointesa es la forma más simple Creo
edc65
@ edc65 Pero no hay forma de convertir 1a 1.0excepción de lo que hice.
Optimizador
No ¿Puedo insinuar?
edc65
4

Pitón 2, 72 68 63 56 55

Obviamente no es tan conciso como otras respuestas, pero de todos modos:

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

Ejecución de muestra:

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

Antiguo (68 caracteres, escrito en Python 3):

x=eval(input())
y=sorted(x)
print([(i-y[0])/(y[-1]-y[0])for i in x])
monopolo
fuente
Puede guardar un personaje más definiendo m=min(x).
FryAmTheEggman
4

CJam, 24 23 bytes

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

La entrada será como:

[5 -20 30]

Pruébelo en línea aquí cuenta que las impresiones del compilador en línea Double 0como 0única. Ejecute en el intérprete de Java que imprime correctamente.

Cómo 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";
Optimizador
fuente
1
Ah, esa es una idea mucho mejor para obtener el mínimo y el máximo.
Martin Ender
Esto imprime en 0;0.5;1lugar de 0.0;0.5;1.0.
CommonGuy
@Manu: Sí, tratando de arreglar eso. Y casi todas las respuestas hacen esto solo.
Optimizador
2
No necesitas la solución. El intérprete de Java representa el doble 0 como 0.0.
Dennis
3

C # 92

Corriendo dentro de LinqPad

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

Prueba en 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();}

Salida

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

APL (15)

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

(o, sin trenes, también 15 caracteres :)

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

Esto lee el argumento desde el teclado e imprime el resultado en la pantalla.

Explicación:

  • : lee una línea desde el teclado y evalúala
  • +-⌊/: resta el elemento más bajo de la matriz de todos los elementos de la matriz
  • +÷⌈/: divide cada elemento de la matriz por el elemento más alto de la matriz
  • 2⍕: formato con dos decimales

Prueba:

      (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
marinus
fuente
Debería agregar el conteo de bytes ...
Optimizer
Que es solo de 24 bytes.
Optimizador
2
@Optimizer: a menos que la pregunta indique lo contrario, cada respuesta se puntúa utilizando la codificación que produce el recuento de bytes más pequeño. Hay una página de códigos APL que representa cada carácter APL por un byte.
Dennis
Corríjame si estoy haciendo algo mal aquí, pero de forma predeterminada, el código de golf se cuenta en bytes y mothereff.in/byte-counter#%282%E2%8D%95+%C3%B7%E2%8C%88/ … La página dice que tiene 24 bytes. Me he perdido algo ?
Optimizador
1
La salida debe estar separada por punto y coma, no por espacios.
CommonGuy
3

Pyth , 18

¡Ahora con el formato correcto!

j\;mc-dhSQ-eSQhSQQ

Prueba:

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

Explicación:

(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))
isaacg
fuente
La salida no está formateada correctamente.
CommonGuy
@Manu Lo siento, lo he arreglado.
isaacg
¿No crea su propio idioma, que cambia con el tiempo, estirando un poco las reglas? Obviamente, ¿puede agregar una nueva función para acortar el programa?
Chris Jefferson
3
@ChrisJefferson Siempre uso la versión más nueva del lenguaje que salió antes de que se preguntara el problema. Como todo se ha enviado a Github, se puede verificar que no agrego nada después de que se publica el problema. Esa es la regla estándar de CG.SE: el lenguaje debe ser más antiguo que la pregunta y yo lo cumplo.
isaacg
2

Octava 25

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

Asume que la entrada está adentro ly dado que es un shell interactivo, el resultado se imprime automáticamente (¿está permitido?)

Grifo
fuente
2
Octave / Matlab sí tiene inputque obtener la entrada del usuario e imitar STDIN. También puedes escribir una función. Además, ¿esto imprime el resultado en el formato correcto?
Martin Ender
Y no, solo regresar y hacer que se imprima el shell generalmente no cuenta. Golfscript y similares son diferentes porque el lenguaje especifica que la pila se imprime al final. Pero este no es el caso, por ejemplo, Javascript. Y tampoco pienso en Matlab / Octave.
Ingo Bürk
2

APL, 31 caracteres / 55 bytes

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

Código antiguo sin dígitos después del punto decimal:

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

Tome el mínimo de vector, tome la diferencia entre máximo y mínimo de vector, reste el mínimo de cada elemento y divida por la diferencia entre mínimo y máximo.

Código editado para imprimir dos dígitos después del punto decimal:

Shujal
fuente
2

CJam, 30 29 bytes

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

Espera la entrada en STDIN como [5 -20 30].

Pruébalo aquí. (Esto imprimirá un entero 0y 1sin punto decimal, pero el intérprete de Java imprime 0.0y 1.0.)

Debido a un error que no puede acortar {e>}*a :e>pesar de que debería ser posible según la especificación (lo que ahorraría 4 bytes cuando se aplica a ambos min y max).

Explicación ligeramente desactualizada: (se enmendará más adelante)

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";

Al final del programa, el contenido de la pila se imprime por defecto.

Estoy seguro de que hay una manera de ahorrar la mitad de la reorganización de la pila, pero todavía no estoy tan cómodo con CJam.

Martin Ender
fuente
Esto imprime en 0;0.5;1lugar de 0.0;0.5;1.0.
CommonGuy
@Manu Vea el comentario de Dennis sobre la respuesta de Optimizer. Funciona bien en el intérprete de 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,";")
silverpie
fuente
2

R, 60 bytes

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

El formateo consume una gran cantidad de bytes debido al 0y 1por defecto se recortan para mostrar nada más allá de la parte entera.

Billywob
fuente
1

Clojure 63

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

No sigue las reglas, ya que devuelve fracciones en lugar de dobles. Si eso no es aceptable, agregue 7 bytes

Sin golf:

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

Llamable así:

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

Salida: (1/2 0 1)

resueman
fuente
1

Rubí, 49

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

Explicación:

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
histocrat
fuente
0

Q (31) FORMATO DE SALIDA INCORRECTO

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

entrada

1 2 3

salida

0 .5 1
protista
fuente
0

Perl - 60

my@a=sort@ARGV;print map{($_-$a[0])/($a[-1]-$a[0])." "}@ARGV
KSFT
fuente
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 y código de prueba:

Pruébalo aquí.

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 })));
  }
}

Salida:

[0.5, 0.0, 1.0]
[0.0, 0.25, 0.5, 0.75, 1.0]
[0.0, 0.0125, 0.25, 1.0]
Kevin Cruijssen
fuente