Seja o mais justo possível

33

Introdução

Neste desafio, você deve dividir um número inteiro em duas partes. Como ninguém gosta de comer o pedaço menor de bolo, seu objetivo é ser o mais justo possível. Por exemplo, se você deseja dividir o número inteiro 7129em duas partes, existem três maneiras possíveis de fazer isso.

7,129, 71,29e 712,9são todas as possibilidades, mas 71,29é a maneira mais justa de dividi-lo em duas partes, porque minimiza a diferença entre as duas:

7 129 -> |7-129| = 122
71 29 -> |71-29| = 42
712 9 -> |712-9| = 703

Desafio

Dado um número inteiro, determine a melhor maneira possível de particioná-lo, conforme descrito acima, e relate a diferença resultante.

Regras

  • A divisão só faz sentido para números inteiros de comprimento pelo menos dois, a entrada sempre será ≥ 10
  • A entrada pode ser um número inteiro, lista de dígitos ou uma sequência
  • Você não precisa lidar com entradas inválidas

Casos de teste

Você só precisa relatar a diferença resultante, o particionamento está aqui apenas para ilustração:

10 -> 1,0 -> 1
11 -> 1,1 -> 0
12 -> 1,2 -> 1
13 -> 1,3 -> 2
101 -> 1,01 -> 0
128 -> 12,8 -> 4
313 -> 3,13 -> 10
1003 -> 1,003 -> 2
7129 -> 71,29 -> 42
81128 -> 81,128 -> 47
999999 -> 999,999 -> 0
9999999 -> 999,9999 or 9999,999 -> 9000
ბიმო
fonte

Respostas:

11

Braquilog , 12 11 bytes

Minha primeira resposta Brachylog

Receber entrada como uma string

{~cĊịᵐ-ȧ}ᶠ⌋

Experimente online!

Explicação:

vai f ind todas as possíveis saídas para o predicado em {…}e armazená-los em uma lista. ~cdiz que a saída é uma lista que, quando c oncatenada, é igual à entrada. Em seguida, Ċafirma que a saída de ~ctem comprimento 2.

ịᵐconverte os dois elementos da saída em números inteiros (isso se livra dos primeiros 0s), leva a diferença absoluta dos dois elementos.

Depois de termos nossa lista de todas as saídas possíveis, obtemos o elemento mínimo com

H.PWiz
fonte
10

Haskell , 48 bytes

f n=minimum[abs$n`div`10^k-n`mod`10^k|k<-[1..n]]

[1..n] torna isso muito lento para os casos de teste maiores.

Experimente online!

Dennis
fonte
Bom trabalho! Fiquei tão cego usando cordas que esqueci que podia usar aritmética.
Wheat Wizard
9

05AB1E , 9 bytes

Código:

ā¤âε£ÆÄ}W

Usa a codificação 05AB1E . Experimente online!

Explicação

ā            # Get the array [1, 2, .., len(input)]
 ¤â          # Cartesian product with the last element, (e.g. for input 12345:
               [[1, 5], [2, 5], [3, 5], [4, 5], [5, 5]])
   ε   }     # For each element:
    £        #   Get the substrings (12345 [3, 5] £ --> [123, 45])
     Æ       #   Reduce by subtraction
      Ä      #   Get the absolute value
        W    # Take the minimum of all results
Adnan
fonte
1
Se você substituir £por °‰não precisará ¤âmais.
Emigna
8

Python 2 , 64 bytes

lambda n:min(abs(int(n[i:])-int(n[:i]))for i in range(1,len(n)))

Experimente online!

Neil
fonte
7

Perl 6 , 40 bytes

{min map {abs [-] @$_},m:ex/^(.+)(.+)$/}

Teste-o

Expandido:

{  # bare block lambda with implicit parameter 「$_」

  min
    map
      {
        abs
          [-]    # reduce with &infix:«-»
            @$_  # the input of this inner block as a Positional
      },

      # split 「$_」 into 2 in every possible way
      m
      :exhaustive
      /^ (.+) (.+) $/
}
Brad Gilbert b2gills
fonte
6

C, 94 bytes

c,r,d,a;f(n){for(c=1,r=0,d=n<11?1:n;n;r+=n%10*c,c*=10,n/=10)a=abs(r-n),d=r&&a<d?a:d;return d;}

Experimente online!

Steadybox
fonte
6

Prolog (SWI) , 195 189 154 117 112 bytes

35 bytes economizados graças ao Eminga

A*H:-findall(X,(between(0,A,I),r(A,I,X)),L),sort(L,[H|_]),!.
r(A,B,C):-Z is 10**B,divmod(A,Z,X,Y),C is abs(X-Y).

Experimente online!

Esta é a minha primeira tentativa no golfe de prólogo, por isso pode ser um pouco horrendo. Aqui está como isso funciona.

No nível mais alto que temos *. *leva Ae H, e determina se Hé a menor maneira de dividir A.

    A*H:-
      findall(X,(between(0,A,I),call(r,A,I,X)),L),
      sort(L,[H|_]),
      !.

A primeira linha aqui usa uma técnica desta postagem do SO , para executar essencialmente um mapa do predicado r(A)sobre os números inteiros de 0até A. Como rconfirma os valores de cada partição, isso nos fornecerá os valores de todas as partições possíveis, além de uma carga completa de lixo adicional. Todas essas partições serão armazenadas Lem nenhuma ordem específica. Feito isso, classificamos a lista para encontrar o menor elemento. Em seguida, usamos um corte para impedir o rastreamento.

Em seguida, temos a definição de r. Primeiro rcalcula os dois resultados da divisão nomeando-os Xe Y.

r(A,B,C):-
  Z is 10**B,
  divmod(A,Z,X,Y),
  C is abs(X-Y).

Então afirmamos que essa Cé a diferença deles e é positiva.

  C is abs(X-Y).
Assistente de Trigo
fonte
Parece haver uma falha aqui, como X is div(A,10**B),Y is div(A,10**B)sempre dará C=0(o significado Hsempre será 0 também). Devo ser Y is mod(A,10**B)eu presumo.
Emigna
A segunda linha também pode estar r(A,B,C):-Z is 10**B,divmod(A,Z,X,Y),C is abs(X-Y).economizando 32 bytes (se você estiver usando o prólogo SWI, pelo menos, não tenha certeza de outras versões).
Emigna
A primeira linha pode começar por exemplo, em A*Hvez de l(A,H)salvar outra 3. E se você estiver usando SWI, poderá adicionar um link TIO
Emigna
Além disso, acho que você não precisa ,!? Não deve haver nenhum retrocesso nesse ponto.
Emigna
@ Emigna Obrigado pelas dicas, em breve as implementarei. Eu também pensei ,!que não seria necessário, mas quando eu testo o programa, ele retorna. Parece tentar todas as ordens possíveis Le depois classifica todas elas. Isso significa que dará os mesmos A!tempos de resposta .
Assistente de trigo
5

Haskell , 68 65 bytes

f x=minimum[abs$read(take i x)-read(drop i x)|i<-[1..length x-1]]

Experimente online!

Explicação

minimum              -- Minimum of ...
 [abs$               -- The absolute value of ...
  read(take i x)     -- The first i characters of x
  -                  -- Minus ...
   read(drop i x)    -- The last i characters of x
 |i<-[1..length x-1] -- From i=1 to i=length x - 1
 ]
Assistente de Trigo
fonte
4

Carvão , 14 bytes

I⌊Eθ↔⁻I…θκI✂θκ

Experimente online! Link é a versão detalhada do código. Convenientemente, uso a variante 2-arg de Slice. Explicação:

   θ            Input string
  E             Map over characters
        θ   θ   Input string
         κ   κ  Current map index
       …        Mold to length (i.e. head)
           ✂    Slice (i.e. tail)
      I   I     Cast to integer
     ⁻          Subtract
    ↔           Absolute value
 ⌊              Minimum
I               Cast to string
                Implicitly print
Neil
fonte
4

Geléia , 9 8 bytes

ḌÐƤḊạḌƤṂ

Experimente online!

-1 byte graças a Dennis. Entrada é uma lista de dígitos.

Explicação

ḌÐƤḊạḌƤṂ
ḌÐƤ          Convert to integer from decimal for all Ƥostfixes. [1,2,3]->[123,23,3]
   Ḋ         Remove the first element ->[23,3]
     ḌƤ      Convert to integer from decimal for all Ƥrefixes [1,2,3]->[1,12,123]
    ạ        Absolute difference. [23,3]ạ[1,12,123]->[22,9,123]
       Ṃ     Minimum
dylnan
fonte
Hum, sua explicação não parece refletir o que seu código realmente faz.
Erik the Outgolfer
@EriktheOutgolfer É a parte “remover o último elemento” quando deve dizer “remover o primeiro elemento”? Eu vou consertar isso, obrigado por apontar isso
dylnan
3

Funky , 159 134 99 bytes

s=>{S={}fori=1i<#s i++{S[#S]=(((v=s::sublist)(0,i)::[email protected](i)::reduce@..)^2)^.5};math.min...S}

Na verdade, o ajuste das especificações é mais curto, parece.

Experimente online!

ATaco
fonte
3

Retina , 36 bytes

\B
,$'¶$`
\d+
$*
(1*),\1

Om`^.*
\G1

Experimente online!

Explicação

\B
,$'¶$`

Isso gera todas as partições possíveis em linhas separadas, bem como uma linha final com a entrada original.

\d+
$*

Converta cada número em cada partição em unário.

(1*),\1

Remova uma quantidade máxima e igual de 1s de ambas as partes de cada partição (ou seja, remova o mínimo e subtraia do máximo, o que indica a diferença absoluta).

Om`^.*

Classifique as linhas.

\G1

Conte os 1s na primeira linha, o que fornece a diferença absoluta mínima.

Martin Ender
fonte
3

J , 32, 27 23 bytes

-5 bytes graças ao FrownyFrog! -4 bytes se a entrada for uma sequência.

[:<./}:@(".\)|@-1}.".\.

Experimente online!

Original: tira um número como entrada

(".\(}:@[([:<./|@-)}.@])".\.)@":

Como funciona:

                             @": - convert the number to list of chars and
(".\                    ".\.)    - form all prefixes/suffixes and convert them to numbers
    (}:@[          }.@])         - drop the last prefix / first suffix
         (     |@-)              - find the absolute differences
          [:<./                  - find the minimum

Experimente online!

Galen Ivanov
fonte
@FrownyFrog - Thanks!
Galen Ivanov
3

JavaScript (ES6), 64 bytes

Recebe a entrada como uma sequência.

f=([c,...s],l=0)=>c?Math.min(Math.abs((l+=c)-s.join``),f(s,l)):l

Casos de teste

Comentado

f = ([c, ...s],           // c = current character, s = array of remaining characters
                l = 0) => // l = left part of the integer, initialized to 0 (see footnote)
  c ?                     // if c is defined:
    Math.min(             //   return the minimum of:
      Math.abs(           //     1) the absolute value of:
        (l += c) -        //       the updated left part
        s.join``          //       minus the right part
      ),                  //     end of Math.abs()
      f(s, l)             //     2) the result of a recursive call
    )                     //   end of Math.min()
  :                       // else:
    l                     //   stop the recursion by returning l (now equal to the input)

Não recursivo (ES7), 65 bytes

Recebe a entrada como uma sequência.

s=>Math.min(...[...s].map(c=>((l+=c)-s.slice(++i))**2,i=l=0))**.5

Casos de teste

Comentado

s =>                            // given s
  Math.min(...                  // get the minimum value in the result of this map():
    [...s].map(c =>             //   for each character c in s:
      ((l += c)                 //     append c to l (the left part)
                - s.slice(++i)) //     and subtract the right part from it
      ** 2,                     //     square the result
      i =                       //     start with i = 0 (split position)
      l = 0                     //     and l = 0 (left part, see footnote)
    )                           //   end of map()
  )                             // end of Math.min()
  ** .5                         // return the square root of the smallest square

Nota : Nas duas versões, lé coagido a uma sequência na primeira iteração. Normalmente, devemos ter cuidado com zeros à esquerda em um literal numérico: 0123 - 10 === 73porque 0123é analisado como um valor octal (agora está obsoleto, mas ainda é válido no modo não estrito). Mas '0123' - '10' === 113, o zero principal sendo desta vez ignorado. Então, é bom fazê-lo.

A partir da especificação da operação abstrata ToNumberaplicada a uma sequência:

Um StringNumericLiteral que é decimal pode ter qualquer número de 0 dígitos iniciais

Arnauld
fonte
3

APL (Dyalog) , 27 bytes

{⌊/|-/⍎¨↑⊂∘⍵¨↓1,∘.=⍨⍳¯1+≢⍵}

Experimente online!

Quão?

¯1+≢⍵- comprimento de nmenos 1

∘.=⍨⍳ - matriz de identidade

      1,∘.=⍨⍳3
1 1 0 0
1 0 1 0
1 0 0 1

1,- preceder 1para cada linha

- dividido por linhas

⊂∘⍵¨ - para cada um, particione a string por ele

      1 0 1 0  '7129'
┌──┬──┐
7129
└──┴──┘

- achatar

-/ - reduza cada par com subtração

| - tomar valores absolutos

⌊/ - mínimo


APL (Dyalog) , 35 bytes

{⌊/|-/⍎¨(⊂∘⍵⍤1)1,∘.=⍨⍳¯1+≢⍵}

Experimente online!

Uriel
fonte
3

Gelatina , 11 bytes

ŒṖṖLÐṂḌạ/€Ṃ

Experimente online!

-3 bytes graças a dylnan

Como funciona

ŒṖṖLÐṂḌạ/€Ṃ - Main link. Argument: n (integer)    e.g    7129
ŒṖ          - Partitions of n's digits;                  [[7, 1, 2, 9], [7, 1, [2, 9]], [7, [1, 2], 9], [7, [1, 2, 9]], [[7, 1], 2, 9], [[7, 1], [2, 9]], [[7, 1, 2], 9], [7, 1, 2, 9]]
  Ṗ         - Remove the final element                   [[7, 1, 2, 9], [7, 1, [2, 9]], [7, [1, 2], 9], [7, [1, 2, 9]], [[7, 1], 2, 9], [[7, 1], [2, 9]], [[7, 1, 2], 9]]
    ÐṂ      - Keep the lists with the minimum...         [[7, [1, 2, 9]], [[7, 1], [2, 9]], [[7, 1, 2], 9]]
   L        -   length
      Ḍ     - From digits                                [[7, 129], [71, 29], [712, 9]]
        /   - Reduce...
         €  - ...each...
       ạ    - ...by absolute difference                  [122, 42, 703]
          Ṃ - Take the minimum                           42
caird coinheringaahing
fonte
Você pode mudar L=2$$Ðfpara ṖLÐṂneste caso
dylnan
2

Python 2 , 58 bytes

lambda n:min(abs(n%10**i-n/10**i)for i in range(len(`n`)))

Experimente online!

ovs
fonte
1

MATL , 15 bytes

"GX@:&)UwU-|vX<

Entrada é uma sequência que representa o número inteiro.

Experimente online! Ou verifique todos os casos de teste .

Explicação

"         % Implicit input. Do the following as many times as input length
  G       %   Push input
  X@      %   Push iteration index (1-based), k
  :       %   Range: gives [1 2 ... k]
  &)      %   Two-ouput reference indexing: gives a substring with the first
          %   k characters in the input and then a substring with the rest
  U       %   Convert to number
  wU      %   Swap, convert to number
  -|      %   Absolute difference
  v       %   Vertically concatenate stack. This concatenates the obtained
          %   absolute difference with the minimum so far; does nothing in 
          %   the first iteration
  X<      %   Minimum of array
          % Implicit end. Implicit display
Luis Mendo
fonte
1

Limpo , 106 83 bytes

import StdEnv
@n#f=toInt o(%)n
=hd(sort[abs(f(0,i)-f(i+1,size n))\\i<-[0..size n]])

Define a função @ , usando uma string.

Principalmente evidente, a única parte complicada é f=toInt o(%)n: Isso pega a toIntclasse de funções e a compõe ( o) com a classe de operador de fatia com curry ( %) já fornecida com o primeiro argumento ( n). Como existe apenas um tipo ( Stringequivalente a {#Char}) que possui sobrecargas para ambos %e toInta linha realmente compila, enquanto normalmente é difícil compor funções durante o golfe devido à falta de informações contextuais fornecidas ao compilador.

Experimente online!

Furioso
fonte
1

Gelatina , 12 bytes

JṬ€œṗ€⁸Ḍạ/€Ṃ

Um link monádico que obtém uma lista de dígitos e retorna o número inteiro.

Experimente online!

Quão?

JṬ€œṗ€⁸Ḍạ/€Ṃ - Link: list of digits     e.g. [7,1,2,9]
J            - range of length               [1,2,3,4]
 Ṭ€          - untruth €ach                  [[1],[0,1],[0,0,1],[0,0,0,1]]
      ⁸      - chain's left argument         [7,1,2,9]
   œṗ€       - partition at truthy for €ach  [[[],[7,1,2,9]],[7,[1,2,9]],[[7,1],[2,9]],[[7,1,2],9]]
       Ḍ     - undecimal (vectorises)        [[0,7129],[7,129],[71,29],[712,9]]
         /€  - reduce €ach by:
        ạ    - absolute difference           [7129,122,42,703]
           Ṃ - minimum                       42
Jonathan Allan
fonte
1

Pitão, 10 bytes

hSaMv<./Ql

Suíte de teste

Recebe a entrada como uma sequência.

Isso usa um dos recursos mais recentes do Pyth, que é aplicar a função a uma lista como padrão para mapear a função na lista, se nenhum outro comportamento for definido. Isso significa que o vaplicado a uma lista de lista de cadeias avalia todas as cadeias.

hSaMv<./Ql
hSaMv<./QlQ    Implicit variable
      ./Q      Form all partitions of the input string.
               Split it in all possible ways, maintaining the order.
               Partitions are ordered from shortest to longest.
     <   lQ    Take the prefix as long as the input string.
               This keeps just the splits into one and two pieces.
    v          Evaluate. All strings are converted to numbers.
  aM           Map the absolute difference function.
hS             Minimum

Observe que a lista de divisões permite a divisão em 1 parte, mas o valor disso sempre será maior que o mínimo, portanto é ignorado com segurança.

isaacg
fonte
1

Tcl , 116 bytes

foreach d [split [set b [set R $argv]] {}] {append L $d
regexp .(.+) $R - R
set b [expr min($b,abs($L-$R))]}
puts $b

Experimente online!

Explicação

b ← R ← input number
for each digit (d) in the input number:
  L += d
  strip first digit off of R using a regular expression
  b ← min( b, distance between L and R )
print b

Ele funciona usando um truque de regex, permitindo um caso final degenerado que sempre será computado para maior que a diferença mínima. Para "12345", os valores são:

1 2345 → 2344
12 345 → 333
123 45 → 78
1234 5 → 1229
12345 5 → 12340 (degenerate case)
Dúthomhas
fonte
Você pode raspar bytes usando em lmapvez de foreach: tio.run/##LYuxCsMgFEV3v@IOb1DaZO8/ZHItDlolBEx4qC2FkG9/…
sergiol
1

APL + WIN, 31 bytes

⌊/|(⍎¨m↓¨⊂n)-⍎¨(m←⍳¯1+⍴n)↑¨⊂n←⎕

Solicita a entrada na tela do número inteiro como uma sequência.

Explicação:

m←⍳¯1+⍴n Create a list of numbers from 1 to length of string - 1

↑¨⊂n←⎕ Using m create a nested vector taking successively characters from the front of the string defined by m

⍎¨ Convert from character to integer

(⍎¨m↓¨⊂n) Using m create a nested vector dropping successively characters from the front of the string defined by m 

⌊/| take the minimum absolute value after subtracting the two vectors of integers
Graham
fonte
Eu não sei APL, existe uma maneira de testar isso?
ბიმო
Infelizmente o APL + WIN não está no TIO. Se você quiser jogar com o APL, pode fazer o download de uma cópia do APLX no site da Dyalog gratuitamente e meu código funciona com ele. Ele não funciona no Try APL da Dyalog on-line. dyalog.com/aplx.htm
Graham
1

Perl 5 , 51 41 + 1 ( -p) = 42 bytes

$\=$_;$\=$\>($"=abs$'-$`)?$":$\while//g}{

Experimente online!

inspirado no comentário de @ Nahuel-Fouilleul

Xcali
fonte
46 bytes$\--;$d=abs$``-$',$\=$\<0|$d<$\?$d:$\while//g}{
Nahuel Fouilleul
1

C # (.NET Core) , 112 107 + 18 = 125 bytes

n=>Enumerable.Range(1,n.Length-1).Min(i=>System.Math.Abs(int.Parse(n.Remove(i))-int.Parse(n.Substring(i))))

Experimente online!

A contagem inclui os 18 bytes em using System.Linq;. Recebe entrada como a string.

  • 5 bytes salvos por Caius Jard!
Charlie
fonte
string.Removepode economizar alguns bytes
Caius Jard
1

Lisp comum, 131 bytes

Minha primeira vez participando de código de golfe e decidi usar o Lisp, já que eu gosto.

Aqui está a minha solução:

(defun f (s) (loop for i from 1 below (length s) minimizing (abs (- (parse-integer (subseq s 0 i)) (parse-integer (subseq s i))))))

A entrada precisa ser uma sequência, não um número inteiro ou lista.

JNevens
fonte
3
Bem-vindo ao PPCG! Infelizmente, eu não conheço o Lisp, mas notei que você pode encurtar isso em 11 bytes se a tornar uma função sem nome e remover algum espaço em branco, veja aqui . Se você ainda não viu este , talvez você vai encontrar algumas dicas.
ბიმო