Znajdź różnicę BCD liczby

20

Różnica BCD

Biorąc pod uwagę liczbę całkowitą n, przekonwertuj ją na BCD ( dziesiętny kodowany binarnie ), zastępując każdą cyfrę dziesiętną jej 4-cyfrową reprezentacją binarną

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

Następnie obróć listę cyfr binarnych, aby znaleźć największe i najmniejsze liczby, reprezentowane przez tę listę bez innych zmian.

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)

Przekształć te liczby z powrotem na dziesiętne, traktując listę bitów jako zwykłą wartość binarną i odejmij najmniejszą od największej:

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

Wynik jest różnicą największych i najmniejszych znalezionych liczb.

Przypadki testowe:

234 -> 3195
1234 -> 52155
12 -> 135
975831 -> 14996295
4390742 -> 235954919
9752348061 -> 1002931578825
Galen Iwanow
źródło

Odpowiedzi:

7

Wolfram Language (Mathematica) , 89 88 bajtów

Dzięki Jenny_mathy za uratowanie 1 bajtu.

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

Wypróbuj online!

Jest to strasznie nieefektywne, ponieważ generuje n obrotów BCD o n , czyli o wiele więcej niż potrzebujemy. Możemy zrobić to jest nieco bardziej wydajny, zapisując wynik Join@@IN ki zastępując #na koniec z Length@k. To pozwala nam dość łatwo wygenerować wykres rozproszenia:

wprowadź opis zdjęcia tutaj

Naprawdę intryguje mnie kontrast lokalnej struktury i ogólnego chaosu.

Martin Ender
źródło
Max@#-Min@#&zapisuje bajt. dobrze?
J42161217
@Jenny_mathy Tak, dziękuję! :)
Martin Ender
1
Zrobiłem to z naszych rozwiązań Max@#-Min@#&[#~FromDigits~2&/@Partition[s=Join@@(i=IntegerDigits)[i@#,2,4],Tr[1^s],1,1]]&89 bajtów ORAZ wydajnych. cholera, ten bajt!
J42161217
W rzeczywistości fabuła jest powtarzającym się ojcem. Te „chaotyczne chmury” zdarzają się co 10 ^ n (fabuła „skacze” i tworzy nową): 1-9,10-99,100-999... oto kilka różnych powiększeń: imgur.com/RXLMkco
J42161217
@Jenny_mathy na pewno, ale struktura w tych interwałach wydaje się bardzo chaotyczna (ze strukturami tylko w znacznie mniejszych skalach).
Martin Ender
6

Galaretka , 13 bajtów

Dd4d2FṙJ$ḄṢIS

Wypróbuj online!

Jak to działa

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
źródło
4

PowerShell , 153 bajty

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

Wypróbuj online!

Głupie długie wywołania .NET do konwersji do / z pliku binarnego naprawdę powiększają się tutaj. ;-)

Bierzemy dane wejściowe jako $args, charzawijamy je w ciąg, a następnie rzutujemy na -array. Pętlimy każdą cyfrę, convertwprowadzając cyfrę toStringdo podstawy 2(tj. Zamieniając cyfrę na liczbę binarną), a następnie .padLeftrobiąc z niej czterocyfrową liczbę binarną. Ta wynikowa tablica ciągów znaków jest następnie edytowana -joinw pojedynczy ciąg znaków i ponownie rzutowana jako chartablica przed zapisaniem $b.

Następnie zapętlamy $b, co zapewnia, że ​​zapętlimy wystarczająco dużo razy, aby uwzględnić każdy obrót. W każdej iteracji odklejamy pierwszy znak, $xa pozostałe znaki, $yużywając wielu przypisań. Następnie łączymy je z powrotem, $b=$y+$xaby przesunąć pierwszy element do końca, tj. Skutecznie obracając tablicę o jeden. Który jest -joined na ciąg znaków, który służy jako wejście do convertrozmowy, aby wyłączyć z podstawy ciąg binarny 2w produkt Int64. Następnie sortwszystkie te liczby wynikowe przechowujemy w $c. Wreszcie bierzemy największe [-1]i odejmujemy najmniejsze [0]. Pozostaje to w potoku, a dane wyjściowe są niejawne.

AdmBorkBork
źródło
4

Ohm v2 , 15 bajtów

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

Wypróbuj online!

Wyjaśnienie:

€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
źródło
4

JavaScript (ES6), 118 100 99 bajtów

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>

Edycja: Zapisano 11 bajtów dzięki @RickHitchcock. Zaoszczędzono 1 bajt dzięki produktom @ETH. Objaśnienie: 0x1Prefiks powoduje, że dane wejściowe są ponownie analizowane jako liczba szesnastkowa, której dane binarne są takie same jak BCD pierwotnego numeru z 1 prefiksem (myślę, że jest to bardziej golfowe niż jakikolwiek inny sposób wypełniania do wielokrotności 4 cyfr) . Z wyłączeniem prefiksu, który jest zmieniany z 1 na 0, powstały ciąg jest następnie obracany w każdej możliwej pozycji i przekształcany z binarnego z powrotem na dziesiętny. Na koniec odejmowane jest maksimum i minimum.

Neil
źródło
1
@ RickHitchcock Owiń sznurek podwójnymi backtickami ... chyba że chcesz napisać coś takiego, .join`` w którym to przypadku potrzebujesz potrójnych backticks itp.
Neil
Dobry pomysł na użycie systemu szesnastkowego. Zaoszczędź 11 bajtów w ten sposób: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 Dzięki, to pomogło mi ... wyciąć ... z kolejnych 7 bajtów, usuwając sliceteż kolejny !
Neil,
1
m=>Math[m]Sztuką jest wielki. Być może zmienić (+`0x1${n}`)na ('0x1'+n-0)lub podobny?
ETHprodukcje
3

Python 2 , 115 113 bajtów

  • Zaoszczędziłem trochę bajtów dzięki ovs .
  • Zaoszczędził dwa bajty dzięki Mr. 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)

Wypróbuj online!

Jonathan Frech
źródło
3

Łuska , 18 bajtów

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

Wypróbuj online!

Powinien istnieć krótszy sposób konwersji cyfry na 4-bitową reprezentację binarną ...

Wyjaśnienie

§-▼▲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
Lew
źródło
3

APL (Dyalog) , 31 bajtów

Pełna treść programu. Monity o numer z STDIN. Wyświetla wynik do STDOUT.

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

Wypróbuj online!

 monit o wiersz tekstu z STDIN

⍎¨ wykonać (ocenić) każdy (znak)

()⊤ Kodować (anti-base) w następującym systemie liczbowym:

4/2 cztery binarne bity

 transponować

, ravel (spłaszczyć)

b← Przechowywać w b(na b inary)

 załącz (abyśmy wykorzystali całą listę dla każdego obrotu)

()⌽¨ Obróć (w lewo) o każdą z następujących kwot:

≢b długość b

I ndices tego

2⊥¨ dekoduj każdy z base-2.

() Zastosuj do tego następującą milczącą funkcję

⌈/ maks. (redukcja)

- minus

⌊/ min (redukcja)

Adám
źródło
możesz łatwo wyszkolić ten fragment: (⍳≢b) ←b ←
ngn
lub nawet lepiej - użyj (≢, /, ⍨) zamiast oczywistego (⍳∘≢⌽¨⊂)
ngn
2

Rubin , 96 91 bajtów

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

Wypróbuj online!

  • Zapisano 5 bajtów dzięki nazwie wyświetlanej
Przywróć Monikę - notmaynard
źródło
-> 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} powinien mieć 91 bajtów
nazwa wyświetlana
@isplayname Ha, tak, masz rację. Dziękuję
przywrócenie Monica - notmaynard
2

Mathematica, 110 99 bajtów

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


Wypróbuj online!

J42161217
źródło
2

Python 3, 141 bajtów

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)

Wypróbuj online

sonrad10
źródło
2

Retina , 96 89 bajtów

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

_

Wypróbuj online!Nieco wolno, więc link zawiera tylko mały przypadek testowy. Edycja: Zapisano 7 bajtów dzięki @MartinEnder. Wyjaśnienie:

.
@@@$&

Prefiks trzy @s do każdej cyfry. (Reprezentują one0 s BCD, ale są bardziej golfowe.)

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

Zmień @s na _s (reprezentujące1 s BCD).

T`E`@
\d
_

Napraw ostatnią cyfrę BCD.

.
$&$'$`¶

Wygeneruj wszystkie obroty.

O`

Posortuj je w porządku rosnącym.

_
@_
+`_@
@__

Przekształć je w jednoargumentowe.

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

_

Odejmij pierwszą od ostatniej liczby, ignorując liczby pośrednie i przekonwertuj na liczbę dziesiętną.

Neil
źródło
Nie ma potrzeby używania %konwersji binarnej na jednoargumentową i można zaoszczędzić kilka dodatkowych bajtów, używając innych znaków niż 0i 1dla binarnych: tio.run
Martin Ender
@MartinEnder Och, myślę, że datowane od czasu, gdy próbowałem i nie użyłem jednej z twoich binarnych procedur konwersji ...
Neil
2

Haskell , 130 bajtów

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]

Wypróbuj online!

Wyjaśnienie / Niegolfowany

Ponieważ mamy zamiar użyć foldl1((+).(2*))do konwersji z systemu binarnego na dziesiętny, to równie dobrze możemy nie używać maximum, a minimumraczej foldl1 max(albo same z minodpowiednio) i użyć krótkiejr = foldr1 .

Teraz zdefiniujmy operator, f#xktóry konwertuje xna BCD, generuje wszystkie obroty, redukuje je za pomocą fi konwertuje na dziesiętny:

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

Teraz jest tylko kwestia użycia tego operatora raz maxi raz z mini odejmowania ich wyników:

f x = max#x - min#x
ბიმო
źródło
2

PHP, 156 153 bajtów

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

Wypróbuj online!

Jo.
źródło
2

Japt -x , 20 bajtów

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

Wypróbuj online!

Wprowadź jako tablicę cyfr.

Wyjaśnienie:

®¤                      #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
źródło
1
Możesz użyć -xflagi, aby zapisać 2 bajty.
Oliver,
1
20 bajtów .
Oliver,
1

J, 43 bajty

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

Wypróbuj online!

Czasami milczący styl utrudnia. Ale prawdopodobnie istnieje sposób, aby to zrobić w sposób milczący, który jest o wiele bardziej zwięzły niż ten. "."0@":Wydaje mi się, że pamiętam lepszy sposób na dzielenie liczb na cyfry inne niż, ale nie mogę sobie tego przypomnieć ...

Wyjaśnienie

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

Wyprzedzające i usuwające 8 ma zapewnić, że obecna jest odpowiednia liczba zer (J przekształci tablice tak, aby były wielkościami ich elementu o maksymalnej długości, a 8 to 4 cyfry dwójkowe, więc zostanie użyte).

kapusta
źródło
1

APL (NARS), 34 znaki, 68 bajtów

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

jakiś mały test:

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

Perl 5 , 97 91 89 + 2 ( -F) = 99 93 91 bajtów

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

Wypróbuj online!

Xcali
źródło