Quantos números decrescentes consecutivos no meu número?


18

Chegou 2019 e provavelmente todos perceberam a peculiaridade desse número: na verdade, é composto por dois subnúmeros (20 e 19), representando uma sequência de números decrescentes consecutivos.

Desafio

Dado um número x, retorne o comprimento da sequência máxima de números consecutivos e decrescentes que podem ser formados assumindo sub-números de x.

Notas :

  • sub-números não podem conter zeros à esquerda (por exemplo, 1009não podem ser divididos em 10, 09)
  • consecutivo e decrescente significa que um número na sequência deve ser igual ao número anterior -1, ou (por exemplo, não pode ser dividido em porque e não é consecutivo )nEu+1=nEu-1525,2522 ≠ 5 - 1
  • a sequência deve ser obtida usando o número completo, por exemplo, 7321você não pode descartar 7e obter a seqüência 3, 2,1
  • apenas uma sequência pode ser obtido a partir do número, por exemplo, 3211098não pode ser dividida em duas sequências 3, 2, 1e 10, 9,8

Entrada

  • Um número inteiro ( >= 0): pode ser um número, uma string ou uma lista de dígitos

Resultado

  • Um único número inteiro, dado o número máximo de sub-números decrescentes (observe que o limite inferior desse número é 1, ou seja, um número é composto por ele mesmo em uma sequência descendente de comprimento um)

Exemplos :

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

Regras gerais:

  • Isso é , então a resposta mais curta em bytes vence.
    Não permita que idiomas com código de golfe o desencorajem a postar respostas com idiomas que não sejam codegolf. Tente encontrar uma resposta o mais curta possível para 'qualquer' linguagem de programação.
  • As regras padrão se aplicam à sua resposta com as regras de E / S padrão , para que você possa usar STDIN / STDOUT, funções / método com os parâmetros adequados e programas completos do tipo retorno. Sua chamada.
  • As brechas padrão são proibidas.
  • Se possível, adicione um link com um teste para o seu código (ou seja, TIO ).
  • Além disso, é altamente recomendável adicionar uma explicação para sua resposta.


1
O caso de teste está 210 -> 2,1,0errado (o mesmo com 0 -> 0)? As tarefas dizem que " sub-números não podem conter zeros à esquerda "; zero é um caso especial?
04/01

2
@BMO: bem, aqui o tópico é meio filosófico ...: D para mim, 0 é um número sem zero (inútil), levando à zero, então sim zero é um caso especial
digEmAll

2
você chamaria esses ... números condescendentes ? xD desculpe que não era nem engraçado
HyperNeutrino 06/01

Desculpe, excluí meu comentário no qual perguntei 212019. Parece que não li todas as regras.
cyclaminist

Respostas:


6

Geléia ,  15  9 bytes

Bugfix graças a Dennis

ŻṚẆDfŒṖẈṀ

Experimente online! (321levaatémeio minuto, já que o código é pelo menos)O(N2)

Quão?

ŻṚẆ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 bytes

Uma porta da resposta Python do ArBo é significativamente menor. No entanto, ele falha em alguns casos de teste devido a muita recursão.

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

Experimente online!


JavaScript (ES6), 66 bytes

Recebe a entrada como uma sequência.

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

Experimente online!

Comentado

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 bytes implementando as alterações no meu código
ArBo 15/01

5

Perl 6 , 43 41 40 bytes

-1 byte graças a nwellnhof

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

Experimente online!

Solução baseada em Regex. Estou tentando encontrar uma maneira melhor de corresponder a partir de uma lista descendente, mas o Perl 6 não faz bem as partições

Explicação:

{                                        }  # 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 3 , 232 228 187 181 180 150 149 bytes

-1 graças a @ 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])])

Experimente online!

Código inicial não destruído:

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 forpode ser s+1for, (t(n[:j])-t(n[j:j+i])==1)*t(n[0])pode ser t(n[:j])-t(n[j:j+i])==1>=t(n[0]).
Jonathan Frech

Parece que a segunda sugestão não funciona, mas não traria nada, porque você precisa de espaço para separar a expressão if.
Nishioka

Verdadeiro ... alternativa 149 .
Jonathan Frech

4

Python 2 , 78 74 73 bytes

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)

Experimente online!

-1 byte graças a Arnauld

Recebe a entrada como uma sequência. O programa corre rapidamente para o limite de profundidade de recursão do Python, mas pode concluir a maioria dos casos de teste.

Como funciona

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
Boa resposta! a+c+1pode ser reduzido para a-~c.
Arnauld

3

05AB1E , 10 bytes

ÝRŒʒJQ}€gà

Extremamente lento, o TIO abaixo funciona apenas para casos de teste abaixo de 750.

Experimente online .

Explicação:

Ý           # 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
Código de golfe - onde a adição de 1 byte para o seu programa de ir de n!que n lg nsimplesmente não vale a pena.
corsiKa 5/01

3

Pitão, 16 bytes

lef!.EhM.+vMT./z

Experimente online aqui ou verifique todos os casos de teste de uma vez aqui .

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

Gelatina , 11 bytes

ŒṖḌ’Dɗ\ƑƇẈṀ

O(n0,3)

Experimente online!

Como funciona

ŒṖḌ’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

Carvão , 26 bytes

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

Experimente online! Link é a versão detalhada do código. Explicação:

F⊕Lθ

Loop ide 0 ao comprimento da entrada.

F⊕Lθ

Loop kde 0 ao comprimento da entrada.

⊞υ⭆κ⁻I…θ⊕ιλ

Calcule os primeiros knúmeros na sequência descendente, começando pelo número fornecido pelos primeiros idígitos da entrada, concatená-los e acumule cada sequência resultante na lista vazia predefinida.

I﹪⌕υθ⊕Lθ

Encontre a posição da primeira cópia correspondente da entrada e reduza o módulo 1 mais do que o comprimento da entrada.

Exemplo: Para uma entrada das 2019seguintes seqüências de caracteres são geradas:

 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 é então encontrado no índice 12, que é o módulo 5 reduzido para dar 2, a resposta desejada.


3

Haskell, 87 bytes

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

Entrada é uma lista de dígitos.

Experimente online!

A função #cria uma lista de todas as divisões possíveis, observando as duas

  • anexando o número atual aa todas as divisões retornadas por uma chamada recursiva com o restante da entrada ( x<-b#c), mas apenas se o próximo número não for zero ( b>0) (ou é o último número na entrada ( c==[])) e afor maior que o primeiro número da respectiva divisão anterior x( a==x!!0+1).

e

  • anexando o próximo dígito bda lista de entrada ao número atual ae continuando com o restante da entrada ( (10*a+b)#c)

O caso base é quando a lista de entrada está vazia (ou seja, não corresponde ao padrão (b:c)). A recursão começa com o número atual asendo 0( (0#)), que nunca atinge a primeira ramificação ( aprecedendo todas as divisões anteriores), porque nunca será maior que qualquer número de divisões.

Pegue o comprimento de cada divisão e encontre o máximo ( maximum.map length).

Uma variante com também 87 bytes:

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

que basicamente funciona da mesma maneira, mas, em vez de manter toda a divisão em uma lista, ele mantém apenas um par (r,x)do comprimento da divisão re o primeiro número na divisão x.


3

Python 3 , 302 282 271 bytes

-10 bytes graças à dica de @ElPedro.

Recebe a entrada como uma sequência. Basicamente, é preciso aumentar fatias maiores do número da esquerda e ver se, para essa fatia do número, uma sequência pode ser formada usando todos os números.

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

Experimente online!


1
Como você está usando rangetrês vezes, pode definir R=rangefora de ambas as funções e usar em R(whatever)vez de range(whatever)para salvar 4 bytes.
ElPedro 5/01

3

Japonês , 27 bytes

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

Experimente online! ou Verifique a maioria dos casos de teste

Isso não tem boa pontuação, mas usa um método único e pode haver espaço para jogar muito mais. Ele também funciona bem o suficiente para que todos os casos de teste, exceto 201200199198evitar o tempo limite.

Explicação:

ò                              #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

Eu acho que isso funciona para 27.
Shaggy


@ Shaggy ambos falham na entrada 21201porque não impõem que o final da sequência esteja alinhado corretamente (da minha versão original, a linha "termina com uma vírgula"). Esta ou esta alternativa funciona.
Kamil Drakari 5/01

Ah ok. Nesse caso: 26 bytes
Shaggy

@ Shaggy Isso e as soluções de 28 bytes que eu tinha falhado 210porque não há um delimitador após 0. Aqui está um byte fixo de 28 bytes que funciona.
Kamil Drakari

2

Haskell, 65 bytes

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

Entrada é uma sequência.

Experimente online!

Completamente diferente da minha outra resposta . Uma força bruta simples que tenta todas as listas de números decrescentes consecutivos até encontrar uma que seja igual à lista de entrada.

Se limitarmos o número de entrada de inteiros de 64 bits, podemos salvar 6 bytes por looping yatravés [1..19], porque o maior número inteiro de 64-bit tem 19 dígitos e não há necessidade de listas de teste com mais elementos.

Haskell, 59 bytes

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

Experimente online!



2

Dyalog APL, 138 bytes

Um pouco, mas funciona rápido para grandes números também. Se você tentar online , prefixe o dfn por ⎕←e forneça entrada à direita como uma lista de dígitos.

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

Explicação

Primeiro, o dfn interno à direita, que recursivamente constrói uma lista de possíveis maneiras de particionar (com ) a lista de dígitos. Por exemplo, 1 0 1 0 ⊂ 2 0 1 9retorna o vetor aninhado (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.

Utilizamos 1,para adicionar uma coluna de 1s no início e terminar com uma matriz de partições válidas para ⍵.

Agora a função trem à esquerda em parênteses. Devido ao argumento esquerdo do trem, está a linha da matriz de partições e o argumento direito é a entrada do usuário. O trem é uma pilha de garfos com o topo da ponta esquerda.

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

Se a partição criar uma sequência de números decrescentes, o trem retornará o comprimento da sequência. Caso contrário, zero.

⍤1⊢aplica o trem de funções entre a entrada do usuário e cada linha da matriz de partições, retornando um valor para cada linha da matriz. é necessário desambiguar entre operando to e argumento para a função derivada de .

⌈/ encontra o máximo.

Poderia encontrar um algoritmo mais curto, mas eu queria tentar dessa maneira, que é a mais direta e declarativa que eu poderia pensar.


Bem-vindo ao PPCG! Este é um primeiro post impressionante!
Rɪᴋᴇʀ

1

TSQL, 169 bytes

Nota: isso só pode ser executado quando a entrada pode ser convertida em um número inteiro.

SQL recursivo usado para loop.

Golfe:

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

Ungolfed:

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

Experimente


0

R , 101 bytes

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}

Experimente online!

Mais de duas semanas se passaram sem nenhuma resposta R, então decidi postar minhas próprias :)

O código é bastante rápido, pois utiliza uma abordagem de força bruta "limitada"

Código desenrolado e explicação:

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
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.