Знайдіть різницю числа 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

Мова Вольфрама (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 Так, спасибі! :)
Мартін Ендер

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... ось кілька різних масштабів
J42161217

@Jenny_mathy впевнений, але структура в цих інтервалах виглядає дуже хаотично (із структурами лише у значно менших масштабах).
Мартін Ендер

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]

Спробуйте в Інтернеті!

Дурні тривалі виклики .NET для перетворення в / з бінарних дійсно зменшує тут довжину. ;-)

Ми приймаємо введення як $args, загортаємо його в рядок, потім charпередаємо його як- масив. Переводимо петлю на кожну цифру, переводячи convertцифру toStringв основу 2(тобто, перетворюючи цифру у двійкове число), потім .padLeftробимо її чотирицифровим двійковим числом. Отриманий масив рядків потім -joinвидається в єдиний рядок і повторно charпередається як-масив, перш ніж зберігатися в $b.

Далі ми перебираємо цикл $b, що просто переконується, що ми достатньо разів циклічно враховуємо кожен обертання. Кожною ітерацією ми знімаємо перший символ, $xа решта символів - за $yдопомогою декількох призначень. Потім ми їх об'єднуємо назад, $b=$y+$xщоб перемістити перший елемент до кінця, тобто ефективно обертати масив на один. Це -joinвведено в рядок, який використовується як вхід до convertвиклику, щоб перетворити рядок з бінарної бази 2в an 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 (я вважаю, що це гольфіст, ніж будь-який інший спосіб прошивки до кратного 4 цифр) . Виключаючи префікс, який змінюється з 1 на 0, отриманий рядок потім обертається у кожному можливому положенні та перетворюється з двійкового назад у десятковий. Нарешті максимум і мінімум віднімаються.


1
@RickHitchcock Оберніть рядок подвійними підставками ... якщо тільки ви не хочете написати щось на зразок, .join`` у такому випадку вам потрібні потрійні заставки тощо
Neil

Гарна ідея використовувати шістнадцятковий. Збережіть 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`
Рік Хічкок

1
@ RickHitchcock Спасибі, що допомогло мені ... зрізати ... ще 7 байт, видаливши ще один slice!
Ніл

1
m=>Math[m]Трюк великий. Можливо змінити (+`0x1${n}`)до ('0x1'+n-0)або подібне?
ETHproductions



3

Лушпиння , 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

⍎¨ виконати (оцінити) кожного (символ)

()⊤ Кодувати (анти-базовий) у такій системі числення:

4/2 чотири двійкові біти

 переносити

, реве (згладжувати)

b← зберігати в b(для b іари)

 додавати (щоб ми використовували весь цей список для кожного обертання)

()⌽¨ Обертати (ліворуч) на кожну з наступних сум:

≢b довжина b

i ndices того

2⊥¨ декодуйте кожну з бази-2.

() Застосувати до цього наступну мовчазну функцію

⌈/ макс. (зменшення)

- мінус

⌊/ хв (-відведення)


Ви можете легко присвоїти цей біт: (⍳≢b) ⌽¨⊂b ←
ngn

а ще краще - використовувати (≢, /, ⍨) замість очевидного (⍳∘≢⌽¨⊂)
ngn



2

Рубі , 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 Ха, так, ти маєш рацію. Спасибі
відновить Моніка - notmaynard



2

Сітківка , 96 89 байт

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

_

Спробуйте в Інтернеті! Трохи повільний, тому посилання включає лише невеликий тестовий випадок. Редагувати: Збережено 7 байт завдяки @MartinEnder. Пояснення:

.
@@@$&

Префікс три @s до кожної цифри. (Вони представляють собою 0BCD, але є гольфістом.)

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

Змініть @s на _s (представляючи 1s BCD), де це доречно.

T`E`@
\d
_

Зафіксуйте останню цифру BCD.

.
$&$'$`¶

Створіть усі обертання.

O`

Сортуйте їх у порядку зростання.

_
@_
+`_@
@__

Перетворіть їх в одинакові.

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

_

Відняти перше від останнього числа, ігноруючи проміжні числа, і перетворити в десятковий.


Не потрібно використовувати %для бінарного для унарного перетворення, і ви можете зберегти ще кілька байтів, використовуючи інші символи, ніж 0і 1для двійкових: tio.run/##K0otycxL/…
Мартін Ендер

@MartinEnder О, я думаю, що датується, коли я намагався і не зміг використати одну з ваших двійкових процедур перетворення ...
Ніл

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]

Спробуйте в Інтернеті!

Пояснення / Недозволений

Оскільки ми будемо використовувати 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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.