Encuentra la diferencia BCD de un número

20

Diferencia BCD

Dado un número entero n, conviértalo a BCD ( decimal codificado en binario ) reemplazando cada dígito decimal con su representación binaria de 4 dígitos

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

Luego gire la lista de dígitos binarios para encontrar los números más grandes y más pequeños, representables por esta lista sin otras reorganizaciones.

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)

Convierta estos números de nuevo a decimal, tratando la lista de bits como binario regular y reste el más pequeño del más grande:

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 salida es la diferencia de los números más grandes y más pequeños encontrados.

Casos de prueba:

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

Respuestas:

7

Wolfram Language (Mathematica) , 89 88 bytes

Gracias a Jenny_mathy por guardar 1 byte.

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

Pruébalo en línea!

Esto es terriblemente ineficiente, porque genera n rotaciones del BCD de n , que es mucho más de lo que necesitamos. Podemos hacer esto es un poco más eficiente guardando el resultado de la Join@@en ky sustitución de la #al final con Length@k. Eso nos permite generar un diagrama de dispersión con bastante facilidad:

ingrese la descripción de la imagen aquí

Estoy realmente intrigado por el contraste de la estructura local y el caos general.

Martin Ender
fuente
Max@#-Min@#&Guarda un byte. ¿Derecha?
J42161217
@ Jenny_mathy Sí, gracias! :)
Martin Ender
1
Hice esto de nuestras soluciones Max@#-Min@#&[#~FromDigits~2&/@Partition[s=Join@@(i=IntegerDigits)[i@#,2,4],Tr[1^s],1,1]]&89 bytes Y eficiente. ¡Maldita sea ese byte!
J42161217
En realidad, la trama es un patrón repetido. Esas "nubes caóticas" suceden cada 10 ^ n (la trama "salta" y crea una nueva): 1-9,10-99,100-999... aquí hay algunos zooms diferentes: imgur.com/RXLMkco
J42161217
@Jenny_mathy seguro, pero la estructura dentro de estos intervalos parece muy caótica (con estructuras solo a escalas mucho más pequeñas).
Martin Ender
6

Jalea , 13 bytes

Dd4d2FṙJ$ḄṢIS

Pruébalo en línea!

Cómo funciona

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
fuente
4

PowerShell , 153 bytes

$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]

Pruébalo en línea!

Estúpidas llamadas largas de .NET para convertir a / desde binario realmente aumentan la longitud aquí. ;-)

Tomamos la entrada como $args, la envolvemos en una cadena y luego la convertimos en una charmatriz. Hacemos un bucle sobre cada dígito, convertcolocando el dígito toStringen la base 2(es decir, convirtiendo el dígito en un número binario), luego .padLeftpara convertirlo en un número binario de cuatro dígitos. Esa matriz resultante de cadenas se edita -joinen una sola cadena y se vuelve a emitir como una charmatriz antes de guardarla $b.

A continuación, hacemos un bucle $b, lo que garantiza que hagamos bucles suficientes veces para tener en cuenta cada rotación. En cada iteración, quitamos el primer carácter $xy los caracteres restantes para $yusar la asignación múltiple. Luego, los fusionamos nuevamente $b=$y+$xpara mover el primer elemento al final, es decir, rotar efectivamente la matriz en uno. Eso se -joinedita en una cadena, que se utiliza como entrada a la convertllamada para convertir la cadena de la base binaria 2en una Int64. Luego, sorttodos esos números resultantes y los almacenamos $c. Finalmente, tomamos la más grande [-1]y restamos la más pequeña [0]. Eso queda en la tubería y la salida es implícita.

AdmBorkBork
fuente
4

Ohm v2 , 15 bytes

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

Pruébalo en línea!

Explicación:

€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
fuente
4

JavaScript (ES6), 118 100 99 bytes

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>

Editar: Guardado 11 bytes gracias a @RickHitchcock. Guardado 1 byte gracias a @ETHproductions. Explicación: El 0x1prefijo hace que la entrada se vuelva a analizar como un número hexadecimal, cuyo binario es el mismo que el BCD del número original con un prefijo 1 (creo que es más elegante que cualquier otra forma de relleno a un múltiplo de 4 dígitos) . Excluyendo el prefijo, que se cambia de 1 a 0, la cadena resultante se gira en cada posición posible y se convierte de binario a decimal. Finalmente se restan el máximo y el mínimo.

Neil
fuente
1
@RickHitchcock Envuelva la cadena en dos puntos de retroceso ... a menos que quiera escribir algo así, .join`` en cuyo caso necesita tres puntos de retroceso, etc.
Neil
Buena idea usar hexadecimal. Ahorre 11 bytes como este: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 Gracias, eso me ayudó a ... cortar ... otros 7 bytes eliminando otro slicetambién.
Neil
1
El m=>Math[m]truco es genial. Tal vez cambiar (+`0x1${n}`)a ('0x1'+n-0)o similar?
ETHproducciones
3

Python 2 , 115 113 bytes

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)

Pruébalo en línea!

Jonathan Frech
fuente
3

Casco , 18 bytes

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

Pruébalo en línea!

Debería haber una forma más corta de convertir un dígito en su representación binaria de 4 bits ...

Explicación

§-▼▲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
León
fuente
3

APL (Dyalog) , 31 bytes

Programa completo del cuerpo. Solicita el número de STDIN. Imprime el resultado en STDOUT.

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

Pruébalo en línea!

 solicitud de línea de texto desde STDIN

⍎¨ ejecutar (evaluar) cada (personaje)

(... )⊤ codificar (anti-base) en el siguiente sistema de números:

4/2 cuatro bits binarios

 transponer

, ravel (aplanar)

b← tienda en b(para b de ciertas piezas)

 adjuntar (para que usemos esta lista completa para cada rotación)

(... )⌽¨ rotar (izquierda) en cada una de las siguientes cantidades:

≢b longitud de b

I nices de eso

2⊥¨ decodificar cada uno de base-2.

(... ) aplique la siguiente función tácita a eso

⌈/ el max (-reducción)

- menos

⌊/ el min (-reducción)

Adán
fuente
fácilmente podría entrenar este bit: (⍳≢b) ⌽¨⊂b ←
ngn
o incluso mejor - uso (≢, /, ⍨) en lugar de lo obvio (⍳∘≢⌽¨⊂)
NGN
2

Ruby , 96 91 bytes

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

Pruébalo en línea!

  • Guardado 5 bytes gracias a displayname
Restablecer a Monica - notmaynard
fuente
-> 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} debe tener 91 bytes
mostrar
@displayname Ha, sí, tienes razón. Gracias
Restablecer Monica - notmaynard
2

Mathematica, 110 99 bytes

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


Pruébalo en línea!

J42161217
fuente
2

Python 3, 141 bytes

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)

Pruébalo en línea

sonrad10
fuente
2

Retina , 96 89 bytes

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

_

Pruébalo en línea! Algo lento, por lo que el enlace solo incluye un pequeño caso de prueba. Editar: Guardado 7 bytes gracias a @MartinEnder. Explicación:

.
@@@$&

Prefije tres @sa cada dígito. (Estos representan los 0s del BCD, pero son más golfistas).

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

Cambie la @s a _s (que representa la 1s del BCD) cuando corresponda.

T`E`@
\d
_

Arregle el último dígito del BCD.

.
$&$'$`¶

Genera todas las rotaciones.

O`

Clasifícalos en orden ascendente.

_
@_
+`_@
@__

Conviértalos en unarios.

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

_

Resta el primero del último número, ignorando los números intermedios, y convierte a decimal.

Neil
fuente
No es necesario utilizar %la conversión de binario a unario y puede guardar algunos bytes más utilizando otros caracteres que no sean 0y 1para binario: tio.run/##K0otycxL/…
Martin Ender
@MartinEnder Oh, creo que eso databa de cuando estaba intentando y no utilicé una de sus rutinas de conversión binarias ...
Neil
2

Haskell , 130 bytes

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]

Pruébalo en línea!

Explicación / Ungolfed

Dado que vamos a usar foldl1((+).(2*))para convertir de binario a decimal, bien podríamos no usar maximumy minimumsino foldl1 max(o lo mismo con minrespectivamente) y usar un short r = foldr1.

Ahora, definamos un operador f#xque convierta xa BCD, genere todas las rotaciones, reduzca estas usando fy conviértalo a decimal:

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

Ahora solo es cuestión de usar este operador una vez con maxy una vez con miny restando sus resultados:

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

PHP 156 153 bytes

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

Pruébalo en línea!

Jo
fuente
2

Japt -x , 20 bytes

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

Pruébalo en línea!

Ingrese como una matriz de dígitos.

Explicación:

®¤                      #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
fuente
1
Puede usar la -xbandera para guardar 2 bytes.
Oliver
1
20 bytes .
Oliver
1

J, 43 bytes

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

Pruébalo en línea!

A veces el estilo tácito dificulta las cosas. Pero probablemente haya una manera de hacerlo con un estilo tácito que sea mucho más conciso que esto. Creo que recuerdo una mejor manera de dividir un número en dígitos que no sean"."0@": pero parece que no puedo recordarlo ...

Explicación

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

La preposición y eliminación de 8 es para garantizar que esté presente el número correcto de ceros (J cambiará la forma de sus matrices para que tengan el tamaño de su elemento de longitud máxima, y ​​8 tiene 4 dígitos en binario para que se use).

col
fuente
1

APL (NARS), 34 caracteres, 68 bytes

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

alguna pequeña prueba:

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

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

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

Pruébalo en línea!

Xcali
fuente