Temukan perbedaan BCD suatu angka

20

Perbedaan BCD

Dengan bilangan bulat n, konversikan ke BCD ( binary-coded decimal ) dengan mengganti setiap digit desimal dengan representasi biner 4 digitnya

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

Kemudian putar daftar angka biner untuk menemukan angka terbesar dan terkecil, diwakili oleh daftar ini tanpa penataan ulang lainnya.

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)

Ubah angka-angka ini kembali menjadi desimal, memperlakukan daftar bit sebagai biner biasa dan kurangi yang terkecil dari yang terbesar:

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

Outputnya adalah selisih angka terbesar dan terkecil yang ditemukan.

Kasus uji:

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

Jawaban:

7

Bahasa Wolfram (Mathematica) , 89 88 byte

Terima kasih kepada Jenny_mathy karena telah menghemat 1 byte.

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

Cobalah online!

Ini sangat tidak efisien, karena menghasilkan rotasi N BCD n , yang jauh lebih dari yang kita butuhkan. Kita dapat membuat ini sedikit lebih efisien dengan menyimpan hasil Join@@di kdan mengganti #di akhir dengan Length@k. Itu memungkinkan kami membuat sebar scatter dengan mudah:

masukkan deskripsi gambar di sini

Saya benar-benar tertarik dengan kontras struktur lokal dan kekacauan keseluruhan.

Martin Ender
sumber
Max@#-Min@#&menghemat satu byte. kanan?
J42161217
@ Jenny_mathy Ya, terima kasih! :)
Martin Ender
1
Saya membuat ini dari solusi kami Max@#-Min@#&[#~FromDigits~2&/@Partition[s=Join@@(i=IntegerDigits)[i@#,2,4],Tr[1^s],1,1]]&89 byte DAN efisien. sialan itu byte!
J42161217
Sebenarnya plotnya adalah pola yang berulang. "Awan kacau" itu terjadi setiap 10 ^ (plot "melompat" dan membuat yang baru): 1-9,10-99,100-999... berikut adalah beberapa pembesaran
J42161217
@ Jenny_mathy yakin, tetapi struktur dalam interval ini tampak sangat kacau (dengan struktur hanya pada skala yang jauh lebih kecil).
Martin Ender
6

Jelly , 13 byte

Dd4d2FṙJ$ḄṢIS

Cobalah online!

Bagaimana itu bekerja

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

PowerShell , 153 byte

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

Cobalah online!

Panggilan NET. Panjang bodoh untuk mengkonversi ke / dari biner benar-benar besar di sini. ;-)

Kami mengambil input sebagai $args, membungkusnya dalam string, lalu melemparkannya sebagai char-array. Kami mengulangi setiap digit, convertmemasukkan digit toStringdi basis 2(yaitu, mengubah digit menjadi angka biner), lalu .padLeftmenjadikannya angka biner empat digit. Array string yang dihasilkan kemudian -joindiedarkan ke dalam string tunggal dan chardicetak ulang sebagai -array sebelum disimpan ke dalam $b.

Selanjutnya, kita mengulang $b, yang hanya memastikan kita mengulang kali cukup untuk memperhitungkan setiap rotasi. Setiap iterasi, kami melepas karakter pertama menjadi $xdan karakter yang tersisa $ymenggunakan beberapa penugasan. Kemudian, kita gabungkan mereka kembali menjadi satu $b=$y+$xuntuk memindahkan elemen pertama ke ujung, yaitu, secara efektif memutar array dengan satu. Itu -joined menjadi string, yang digunakan sebagai input ke convertpanggilan untuk mengubah string dari basis biner 2menjadi Int64. Kami kemudian sortsemua angka-angka yang dihasilkan dan menyimpannya ke dalam $c. Akhirnya, kami mengambil yang terbesar [-1]dan mengurangi yang terkecil [0]. Yang tersisa pada pipa dan output tersirat.

AdmBorkBork
sumber
4

Ohm v2 , 15 byte

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

Cobalah online!

Penjelasan:

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

JavaScript (ES6), 118 100 99 byte

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>

Sunting: Disimpan 11 byte berkat @RickHitchcock. Disimpan 1 byte berkat @ETHproductions. Penjelasan: 0x1Awalan menyebabkan input untuk diulang sebagai bilangan heksadesimal, yang binernya sama dengan BCD dari angka asli dengan awalan 1 (saya pikir ini lebih golf daripada cara lain untuk melipat ke kelipatan 4 digit) . Tidak termasuk awalan, yang diubah dari 1 ke 0, string yang dihasilkan kemudian diputar pada setiap posisi yang mungkin dan dikonversi dari kembali biner ke desimal. Akhirnya maksimum dan minimum dikurangi.

Neil
sumber
1
@RickHitchcock Bungkus string dengan backticks ganda ... kecuali jika Anda ingin menulis sesuatu .join`` dalam hal ini Anda perlu triple backticks dll.
Neil
Ide bagus untuk menggunakan heksadesimal. Simpan 11 byte seperti ini: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 Terima kasih, itu membantu saya ... mengiris ... dari 7 byte lainnya dengan menghapus yang lain slicejuga!
Neil
1
The m=>Math[m]trick besar. Mungkin berubah (+`0x1${n}`)ke ('0x1'+n-0)atau serupa?
ETHproduksi
3

Python 2 , 115 113 byte

  • Menyimpan beberapa byte berkat ovs .
  • Disimpan dua byte berkat Tn . 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)

Cobalah online!

Jonathan Frech
sumber
3

Sekam , 18 byte

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

Cobalah online!

Seharusnya ada cara yang lebih pendek untuk mengubah digit menjadi representasi biner 4-bit ...

Penjelasan

§-▼▲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
sumber
3

APL (Dyalog) , 31 byte

Badan program penuh. Meminta nomor dari STDIN. Mencetak hasil ke STDOUT.

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

Cobalah online!

 meminta baris teks dari STDIN

⍎¨ mengeksekusi (mengevaluasi) masing-masing (karakter)

(... )⊤ mengkodekan (anti-basis) dalam sistem angka berikut:

4/2 empat bit biner

 mengubah urutan

, ravel (meratakan)

b← simpan di b(untuk b inary)

 terlampir (sehingga kami akan menggunakan seluruh daftar ini untuk setiap rotasi)

(... )⌽¨ putar (kiri) dengan masing-masing jumlah berikut:

≢b panjang dari b

Saya menemukan itu

2⊥¨ decode masing-masing dari base-2.

(... ) terapkan fungsi diam-diam berikut untuk itu

⌈/ maks (-pengurangan)

- minus

⌊/ min (reduksi)

Adm
sumber
Anda dapat dengan mudah melatih bit ini: (⍳≢b) ⌽¨⊂b ←
ngn
atau bahkan lebih baik - gunakan (≢, /, ⍨) alih-alih yang jelas (⍳∘≢⌽¨⊂)
ngn
2

Jelly , 21 byte

DB0;$4¡€ṫ€-3FṙJ$ḄµṀ_Ṃ

Cobalah online!

HyperNeutrino
sumber
2

Ruby , 96 91 byte

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

Cobalah online!

  • Disimpan 5 byte berkat tampilanname
Pasang kembali Monica - notmaynard
sumber
-> 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} harus 91 byte
displayname
@displayname Ha, ya, Anda benar. Terima kasih
mengembalikan Monica - notmaynard
2

Mathematica, 110 99 byte

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


Cobalah online!

J42161217
sumber
2

Python 3, 141 byte

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)

Cobalah online

sonrad10
sumber
2

Retina , 96 89 byte

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

_

Cobalah online! Agak lambat, jadi tautan hanya mencakup test case kecil. Sunting: Disimpan 7 byte berkat @MartinEnder. Penjelasan:

.
@@@$&

Awalan tiga @s untuk setiap digit. (Ini mewakili 0huruf BCD, tetapi lebih golf.)

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

Ubah @s ke _s (mewakili 1s dari BCD) jika sesuai.

T`E`@
\d
_

Perbaiki digit terakhir BCD.

.
$&$'$`¶

Hasilkan semua rotasi.

O`

Urutkan ke dalam urutan menaik.

_
@_
+`_@
@__

Ubah mereka menjadi unary.

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

_

Kurangi yang pertama dari angka terakhir, abaikan angka menengah, dan ubah menjadi desimal.

Neil
sumber
Tidak perlu menggunakan %untuk konversi biner ke unary dan Anda dapat menyimpan beberapa byte lagi dengan menggunakan karakter lain selain 0dan 1untuk biner: tio.run/##K0otycxL/…
Martin Ender
@ MartinEnder Oh, saya pikir itu berasal dari ketika saya mencoba dan gagal menggunakan salah satu rutinitas konversi biner Anda ...
Neil
2

Haskell , 130 byte

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]

Cobalah online!

Penjelasan / Tidak Diundang

Karena kita akan menggunakan foldl1((+).(2*))untuk mengkonversi dari biner ke desimal, kita mungkin juga tidak menggunakan maximumdan minimummelainkan foldl1 max(atau sama dengan minmasing - masing) dan menggunakan shortr = foldr1 .

Sekarang, mari kita definisikan operator f#xyang mengonversi xke BCD, menghasilkan semua rotasi, mengurangi penggunaan ini fdan mengubahnya menjadi desimal:

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

Sekarang tinggal menggunakan operator ini satu kali dengan maxdan satu kali dengan mindan mengurangi hasil mereka:

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

PHP, 156 153 byte

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

Cobalah online!

Jo.
sumber
2

Japt -x , 20 byte

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

Cobalah online!

Input sebagai array angka.

Penjelasan:

®¤                      #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
sumber
1
Anda dapat menggunakan -xbendera untuk menyimpan 2 byte.
Oliver
1
20 byte .
Oliver
1

J, 43 byte

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

Cobalah online!

Terkadang gaya diam-diam membuat segalanya menjadi sulit. Tapi mungkin ada cara untuk melakukannya dengan gaya diam-diam yang jauh lebih ringkas dari ini. Saya pikir saya ingat cara yang lebih baik untuk membagi angka ke angka selain "."0@":tetapi saya tidak dapat mengingatnya ...

Penjelasan

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

Prepending dan menghapus 8 adalah untuk memastikan bahwa jumlah nol yang tepat ada (J akan membentuk kembali arraynya menjadi ukuran elemen panjang maksimumnya, dan 8 adalah 4 digit dalam biner sehingga digunakan).

cole
sumber
1

APL (NARS), 34 karakter, 68 byte

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

beberapa tes kecil:

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

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

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

Cobalah online!

Xcali
sumber