Faça-me uma soma mágica mínima

27

Mantendo este desafio curto.

Você recebe quatro números: p1, p2, p3 e p4.

A soma mágica dos números é definida da seguinte forma:

magic_sum = |p1 - p2| + |p2 - p3| + |p3 - p4| + |p4 - p1|

Você só pode alterar um dos valores inteiros acima (p1, p2, p3 ou p4). Você precisa alterar o valor para que a soma mágica dos valores atinja seu valor mínimo.

Por exemplo:

p1, p2, p3, p4 = 17, -6, 15, 33. O valor da soma mágica é 78 neste caso.

Você pode alterar o -6 aqui para 16, e o valor da soma mágica será 36, que é o valor mínimo atingível.

Lembre-se de que os números podem ser números inteiros positivos ou negativos.

Isso é código-golfe, portanto, menos bytes em código vencem. Brownie aponta para o uso de uma linguagem prática sobre uma linguagem recreativa. Que o dia 4 esteja com você.

Reiterar:

Amostra 1

Entrada 1

17 -6 15 33

Saída 1

36

Explicação 1

O -6 pode ser substituído por 16 e isso nos dá a soma mágica mínima possível.

Amostra 2

Entrada 2

10 10 10 10

Saída 2

0 or 2

qualquer um é aceitável

Explicação 2

A soma mágica mínima atingível é 0, pois a soma mínima de 4 números inteiros positivos é 0. Se um número tiver que ser alterado, um dos 10 pode ser alterado para 9 e, assim, produzirá a saída 2.

Amostra 3

Entrada 3

1 2 3 4

Saída 3

4

Explicação 3

A entrada por si só produz 6 como sua soma mágica. Alterar o 4 para 1 e a soma mágica mínima é atingida, que é 4.

Koishore Roy
fonte
10
+1, mas poderia ter mais exemplos.
Jonathan Allan
2
Um exemplo totalmente trabalhado e mais alguns casos de teste, e é +1de minha parte.
Shaggy
@Shaggy done. onde está o meu +1? : P
Koishore Roy
1
@KoishoreRoy O caso de teste 3 não seria 6 sem a alteração?
wizzwizz4
@ wizzwizz4 | 1 - 2 | + | 2 - 3 | + | 3 - 4 | + | 4 - 1 | = 1 + 1 + 1 + 3 = 6. Você está certo. Feito a edição.
Koishore Roy

Respostas:

14

Gelatina , 6 bytes

ṢŒœIṂḤ

Experimente online!

Uma porta da minha resposta Python .

     (input)        [17, -6, 15, 33]
Ṣ    sort           [-6, 15, 17, 33]
Œœ   odd-even elts  [[-6, 17], [15, 33]]
I    increments     [23, 18]
M    minimum        18
Ḥ    double         36 
xnor
fonte
20

Python 2 , 44 bytes

a,b,c,d=sorted(input())
print min(c-a,d-b)*2

Experimente online!

Classifica a entrada como a,b,c,d,em ordem crescente, pega a menor de c-ae d-be a dobra. Por que isso funciona?

Primeiro, observe que quando alteramos um elemento para maximizar a soma cíclica total de distâncias, é ideal (ou vinculado para o ideal) alterá-lo para igualar um vizinho, como 17, -6, 15, 33 -> 17, 17, 15, 33. Isso ocorre porque sua nova distância total para seus vizinhos cíclicos esquerdo e direito é pelo menos a distância entre esses vizinhos, portanto, torná-los iguais é o melhor que podemos fazer.

Agora, excluir uma das duas cópias adjacentes de um número fornece a mesma soma cíclica de distâncias. No exemplo, isto é 17, 15, 33, dando distâncias 2 + 18 + 16. Portanto, em vez de substituir um dos quatro números, é equivalente apenas excluí-lo, deixando três números e usando a soma de suas distâncias cíclicas.

Observe que, com 3 números, a maior distância é a soma dos dois menores. Isso ocorre porque, se ordenarmos os números a ≤ b ≤ c, então |a - c| = |a - b| + |b - c|. Em outras palavras, viajamos entre o número maior e o menor duas vezes, usando o número médio como um pit stop uma das vezes. Portanto, a soma das três distâncias é apenas o dobro da distância entre o mínimo e o máximo (c-a)*2.

Portanto, a questão é qual número excluímos para obter a menor distância entre o mínimo e o máximo dos três números restantes. Claramente, excluímos o menor ou o maior dos números. Chamando-os a, b, c, dem ordem classificada, excluindo afolhas d - be excluindo dfolhas c - a, e o resultado final é o dobro, o que for menor.

xnor
fonte
me ajude com um caso de teste aqui. e se a soma mágica já for 0, que é o menor número possível. nesse caso, a resposta deve ser 0? ou o próximo número mais baixo possível. No caso de a entrada ser [10,10,10,10], a soma mágica é 0. a segunda menor possível é 2. Deixe-me saber o que você pensa.
Koishore Roy
O que eu ouvi você dizer é que você pode simplesmente ignorar a ordem dos quatro números dados (seu primeiro passo é classificá-los). Mas o que se tinha pedido cinco números p1através p5, e ainda só permitiu mudar um número? O caso de quatro números parece muito fácil (somente depois de ver sua resposta).
Jeppe Stig Nielsen
@KoishoreRoy Eu gosto da sua solução de permitir qualquer um.
xnor
@JeppeStigNielsen Sim, o fato de que a ordem não importa é especial para 4 números, e isso acontece porque depois de excluir um para formar três números, todos os pares de números são ciclicamente adjacentes. Com cinco números, isso não funcionaria (você certamente encontrará um exemplo), e o desafio seria muito diferente.
xnor
Gostaria de poder votar duas vezes. Bela observação, bem explicada.
Jonah
9

R , 66 33 bytes

function(x)2*min(diff(sort(x),2))

Experimente online!

Muito mais curto com o algoritmo do xnor (leia a explicação deles e atualize a publicação deles!).

Versão antiga:

R , 66 bytes

function(x,m=matrix(x,3,4))min(colSums(abs(diff(rbind(m,m[1,])))))

Experimente online!

Recebe entrada como um vetor de 4 números inteiros.

p2p2p1p2p3|p1p2|+|p2p3|p2=p1.

Existem 4 maneiras de escolher qual número mudamos; para cada uma delas, precisamos apenas calcular a soma de 3 diferenças absolutas.

3×4rbind

Robin Ryder
fonte
4

Geléia , 11 10 bytes

I;SASƲ$-ƤṂ

Experimente online!

Um link monádico que leva uma lista se números inteiros como entrada. Deve funcionar para o tamanho da lista arbitrária. Funciona com base no fato de que a soma mínima pode ser obtida testando a remoção de cada número da lista, calculando a soma mágica e levando o mínimo.

Nick Kennedy
fonte
3

Geléia , 8 bytes

ṁ-Ƥ⁸IA§Ṃ

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

* pode ser qualquer número, desde que haja mais de 1; usando a fórmula mágica do mesmo estilo, somando as diferenças dos vizinhos.

Experimente online!

Quão?

ṁ-Ƥ⁸IA§Ṃ - Link: list of integers, X       e.g. [17,-6,15,33]
 -Ƥ      - for overlapping "outfixes" of length length(X)-1:
         -                                      [[-6,15,33],[17,15,33],[17,-6,33],[17,-6,15]]
ṁ  ⁸     -   mould like X                       [[-6,15,33,-6],[17,15,33,17],[17,-6,33,17],[17,-6,15,17]]
    I    - incremental differences              [[21,18,-39],[-2,18,-16],[-23,39,-16],[-23,21,2]]
     A   - absolute (vectorises)                [[21,18,39],[2,18,16],[23,39,16],[23,21,2]]
      §  - sums                                 [78,36,78,46]
       Ṃ - minimum                              36
Jonathan Allan
fonte
3

Japonês -Q , 11 bytes

ñÍó ®r- ÑÃn

Usa o algoritmo do @ xnor, que me salvou em 4 bytes.

Guardado 5 bytes graças a @Shaggy

Tente

Modalidade de ignorância
fonte
parece estar funcionando bem, mas você explicaria por que isso funciona?
Koishore Roy
@KoishoreRoy Adicionada uma explicação
Modalidade de Ignorância
29 bytes (eu acho )
Shaggy
@ Shaggy quando atualizei minha resposta, substituí acidentalmente soma pelo mapa, invalidando alguns campos de golfe, mas outros são bons
Modalidade de Ignorância
Muito bem jogado :) Você pode economizar mais 1 byte substituindo ÃÃpor uma nova linha.
Shaggy
3

J , 24 20 18 17 bytes

versão alternativa usando o algoritmo xnor:

2*[:<./2 2-/@$\:~

quão

Duas vezes 2 *o mínimo da [:<./2ª linha subtraído da primeira linha [:-/da matriz 2x2 formada pela modelagem 2 2$da entrada classificada\:~

Experimente online!

resposta original: J , 24 bytes

[:<./1(1#.2|@-/\],{.)\.]

Experimente online!

Usando a ideia de Nick Kennedy.

  • 1(...)\.] aplique o verbo in parens a todos os outfixes de comprimento 1 (um outfix de comprimento n é uma lista com n elementos contíguos removidos, portanto, isso produz todas as listas possíveis com 1 olmo removido)
  • (1 #. 2 |@-/\ ] , {.)isso calcula a soma mágica anexando o primeiro olmo à entrada ] , {.e aplicando a diferença abs |@-/nos infixes de comprimento 2 2 ...\e somando o resultado 1 #..
  • [:<./ retorna o min
Jonah
fonte
2

05AB1E , 11 7 bytes

Porto de @xnor resposta Jelly 's .
-4 bytes graças a @Emigna e @Grimy .

{2ô`αß·

Experimente online.

Alternativa de 7 bytes, que funciona apenas na versão herdada de 05AB1E (exigiria um antes do ¥na nova versão):

{2ôø¥W·

Experimente online.

Explicação:

{        # Sort the (implicit) input-list
         #  i.e. [17,-6,15,33] → [-6,15,17,33]
 2ô      # Split this list into parts of size 2
         #  → [[-6,15],[17,33]]
   `     # Push both separated to the stack
    α    # And take their absolute differences
         #  → [23,18]
     ß   # Pop and push the minimum
         #  → 18
      ·  # Double it (and output implicitly as result)
         #  → 36

{        # Sort the (implicit) input-list
         #  i.e. [17,-6,15,33] → [-6,15,17,33]
 2ô      # Split this list into parts of size 2
         #  → [[-6,15],[17,33]]
   ø     # Zip/transpose, swapping rows/columns
         #  → [[-6,17],[15,33]]
    ¥    # Get the deltas/forward differences of the inner lists
         #  → [[23],[18]]
     W   # Get the flattened minimum (without popping)
         #  → 18
      ·  # Double it (and output implicitly as result)
         #  → 36
Kevin Cruijssen
fonte
1
7 bytes no legado: {2ôø¥W·ou 8 com na reescrita.
Emigna
2
7 bytes não legados:{2ô`αW·
Grimmy
@ Emigna Smart, obrigado!
Kevin Cruijssen
@ Grimy Obrigado também!
Kevin Cruijssen
1

C ++ (gcc)

programa completo: 138 bytes

#include<iostream>
#include<regex>
using namespace std;int main(){int a[4];for(int&b:a)cin>>b;sort(a,a+4);cout<<min(a[2]-*a,a[3]-a[1])*2;}

Experimente online!

função principal: 84 bytes

#include<regex>
int m(int*a){std::sort(a,a+4);return std::min(a[2]-*a,a[3]-a[1])*2;}

Experimente online!

Também usando o algoritmo xnor explicado em seu post no Python 2.

movatica
fonte
0

Carvão , 20 bytes

I⌊EEθΦθ⁻κμΣEι↔⁻λ§ι⊕μ

Experimente online! Link é a versão detalhada do código. Acontece que estou usando a ideia de @ NickKennedy. Explicação:

   Eθ                   Map over input array
     Φθ                 Filter over input array where
       ⁻κμ              Outer and inner indices differ
  E                     Map over resulting list of lists
           Eι           Map over remaining values in list
                §ι⊕μ    Get the next value in the list
             ↔⁻λ        Compute the absolute difference with the current value
          Σ             Take the sum of absolute differences
 ⌊                      Take the minimum sum
I                       Cast to string and implicitly print
Neil
fonte
0

JavaScript (ES6), 51 bytes

Usando o método muito mais inteligente do xnor :

a=>([a,b,c,d]=a.sort((a,b)=>a-b),b+c<a+d?c-a:d-b)*2

Experimente online!


Resposta original, 96 bytes

Recebe a entrada como uma matriz de 4 números inteiros. Provavelmente definitivamente não é a abordagem mais curta.

a=>a.map(m=x=>a.map((y,i)=>a[m=a.map(v=>s+=Math.abs(p-(p=v)),a[i]=x,p=a[3],s=0)|m<s?m:s,i]=y))|m

Experimente online!

Arnauld
fonte
0

Java 8 , 235 bytes

Uma porta da resposta e algoritmo Python do @ xnor

import java.util.*;interface M{static void main(String[]A){Scanner I=new Scanner(System.in);int a[]={0,0,0,0};for(int i=0;i<4;a[i++]=I.nextInt());java.util.Arrays.sort(a);System.out.print(2*(a[2]-a[0]>a[3]-a[1]?a[3]-a[1]:a[2]-a[0]));}}

Experimente online!

Java 10 , não comprovado, 222 bytes

Com o Java 10, eu devo substituir o lado esquerdo da declaração do Scanner por var, embora não possa compilá-lo on-line e, portanto, só posso adicioná-lo como uma trivialidade. Desculpe.

interface M{static void main(String[]A){var I=new java.util.Scanner(System.in);int a[]={0,0,0,0};for(int i=3;i<4;a[i++]=I.nextInt());java.util.Arrays.sort(a);System.out.print(2*(a[2]-a[0]>a[3]-a[1]?a[3]-a[1]:a[2]-a[0]));}}
Pó de diamante
fonte
1
No AFAIK, você pode apenas ter uma função como envio, como as outras respostas. Não há necessidade de incluir a classe circundante, a interface etc.
Tau