数値のBCD差を見つける


20

BCD差

整数nが与えられた場合、各10進数を4桁のバイナリ表現で置き換えることにより、BCD(バイナリコード10進数)に変換します。

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

次に、他の再配置なしでこのリストで表現できる最大数と最小数を見つけるために、2進数のリストを回転させます。

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)

これらの数値を10進数に変換し、ビットのリストを通常のバイナリとして扱い、最大から最小を減算します。

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バイト

1バイトを節約してくれたJenny_mathyに感謝します。

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

オンラインでお試しください!

これは、nのBCDのn回転を生成するため、ひどく非効率的です。これは、必要以上の方法です。in の結果を保存し、最後をで置き換えることで、これをもう少し効率的にすることができます。これにより、散布図を非常に簡単に生成できます。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

:実際のプロットが繰り返さpatern.Those「混沌の雲」は、すべての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呼び出しは、ここで本当に長さを膨らませます。;-)

入力をとして取得$argsし、文字列でラップしてから、char-array としてキャストします。各桁をループし、convertその桁toStringを底に入れて2(つまり、桁を2進数に変換して)、.padLeft4桁の2進数にします。結果の文字列の配列は-join、1つの文字列にedされ、charに保存される前に-array として再キャストされ$bます。

次に、ループを繰り返します$b。これは、すべての回転を考慮して十分な回数だけループするようにします。繰り返しごとに、複数の割り当て$x$y使用して最初の文字を切り離し、残りの文字を切り離します。次に、それらを一緒にマージし$b=$y+$xて最初の要素を最後に移動します。つまり、配列を1つずつ効果的に回転させます。それはだ-joinへの入力として使用される文字列の中に編convertバイナリベースから文字列をオンにするコール2Int64。次にsort、これらの結果の数値すべてをに保存します$c。最後に、最大のものを取得し[-1]、最小のものを減算し[0]ます。それはパイプラインに残り、出力は暗黙的です。


4

Ohm 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接頭辞により、入力は16進数として再解析されます。そのバイナリは、1の接頭辞を持つ元の数値のBCDと同じです(これは、4桁の倍数にパディングする他の方法よりもゴルファーだと思います) 。1から0に変更される接頭辞を除いて、結果の文字列は可能な各位置で回転され、バイナリから10進数に変換されます。最後に、最大値と最小値が減算されます。


1
@RickHitchcock二重バックティックで文字列をラップします... .join`` トリプルバックティックなどが必要な場合を書きたい場合を除きます。-
ニール

16進数を使用することをお勧めします。このような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 4つのバイナリビット

 転置

, ラベル(平坦化)

b← 格納bb inaryの場合)

 囲みます(したがって、各ローテーションにこのリスト全体を使用します)

()⌽¨ 次の各量だけ回転(左)します。

≢b の長さ b

私はそのことをndices

2⊥¨ base-2からそれぞれデコードします。

() 次の暗黙関数を適用します

⌈/ max(-リダクション)

- マイナス

⌊/ min(-リダクション)


このビットを簡単にトレーニングできます:(⍳≢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}

オンラインでお試しください!

  • displaynameのおかげで5バイト節約

-> 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ええ、そうです。ありがとう
モニカiamnotmaynardを


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 を付けます。(これら0はBCDのsを表しますが、ゴルファーです。)

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

必要に応じて、@sを_s(1BCDのsを表す)に変更します。

T`E`@
\d
_

BCDの最後の桁を修正します。

.
$&$'$`¶

すべての回転を生成します。

O`

それらを昇順で並べ替えます。

_
@_
+`_@
@__

それらを単項に変換します。

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

_

中間の数値を無視して、最後の数値から最初の数値を減算し、10進数に変換します。


そこ使用する必要ません%単項変換バイナリのためには、あなたは、いくつかのより多くの以外の文字を使用してバイト保存することができます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*))2進数から10進数への変換に使用するので、maximumandを使用せずminimum、むしろfoldl1 max(またはminそれぞれと同じ)shortを使用することもできますr = foldr1

次に、BCDにf#x変換xし、すべての回転を生成し、これらを使用fしてこれらを減らし、10進数に変換する演算子を定義します。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.