Berapa banyak angka yang turun berturut-turut di nomor saya?

18

2019 telah datang dan mungkin semua orang telah memperhatikan keanehan dari angka ini: itu sebenarnya disusun oleh dua sub-angka (20 dan 19) yang mewakili urutan angka-angka menurun berurutan.

Tantangan

Diberi nomor x, kembalikan panjang urutan maksimum berturut-turut, angka menurun yang dapat dibentuk dengan mengambil sub-angka x.

Catatan:

  • sub-angka tidak boleh mengandung angka nol di depan (mis. 1009tidak bisa dibagi menjadi 10, 09)
  • berturut-turut dan menurun berarti bahwa angka dalam urutan harus sama dengan angka sebelumnya -1, atau (mis. tidak dapat dibagi menjadi karena dan tidak berturut-turut, )ni+1=ni1525,2522 ≠ 5 - 1
  • urutan harus diperoleh dengan menggunakan jumlah penuh, misalnya dalam 7321Anda tidak bisa membuang 7dan mendapatkan urutan 3, 2,1
  • hanya satu urutan dapat diperoleh dari angka, misalnya 3211098tidak dapat dibagi menjadi dua urutan 3, 2, 1dan 10, 9,8

Memasukkan

  • Angka integer ( >= 0): bisa berupa angka, atau string, atau daftar digit

Keluaran

  • Sebuah bilangan bulat tunggal yang diberikan jumlah maksimum dari pengurangan sub-angka (perhatikan bahwa batas bawah dari angka ini adalah 1, yaitu angka yang disusun dengan sendirinya dalam urutan panjang satu yang menurun)

Contoh:

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

Aturan umum:

  • Ini adalah , jadi jawaban tersingkat dalam byte menang.
    Jangan biarkan bahasa kode-golf mencegah Anda memposting jawaban dengan bahasa non-codegolf. Cobalah untuk memberikan jawaban sesingkat mungkin untuk bahasa pemrograman 'apa saja'.
  • Aturan standar berlaku untuk jawaban Anda dengan aturan I / O default , sehingga Anda diizinkan untuk menggunakan STDIN / STDOUT, fungsi / metode dengan parameter yang tepat dan tipe pengembalian, program penuh. Panggilanmu.
  • Celah default tidak diperbolehkan.
  • Jika memungkinkan, silakan tambahkan tautan dengan tes untuk kode Anda (yaitu TIO ).
  • Juga, menambahkan penjelasan untuk jawaban Anda sangat dianjurkan.
menggali semua
sumber
1
Bermigrasi dari kotak pasir: codegolf.meta.stackexchange.com/questions/2140/…
digEmAll
1
Apakah test case 210 -> 2,1,0salah (sama dengan 0 -> 0)? Tugas mengatakan " sub-angka tidak boleh mengandung angka nol di depan ", apakah nol kasus khusus?
ბიმო
2
@BMO: yah, di sini topiknya agak filosofis ...: D bagi saya, 0 adalah angka tanpa nol (tidak berguna) yang mengarah nol, jadi ya nol adalah kasus khusus
digEmAll
2
Anda akan memanggil ini ... nomor merendahkan ? xD maaf itu seperti tidak lucu
HyperNeutrino
Maaf, hapus komentar saya di mana saya bertanya 212019. Sepertinya saya tidak membaca semua aturan.
pengendara sepeda

Jawaban:

6

Jelly ,  15  9 byte

Perbaikan bug berkat Dennis

ŻṚẆDfŒṖẈṀ

Cobalah online! (bahkan321membutuhkan setengah menit karena kode setidaknya)O(N2)

Bagaimana?

ŻṚẆ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
Jonathan Allan
sumber
6

JavaScript (ES6), 56 byte

Port jawaban Python ArBo secara signifikan lebih pendek. Namun, itu gagal pada beberapa kasus uji karena terlalu banyak rekursi.

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

Cobalah online!


JavaScript (ES6), 66 byte

Mengambil input sebagai string.

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++])

Cobalah online!

Berkomentar

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
Arnauld
sumber
54 byte dengan menerapkan perubahan pada kode saya
ArBo
5

Perl 6 , 43 41 40 byte

-1 byte terima kasih kepada nwellnhof

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

Cobalah online!

Solusi berbasis Regex. Saya mencoba menemukan cara yang lebih baik untuk mencocokkan dari daftar yang menurun, tetapi Perl 6 tidak melakukan partisi dengan baik

Penjelasan:

{                                        }  # 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
Jo King
sumber
40 byte
nwellnhof
4

Python 3 , 232 228 187 181 180 150 149 byte

-1 terima kasih kepada @ 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])])

Cobalah online!

Kode ungolfed awal:

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
Nishioka
sumber
1
s+1 forbisa s+1for, (t(n[:j])-t(n[j:j+i])==1)*t(n[0])mungkin bisa t(n[:j])-t(n[j:j+i])==1>=t(n[0]).
Jonathan Frech
Tampaknya saran kedua tidak berfungsi meskipun tidak akan membawa apa-apa karena Anda memerlukan ruang untuk memisahkan ekspresi if.
Nishioka
Benar ... alternatif 149 .
Jonathan Frech
4

Python 2 , 78 74 73 byte

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)

Cobalah online!

-1 byte terima kasih kepada Arnauld

Mengambil input sebagai string. Program agak cepat berjalan ke batas kedalaman rekursi Python, tetapi dapat menyelesaikan sebagian besar kasus uji.

Bagaimana itu bekerja

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
ArBo
sumber
1
Jawaban bagus! a+c+1dapat disingkat menjadi a-~c.
Arnauld
3

05AB1E , 10 byte

ÝRŒʒJQ}€gà

Sangat lambat, jadi TIO di bawah ini hanya berfungsi untuk test case di bawah 750 ..

Cobalah online .

Penjelasan:

Ý           # 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
Kevin Cruijssen
sumber
2
Kode golf - mana menambahkan 1 byte untuk program Anda untuk pergi dari n!ke n lg nhanya tidak layak.
corsiKa
3

Pyth, 16 byte

lef!.EhM.+vMT./z

Coba online di sini , atau verifikasi semua uji sekaligus di sini .

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
Sok
sumber
3

Jelly , 11 byte

ŒṖḌ’Dɗ\ƑƇẈṀ

O(n0.3)

Cobalah online!

Bagaimana itu bekerja

ŒṖḌ’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.
Dennis
sumber
3

Arang , 26 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

F⊕Lθ

Loop idari 0 hingga panjang input.

F⊕Lθ

Loop kdari 0 hingga panjang input.

⊞υ⭆κ⁻I…θ⊕ιλ

Hitung kangka pertama dalam urutan menurun mulai dari angka yang diberikan oleh idigit pertama input, gabungkan mereka, dan kumpulkan setiap string yang dihasilkan dalam daftar kosong yang telah ditentukan.

I﹪⌕υθ⊕Lθ

Temukan posisi salinan yang cocok pertama dari input dan kurangi itu modulo 1 lebih dari panjang input.

Contoh: Untuk input dari 2019string berikut dihasilkan:

 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 kemudian ditemukan pada indeks 12, yang direduksi modulo 5 untuk memberikan 2, jawaban yang diinginkan.

Neil
sumber
3

Haskell, 87 byte

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

Input adalah daftar digit.

Cobalah online!

Function #membangun daftar semua kemungkinan split dengan melihat keduanya

  • mengawali nomor saat ini ake semua pemisahan yang dikembalikan oleh panggilan rekursif dengan sisa input ( x<-b#c), tetapi hanya jika nomor berikutnya bukan nol ( b>0) (atau itu adalah nomor terakhir dalam input ( c==[])) dan amerupakan yang lebih besar dari yang pertama jumlah masing-masing split sebelumnya x( a==x!!0+1).

dan

  • menambahkan digit berikutnya bdari daftar input ke nomor saat ini adan melanjutkan dengan sisa input ( (10*a+b)#c)

Kasing dasar adalah ketika daftar input kosong (mis. Tidak cocok dengan pola (b:c)). Rekursi dimulai dengan angka saat ini amenjadi 0( (0#)), yang tidak pernah mengenai cabang pertama (prabayar ake semua pemisahan sebelumnya), karena angka itu tidak akan pernah lebih besar dari jumlah perpecahan mana pun.

Ambil panjang setiap perpecahan dan temukan maksimum ( maximum.map length).

Varian dengan juga 87 byte:

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

yang pada dasarnya bekerja dengan cara yang sama, tetapi alih-alih menjaga seluruh perpecahan dalam daftar, itu hanya membuat sepasang (r,x)panjang perpecahan rdan angka pertama dalam perpecahan x.

nimi
sumber
3

Python 3 , 302 282 271 byte

-10 byte berkat tipnya oleh @ElPedro.

Mengambil input sebagai string. Pada dasarnya, dibutuhkan irisan angka yang lebih besar dari kiri, dan melihat apakah untuk irisan nomor itu urutan dapat dibentuk menggunakan semua angka.

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

Cobalah online!

Neil A.
sumber
1
Karena Anda menggunakan range3 kali, Anda dapat menentukan di R=rangeluar kedua fungsi dan kemudian menggunakan R(whatever)alih-alih range(whatever)menyimpan 4 byte.
ElPedro
3

Japt , 27 byte

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

Cobalah online! atau Periksa sebagian besar kasus uji

Ini tidak menghasilkan skor yang baik, tetapi menggunakan metode yang unik dan mungkin ada ruang untuk bermain golf lebih banyak. Ini juga berkinerja cukup baik sehingga semua test case selain 201200199198menghindari penghentian waktu.

Penjelasan:

ò                              #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
Kamil Drakari
sumber
Saya pikir ini bekerja untuk 27.
Shaggy
25 byte
Shaggy
@Shaggy keduanya gagal pada input 21201karena mereka tidak memaksakan bahwa urutan akhir menyelaraskan dengan benar (dari versi asli saya, baris "berakhir dengan koma"). Ini atau ini karya alternatif.
Kamil Drakari
Ah, baiklah. Dalam hal ini: 26 byte
Shaggy
@ Shaggy Itu dan solusi 28 byte saya gagal 210karena tidak ada pembatas setelah 0. Berikut ini adalah byte tetap 28 yang berfungsi.
Kamil Drakari
2

Haskell, 65 byte

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

Input adalah sebuah string.

Cobalah online!

Sangat berbeda dengan jawaban saya yang lain . Suatu kekuatan kasar sederhana yang mencoba semua daftar angka-angka menurun berurutan sampai menemukan satu yang sama dengan daftar input.

Jika kita membatasi jumlah input ke 64-bit bilangan bulat, kita dapat menghemat 6 byte dengan perulangan ymelalui [1..19], karena terbesar 64-bit integer memiliki 19 digit dan tidak perlu untuk daftar uji dengan unsur-unsur yang lebih.

Haskell, 59 byte

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

Cobalah online!

nimi
sumber
2

Python 2 , 95 byte

lambda n:max(j-i for j in range(n+1)for i in range(-1,j)if''.join(map(str,range(j,i,-1)))==`n`)

Solusi lain yang lambat dan kasar.

Cobalah online!

Dennis
sumber
2

Dyalog APL, 138 byte

Sedikit suap, tetapi bekerja cepat untuk jumlah besar juga Jika Anda mencobanya secara online , awali dfn dengan ⎕←dan berikan input di sebelah kanan sebagai daftar angka.

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

Penjelasan

Pertama, dfn bagian dalam di sebelah kanan yang secara rekonstruk menyusun daftar cara yang mungkin untuk mem-partisi (dengan ) daftar digit. Misalnya 1 0 1 0 ⊂ 2 0 1 9mengembalikan vektor bersarang (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.

Kami menggunakan 1,untuk menambahkan kolom 1s di awal dan berakhir dengan matriks partisi yang valid untuk ⍵.

Sekarang fungsi kereta di sebelah kiri di parens. Karena argumen kiri ke kereta adalah deretan matriks partisi dan argumen yang tepat adalah input pengguna. Kereta adalah tumpukan garpu dengan puncak sebagai tine paling kiri.

((≢⊂)×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.

Jika partisi menciptakan urutan angka menurun, kereta mengembalikan panjang urutan. Kalau tidak nol.

⍤1⊢menerapkan fungsi kereta antara input pengguna dan setiap baris dari matriks partisi, mengembalikan nilai untuk setiap baris matriks. Diperlukan untuk mendua antara operan dan argumen ke fungsi turunan dari .

⌈/ menemukan maksimum.

Bisa menemukan algoritma yang lebih pendek tetapi saya ingin mencoba cara ini yang paling langsung dan deklaratif yang bisa saya pikirkan.

akhmorn
sumber
Selamat datang di PPCG! Ini adalah pos pertama yang mengesankan!
Rɪᴋᴇʀ
1

TSQL, 169 byte

Catatan: ini hanya dapat dieksekusi ketika input dapat dikonversi ke integer.

Sql rekursif digunakan untuk perulangan.

Golf:

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

Tidak Disatukan:

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

Cobalah

t-clausen.dk
sumber
0

R , 101 byte

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}

Cobalah online!

Lebih dari 2 minggu telah berlalu tanpa jawaban R, jadi saya memutuskan untuk memposting sendiri :)

Kode ini cukup cepat karena menggunakan pendekatan brute force "terbatas"

Kode dan penjelasan yang belum dibuka:

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
}
menggali semua
sumber