Soyez le plus juste possible


33

introduction

Dans ce défi, vous devez diviser un entier en deux parties. Étant donné que personne n'aime manger le plus petit morceau de gâteau, votre objectif est d'être aussi juste que possible. Par exemple, si vous souhaitez scinder le nombre entier 7129en deux parties, vous avez trois possibilités.

7,129, 71,29et 712,9sont toutes des possibilités, mais 71,29est le moyen le plus juste de le scinder en deux, car il minimise la différence entre les deux:

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

Défi

Étant donné un entier, déterminez le meilleur moyen de le partitionner comme décrit ci-dessus et signalez la différence résultante.

Règles

  • La division n'a de sens que pour des entiers de longueur au moins deux, l'entrée sera toujours ≥ 10
  • L'entrée peut être un entier, une liste de chiffres ou une chaîne
  • Vous n'êtes pas obligé de gérer une entrée invalide

Testcases

Il vous suffit de signaler la différence résultante, le partitionnement n’est ici qu’à titre d’illustration:

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

Réponses:


11

Brachylog , 12 à 11 octets

Ma première réponse au Brachylog

Prendre l'entrée comme une chaîne

{~cĊịᵐ-ȧ}ᶠ⌋

Essayez-le en ligne!

Explication:

sera f ind toutes les sorties possibles pour le prédicat {…}et les stocker dans une liste. ~cindique que la sortie est une liste qui, une fois c oncatenated, est égale à l'entrée. Next Ċaffirme que la sortie de ~ca longueur 2.

ịᵐconvertit les deux éléments de la sortie en nombres entiers (cela supprime les premiers 0s), prend la différence absolue des deux éléments.

Une fois que nous avons notre liste de toutes les sorties possibles, nous obtenons l’élément minimum avec


10

Haskell , 48 octets

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

[1..n] rend cela trop lent pour les cas de test plus grands.

Essayez-le en ligne!


Bon travail! Je me suis tellement aveuglé en utilisant des chaînes que j'ai oublié que je pouvais utiliser l'arithmétique.
Wheat Wizard

9

05AB1E , 9 octets

Code:

ā¤âε£ÆÄ}W

Utilise le codage 05AB1E . Essayez-le en ligne!

Explication

ā            # 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

1
Si vous remplacez £par °‰vous n'en aurez ¤âplus besoin .
Emigna


7

Perl 6 , 40 octets

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

Essaye-le

Étendu:

{  # 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
      /^ (.+) (.+) $/
}



6

Prolog (SWI) , 195 189 154 117 bytes

35 octets sauvés grâce à 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).

Essayez-le en ligne!

C’est la première fois que je joue au golf avec prologue, alors c’est peut-être un peu horrible. Voici comment cela fonctionne.

Au plus haut niveau que nous avons *. *prend Aet H, et détermine si Hest le plus petit moyen de se séparer A.

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

La première ligne utilise ici une technique de ce poste SO , pour essentiellement réaliser une carte du prédicat r(A)sur les entiers de 0à A. Puisque rconfirme les valeurs de chaque partition, cela nous donnera les valeurs de toutes les partitions possibles, plus toute une charge de déchets supplémentaires. Toutes ces partitions seront stockées Ldans aucun ordre particulier. Une fois que cela est fait, nous trions la liste pour trouver le plus petit élément. Nous utilisons ensuite une coupe pour éviter les retours en arrière.

Ensuite, nous avons la définition de r. rCalcule d’ abord les deux résultats de la scission en les nommant Xet Y.

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

Ensuite, nous affirmons que Cc’est la différence et que c’est positif.

  C is abs(X-Y).

Il semble y avoir là un méfait, comme ce X is div(A,10**B),Y is div(A,10**B)sera toujours le cas C=0(le sens Hsera toujours égal à 0 ). Devrais Y is mod(A,10**B)je présume.
Emigna

La deuxième ligne pourrait également r(A,B,C):-Z is 10**B,divmod(A,Z,X,Y),C is abs(X-Y).économiser 32 octets (si vous utilisez au moins le prologue SWI, vous n'êtes pas sûr des autres versions).
Emigna

La première ligne pourrait par exemple commencer par au A*Hlieu d' l(A,H)enregistrer 3 autres. Et si vous utilisez SWI, vous pouvez ajouter un lien TIO
Emigna

De plus, je ne pense pas que vous ayez besoin de ça, n'est- ,!ce pas? Il ne devrait pas y avoir de retour en arrière à ce stade.
Emigna

@ Emigna Merci pour les astuces, je les implémenterai bientôt. J'ai également pensé que ,!ce ne serait pas nécessaire, mais lorsque je teste le programme, il effectue une trace. Il semble essayer toutes les commandes possibles L, puis les trie toutes. Cela signifie que cela donnera les mêmes A!temps de réponse .
Wheat Wizard

5

Haskell , 68 ans 65 octets

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

Essayez-le en ligne!

Explication

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
 ]

4

Charbon de bois , 14 octets

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

Essayez-le en ligne! Le lien est vers la version verbeuse du code. De manière pratique, je peux utiliser la variante à 2 arguments de Slice. Explication:

   θ            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

4

Gelée , 9 à 8 octets

ḌÐƤḊạḌƤṂ

Essayez-le en ligne!

-1 octet grâce à Dennis. L'entrée est une liste de chiffres.

Explication

ḌÐƤḊạḌƤṂ
ḌÐƤ          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

Hm, votre explication ne semble pas refléter ce que votre code fait réellement.
Erik l'Outgolfer

@EriktheOutgolfer S'agit-il de la partie «supprime le dernier élément» alors qu'elle devrait indiquer «supprimer le premier élément»? Je vais arranger ça, merci de me l'avoir signalé
dylnan

3

Funky , 159 134 99 octets

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

En fait, il semble que la pose soit conforme aux spécifications.

Essayez-le en ligne!


3

Retina , 36 octets

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

Om`^.*
\G1

Essayez-le en ligne!

Explication

\B
,$'¶$`

Cela génère toutes les partitions possibles sur des lignes séparées, ainsi qu'une ligne de fin avec l'entrée d'origine.

\d+
$*

Convertissez chaque nombre de chaque partition en unaire.

(1*),\1

Supprimer une quantité maximale et égale de 1s des deux parties de chaque partition (c'est-à-dire supprimer le minimum et le soustraire du maximum, ce qui donne la différence absolue).

Om`^.*

Triez les lignes.

\G1

Comptez le 1s sur la première ligne, ce qui donne la différence absolue minimale.


3

J , 32, 27 23 octets

-5 octets grâce à FrownyFrog! -4 octets si l'entrée est une chaîne.

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

Essayez-le en ligne!

Original: prend un nombre en entrée

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

Comment ça marche:

                             @": - 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

Essayez-le en ligne!


@FrownyFrog - Merci!
Galen Ivanov

3

JavaScript (ES6), 64 octets

Prend l'entrée sous forme de chaîne.

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

Cas de test

Commenté

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)

Non récursif (ES7), 65 octets

Prend l'entrée sous forme de chaîne.

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

Cas de test

Commenté

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

Remarque : Dans les deux versions, lune chaîne est forcée lors de la première itération. Normalement, nous devrions faire attention aux zéros non significatifs dans un littéral numérique: 0123 - 10 === 73car 0123est analysé comme une valeur octale (ceci est maintenant déconseillé, mais reste valide en mode non strict). Mais '0123' - '10' === 113, le zéro de tête étant cette fois ignoré. Donc, il est judicieux de le faire.

A partir de la spécification de l'opération abstraite ToNumberappliquée à une chaîne:

Un StringNumericLiteral qui est décimal peut avoir un nombre quelconque de 0 premiers chiffres


3

APL (Dyalog) , 27 octets

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

Essayez-le en ligne!

Comment?

¯1+≢⍵- longueur de nmoins 1

∘.=⍨⍳ - matrice d'identité

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

1,- Préposer 1pour chaque ligne

- divisé en rangées

⊂∘⍵¨ - pour chaque partitionner la chaîne par celle-ci

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

- aplatir

-/ - réduire chaque paire avec soustraction

| - prendre des valeurs absolues

⌊/ - le minimum


APL (Dyalog) , 35 octets

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

Essayez-le en ligne!


3

Gelée , 11 octets

ŒṖṖLÐṂḌạ/€Ṃ

Essayez-le en ligne!

-3 octets grâce à dylnan

Comment ça marche

ŒṖṖ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

Vous pouvez changer L=2$$Ðfpour ṖLÐṂdans ce cas
dylnan



1

MATL , 15 octets

"GX@:&)UwU-|vX<

L'entrée est une chaîne représentant l'entier.

Essayez-le en ligne! Ou vérifiez tous les cas de test .

Explication

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


1

Propre , 106 83 octets

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

Définit la fonction @ en prenant une chaîne.

Le problème le plus complexe est le suivant f=toInt o(%)n: Il prend la toIntclasse de fonctions et la compose ( o) avec la classe d'opérateur de tranche au curry ( %) déjà fournie avec le premier argument ( n). Puisqu'il n'y a qu'un seul type ( Stringéquivalent à {#Char}) qui a des surcharges pour les deux %ettoInt la ligne est effectivement compilée, alors qu'il est normalement difficile de composer des fonctions lorsque vous jouez au golf en raison du manque d'informations contextuelles données au compilateur.

Essayez-le en ligne!


1

Gelée , 12 octets

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

Un lien monadique prenant une liste de chiffres et renvoyant l'entier.

Essayez-le en ligne!

Comment?

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

1

Pyth, 10 octets

hSaMv<./Ql

Suite de tests

Prend l'entrée sous forme de chaîne.

Cela utilise l'une des fonctionnalités les plus récentes de Pyth, c'est-à-dire que l'application d'une fonction à une liste permet par défaut de mapper la fonction sur la liste, si aucun autre comportement n'est défini. Cela signifie que l' vapplication à une liste de chaînes évalue toutes les chaînes.

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

Notez que la liste des divisions permet la division en une seule pièce, mais que la valeur de celle-ci sera toujours supérieure au minimum, elle est donc ignorée en toute sécurité.


1

Tcl , 116 octets

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

Essayez-le en ligne!

Explication

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

Cela fonctionne en utilisant une astuce regex permettant un cas final dégénéré qui calculera toujours à une différence supérieure à la différence minimale. Pour «12345», les valeurs sont:

1 2345 → 2344
12 345 → 333
123 45 → 78
1234 5 → 1229
12345 5 → 12340 (degenerate case)

You can shave bytes using lmap instead of foreach: tio.run/##LYuxCsMgFEV3v@IOb1DaZO8/ZHItDlolBEx4qC2FkG9/…
sergiol


1

APL+WIN, 31 bytes

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

Prompts for screen input of integer as a string.

Explanation:

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

I don't know APL, is there a way to test this?
ბიმო

Unfortunately APL+WIN is not in TIO. If you want to play with APL you can download a copy of APLX from the Dyalog website for free and my code works with it. It does not work in Dyalog's Try APL on-line. dyalog.com/aplx.htm
Graham


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

Try it online!

The count includes the 18 bytes in using System.Linq;. Takes input as a string.

  • 5 bytes saved by Caius Jard!

string.Remove might save you a few bytes
Caius Jard

1

Common Lisp, 131 bytes

My first time participating in code golf and I decided to use Lisp, since I like it.

Here is my solution:

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

Input needs to be a string, not integer or list.


3
Welcome to PPCG! Unfortunately I don't know Lisp, but I noticed that you can shorten this by 11 bytes if you make it an unnamed function and remove some whitespace, see here. If you haven't seen this, maybe you'll find some tips.
ბიმო
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.