数字を最大桁で減らす


33

仕事:

10進法で整数を指定した場合、次のように1桁の10進数に減らします。

  1. 数値を10進数のリストに変換します。
  2. 最大桁Dを見つける
  3. リストからDを削除します。Dが複数ある場合は、左から1番目(最も重要な位置)を選択します。他のすべてはそのまま残ります。
  4. 結果のリストを10進数に変換し、Dを掛けます。
  5. 数値が9より大きい(10進数が1桁以上)場合は、手順全体を繰り返して、結果をそれに入力します。1桁の結果が得られたら停止します。
  6. 結果を表示します。

例:

26364 -> 
1. 2 6 3 6 4 
2. The largest digit is 6, so D=6
3. There are two occurrences or 6: at positions 1 and 3 (0-based). We remove the left one,
    at position 1 and get the list 2 3 6 4 
4. we convert the list 2 3 6 4 to 2364 and multiply it by D:
   2364 * 6 = 14184
5. 14184 is greater than 9 so we repeat the procedure, feeding 14184 into it.

14184などの手順を繰り返し、次の中間結果を経て、最終的に8に到達します。

11312
3336
1998
1782
1376
952
468
368
288
224
88
64
24
8

したがって、26364の結果は8です。

入力:整数/整数を表す文字列

出力: 1桁、数値に適用された削減の結果。

テストケース:

9 -> 9
27 -> 4
757 -> 5
1234 -> 8
26364 -> 8
432969 -> 0
1234584 -> 8
91273716 -> 6

これはであるため、各言語のバイト単位の最短回答が優先されます。


3
それで数が10より大きい場合小数第1桁以上のものを持っています。数値10には10進数が1桁以上ありますが、10桁以下です。
アダム

@Adámロジックをコーディングすることで、そうすべき10 -> 10でしょうか?
イアンH.

1
@Adámあなたは正しいです、私は「9より大きい」と書くべきでした。説明を編集します。ありがとう!
ガレンイワノフ

誰かが十分に大きな領域についてこの関数のヒストグラムを調べましたか?多くのゼロがあるようです。また、テストケースの作成中に多くの8を獲得しました。
ガレンイワノフ

2
また、4で割り切れる乱数は、最後の2桁の積が8で割り切れる確率が3/5です。
ØrjanJohansen

回答:



11

JavaScript(ES6)、49バイト

f=n=>n>9?f(""+n.replace(m=Math.max(...n),"")*m):n

のような整数の文字列表現として入力を受け取りますf("26364")

テストケース



6

Pyth、16バイト

.WtH`*s.-ZKeSZsK

入力を文字列として受け取ります。ここで試してみてください! (別の方法:.WtH`*s.-ZeSZseS

Pyth、18バイト

.WgHT*s.-`ZKeS`ZsK

入力を整数として受け取ります。ここで試してみてください!

使い方

16バイト

.WtH` * s.-ZKeSZsK〜完全なプログラム。

.W〜機能中。A(値)は真実ですが、値= B(値)です。
                 〜最終値が返されます。
  tH〜A、条件:value [1:]は真実ですか?長さは2以上ですか?
    `* s.-ZKeSZsK〜B、セッター。
       .-〜バグごとの減算、最高桁の削除に使用、...
         Z〜現在の値Z、および...
          KeSZ〜Zの最高桁(文字列として)。また、変数Kに割り当てます。
      s〜整数にキャストされます。
     *〜によって乗算...
              sK〜最上位の桁。
    `〜文字列に変換します。

18バイト

.WgHT * s.-`ZKeS`ZsK〜完全なプログラム。

.W〜機能中。A(値)は真実ですが、値= B(値)です。
                   〜最終値が返されます。
  gHT〜A、条件:値(H)≥10ですか?
     * s.-`ZKeS`ZsK〜B、セッター。
       .-〜Bagwise substraction(最初の出現を削除するために使用)。
         `Z〜Zの文字列表現。
           KeS`Z〜そしてZ(最高桁)の最高(辞書編集)文字。
                     また、Kという変数に割り当てます。
      s〜整数にキャストします。
     *〜乗算...
                sK〜Kはintにキャストされます。

ビーイング近いという挑戦のようなタイプのゼリーには、IMO Pythのための非常に良いです:-)


6

14 13 12バイト

1バイトを保存してくれたZgarbに感謝します。

Ω≤9oṠS*od-▲d

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

説明:

Ω≤9            Repeat the following function until the result is ≤ 9
           d     Convert to a list of digits
         -▲      Remove the largest one
       od        Convert back to an integer
   oṠS*          Multiply by the maximum digit

いくつかの再配置を伴う12バイト
ズガーブ

@Zgarbありがとう、私はそのようなものを探していました。
H.PWiz

6

R99 95バイト

f=function(x)"if"(n<-nchar(x)-1,f(10^(n:1-1)%*%(d=x%/%10^(n:0)%%10)[-(M=which.max(d))]*d[M]),x)

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

再帰関数。f(number)フッターの追加は、の他の値をテストするために使用できますnumber。簡単な実装dは、数字のリストであり10^(n:2-2)%*%d[-M]、最大の数字を削除して数値を計算します。


5

Python 2、72バイト

f=lambda n:`n`*(n<=9)or f(int(`n`.replace(max(`n`),'',1))*int(max(`n`)))

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


1
...私はこれで愚かな間違いをデバッグしていました。くそー、私は忍者を手に入れました。
完全に人間

入力9でエラーが発生しています
-RoryT

これはテストケースでは失敗したよう432969です。「とValueError:ベース10とのint()のための無効なリテラル: 『』」
ジェームズ・ウェブスター

@JamesWebsterは現在修正されているはずです。
FlipTack

1
@recursiveいいえ、あたかもn0であったとしてn*(n<=9)も、偽の値0と評価され、再帰が継続されてエラーが発生しますが、文字列'0'は真の値であるため、再帰は停止します。
FlipTack


4

ゼリー、15 バイト

D×Ṁ$œṡṀ$FḌµ>9µ¿

オンラインでお試しください!またはテストスイートを参照してください。

どうやって?

D×Ṁ$œṡṀ$FḌµ>9µ¿ - Link: number, n
              ¿ - while:
             µ  - ...condition (monadic):
            9   -    literal 9
           >    -    loop value greater than (9)?
          µ     - ...do (monadic):               e.g. 432969
D               -    convert to a decimal list        [4,3,2,9,6,9]
   $            -    last two links as a monad:
  Ṁ             -      maximum                         9
 ×              -      multiply (vectorises)          [36,27,18,81,54,81]
       $        -    last two links as a monad:
      Ṁ         -      maximum                         81
    œṡ          -      split at first occurrence      [[36,27,18],[54,81]]
        F       -    flatten                          [36,27,18,54,81]
         Ḍ      -    convert from base 10              389421  (i.e. 360000 + 27000 + 1800 + 540 + 81)


4

C#(.NET Core)、126バイト

int F(int n){var x=(n+"").ToList();var m=x.Max();x.RemoveAt(x.IndexOf(m));return n>9?F(int.Parse(string.Concat(x))*(m-48)):n;}

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



@EriktheOutgolferありがとー
Timmeh

1
@totallyhumanいくつかのリファクタリングの後、137にまでありがとう。
Timmeh

あなたは変更することができますif(n<10)return n;...return F(...);:このような、三元-IFを持つ単一のリターンにint F(int n){var x=(n+"").ToList();var m=x.Max(d=>d);x.RemoveAt(x.IndexOf(m));return n<10?n:F(int.Parse(string.Concat(x))*(m-48));}131バイト
ケビンCruijssen

using System.Linq;バイトカウントに(18バイト)を含める必要があると思います。
イアンH.

4

APL(Dyalog)36 35 33バイト

-1更新されたOP仕様のため。-2 ngnに感謝します。

匿名の暗黙の接頭辞関数。引数として整数を取ります。

{⍵>9:∇(⌈/×10⊥⊂⌷⍨¨⍳∘≢~⊢⍳⌈/)⍎¨⍕⍵⋄⍵}

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

{… 引数が}ある関数

⍵>9: 引数が9より大きい場合:

  ⍕⍵ 引数をフォーマット(文字列化)

  ⍎¨ それぞれを実行(評価)します(これにより、数字として数字が取得されます)

  () それらに次の暗黙関数を適用する

   ⌈/ 最大桁

   × 回

   10⊥ (数字を収集する)のベース10デコード

    すべての数字

   ⌷⍨¨ それぞれのインデックス

   ⍳∘≢I桁数のndices

    とは異なり

   ⊢⍳⌈/ 桁のリスト全体の最大桁のi ndex

   その上で再帰(つまり、自己呼び出し)

 他に

   引数を変更せずに返します


するべきでは>10ない>9
エリックアウトゴルファー

@EriktheOutgolferおそらく、しかし、OPは実際にはそれについて不明確です(自己矛盾)。
アダム

それは本当ですが>9、バイトを節約します。
エリックアウトゴルファー

@EriktheOutgolferが更新されました。
アダム

@Adám∇の代わりに⍣= -1バイトの場合:{⍵> 9:∇(⌈/ ...⋄⍵}
ngn

3

Perl 6の 45の  41バイト

{($_,{$/=.comb.max;S/"$/"//*$/}...10>*).tail}

試して

{($_,{S/"{.comb.max}"//*$/}...10>*).tail}

試して

拡張:

{  # bare block lambda with implicit parameter 「$_」

  (  # generate the sequence

      $_,                      # start the sequence with the input

      {                        # generate the rest of the values in the sequence

          S/                   # find and replace (not in-place)
            "{  .comb.max  }"  # find the max digit and match against it
          //                   # replace it with nothing
          *                    # multiply the result with
          $/                   # the digit that was removed
      }

      ...                      # keep generating values until

      10 > *                   # the value is less than 10

  ).tail                       # get the last value from the sequence
}

3

網膜、67バイト

{1`(..+)?
1$&;$&
O`\G\d
.+((.);.*?)\2
$1
\d+
$*
1(?=.*;(1+))|.
$1
1

オンラインでお試しください!リンクには、デニスのサーバーを破壊しないほど高速なテストケースが含まれています。説明:

{1`(..+)?
1$&;$&

2桁の数字の場合、これは数字を;区切り記号で複製し、その先頭に1を付けます。1桁の番号の場合、これ1;は番号のプレフィックスです。

O`\G\d

複製の数字を並べ替えます。(1桁の数値の場合、これは効果がありません。)

.+((.);.*?)\2
$1

最も大きい数字の最初の出現箇所を見つけて削除し、複製内の他の数字と、以前に追加された余分な1を削除します。(1桁の数字の場合、一致は失敗するため、何も実行されません。)

\d+
$*
1(?=.*;(1+))|.
$1
1

数字に数字を掛けます。1桁の番号の場合、これは元の番号になり、ループは終了します。それ以外の場合、プログラムは1桁に達するまでループします。


3

C#(.NETコア)177 + 18バイト

@raznagulのおかげで13バイト節約されました!

int f(int n){string s=n+"",m=s.Max(d=>d)+"";if(n<10)return n;var x=s.ToList();x.RemoveAt(s.IndexOf(m));int y=int.Parse(string.Join("",x))*int.Parse(m);return f(y);}

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


あなたは変更することができますs.Length<2n<10。また、再帰の次のステップでreturn f(y)ケースが処理されるため、最後に三項演算子を削除できifます。
raznagul

3

Java 8、126 104バイト

n->{for(;n>9;n=new Long((n+"").replaceFirst((n=(n+"").chars().max().getAsInt()-48)+"",""))*n);return n;}

@OlivierGrégoireのおかげで-22バイト。

説明:

ここで試してみてください。

n->{         // Method with long as both parameter and return-type
  for(;n>9;  //  Loop as long as the number contains more than 1 digit
    n=       //   Replace the current number with:
      new Long((n+"").replaceFirst((n=(n+"").chars().max().getAsInt()-48)+"",""))
             //    Remove the first largest digit from the number,
      *n     //    and multiply this new number with the removed digit
  );         //  End of loop
  return n;  //  Return the result
}            // End of method


1
104バイト(上記と同じですが、再帰的ではなく反復的で、n>9条件ではなく条件を元に戻しますn<10)。
オリビエグレゴワール

2

Jq 1.5、86バイト

until(.<10;"\(.)"|(./""|max)as$v|index($v)as$x|.[:$x]+.[1+$x:]|tonumber*($v|tonumber))

拡大

until(
    .<10                    # until number is below 10
  ; "\(.)"                  # convert to string
  | (./""|max) as $v        # find largest digit, call it $v
  | index($v) as $x         # find index of digit
  | .[:$x]+.[1+$x:]         # remove digit
  | tonumber*($v|tonumber)  # convert back to number and multiply by $v
)

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



2

Lua、137108バイト

function f(n)while n>9 do b="0"g=b.gsub g(n,".",function(m)b=math.max(m,b)end)n=b*g(n,b,"",1)end print(n)end

29バイトのゴルフをしてくれたJonathan Sに感謝します。

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



ありがとう。それはそれ自身の答えに値するように見えます-あなたがそれのために作る投稿にリンクします、さもなければ編集してクレジットします。
MCAdventure10

編集するだけです。それはまだあなたのコードです。私はそれを最初から書いていません。
ジョナサンS.

2

D188 186 185バイト

import std.conv,std.algorithm;T f(T,U=string)(T u){if(u<10)return u;T[]r;u.text.each!(n=>r~=n.to!T-48);T m=r.maxElement;U s;r.remove(r.maxIndex).each!(n=>s~=n.to!U);return f(m*s.to!T);}

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

私は怠zyな評価がとても嫌いです。どんなヒントでも大歓迎です!


2

Lua、154バイト

これをゴルフで打ついくつかの方法があるはずです。今、実験中です。

n=...z=table
while n+0>9 do
t={}T={}n=n..''n:gsub(".",function(c)t[#t+1]=c T[#T+1]=c
end)z.sort(t)x=t[#t]z.remove(T,n:find(x))n=z.concat(T)*x
end
print(n)

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

説明

n=...                    -- define n as a shorthand for the argument
z=table                  -- define z as a pointer to the object table
while n+0>9              -- iterate as long as n is greater than 9
do                       -- n+0 ensure that we're using a number to do the comparison
  t={}                   -- intialise two tables, one is used to find the greatest digit
  T={}                   -- the other one is used to remove it from the string
  n=n..''                -- ensure that n is a string (mandatory after the first loop)
  n:gsub(".",function(c) -- apply an anonymous function to each character in n
               t[#t+1]=c -- fill our tables with the digits
               T[#T+1]=c
             end)        
  z.sort(t)              -- sort t to put the greatest digit in the last index
  x=t[#t]                -- intialise x to the value of the greatest digit
  z.remove(T,n:find(x))  -- remove the first occurence of x from the table T 
                         -- based on its position in the input string
  n=z.concat(T)*x        -- assign the new value to n
end                      -- if it still isn't a single digit, we're looping over again
print(n)                 -- output the answer

2

PowerShell、123バイト

[Collections.ArrayList]$a=[char[]]"$args"
while(9-lt-join$a){$a.remove(($b=($a|sort)[-1]));$a=[char[]]"$(+"$b"*-join$a)"}$a

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

やばい。PowerShell配列は不変なので、長い配列を使用する必要があります[Collections.ArrayList].remove()後で呼び出すためにここでキャスト。

入力を受け取り$args、それを文字列に変換し、次にchar-array、次にに変換しArrayListます。それをに保存し$aます。それからwhile、以下になるまでループします9。繰り返しごとに.remove$a(によって行われsort、最後の要素を取得する)の最大要素を呼び出しています[-1])格納し$bます。これは、ASCII値がリテラル数字と同じ方法でソートされるために起こります。

次に、$a再びchar-array として再計算します(そしてArrayList$b(現在はchar)を文字列にキャストし、次にintを文字列にキャストし、+それを$a -joinedに文字列に乗算する(暗黙的にintにキャストする)ことにより暗黙的に)ます。これは、チャレンジの「Dによる乗算」部分を満たします。

最後に、ループを抜けたら、 $a、パイプラインにされ、出力が暗黙的になります。


2

ピップ22 21バイト

Wa>9a:aRAa@?YMXax*:ya

入力をコマンドライン引数として受け取ります。すべてのテストケースを確認します。オンラインで試してください!

説明

Ungolfed、コメント付き:

                 a is 1st cmdline arg
W a>9 {          While a > 9:
  Y MXa           Yank max(a) into y
  a RA: a@?y ""   Find index of y in a; replace the character at that position with ""
  a *: y          Multiply a by y
}
a                Autoprint a

ゴルフバージョンでは、ループ本体が単一の式に凝縮されます。

a:aRAa@?YMXax*:y
        YMXa      Yank max(a)
     a@?          Find its index in a
  aRA       x     Replace at that index with x (preinitialized to "")
             *:y  Multiply that result by y (using : meta-operator to lower the precedence)
a:                Assign back to a


2

Java 8:115バイト


Jo Kingのおかげで-10バイト

残念ながら、ラムダ関数を再帰的に呼び出すことはできないため、メソッドヘッダーには11バイトが余分に必要です。代わりにループする短いJavaの回答があることは承知していますが、これを自分で考え出すことにしました。

long f(long n){int m=(n+"").chars().max().getAsInt()-48;return n>9?f(new Long((n+"").replaceFirst(""+m,""))*m):n;};

オンラインで試す


-48マップからm定義の最後に移動できます。オンラインでお試しください!また、TIOリンクに余分な空白があります
Jo King

@JoKingありがとう。
ベンジャミンアーカート

1

J、40バイト

((]*<^:3@i.{[)>./)&.(10&#.inv)^:(9&<)^:_

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

説明

(      iterate                   )^:(9&<)^:_    NB. keep iterating while the number is > 9
 (     stuff         )&.(10&#.inv)              NB. convert to digits, do stuff, convert back to number
 (           )>./)                              NB. stuff is a hook, with max digit >./  on the right
 (]*<^:3@i.{[)                                  NB. so that in this phrase, ] means "max" and [ means "all digits"
  ]                                             NB. the max digit...
   *                                            NB. times...        
    <^:3@                                       NB. triple box...
         i.                                     NB. the first index of the max in the list of all digits
           {                                    NB. "from" -- which because of the triple box means "take all indexes except..."
            [                                   NB. from all the digits of the number

1
本日、トリプルボックスの選択について学びました。ありがとうございます。
ガレンイヴァノフ

1

PowerShell、230バイト

$n="$args";do{$n=$n.ToString();$a=@();0..$n.Length|%{$a+=$n[$_]};$g=[convert]::ToInt32(($a|sort|select -last 1),10);[regex]$p=$g.ToString();[int]$s=$p.replace($n,'',1);if($n.Length-eq1){$n;exit}else{$r=$s*$g}$n=$r}until($r-lt10)$r

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

すべてのタイプの鋳造で無駄が多すぎます。




1

Bash、80バイト

パッケージCore Utilities(for sortおよびtail)およびを使用しますgrep

while((n>9));do m=$(grep -o .<<<$n|sort|tail -n1);n=$((${n/$m/}*m));done;echo $n

どのように機能しますか?

while (( n > 9 )); do  # C-style loop conditional
    grep -o .          # Separate the string into one char per line
              <<< $n   # Use the content of variable `n` as its stdin
    | sort             # Pipe to `sort`, which sorts strings by line
    | tail -n 1        # Take the last line

m=$(                 ) # Assign the output of the command chain to `m`
n=$((          ))      # Assign the result of the evaluation to n
     ${n/$m/}          # Replace the first occurrence of $m with empty
             *m        # ... and multiply it by the value of `m`
done; echo $n          # After loop, print the value of `n`
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.