找出数字的BCD差异


20

BCD差异

给定一个整数n,通过将每个十进制数字替换为其4位二进制表示形式,将其转换为BCD(二进制编码的十进制

 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

Answers:


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@@in 的结果并将末尾的k替换为#,我们可以使效率更高一些Length@k。这使我们可以很容易地生成散点图:

在此处输入图片说明

本地结构与整体混乱的对比让我真的很感兴趣。


Max@#-Min@#&保存一个字节。对?
J42161217 '17

@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可以肯定,但是在这些时间间隔内的结构看起来非常混乱(仅在较小尺度上具有结构)。
马丁·恩德

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转换为二进制或从二进制转换的调用确实使这里的长度length肿。;-)

我们将输入作为$args,将其包装在字符串中,然后将其转换为char-array。我们遍历每个数字,convert将数字加toString2(即,将数字转换为二进制数),然后.padLeft将其变为四位数的二进制数。然后,将所得的字符串数组-join编入单个字符串,并以char-array 重新广播,然后保存到中$b

接下来,我们遍历$b,这只是确保我们遍历足够的时间以说明每次旋转。每次迭代,我们使用多个分配将第一个字符剥离$x,其余字符剥离$y。然后,我们将它们合并回一起$b=$y+$x以将第一个元素移到末尾,即有效地将数组旋转一个。将其-join编入字符串,用作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>

编辑:由于@RickHitchcock,节省了11个字节。@ETHproductions节省了1个字节。说明: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`
Rick Hitchcock

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 inary)

 附上(以便我们将整个列表用于每次旋转)

()⌽¨ 旋转(左)以下每个量:

≢b 的长度 b

我的想法

2⊥¨ 从base-2解码每个。

(…… ) 对它应用以下默认功能

⌈/ 最大(减少)

- 减去

⌊/ 最小(减少)


你可以很容易trainify该位:(⍳≢b)⌽¨⊂b←
NGN

甚至更好-使用(≢,/,⍨),而不是显而易见的(⍳∘≢⌽¨⊂)
NGN




2

Mathematica,110 99字节

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


在线尝试!


2

Python 3,141个字节

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)

在线尝试


2

视网膜96 89字节

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

_

在线尝试!有点慢,所以链接仅包含一个小的测试用例。编辑:由于@MartinEnder,节省了7个字节。说明:

.
@@@$&

@在每个数字前面加上3 s。(这些代表0BCD的,但是更高尔夫球。)

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

在适当的地方将s 更改@_s(代表1BCD 的s)。

T`E`@
\d
_

修正BCD的最后一位数字。

.
$&$'$`¶

生成所有旋转。

O`

将它们按升序排序。

_
@_
+`_@
@__

将它们转换为一元。

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

_

从最后一个数字减去第一个,忽略中间数字,然后转换为十进制。


有没有必要使用%的二进制一元的转换,你可以保存几个使用其它字符不是字节01二进制:tio.run/##K0otycxL/...
马丁安德

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

在线尝试!

解释/取消包装

由于我们将要使用foldl1((+).(2*))从二进制到十进制的转换,我们不建议使用maximumminimum,而是foldl1 max(或min分别使用)和使用short 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

PHP,156个 153字节

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

在线尝试!


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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.