Bir sayının BCD farkını bulma


20

BCD farkı

N tamsayısı verildiğinde, her ondalık basamağı 4 basamaklı ikili gösterimle değiştirerek BCD'ye ( ikili kodlu ondalık ) dönüştürün

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

Ardından, diğer düzenlemeler olmadan bu liste tarafından temsil edilebilen en büyük ve en küçük sayıları bulmak için ikili basamakların listesini döndürün.

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)

Bu sayıları ondalık sayıya dönüştürün, bit listesini normal ikili olarak ele alın ve en küçüğünü en büyüğünden çıkarın:

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

Çıktı, bulunan en büyük ve en küçük sayıların farkıdır.

Test senaryoları:

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

Yanıtlar:


7

Wolfram Dili (Mathematica) , 89 88 bayt

1 bayt kaydettiği için Jenny_mathy'ye teşekkürler.

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

Çevrimiçi deneyin!

Oluşturduğu, çünkü bu, korkunç verimsizdir n ait BCD'nin rotasyonlar n yol daha ihtiyacımız olandan olduğunu. Biz bu biraz daha verimli sonucunu kaydederek olduğunu anlayabiliriz Join@@in kve değiştirilmesi #ile sonunda Length@k. Bu, bir dağılım grafiğini kolayca oluşturmamızı sağlar:

resim açıklamasını buraya girin

Yerel yapının ve genel kaosun kontrastından gerçekten çok etkilendim.


Max@#-Min@#&bir bayt kaydeder. sağ?
J42161217

@Jenny_mathy Evet, teşekkürler! :)
Martin Ender

1
Bunu Max@#-Min@#&[#~FromDigits~2&/@Partition[s=Join@@(i=IntegerDigits)[i@#,2,4],Tr[1^s],1,1]]&89 bayt VE verimli çözümlerimizden yaptım . lanet olsun bayt!
J42161217

: Aslında arsa Tekrarlanan patern.Those "kaotik bulutlar" her 10 ^ n (arsa "atlar" ve yeni bir tane oluşturun) gerçekleşmesi edilir 1-9,10-99,100-999... burada bazı farklı yakınlaştırır: imgur.com/RXLMkco
J42161217

@Jenny_mathy emin, ama bu aralıklar içindeki yapı çok kaotik görünüyor (sadece çok daha küçük ölçeklerde yapılarla).
Martin Ender

6

Jöle , 13 bayt

Dd4d2FṙJ$ḄṢIS

Çevrimiçi deneyin!

Nasıl çalışır

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.


4

PowerShell , 153 bayt

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

Çevrimiçi deneyin!

Aptal uzun .NET ikili / dönüştürmek için çağırır gerçekten burada uzunluğu şişiriyor. ;-)

Girişi şu şekilde alırız $args, bir chardizgiye sararız , sonra da -dizisi olarak yayınlarız. Her hane üzerinde biz döngü, convertrakamı ing toStringtabanında 2(yani ikili bir sayıya rakamı dönüm), sonra .padLeftbunu bir dört basamaklı ikili sayıda yapmak. Sonuçta elde edilen dize dizisi daha sonra -jointek bir dize halinde düzenlenir ve charkaydedilmeden önce -dizisi olarak yeniden yayınlanır $b.

Daha sonra, üzerinden dönüyoruz $b, bu da her dönüşü hesaba katmak için yeterli zamanı döngü yaptığımızdan emin oluyor. Her yinelemede, ilk karakteri içine $xve kalan karakterleri $ybirden çok atama kullanarak soyarız. Daha sonra, $b=$y+$xilk öğeyi sonuna taşımak, yani diziyi etkili bir şekilde bir döndürmek için bunları tekrar birleştiriyoruz . Bu , dizeyi ikili tabandan bir konumuna dönüştürmek -joiniçin convertçağrının girdisi olarak kullanılan bir dizeye 2dönüştürülür Int64. Sonra sorttüm bu sonuç numaralarını kaydedip saklıyoruz $c. Son olarak, en büyüğünü alırız [-1]ve en küçüğünü çıkarırız [0]. Boru hattında kalan ve çıktı örtük.


4

Ohm v2 , 15 bayt

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

Çevrimiçi deneyin!

Açıklama:

€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

4

JavaScript (ES6), 118 100 99 bayt

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>

Düzenleme: @RickHitchcock sayesinde 11 bayt kaydedildi. @ETHproductions sayesinde 1 bayt kaydedildi. Açıklama: 0x1Önek, girdinin ikili değeri 1 önekle orijinal sayının BCD'si ile aynı olan onaltılık bir sayı olarak yeniden oluşturulmasına neden olur (Bence bu, 4 hanenin katlarına doldurmanın diğer yollarından daha golfçüdür) . 1'den 0'a değiştirilen önek hariç tutulduğunda, elde edilen dize daha sonra olası her konumda döndürülür ve ikili değerden ondalığa dönüştürülür. Son olarak, maksimum ve minimum çıkarılır.


1
@RickHitchcock Dize çift backticks sarın ... .join`` bu durumda üçlü backticks vb.Gibi bir şey yazmak istemiyorsanız
Neil

Onaltılık kullanmak iyi fikirdir. 11 bayt şöyle kaydet: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 Teşekkürler, bu bana yardımcı oldu ... başka bir 7 bayt daha dilimlemek ... başka bir slicede kaldırarak !
Neil

1
m=>Math[m]Hile büyüktür. Belki değiştirmek (+`0x1${n}`)için ('0x1'+n-0)ya da benzer?
ETHproductions 16:17



3

Kabuk , 18 bayt

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

Çevrimiçi deneyin!

Bir rakamı 4 bitlik ikili gösterimine dönüştürmenin daha kısa bir yolu olmalı ...

açıklama

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

3

APL (Dyalog) , 31 bayt

Tam program gövdesi. STDIN'den numara istenir. Sonucu STDOUT olarak yazdırır.

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

Çevrimiçi deneyin!

 STDIN'den metin satırı istemi

⍎¨ her birini (karakteri) yürüt (değerlendir)

()⊤ Aşağıdaki sayı sisteminde kodlama (baz karşıtı):

4/2 dört ikili bit

 devrik

, ravel (düzleştir)

b← mağazada b( b için) inary için)

 enclose (böylece her rotasyon için bu listenin tamamını kullanacağız)

(...)⌽¨  Aşağıdaki miktarların her birine göre döndürün (solda):

≢b uzunluğu b

ben Bunun ndices

2⊥¨ her birini taban-2'den deşifre edin.

(… Buna ) aşağıdaki tacit fonksiyonunu uygulayın

⌈/ maksimum (azaltma)

- eksi

⌊/ min (azaltma)


Bu biti kolayca eğitebilirsiniz: ()b) ⌽¨⊂b ←
ngn

veya daha iyisi - bariz (⍳∘≢⌽¨⊂) yerine (≢, /, ⍨) kullanın
ngn





2

Python 3, 141 bayt

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)

Çevrimiçi deneyin


2

Retina , 96 89 bayt

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

_

Çevrimiçi deneyin! Biraz yavaş, bu yüzden bağlantı sadece küçük bir test durumu içerir. Düzenleme: @MartinEnder sayesinde 7 bayt kaydedildi. Açıklama:

.
@@@$&

@Her basamağa üç s öneki ekleyin . (Bunlar 0BCD'leri temsil eder , ancak daha golfçüdür.)

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

S'yi uygun olan yerlerde @s olarak değiştirin _( 1BCD'nin s'yi temsil eder ).

T`E`@
\d
_

BCD'nin son basamağını sabitleyin.

.
$&$'$`¶

Tüm rotasyonları oluşturun.

O`

Onları artan düzende sıralayın.

_
@_
+`_@
@__

Bunları tekli olarak dönüştürün.

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

_

Ara sayıları yoksayarak ilkini son sayıdan çıkarın ve ondalık sayıya dönüştürün.


İkili dosyadan% tekli dönüşüme gerek yoktur ve ikili karakterden 0ve 1ikili karakterden başka karakterler kullanarak birkaç bayt daha kaydedebilirsiniz : tio.run/##K0otycxL/…
Martin Ender

@MartinEnder Oh, sanırım ikili dönüşüm rutinlerinden birini kullanmaya çalıştığım zamandan beri ...
Neil

2

Haskell , 130 bayt

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]

Çevrimiçi deneyin!

Açıklama / Ungolfed

foldl1((+).(2*))İkiliden ondalığa dönüştürmek için kullanacağımızdan , kullanamıyoruz maximumve minimumdaha doğrusu foldl1 max(veya minsırasıyla ile aynı ) ve kısa birr = foldr1 .

Şimdi, BCD'ye f#xdönüşen x, tüm dönüşleri üreten, bunları kullanarak azaltan fve ondalık sayıya dönüştüren bir operatör tanımlayalım :

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

Şimdi sadece bu operatörü bir kez maxve bir kez kullanmak minve sonuçlarını çıkarmak meselesi :

f x = max#x - min#x

2

PHP, 156153 bayt

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

Çevrimiçi deneyin!


2

Japt -x , 20 bayt

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

Çevrimiçi deneyin!

Bir basamak dizisi olarak girin.

Açıklama:

®¤                      #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

1
-xBayrağı 2 bayt kaydetmek için kullanabilirsiniz .
Oliver



1

J, 43 bayt

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

Çevrimiçi deneyin!

Bazen örtük stil işleri zorlaştırır. Ama muhtemelen bunu yapmanın bir yolu var, bundan çok daha özlü. Sanırım bir rakamı rakamlardan başka rakamlara ayırmanın daha iyi bir yolunu hatırlıyorum"."0@": ama hatırlamıyorum ...

açıklama

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

Yukarıdaki ve çıkarma 8, doğru sıfır sayısının mevcut olmasını sağlamak içindir (J, dizilerini maksimum uzunluk elemanının boyutu olacak şekilde yeniden şekillendirir ve 8, ikili olarak 4 basamaklıdır, bu yüzden kullanılır).


1

APL (NARS), 34 karakter, 68 bayt

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

bazı küçük testler:

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.