Combien de nombres décroissants consécutifs dans mon numéro?

18

2019 est arrivé et tout le monde a probablement remarqué la particularité de ce nombre: il est en fait composé de deux sous-nombres (20 et 19) représentant une séquence de nombres décroissants consécutifs.

Défi

Étant donné un nombre x, renvoyez la longueur de la séquence maximale de nombres descendants consécutifs qui peuvent être formés en prenant des sous-nombres de x.

Remarques :

  • les sous-numéros ne peuvent pas contenir de zéros de tête (par exemple, 1009ne peuvent pas être divisés en 10, 09)
  • consécutif et décroissant signifie qu'un nombre dans la séquence doit être égal au nombre précédent -1, ou (par exemple ne peut pas être divisé en car et ne sont pas consécutifs, )ni+1=nje1525,2522 ≠ 5 - 1
  • la séquence doit être obtenue en utilisant le numéro complet, par exemple dans 7321vous ne pouvez pas jeter 7et obtenir la séquence 3, 2,1
  • une seule séquence peut être obtenue à partir du nombre, par exemple , 3211098ne peut pas être divisé en deux séquences 3, 2, 1et 10, 9,8

Contribution

  • Un nombre entier ( >= 0): peut être un nombre, une chaîne ou une liste de chiffres

Production

  • Un entier unique étant donné le nombre maximum de sous-nombres décroissants (notez que la borne inférieure de ce nombre est 1, c'est-à-dire qu'un nombre est composé par lui-même dans une séquence décroissante de longueur un)

Exemples :

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

Règles générales:

  • C'est le , donc la réponse la plus courte en octets l'emporte.
    Ne laissez pas les langues de golf de code vous décourager de publier des réponses avec des langues autres que le golf de code. Essayez de trouver une réponse aussi courte que possible pour «n'importe quel» langage de programmation.
  • Des règles standard s'appliquent à votre réponse avec des règles d'E / S par défaut , vous êtes donc autorisé à utiliser STDIN / STDOUT, des fonctions / méthodes avec les paramètres appropriés et des programmes complets de type retour. Ton appel.
  • Les failles par défaut sont interdites.
  • Si possible, veuillez ajouter un lien avec un test pour votre code (par exemple TIO ).
  • De plus, l'ajout d'une explication à votre réponse est fortement recommandé.
digEmAll
la source
1
Migré à partir du bac à sable: codegolf.meta.stackexchange.com/questions/2140/…
digEmAll
1
Le scénario de test est-il 210 -> 2,1,0incorrect (identique à 0 -> 0)? La tâche indique que "les sous-numéros ne peuvent pas contenir de zéros de tête ", le zéro est-il un cas particulier?
ბიმო
2
@BMO: eh bien, ici le sujet est un peu phylosofical ...: D pour moi, 0 est un nombre sans zéro (inutile) menant à zéro, donc oui zéro est un cas spécial
digEmAll
2
appeleriez-vous ces ... numéros condescendants ? xD désolé, ce n'était même pas drôle
HyperNeutrino
Désolé, supprimé mon commentaire dans lequel j'ai posé des questions 212019. Il semble que je n'ai pas lu toutes les règles.
cyclaminist

Réponses:

6

Gelée ,  15  9 octets

Correction de bug grâce à Dennis

ŻṚẆDfŒṖẈṀ

Essayez-le en ligne! (321prendmêmeune demi-minute car le code est au moinsO(N2) )

Comment?

ŻṚẆ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
la source
6

JavaScript (ES6), 56 octets

Un port de la réponse Python d' ArBo est beaucoup plus court. Cependant, il échoue sur certains cas de test en raison de trop de récursivité.

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

Essayez-le en ligne!


JavaScript (ES6), 66 octets

Prend l'entrée sous forme de chaîne.

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

Essayez-le en ligne!

Commenté

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
la source
54 octets en implémentant les modifications de mon code
ArBo
5

Perl 6 , 43 41 40 octets

-1 octet grâce à nwellnhof

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

Essayez-le en ligne!

Solution basée sur Regex. J'essaie de trouver une meilleure façon de faire correspondre à partir d'une liste décroissante, mais Perl 6 ne fait pas bien les partitions

Explication:

{                                        }  # 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
la source
40 octets
nwellnhof
4

Python 3 , 232 228 187 181 180 150 149 octets

-1 merci à @ 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])])

Essayez-le en ligne!

Code initial non golfé:

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
la source
1
s+1 forpeut être s+1for, (t(n[:j])-t(n[j:j+i])==1)*t(n[0])peut éventuellement être t(n[:j])-t(n[j:j+i])==1>=t(n[0]).
Jonathan Frech
Il semble que la deuxième suggestion ne fonctionne pas bien qu'elle n'apporterait rien car alors vous avez besoin d'espace pour séparer l'expression de if.
Nishioka
Vrai ... alternative 149 .
Jonathan Frech
4

Python 2 , 78 74 73 octets

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)

Essayez-le en ligne!

-1 octet grâce à Arnauld

Prend l'entrée sous forme de chaîne. Le programme fonctionne assez rapidement dans la limite de profondeur de récursivité de Python, mais il peut terminer la plupart des cas de test.

Comment ça fonctionne

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
la source
1
Bonne réponse! a+c+1peut être raccourci a-~c.
Arnauld
3

05AB1E , 10 octets

ÝRŒʒJQ}€gà

Extrêmement lent, le TIO ci-dessous ne fonctionne que pour les cas de test inférieurs à 750 ..

Essayez-le en ligne .

Explication:

Ý           # 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
la source
2
Code de golf - où ajouter 1 octet à votre programme pour aller de n!à n lg nest tout simplement pas la peine.
corsiKa
3

Pyth, 16 octets

lef!.EhM.+vMT./z

Essayez-le en ligne ici ou vérifiez tous les cas de test en même temps ici .

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
la source
3

Gelée , 11 octets

ŒṖḌ’Dɗ\ƑƇẈṀ

Octet par octet, aucune correspondance avec l'autre solution Jelly, mais celle-ci devrait être à peu près O(n0,3).

Essayez-le en ligne!

Comment ça fonctionne

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

Fusain , 26 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

F⊕Lθ

Boucle ide 0 à la longueur de l'entrée.

F⊕Lθ

Boucle kde 0 à la longueur de l'entrée.

⊞υ⭆κ⁻I…θ⊕ιλ

Calculez les premiers knombres dans la séquence décroissante à partir du nombre donné par les premiers ichiffres de l'entrée, concaténez-les et accumulez chaque chaîne résultante dans la liste vide prédéfinie.

I﹪⌕υθ⊕Lθ

Recherchez la position de la première copie correspondante de l'entrée et réduisez-la de 1 module de plus que la longueur de l'entrée.

Exemple: Pour une entrée des 2019chaînes suivantes sont générées:

 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 se trouve alors à l'indice 12, qui est réduit modulo 5 pour donner 2, la réponse souhaitée.

Neil
la source
3

Haskell, 87 octets

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

L'entrée est une liste de chiffres.

Essayez-le en ligne!

La fonction #crée une liste de toutes les divisions possibles en examinant les deux

  • ajouter le numéro actuel aà toutes les divisions renvoyées par un appel récursif avec le reste de l'entrée ( x<-b#c), mais uniquement si le numéro suivant n'est pas zéro ( b>0) (ou s'il s'agit du dernier numéro de l'entrée ( c==[])) et asupérieur de un au premier numéro de la division précédente respective x( a==x!!0+1).

et

  • ajouter le chiffre suivant bde la liste d'entrée au numéro actuel aet continuer avec le reste de l'entrée ( (10*a+b)#c)

Le cas de base est lorsque la liste d'entrée est vide (c'est-à-dire qu'elle ne correspond pas au modèle (b:c)). La récursion commence avec le nombre actuel aétant 0( (0#)), qui ne frappe jamais la première branche (en ajoutant aà toutes les divisions précédentes), car il ne sera jamais supérieur à n'importe quel nombre de divisions.

Prenez la longueur de chaque division et trouvez le maximum ( maximum.map length).

Une variante avec également 87 octets:

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

ce qui fonctionne essentiellement de la même manière, mais au lieu de conserver la totalité du fractionnement dans une liste, il ne conserve qu'une paire (r,x)de la longueur du fractionnement ret le premier nombre de la division x.

nimi
la source
3

Python 3 , 302 282 271 octets

-10 octets grâce au tip de @ElPedro.

Prend l'entrée sous forme de chaîne. Fondamentalement, cela prend de plus en plus de tranches plus grandes du nombre à partir de la gauche, et voit si pour cette tranche du nombre une séquence peut être formée en utilisant tous les nombres.

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

Essayez-le en ligne!

Neil A.
la source
1
Étant donné que vous utilisez range3 fois, vous pouvez définir en R=rangedehors des deux fonctions, puis utiliser R(whatever)au lieu de range(whatever)pour enregistrer 4 octets.
ElPedro
3

Japt , 27 octets

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

Essayez-le en ligne! ou Vérifiez la plupart des cas de test

Cela ne marque pas bien, mais il utilise une méthode unique et il pourrait y avoir beaucoup plus de terrain de golf. Il fonctionne également suffisamment bien pour que tous les cas de test autres que201200199198 temporisation.

Explication:

ò                              #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
la source
Je pense que cela fonctionne pour 27.
Shaggy
25 octets
Shaggy
@Shaggy ces deux échouent en entrée 21201car ils n'imposent pas que la fin de la séquence s'aligne correctement (à partir de ma version originale, la ligne "se termine par une virgule"). Ceci ou cette alternative fonctionne.
Kamil Drakari
Ah ok. Dans ce cas: 26 octets
Shaggy
@Shaggy That et les solutions de 28 octets sur lesquelles j'ai échoué 210car il n'y a pas de délimiteur après 0. Voici un 28 octet fixe qui fonctionne.
Kamil Drakari
2

Haskell, 65 octets

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

L'entrée est une chaîne.

Essayez-le en ligne!

Complètement différent de mon autre réponse . Une force brute simple qui essaie toutes les listes de nombres décroissants consécutifs jusqu'à ce qu'elle en trouve un qui soit égal à la liste d'entrée.

Si nous limitons le nombre d'entrée entiers 64 bits, nous pouvons économiser 6 octets en boucle ypar[1..19] , parce que le plus grand entier de 64 bits a 19 chiffres et il n'y a pas besoin de listes d'essai avec plus d' éléments.

Haskell, 59 octets

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

Essayez-le en ligne!

nimi
la source
2

Python 2 , 95 octets

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

Une autre solution lente et brutale.

Essayez-le en ligne!

Dennis
la source
2

Dyalog APL, 138 octets

Une bouchée, mais ça marche vite aussi pour les grands nombres. Si vous l' essayez en ligne , préfixez le dfn par⎕← et fournissez une entrée à droite sous forme de liste de chiffres.

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

Explication

Tout d'abord, le dfn interne à droite qui construit récursivement une liste de façons possibles de partitionner (avec ) la liste des chiffres. Par exemple, 1 0 1 0 ⊂ 2 0 1 9renvoie le vecteur imbriqué (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.

Nous utilisons 1, pour ajouter une colonne de 1 au début et pour finir avec une matrice de partitions valides pour ⍵.

Maintenant, la fonction s'entraîne à gauche en parens. En raison de l'argument de gauche du train est la ligne de la matrice des partitions et l'argument de droite est l'entrée utilisateur. Le train est un tas de fourches avec un sommet comme la dent la plus à gauche.

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

Si la partition crée une séquence de nombres décroissants, le train renvoie la longueur de la séquence. Sinon zéro.

⍤1⊢applique le train de fonctions entre l'entrée utilisateur et chaque ligne de la matrice de partitions, en renvoyant une valeur pour chaque ligne de la matrice. est nécessaire pour lever l'ambiguïté entre l'opérande et l'argument de la fonction dérivée de .

⌈/ trouve le maximum.

Pourrait trouver un algorithme plus court mais je voulais essayer de cette façon qui est la plus directe et déclarative à laquelle je pouvais penser.

akhmorn
la source
Bienvenue chez PPCG! Ceci est un premier post impressionnant!
Rɪᴋᴇʀ
1

TSQL, 169 octets

Remarque: cela ne peut être exécuté que lorsque l'entrée peut être convertie en entier.

SQL récursif utilisé pour le bouclage.

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

Non 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+1
  FROM C
  WHERE i<9
)
SELECT max(i)
FROM C
WHERE z=@

Essaye le

t-clausen.dk
la source
0

R , 101 octets

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}

Essayez-le en ligne!

Plus de 2 semaines se sont écoulées sans réponse R, j'ai donc décidé de poster la mienne :)

Le code est assez rapide car il utilise une approche de force brute "limitée"

Code déroulé et explication:

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
}
digEmAll
la source