番号に連続した降順の番号はいくつありますか?


18

2019年が到来し、おそらく誰もがこの数字の特異性に気づいたでしょう:実際には、連続した降順の数字を表す2つのサブ番号(20と19)で構成されています。

チャレンジ

数所与xのサブ数を取ることによって形成することができる数値を降順、連続の最大配列の長さを返しますx

ノート :

  • サブ番号に先行ゼロを含めることはできません(たとえば、1009に分割することはできません)1009
  • 連続および降順は、シーケンス内の数値が前の数値-1またはと等しくなければならないことを意味します(たとえば、連続していないために分割できない、など)n+1=n1525,2522 ≠ 5 - 1
  • シーケンスで例えば、完全な番号を使用することによって取得する必要があり7321ます破棄することはできません7シーケンスを取得すると321
  • 唯一の1つの配列が番号から得ることができ、例えば3211098二つの配列に分割することができない321および1098

入力

  • 整数(>= 0):数字、文字列、または数字のリストを指定できます

出力

  • 減少するサブ番号の最大数が指定された単一の整数(この番号の下限はであることに注意してください1。つまり、番号は長さ1の降順で構成されます)

例:

2019         --> 20,19           --> output : 2
201200199198 --> 201,200,199,198 --> output : 4
3246         --> 3246            --> output : 1
87654        --> 8,7,6,5,4       --> output : 5
123456       --> 123456          --> output : 1
1009998      --> 100,99,98       --> output : 3
100908       --> 100908          --> output : 1
1110987      --> 11,10,9,8,7     --> output : 5
210          --> 2,1,0           --> output : 3
1            --> 1               --> output : 1
0            --> 0               --> output : 1
312          --> 312             --> output : 1
191          --> 191             --> output : 1

一般的なルール:

  • これはであるため、バイト単位の最短回答が優先されます。
    コードゴルフ言語では、非コードゴルフ言語で回答を投稿しないようにしてください。「任意の」プログラミング言語の可能な限り短い答えを考えてみてください。
  • 標準のルールデフォルトのI / Oルールを使用した回答に適用されるため、STDIN / STDOUT、適切なパラメーターと戻り値型、完全なプログラムを備えた関数/メソッドを使用できます。あなたの電話。
  • デフォルトの抜け穴は禁止されています。
  • 可能であれば、コードのテストへのリンク(TIOなど)を追加してください。
  • また、回答の説明を追加することを強くお勧めします。

1
サンドボックスから移行:codegolf.meta.stackexchange.com/questions/2140/...
digEmAll

1
テストケースは210 -> 2,1,0間違ってい0 -> 0ますか?タスクでは、「サブ番号に先行ゼロを含めることはできません」と表示されますが、ゼロは特別な場合ですか?
ბიმო

2
@BMO:さて、ここで話題は...ちょっとphylosoficalです:私にはD、0は無し(役に立たない)との数がゼロをリードする、そうそうゼロは特殊なケースである
digEmAll

2
あなたは...これらを呼ぶような恩着せがましい番号を?xD申し訳ありませんが、それも面白くなかったようです
HyperNeutrino

申し訳ありませんが、について尋ねたコメントを削除しました212019。すべてのルールを読んだわけではないようです。
シクラミニスト

回答:


6

ゼリー 15  9 バイト

デニスのバグ修正

ŻṚẆDfŒṖẈṀ

オンラインでお試しください!321コードは少なくとも、30分もかかります)ON2

どうやって?

ŻṚẆDfŒṖẈṀ - Link: integer, n
Ż         - [0..n]
 Ṛ        - reverse
  Ẇ       - all contiguous slices (of implicit range(n)) = [[n],...,[2],[1],[0],[n,n-1],...,[2,1],[1,0],...,[n,n-1,n-2,...,2,1,0]]
   D      - to decimal (vectorises)
     ŒṖ   - partitions of (implicit decimal digits of) n
    f     - filter discard from left if in right
       Ẉ  - length of each
        Ṁ - maximum

6

JavaScript(ES6)、56バイト

ArBoのPythonの回答のポートは大幅に短くなっています。ただし、再帰が多すぎるため、一部のテストケースで失敗します。

f=(n,a=0,c=0,s)=>a<0?f(n,a-~c):n==s?c:f(n,--a,c+1,[s]+a)

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


JavaScript(ES6)、66バイト

入力を文字列として受け取ります。

f=(s,n=x='',o=p=n,i=0)=>s[i++]?o==s?i:f(s,--n,o+n,i):f(s,p+s[x++])

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

コメント済み

f = (               // f = recursive function taking:
  s,                //   s = input number, as a string
  n =               //   n = counter
  x = '',           //   x = position of the next digit to be added to p
  o = p = n,        //   o = generated output; p = prefix
  i = 0             //   i = number of consecutive descending numbers
) =>                //
  s[i++] ?          // increment i; if s[i] was defined:
    o == s ?        //   if o is matching s:
      i             //     stop recursion and return i
    :               //   else:
      f(            //     do a recursive call with:
        s,          //       s unchanged
        --n,        //       n - 1
        o + n,      //       (n - 1) appended to o
        i           //       i unchanged (but it was incremented above)
      )             //     end of recursive call
  :                 // else:
    f(              //   this is a dead end; try again with one more digit in the prefix:
      s,            //     s unchanged
      p + s[x++]    //     increment x and append the next digit to p
    )               //   end of recursive call

コードの変更を実装して54バイト
ArBo

5

Perl 6の43の41、40バイト

nwellnhofのおかげで-1バイト

{/(<-[0]>.*?|0)+<?{[==] 1..*Z+$0}>/;+$0}

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

正規表現ベースのソリューション。私は代わりに降順リストから一致するより良い方法を考え出そうとしていますが、Perl 6はパーティションをうまく行いません

説明:

{                                        }  # Anonymous code block
 /                                /;        # Match in the input
   <-[0]>.*?      # Non-greedy number not starting with 0
            |0    # Or 0
  (           )+  # Repeatedly for the rest of the number
                <?{             }>  # Where
                        1..*Z+$0       # Each matched number plus the ascending numbers
                                       # For example 1,2,3 Z+ 9,8,7 is 10,10,10
                   [==]                # Are all equal
                                    +$0  # Return the length of the list


4

Pythonの3232の 228 187 181 180 150 149バイト

-1 @ Jonathan Frechに感謝

e=enumerate
t=int
h=lambda n,s=1:max([1]+[i-len(n[j:])and h(n[j:],s+1)or s+1for j,_ in e(n)for i,_ in e(n[:j],1)if(t(n[:j])-t(n[j:j+i])==1)*t(n[0])])

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

最初の未コード:

def count_consecutives(left, right, so_far=1):
    for i,_ in enumerate(left, start=1):
        left_part_of_right, right_part_of_right = right[:i], right[i:]
        if (int(left) - int(left_part_of_right)) == 1:
            if i == len(right):
                return so_far + 1
            return count_consecutives(left_part_of_right, right_part_of_right, so_far + 1)
    return so_far

def how_many_consecutives(n):
    for i, _ in enumerate(n):
        left, right = n[:i], n[i:]
        for j, _ in enumerate(left, start=1):            
            left_part_of_right = right[:j]
            if int(left) - int(left_part_of_right) == 1 and int(n[i]) > 0:     
                return count_consecutives(left, right)
    return 1

1
s+1 forすることができますs+1for(t(n[:j])-t(n[j:j+i])==1)*t(n[0])可能性がありますt(n[:j])-t(n[j:j+i])==1>=t(n[0])
ジョナサンフレッチ

2番目の提案は機能しないようです。ただし、表現をから分離するにはスペースが必要なので、何ももたらされませんif
西岡

本当...代替案149
ジョナサンフレッチ

4

パイソン278の 74 73バイト

l=lambda n,a=0,c=0,s="":c*(n==s)or a and l(n,a-1,c+1,s+`a-1`)or l(n,a-~c)

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

Arnauldのおかげで-1バイト

入力を文字列として受け取ります。このプログラムは、Pythonの再帰の深さの制限にかなり早く到達しますが、ほとんどのテストケースを終了できます。

使い方

l=lambda n,                              # The input number, in the form of a string
         a=0,                            # The program will attempt to reconstruct n by
                                         #  building a string by pasting decreasing
                                         #  numbers, stored in a, after each other.
         c=0,                            # A counter of the amount of numbers
         s="":                           # The current constructed string
              c*(n==s)                   # Return the counter if s matches n
              or                         # Else
              a and l(n,a-1,c+1,s+`a-1`) # If a is not yet zero, paste a-1 after s
              or                         # Else
              l(n,a-~c)                  # Start again, from one higher than last time

1
いい答え!a+c+1に短縮できますa-~c
アーナウルド

3

05AB1E、10 バイト

ÝRŒʒJQ}€gà

非常に遅いため、以下のTIOは750以下のテストケースでのみ機能します。

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

説明:

Ý           # Create a list in the range [0, (implicit) input]
            #  i.e. 109 → [0,1,2,...,107,108,109]
 R          # Reverse it
            #  i.e. [0,1,2,...,107,108,109] → [109,108,107,...,2,1,0]
  Œ         # Get all possible sublists of this list
            #  i.e. [109,108,107,...,2,1,0]
            #   → [[109],[109,108],[109,108,107],...,[2,1,0],[1],[1,0],[0]]
   ʒ  }     # Filter it by:
    J       #  Where the sublist joined together
            #   i.e. [10,9] → "109"
            #   i.e. [109,108,107] → "109108107"
     Q      #  Are equal to the (implicit) input
            #   i.e. 109 and "109" → 1 (truthy)
            #   i.e. 109 and "109108107" → 0 (falsey)
       g   # After filtering, take the length of each remaining inner list
            #  i.e. [[109],[[10,9]] → [1,2]
         à  # And only leave the maximum length (which is output implicitly)
            #  i.e. [1,2] → 2

2
コードゴルフ-1バイトをプログラムに追加して、そこから移動n!するn lg nだけの価値はありません。
corsiKa

3

Pyth、16バイト

lef!.EhM.+vMT./z

ここでオンライン試すか、ここですべてのテストケースを一度に確認してください

lef!.EhM.+vMT./z   Implicit: z=input as string
             ./z   Get all divisions of z into disjoint substrings
  f                Filter the above, as T, keeping those where the following is truthy:
          vMT        Parse each substring as an int
        .+           Get difference between each pair
      hM             Increment each
   !.E               Are all elements 0? { NOT(ANY(...)) }
 e                 Take the last element of the filtered divisions
                     Divisions are generated with fewest substrings first, so last remaining division is also the longest
l                  Length of the above, implicit print

3

ゼリー、11バイト

ŒṖḌ’Dɗ\ƑƇẈṀ

On0.3

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

使い方

ŒṖḌ’Dɗ\ƑƇẈṀ  Main link. Argument: n (integer)

ŒṖ           Yield all partitions of n's digit list in base 10.
        Ƈ    Comb; keep only partitions for which the link to the left returns 1.
       Ƒ       Fixed; yield 1 if calling the link to the left returns its argument.
      \          Cumulatively reduce the partition by the link to the left.
     ɗ             Combine the three links to the left into a dyadic chain.
  Ḍ                  Undecimal; convert a digit list into an integer.
   ’                 Decrement the result.
    D                Decimal; convert the integer back to a digit list.

3

、26バイト

F⊕LθF⊕Lθ⊞υ⭆κ⁻I…θιλI﹪⌕υθ⊕Lθ

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

F⊕Lθ

i0から入力の長さまでループします。

F⊕Lθ

k0から入力の長さまでループします。

⊞υ⭆κ⁻I…θ⊕ιλ

入力のk最初のi桁で指定された数字から降順で最初の数字を計算し、それらを連結して、結果の各文字列を事前定義された空のリストに蓄積します。

I﹪⌕υθ⊕Lθ

入力の最初に一致するコピーの位置を見つけ、入力の長さよりも1を法としてそれを減らします。

例:2019次の文字列の入力の場合、生成されます:

 0
 1  0
 2  0-1
 3  0-1-2
 4  0-1-2-3
 5  
 6  2
 7  21
 8  210
 9  210-1
10  
11  20
12  2019
13  201918
14  20191817
15  
16  201
17  201200
18  201200199
19  201200199198
20  
21  2019
22  20192018
23  201920182017
24  2019201820172016

2019 次に、インデックス12で検出されます。これは、5を法として減じられ、2の望ましい答えが得られます。


3

Haskell、87バイト

maximum.map length.(0#)
a#(b:c)=[a:x|c==[]||b>0,x<-b#c,a==x!!0+1]++(10*a+b)#c
a#b=[[a]]

入力は数字のリストです。

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

関数#は両方を見ることにより、可能なすべての分割のリストを作成します

  • a入力の残りの再帰呼び出しによって返されたすべての分割に現在の番号を追加します(x<-b#c)、ただし次の番号がゼロ(b>0)でない場合(または入力の最後の番号(c==[]))でありa、最初の番号よりも大きい場合のみそれぞれの前の分割の数xa==x!!0+1)。

そして

  • b入力リストの次の数字を現在の番号に追加aし、残りの入力を続けます((10*a+b)#c

基本ケースは、入力リストが空の場合(つまり、パターンマッチしない場合(b:c))です。再帰は、現在の数字で始まるaもの0(0#)(前に付ける最初の分岐当たることはありません)、aそれは分割の任意の数よりも大きくなることはありませんので、以前のすべての分割にします)。

各分割の長さを取り、最大値(maximum.map length)を見つけます。

87バイトのバリアント:

fst.maximum.(0#)
a#(b:c)=[(r+1,a)|c==[]||b>0,(r,x)<-b#c,a==x+1]++(10*a+b)#c
a#b=[(1,a)]

これは基本的に同じように機能しますが、リスト全体に分割を保持する代わり(r,x)に、分割の長さと分割rの最初の数のペアのみを保持しxます。


3

Pythonの3302の 282 271バイト

@ElPedroによるヒントのおかげで-10バイト。

入力を文字列として受け取ります。基本的に、左から番号のより大きなスライスを増やし、その番号のスライスについて、すべての番号を使用してシーケンスを形成できるかどうかを確認します。

R=range
I=int
L=len
def g(n,m,t=1):
 for i in R(1,L(m)+1):
  if I(m)==I(n[:i])+1:
   if i==L(n):return-~t
   return g(n[i:],n[:i],t+1)
 return 1
def f(n):
 for i in R(L(n)):
  x=n[:i]
  for j in R(1,L(x)+1):
   if (I(x)==I(n[i:i+j])+1)*I(n[i]):return g(n[i:],x)
 return 1

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


1
range3回使用しているためR=range、両方の関数の外部で定義し、R(whatever)代わりにrange(whatever)4バイトを節約するために使用できます。
エルペドロ

3

Japt、27バイト

ò pÊÔpÊqÊfl²i1Uì q"l?"¹ÌèÊÉ

オンラインでお試しください!またはほとんどのテストケースをチェック

これは得点が良くありませんが、独自の方法を使用しており、ゴルフをする余地がもっとあるかもしれません。また、201200199198タイムアウトを回避する以外のすべてのテストケースに十分なパフォーマンスを発揮します。

説明:

ò                              #Get the range [0...input]
  pÊ                           #Add an "l" to the end
    Ô                          #Reverse it
     pÊ                        #Add an "l" to the end
       qÊ                      #Add an "l" between each number and turn to a string
         f            ¹        #Find the substrings that match this regex:
          l²                   # The string "ll"
            i1                 # With this inserted between the "l"s:
              Uì               #  All the digits of the input
                 q"l?"         #  With optional spaces between each one
                       Ì       #Get the last match
                        èÊ     #Count the number of "l"s
                          É    #Subtract 1

私が思うに、これは 27の作品
シャギー


@Shaggyは両方とも入力に失敗します。21201これは、シーケンスの端が正しく整列することを強制しないためです(元のバージョンからは「コンマで終わる」行)。これまたはこの代替は機能します。
カミルドラカリ

ああ、わかった。その場合:26バイト
シャギー

@Shaggy Thatと、2100の後に区切り文字がないために失敗した28バイトのソリューション。ここでは、動作する固定の28バイトです。
カミルドラカリ

2

Haskell、65バイト

f i=[y|x<-[0..],y<-[1..length i],i==(show=<<[x+y-1,x+y-2..x])]!!0

入力は文字列です。

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

私の他の答えとは全く異なる。入力リストに等しいリストが見つかるまで、連続した降順のリストをすべて試行する単純な総当たり攻撃。

入力数を64ビット整数に制限する場合、最大の64ビット整数は19桁であり、より多くの要素を含むリストをテストする必要がないため、ループyすることで6バイト節約できます[1..19]

Haskell、59バイト

f i=[y|x<-[0..],y<-[1..19],i==(show=<<[x+y-1,x+y-2..x])]!!0

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



2

Dyalog APL、138バイト

ちょっとした口数ですが、大きな数字でも高速に動作します。オンライン試してみる場合は、dfnの前に接頭辞を⎕←付け、右側に数字のリストとして入力してください。

{⌈/⍵((≢⊂)×1∧.=2-/10⊥¨⊂)⍨⍤1⊢1,{⍬≡1↓⍵:↑⍬1⋄0=⊃⍵:0,∇1↓⍵⋄↑,0 1∘.,⊂⍤1∇1↓⍵}1↓⍵}

説明

まず、右側の内側のdfnは、数字のリストを(で)分割する可能な方法のリストを再帰的に構築します。たとえば1 0 1 0 ⊂ 2 0 1 9、ネストされたベクターを返します(2 0)(1 9)

{
   ⍬≡1↓⍵: ↑⍬1       ⍝ Edge case: If ⍵ is singleton list, return the column matrix (0 1)
   0=⊃⍵: 0,∇1↓⍵     ⍝ If head of ⍵ is 0, return 0 catenated to this dfn called on tail ⍵
   ↑,0 1∘.,⊂⍤1∇1↓⍵  ⍝ Finds 1 cat recursive call on tail ⍵ and 0 cat recursive call on ⍵. 
}                    ⍝ Makes a matrix with a row for each possibility.

私たちは、使用1,開始時に1の列を追加し、⍵のための有効なパーティションの行列で終わるために。

これで、左側の関数は括弧で囲まれています。トレインへの左引数がパーティション行列の行であり、右引数がユーザー入力であるため。列車はフォークの山で、一番左に尖ったものがあります。

((≢⊂)×1∧.=2-/10⊥¨⊂)⍨     ⍝ ⍨ swaps left and right arguments of the train.
                  ⊂       ⍝ Partition ⍵ according to ⍺. 
             10⊥¨         ⍝ Decode each partition (turns strings of digits into numbers)
          2-/             ⍝ Difference between adjacent cells
      1∧.=                ⍝ All equal 1?
   ⊂                      ⍝ Partition ⍵ according to ⍺ again
  ≢                       ⍝ Number of cells (ie number of partitions)
     ×                    ⍝ Multiply.

パーティションが降順のシーケンスを作成する場合、トレインはシーケンスの長さを返します。それ以外の場合はゼロ。

⍤1⊢ユーザー入力とパーティションマトリックスの各行の間に関数列を適用し、マトリックスの各行の値を返します。のオペランドとの派生関数の引数を明確にするために必要です

⌈/ 最大値を見つけます。

より短いアルゴリズムを見つけることはできましたが、私が考えることができる最も直接的で宣言的なこの方法を試してみたかったです。


PPCGへようこそ!これは印象的な最初の投稿です!
Rɪᴋᴇʀ

1

TSQL、169バイト

注:これは、入力を整数に変換できる場合にのみ実行できます。

ループに使用される再帰SQL。

ゴルフ:

DECLARE @ varchar(max) = '1211109876';

WITH C as(SELECT left(@,row_number()over(order by 1/0))+0t,@+null z,0i
FROM spt_values UNION ALL
SELECT t-1,concat(z,t),i+1FROM C WHERE i<9)SELECT
max(i)FROM C WHERE z=@

ゴルフをしていない:

DECLARE @ varchar(max) = '1211109876';

WITH C as
(
  SELECT
    left(@,row_number()over(order by 1/0))+0t,
    @+null z,
    0i
  FROM
    spt_values
  UNION ALL
  SELECT
    t-1,
    concat(z,t),
    i+1
  FROM C
  WHERE i<9
)
SELECT max(i)
FROM C
WHERE z=@

やってみよう


0

R、101バイト

function(a,N=nchar(a)){for(x in 1:N)F=max(F,which(Reduce(paste0,seq(substr(a,1,x),,-1,N),a=T)==a));F}

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

Rの回答がなくても2週間以上が経過したため、自分で投稿することにしました:)

「制限された」ブルートフォースアプローチを使用するため、コードは非常に高速です。

展開されたコードと説明:

function(a){                  # get string a as input (e.g. "2019")

  N = nchar(a)                # set N = length of a (e.g. 4)
  Y = 0                       # initialize Y = 0 (in the actual code we abuse F)

  for(x in 1:N){              # for x in 1 ... N    

    S = substr(a,1,x)         # get the first x characters of a (e.g. "20" for x=2)

    Q = seq(S,,-1,N)          # create a decreasing sequence (step = -1) 
                              # of length N starting from S converted into integer
                              # (e.g. Q = c(20,19,18,17) for x=2)

    R = Reduce(paste0,Q,a=T)  # concatenate all the increasing sub-sequences of Q
                              # (e.g. R = c("20","2019","201918","20191817") for x=2)

    I = which(R == a)         # Get the index where R == a, if none return empty vector
                              # (e.g. I = 2 for x=2)

    Y = max(Y,I)              # store the maximum index found into Y
  }
  return(Y)                   # return Y
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.