ค้นหาความแตกต่าง BCD ของตัวเลข


20

ความแตกต่าง BCD

กำหนดจำนวนเต็ม n ให้แปลงเป็น BCD ( ทศนิยมทศนิยมด้วยรหัสไบนารี ) โดยแทนที่ทศนิยมแต่ละหลักด้วยการแทนเลขฐานสอง 4 หลัก

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

จากนั้นหมุนรายการของเลขฐานสองเพื่อหาจำนวนที่มากที่สุดและน้อยที่สุดซึ่งสามารถแทนได้โดยรายการนี้โดยไม่มีการจัดเรียงใหม่

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)

แปลงตัวเลขเหล่านี้กลับเป็นทศนิยมโดยถือว่ารายการของบิตเป็นไบนารีปกติและลบขนาดที่เล็กที่สุดจากค่าที่ใหญ่ที่สุด:

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

ผลลัพธ์คือความแตกต่างของจำนวนที่มากที่สุดและน้อยที่สุดที่พบ

กรณีทดสอบ:

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

คำตอบ:


7

ภาษา Wolfram (Mathematica) , 89 88 ไบต์

ขอบคุณ Jenny_mathy ที่ช่วยประหยัด 1 ไบต์

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

ลองออนไลน์!

นี้จะไม่มีประสิทธิภาพชะมัดเพราะสร้างnผลัด BCD ของnซึ่งเป็นวิธีที่มากกว่าที่เราต้องการ เราสามารถทำให้เป็นบิตมีประสิทธิภาพมากขึ้นโดยการบันทึกผลมาจากการที่Join@@ในkและเปลี่ยนในตอนท้ายด้วย# Length@kที่ช่วยให้เราสร้างแผนการกระจายค่อนข้างง่าย:

ป้อนคำอธิบายรูปภาพที่นี่

ฉันรู้สึกทึ่งกับความแตกต่างของโครงสร้างท้องถิ่นและความวุ่นวายโดยรวม


Max@#-Min@#&บันทึกเป็นไบต์ ขวา?
J42161217

@Jenny_mathy ใช่ขอบคุณ! :)
Martin Ender

1
ฉันทำสิ่งนี้จากวิธีแก้ปัญหาของเราMax@#-Min@#&[#~FromDigits~2&/@Partition[s=Join@@(i=IntegerDigits)[i@#,2,4],Tr[1^s],1,1]]&89 ไบต์และมีประสิทธิภาพ แช่ง!
J42161217

ที่จริงแล้วพล็อตนั้นเป็นพ่อซ้ำแล้วซ้ำอีกดังนั้น "เมฆอลหม่าน" จะเกิดขึ้นทุก ๆ 10 ^ n (พล็อต "กระโดด" และสร้างใหม่): 1-9,10-99,100-999... นี่คือการซูมที่แตกต่างกัน: imgur.com/RXLMkco
J42161217

@ Jenny_mathy แน่นอน แต่โครงสร้างภายในช่วงเวลาเหล่านี้ดูเหมือนจะวุ่นวายมาก (มีโครงสร้างในระดับที่เล็กกว่ามาก)
Martin Ender

6

เยลลี่ขนาด 13 ไบต์

Dd4d2FṙJ$ḄṢIS

ลองออนไลน์!

มันทำงานอย่างไร

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 ไบต์

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

ลองออนไลน์!

Stupid lengthy. NET เรียกร้องให้แปลงจาก / เป็นไบนารี่จริง ๆ แล้วขยายความยาวได้ที่นี่ ;-)

เรารับข้อมูลเป็น$argsห่อในสตริงแล้วโยนเป็นchar-array เราวนรอบแต่ละหลักโดยconvertอิงตัวเลขเป็นtoStringฐาน2(เช่นเปลี่ยนตัวเลขเป็นเลขฐานสอง) จากนั้นจึง.padLeftทำให้เป็นเลขฐานสองสี่หลัก ที่ส่งผลให้อาเรย์ของสตริงแล้ว-joined เป็นหนึ่งสตริงและอีกหล่อเป็นchar-array $bก่อนที่จะถูกบันทึกลงใน

ต่อไปเราวนซ้ำ$bซึ่งทำให้แน่ใจว่าเราวนรอบเวลาเพียงพอสำหรับการหมุนเวียนทุกครั้ง การวนซ้ำแต่ละครั้งเราลอกอักขระตัวแรกออก$xและตัวละครที่เหลืออยู่$yโดยใช้การกำหนดหลายครั้ง จากนั้นเรารวมมันเข้าด้วยกัน$b=$y+$xเพื่อย้ายองค์ประกอบแรกไปยังจุดสิ้นสุดนั่นคือการหมุนอาร์เรย์อย่างมีประสิทธิภาพทีละรายการ ที่-joined เป็นสตริงซึ่งจะใช้เป็นข้อมูลเพื่อconvertเรียกร้องให้เปิดสตริงจากฐานไบนารีเป็น2 Int64จากนั้นเราจะทั้งหมดของตัวเลขผลเหล่านั้นและเก็บพวกเขาเป็นsort $cสุดท้ายเราใช้เวลาที่ยิ่งใหญ่ที่สุดและลบที่เล็กที่สุด[-1] [0]ที่เหลืออยู่บนไปป์ไลน์และเอาท์พุทเป็นนัย


4

โอห์ม v2 , 15 ไบต์

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

ลองออนไลน์!

คำอธิบาย:

€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 ไบต์

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>

แก้ไข: บันทึก 11 ไบต์ขอบคุณ @RickHitchcock บันทึกแล้ว 1 ไบต์ขอบคุณ @ETHproductions คำอธิบาย: 0x1คำนำหน้าทำให้อินพุตได้รับการวิเคราะห์ใหม่เป็นเลขฐานสิบหกซึ่งมีเลขฐานสองเหมือนกับ BCD ของหมายเลขเดิมที่มีคำนำหน้า 1 (ฉันคิดว่านี่เป็น golfier กว่าวิธีอื่น ๆ ของการเติมเป็นหลายหลัก 4) . ไม่รวมส่วนนำหน้าซึ่งเปลี่ยนจาก 1 เป็น 0 สตริงผลลัพธ์จะถูกหมุนในแต่ละตำแหน่งที่เป็นไปได้และแปลงจากไบนารีกลับเป็นทศนิยม ในที่สุดจำนวนสูงสุดและต่ำสุดจะถูกหักออก


1
@RickHitchcock Wrap สตริงใน backticks คู่ ... ถ้าคุณต้องการที่จะเขียนบางอย่างเช่น.join`` ในกรณีที่คุณจำเป็นต้องสาม backticks ฯลฯ
นีล

ความคิดที่ดีที่จะใช้เลขฐานสิบหก บันทึก 11 ไบต์เช่นนี้: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 ขอบคุณที่ช่วยฉัน ... หั่น ... เพิ่มอีก 7 ไบต์ด้วยการลบอีกsliceด้วย!
Neil

1
m=>Math[m]เคล็ดลับคือการที่ดี อาจจะเปลี่ยน(+`0x1${n}`)เป็น('0x1'+n-0)หรือคล้ายกัน?
ETHproductions



3

Husk , 18 ไบต์

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

ลองออนไลน์!

ควรมีวิธีที่สั้นกว่าในการแปลงตัวเลขให้เป็นเลขฐานสองแบบ 4 บิต ...

คำอธิบาย

§-▼▲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 ไบต์

โปรแกรมร่างกายเต็ม แจ้งหมายเลขจาก STDIN พิมพ์ผลลัพธ์ไปที่ STDOUT

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

ลองออนไลน์!

 พรอมต์สำหรับบรรทัดข้อความจาก STDIN

⍎¨ ดำเนินการ (ประเมิน) แต่ละตัวละคร

()⊤ เข้ารหัส (anti-base) ในระบบหมายเลขต่อไปนี้:

4/2 สี่บิตไบนารี

 transpose

, ravel (แบน)

b← เก็บในb(สำหรับb inary)

 ใส่ (เพื่อที่เราจะใช้รายการทั้งหมดนี้สำหรับการหมุนแต่ละครั้ง)

()⌽¨ หมุน (ซ้าย) โดยจำนวนดังต่อไปนี้:

≢b ความยาวของ b

ฉัน ndices ของที่

2⊥¨ ถอดรหัสแต่ละตัวจาก base-2

(... ) ใช้ฟังก์ชั่นโดยปริยายต่อไปนี้กับสิ่งนั้น

⌈/ สูงสุด (- ลด)

- ลบ

⌊/ นาที (- ลด)


คุณสามารถฝึกฝนเรื่องนี้ได้อย่างง่ายดาย: (⍳≢b) ←b←
ก.ย.

หรือดียิ่งขึ้น - ใช้ (≢, /, ⍨) แทนชัด (⍳∘≢⌽¨⊂)
ก.ย.



2

Ruby , 96 91 ไบต์

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

ลองออนไลน์!

  • บันทึก 5 ไบต์ด้วย displayname

-> 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} ควรจะเป็น 91 ไบต์
DisplayName

@displayname Ha, ใช่คุณพูดถูก ขอบคุณ
Reinstate Monica - notmaynard



2

เรติน่า , 96 89 ไบต์

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

_

ลองออนไลน์! ค่อนข้างช้าดังนั้นลิงก์จะมีเพียงกรณีทดสอบเล็ก ๆ เท่านั้น แก้ไข: บันทึกแล้ว 7 ไบต์ด้วย @MartinEnder คำอธิบาย:

.
@@@$&

คำนำหน้าสาม@s ถึงแต่ละหลัก (สิ่งเหล่านี้เป็นตัวแทน0ของ BCD แต่เป็นนักกอล์ฟ)

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

เปลี่ยน@s เป็น_s (แทน1s ของ BCD) ตามความเหมาะสม

T`E`@
\d
_

แก้ไขตัวเลขสุดท้ายของ BCD

.
$&$'$`¶

สร้างการหมุนทั้งหมด

O`

เรียงลำดับจากน้อยไปหามาก

_
@_
+`_@
@__

แปลงพวกเขาเป็นเอก

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

_

ลบหมายเลขแรกจากตัวเลขสุดท้ายโดยไม่สนใจตัวเลขกลางและแปลงเป็นทศนิยม


ไม่จำเป็นต้องใช้%สำหรับไบนารีเป็นการแปลงแบบ unary และคุณสามารถบันทึกอีกสองสามไบต์โดยใช้อักขระอื่นที่ไม่ใช่0และ1สำหรับไบนารี: tio.run/##K0otycxL/…
Martin Ender

@MartinEnder โอ้ฉันคิดว่าวันที่เมื่อฉันพยายามและล้มเหลวในการใช้หนึ่งในกิจวัตรการแปลงไบนารีของคุณ ...
Neil

2

Haskell , 130 ไบต์

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]

ลองออนไลน์!

คำอธิบาย / Ungolfed

เนื่องจากเรากำลังจะใช้foldl1((+).(2*))การแปลงจากเลขฐานสองเป็นทศนิยมเราอาจไม่ได้ใช้maximumและminimumแต่ใช้foldl1 max(หรือเหมือนกันminตามลำดับ) และใช้ตัวย่อr = foldr1และการใช้งานสั้น

ตอนนี้ให้เรากำหนดโอเปอเรเตอร์f#xที่แปลงxเป็น BCD สร้างการหมุนทั้งหมดลดการใช้fและแปลงเป็นทศนิยม:

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

ตอนนี้มันเป็นเรื่องของการใช้ตัวดำเนินการนี้เพียงครั้งเดียวmaxและครั้งเดียวด้วยminและลบผลลัพธ์ของพวกเขา:

f x = max#x - min#x


2

Japt -x , 20 ไบต์

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

ลองออนไลน์!

ใส่เป็นอาร์เรย์ของตัวเลข

คำอธิบาย:

®¤                      #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
คุณสามารถใช้การ-xตั้งค่าสถานะเพื่อบันทึก 2 ไบต์
โอลิเวอร์


1

Pyth, 24/26 ไบต์

s.+Smi.>Gd2l=Gsm.[\04.Bs

รับอินพุตเป็นสตริงที่ยกมา 26 ไบต์ถ้าจำเป็นต้องป้อนค่าเป็นจำนวนเต็ม; ผนวกdzในกรณีนั้น

กรณีทดสอบ (อินพุตเป็นสตริง 24 ไบต์)

กรณีทดสอบ (ใส่เป็นตัวเลข 26 ไบต์)


1

J, 43 ไบต์

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

ลองออนไลน์!

บางครั้งลักษณะโดยปริยายทำให้สิ่งต่าง ๆ ยาก แต่อาจมีวิธีที่จะทำมันให้เป็นสไตล์ที่มีความกระชับมากกว่านี้ ฉันคิดว่าฉันจำวิธีที่ดีกว่าในการแบ่งตัวเลขเป็นตัวเลขอื่นที่ไม่ใช่"."0@":แต่ฉันจำไม่ได้ ...

คำอธิบาย

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

การเตรียมและการลบ 8 คือเพื่อให้แน่ใจว่ามีเลขศูนย์ที่ถูกต้อง (J จะปรับรูปร่างอาร์เรย์ให้มีขนาดขององค์ประกอบความยาวสูงสุดและ 8 คือ 4 หลักในไบนารีดังนั้นจึงถูกใช้)


1

APL (NARS), 34 ตัวอักษร, 68 ไบต์

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

ทดสอบเล็กน้อย:

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.