Trouver la différence BCD d'un nombre

20

Différence BCD

Étant donné un entier n, convertissez-le en BCD ( décimal codé binaire ) en remplaçant chaque chiffre décimal par sa représentation binaire à 4 chiffres

 234 -> 0 0 1 0 0 0 1 1 0 1 0 0

Faites ensuite pivoter la liste des chiffres binaires afin de trouver les plus grands et les plus petits nombres, représentables par cette liste sans autres réarrangements.

max: 1 1 0 1 0 0 0 0 1 0 0 0  (the entire list rotated left 6 times)
min: 0 0 0 0 1 0 0 0 1 1 0 1 (the entire list rotated right 2 times)

Convertissez ces nombres en décimal, en traitant la liste de bits comme un binaire normal et soustrayez le plus petit du plus grand:

1 1 0 1 0 0 0 0 1 0 0 0 -> 3336
0 0 0 0 1 0 0 0 1 1 0 1 -> 141

3336 - 141 -> 3195

La sortie est la différence entre le plus grand et le plus petit nombre trouvé.

Cas de test:

234 -> 3195
1234 -> 52155
12 -> 135
975831 -> 14996295
4390742 -> 235954919
9752348061 -> 1002931578825
Galen Ivanov
la source

Réponses:

7

Wolfram Language (Mathematica) , 89 88 octets

Merci à Jenny_mathy d'avoir enregistré 1 octet.

i=IntegerDigits;Max@#-Min@#&[#~FromDigits~2&/@NestList[RotateRight,Join@@i[i@#,2,4],#]]&

Essayez-le en ligne!

C'est terriblement inefficace, car il génère n rotations du BCD de n , ce qui est bien plus que ce dont nous avons besoin. Nous pouvons rendre cela un peu plus efficace en enregistrant le résultat de Join@@in ket en remplaçant le #à la fin par Length@k. Cela nous permet de générer un nuage de points assez facilement:

entrez la description de l'image ici

Je suis vraiment intrigué par le contraste de la structure locale et du chaos général.

Martin Ender
la source
Max@#-Min@#&enregistre un octet. droite?
J42161217
@Jenny_mathy Ouais, merci! :)
Martin Ender
1
Je l'ai fait à partir de nos solutions Max@#-Min@#&[#~FromDigits~2&/@Partition[s=Join@@(i=IntegerDigits)[i@#,2,4],Tr[1^s],1,1]]&89 octets ET efficaces. bon sang cet octet!
J42161217
En fait, l'intrigue est une répétition répétée. Ces "nuages ​​chaotiques" se produisent tous les 10 ^ n (l'intrigue "saute" et en crée un nouveau): 1-9,10-99,100-999... voici quelques zooms différents: imgur.com/RXLMkco
J42161217
@Jenny_mathy bien sûr, mais la structure à l'intérieur de ces intervalles semble très chaotique (avec des structures uniquement à des échelles beaucoup plus petites).
Martin Ender
6

Gelée , 13 octets

Dd4d2FṙJ$ḄṢIS

Essayez-le en ligne!

Comment ça fonctionne

Dd4d2FṙJ$ḄṢIS  Main link. Argument: n

D              Decimal; convert n to base 10 (digit array).
 d4            Divmod 4; map each digit d to [d/4, d%4].
   d2          Divmod 2; map each [d/4, d%4] to [[d/8, d/4%2], [d%4/2, d%2]].
     F         Flatten the resulting 3D binary array.
      ṙJ$      Take all possible rotations.
         Ḅ     Convert each rotation from binary to integer.
          Ṣ    Sort the resulting integer array.
           I   Take the forward differences.
            S  Take the sum.
Dennis
la source
4

PowerShell , 153 octets

$b=[char[]]-join([char[]]"$args"|%{[convert]::toString(+"$_",2).PadLeft(4,'0')})
($c=$b|%{$x,$y=$b;[convert]::ToInt64(-join($b=$y+$x),2)}|sort)[-1]-$c[0]

Essayez-le en ligne!

De longs appels .NET stupides pour convertir vers / à partir de binaires gonflent vraiment la longueur ici. ;-)

Nous prenons l'entrée comme $args, l'enveloppons dans une chaîne, puis la charconvertissons en un tableau. Nous faisons une boucle sur chaque chiffre, converting le chiffre toStringdans la base 2(c'est-à-dire, en transformant le chiffre en un nombre binaire), puis.padLeft en en faisant un nombre binaire à quatre chiffres. Ce tableau de chaînes résultant est ensuite -joinédité en une seule chaîne et retransmis en tant que chartableau avant d'être enregistré dans $b.

Ensuite, nous bouclons $b, ce qui garantit que nous bouclons suffisamment de fois pour tenir compte de chaque rotation. Chaque itération, nous décollons le premier caractère $xet les caractères restants pour $yutiliser plusieurs affectations. Ensuite, nous les fusionnons à nouveau $b=$y+$xpour déplacer le premier élément à la fin, c'est-à-dire en faisant tourner efficacement le tableau de un. C'est -joined dans une chaîne, qui est utilisée comme entrée de l' convertappel pour transformer la chaîne de la base binaire 2en un Int64. Nous avons ensuite sorttous ces nombres résultants et les stockons dans $c. Enfin, nous prenons le plus grand [-1]et soustrayons le plus petit [0]. Cela reste sur le pipeline et la sortie est implicite.

AdmBorkBork
la source
4

Ohm v2 , 15 octets

€b4Ü. 0\;Jγó↕]a

Essayez-le en ligne!

Explication:

€b4Ü. 0\;Jγó↕]a  Main wire, arguments: a (integer)

€       ;        Map the following over each digit of a...
 b                 Convert to binary
  4Ü               Right-justify w/ spaces to length 4
    . 0\           Replace all spaces with zeroes
         J       Join together binary digits
          γó     Get all possible rotations and convert back to decimal
            ↕    Find the minimum *and* maximum rotation
             ]a  Flatten onto stack and get the absolute difference
Nick Clifford
la source
4

JavaScript (ES6), 118 100 99 octets

f=
n=>(g=m=>Math[m](...[...s=(`0x1`+n-0).toString(2)].map(_=>`0b${s=0+s.slice(2)+s[1]}`)))`max`-g`min`
<input type=number min=0 oninput=o.textContent=f(this.value)><pre id=o>

Edit: enregistré 11 octets grâce à @RickHitchcock. 1 octet enregistré grâce à @ETHproductions. Explication: Le 0x1préfixe fait que l'entrée est analysée comme un nombre hexadécimal, dont le binaire est le même que le BCD du numéro d'origine avec un préfixe 1 (je pense que c'est plus golfique que toute autre façon de remplir un multiple de 4 chiffres) . En excluant le préfixe, qui est changé de 1 à 0, la chaîne résultante est ensuite tournée à chaque position possible et convertie du retour binaire en décimal. Enfin, le maximum et le minimum sont soustraits.

Neil
la source
1
@RickHitchcock Enveloppez la chaîne de doubles backticks ... à moins que vous ne vouliez écrire quelque chose comme .join`` dans ce cas, vous avez besoin de triple backticks etc.
Neil
Bonne idée d'utiliser hexadécimal. Économisez 11 octets comme ceci:n=>(g=m=>Math[m](...[...s=(+`0x1${n}`).toString(2).slice(1)]‌​.map(_=>`0b${s=s.sli‌​ce(1)+s[0]}`)))`max`‌​-g`min`
Rick Hitchcock
1
@RickHitchcock Merci, cela m'a aidé ... à couper ... encore 7 octets en supprimant un autre sliceaussi!
Neil
1
L' m=>Math[m]astuce est géniale. Peut-être changer (+`0x1${n}`)à ('0x1'+n-0)ou similaire?
ETHproductions
3

Python 2 , 115 113 octets

  • Enregistré quelques octets grâce aux ovs .
  • Enregistré deux octets grâce à M. Xcoder .
b="".join(format(int(n),"04b")for n in`input()`)
b=[int(b[s:]+b[:s],2)for s in range(len(b))]
print max(b)-min(b)

Essayez-le en ligne!

Jonathan Frech
la source
3

Décortiquer , 18 octets

§-▼▲mḋUMṙNṁȯtḋ+16d

Essayez-le en ligne!

Il devrait y avoir un moyen plus court de convertir un chiffre en sa représentation binaire 4 bits ...

Explication

§-▼▲mḋUMṙNṁȯtḋ+16d
                 d    Get the list of digits of the input
          ṁȯ          For each digit...
              +16      add 16
             ḋ         convert to binary
            t          drop the first digit
       MṙN            Rotate the list by all possible (infinite) numbers
      U               Get all rotations before the first duplicated one
    mḋ                Convert each rotation from binary to int
§-▼▲                  Subtract the minimum from the maximum value
Leo
la source
3

APL (Dyalog) , 31 octets

Corps du programme complet. Demande le numéro de STDIN. Imprime le résultat vers STDOUT.

(⌈/-⌊/)2⊥¨(⍳≢b)⌽¨⊂b←,⍉(4/2)⊤⍎¨⍞

Essayez-le en ligne!

 invite pour la ligne de texte de STDIN

⍎¨ exécuter (évaluer) chacun (caractère)

()⊤ Encoder (anti-base) dans le système de numérotation suivant:

4/2 quatre bits binaires

 transposer

, défiler (aplatir)

b← stocker dans b(pour b inaire)

 joindre (afin que nous utilisions toute cette liste pour chaque rotation)

()⌽¨ Tourner (à gauche) de chacun des montants suivants:

≢b longueur de b

les indices de cela

2⊥¨ décoder chacun de la base-2.

() Appliquer la fonction tacite suivante à ce

⌈/ le max (-réduction)

- moins

⌊/ le min (-réduction)

Adam
la source
vous pouvez facilement former ce bit: (⍳≢b) ⌽¨⊂b ←
ngn
ou encore mieux - utilisez (≢, /, ⍨) au lieu de l'évidence (⍳∘≢⌽¨⊂)
ngn
2

Rubis , 96 91 octets

->n{r=""
n.digits.map{|d|r="%04b"%d+r}
s=r.chars.map{(r=r[1..-1]+r[0]).to_i 2}
s.max-s.min}

Essayez-le en ligne!

  • Enregistré 5 octets grâce à displayname
Réintégrer Monica - notmaynard
la source
-> n {r = "" n.digits.map {| d | r = "% 04b"% d + r} s = r.chars.map {(r = r [1 ..- 1] + r [ 0]). To_i 2} s.max-s.min} doit être de 91 octets
displayname
@displayname Ha, oui, vous avez raison. Merci
Réintégrer Monica - notmaynard
2

Mathematica, 110 99 octets

Max@#-Min@#&[#~FromDigits~2&/@Partition[s=Join@@Tuples[{0,1},4][[IntegerDigits@#+1]],Tr[1^s],1,1]]&


Essayez-le en ligne!

J42161217
la source
2

Python 3, 141 octets

def f(a):a=''.join([format(int(i),'#010b')[-4:]for i in str(a)]);b=[int(''.join(a[-i:]+a[:-i]),2)for i in range(len(a))];return max(b)-min(b)

Essayez-le en ligne

sonrad10
la source
2

Rétine , 96 89 octets

.
@@@$&
@(?=@@[89]|@[4-7]|[2367])
_
T`E`@
\d
_
.
$&$'$`¶
O`
_
@_
+`_@
@__
s`(_+).*\W\1

_

Essayez-le en ligne! Un peu lent, donc le lien ne comprend qu'un petit cas de test. Edit: 7 octets enregistrés grâce à @MartinEnder. Explication:

.
@@@$&

Préfixez trois @s à chaque chiffre. (Ceux-ci représentent les 0s du BCD, mais sont plus golfeurs.)

@(?=@@[89]|@[4-7]|[2367])
_

Remplacez le @s par _s (représentant le 1s du BCD) le cas échéant.

T`E`@
\d
_

Fixez le dernier chiffre du BCD.

.
$&$'$`¶

Générez toutes les rotations.

O`

Triez-les par ordre croissant.

_
@_
+`_@
@__

Convertissez-les en unaire.

s`(_+).*\W\1

_

Soustrayez le premier du dernier nombre, en ignorant les nombres intermédiaires, et convertissez-les en décimal.

Neil
la source
Il n'est pas nécessaire d'utiliser %la conversion binaire en unaire et vous pouvez économiser quelques octets de plus en utilisant d'autres caractères que 0et 1pour le binaire: tio.run/##K0otycxL/…
Martin Ender
@MartinEnder Oh, je pense que cela date de quand j'essayais et échouais d'utiliser l'une de vos routines de conversion binaire ...
Neil
2

Haskell , 130 octets

r=foldl1
f x=max#x-min#x
f#x|s<-show x=r((+).(2*)).r f.take(sum$4<$s).iterate(drop<>take$1)$do d<-s;mapM(pure[0,1])[1..4]!!read[d]

Essayez-le en ligne!

Explication / Non golfé

Puisque nous allons utiliser foldl1((+).(2*))pour convertir du binaire en décimal, nous pourrions aussi bien ne pas utiliser maximumet minimummais plutôt foldl1 max(ou même avec minrespectivement) et utiliser un courtr = foldr1 .

Maintenant, définissons un opérateur f#xqui convertit xen BCD, génère toutes les rotations, réduisons celles-ci en utilisant fet convertissons-le en décimal:

f # xs
  | s <- show xs
  = foldr1 ((+).(2*))                             -- convert from binary to decimal
  . foldr1 f                                      -- reduce by either max or min
  . take (4 * length s)                           -- only keep 4*length s (ie. all "distinct" rotations)
  . iterate (drop<>take $ 1)                      -- generate infinite list of rotations
  $ do d<-s; mapM (pure[0,1]) [1..4] !! read [d]  -- convert to BCD

Il ne reste plus qu'à utiliser cet opérateur une fois avec maxet une fois avec minet à soustraire leurs résultats:

f x = max#x - min#x
ბიმო
la source
2

PHP, 156 153 octets

<?foreach(str_split($argv[1])as$n)$s.=str_pad(decbin($n),4,0,0);for(;$i<$a=strlen($s);)$r[]=bindec(substr($s,$i).substr($s,0,$i++));echo max($r)-min($r);

Essayez-le en ligne!

Jo.
la source
2

Japt -x , 20 octets

®¤ùT4쬣ZéY ì2Ãn äa

Essayez-le en ligne!

Entrez sous forme de tableau de chiffres.

Explication:

®¤                      #Map each digit to base 2
  ùT4Ã                  #Pad each one to 4 places
      ¬                 #Join them to a single binary string
       ¬                #Split them to an array of single characters
        £      Ã        #For each index Y in that array:
         ZéY            # Get the array rotated Y times
             ì2         # Convert the array from binary to decimal
                n       #Sort the results
                  äa    #Get the absolute difference between each element
                        #Implicitly output the sum
Kamil Drakari
la source
1
Vous pouvez utiliser l' -xindicateur pour enregistrer 2 octets.
Oliver
1
20 octets .
Oliver
1

J, 43 octets

3 :'(>./-<./)#.(i.@#|."0 1]),}.#:8,"."0":y'

Essayez-le en ligne!

Parfois, le style tacite rend les choses difficiles. Mais il y a probablement un moyen de le faire tacitement qui est beaucoup plus concis que cela. Je pense que je me souviens d'une meilleure façon de diviser un nombre en chiffres autres que "."0@":mais je n'arrive pas à m'en souvenir ...

Explication

3 :'(>./-<./)#.(i.@#|."0 1]),}.#:8,"."0":y'
                                         y  the input (integer)
                                       ":   convert to string
                                   "."0     evaluate each char (split to digits)
                                 8,         prepend 8
                               #:           debase 2
                             }.             behead (remove the 8)
                            ,               ravel (flatten)
               (i.@#|."0 1])                create a list of rotations
                    |.    ]                   rotate the list
                      "0 1                    for each number on the left
                i.@#                          range 0 ... length - 1
             #.                             convert rotations back to base 10
    (>./-<./)                               max minus min

Le préfixe et la suppression de 8 visent à garantir la présence du bon nombre de zéros (J remodèlera ses tableaux pour qu'ils correspondent à la taille de leur élément de longueur maximale, et 8 correspond à 4 chiffres en binaire, il est donc utilisé).

cole
la source
1

APL (NARS), 34 caractères, 68 octets

{(⌈/-⌊/)2⊥¨{⍵⌽a}¨⍳≢a←∊⍉(4⍴2)⊤⍎¨⍕⍵}

un petit test:

  h←{(⌈/-⌊/)2⊥¨{⍵⌽a}¨⍳≢a←∊⍉(4⍴2)⊤⍎¨⍕⍵}
  h 9752348061
1002931578825
  h 0
0
RosLuP
la source
1

Perl 5 , 97 91 89 + 2 ( -F) = 99 93 91 octets

$a=sprintf"%04b"x@F,@F;@r=sort{$b<=>$a}map{oct"0b".($a=(chop$a).$a)}(@F)x4;say$r[0]-pop@r

Essayez-le en ligne!

Xcali
la source