Quanti numeri decrescenti consecutivi nel mio numero?


18

Il 2019 è arrivato e probabilmente tutti hanno notato la peculiarità di questo numero: è infatti composto da due sotto-numeri (20 e 19) che rappresentano una sequenza di numeri discendenti consecutivi.

Sfida

Dato un numero x, restituisce la lunghezza della sequenza massima di numeri consecutivi in ​​ordine decrescente che possono essere formati prendendo sotto-numeri di x.

Appunti :

  • i numeri secondari non possono contenere zeri iniziali (ad es. 1009non possono essere suddivisi in 10, 09)
  • consecutivo e decrescente significa che un numero nella sequenza deve essere uguale al numero precedente -1, oppure ni+1=ni1 (ad es. 52non può essere suddiviso in 5,2perché 5e 2non sono consecutivi 2 ≠ 5 - 1)
  • la sequenza deve essere ottenuto utilizzando il numero completo, ad esempio in 7321non può scartare 7ed ottenere la sequenza 3, 2,1
  • solo una sequenza può essere ottenuta dal numero, ad esempio, 3211098non può essere diviso in due sequenze 3, 2, 1e 10, 9,8

Ingresso

  • Un numero intero ( >= 0): può essere un numero, una stringa o un elenco di cifre

Produzione

  • Un singolo intero dato il numero massimo di sotto-numeri decrescenti (si noti che il limite inferiore di questo numero è 1, cioè un numero è composto da solo in una sequenza decrescente di lunghezza uno)

Esempi:

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

Regole generali:

  • Questo è , quindi vince la risposta più breve in byte.
    Non lasciare che le lingue di code-golf ti scoraggino dal pubblicare risposte con lingue non codegolfing. Prova a trovare una risposta il più breve possibile per "qualsiasi" linguaggio di programmazione.
  • Per la tua risposta valgono regole standard con regole I / O predefinite , quindi puoi usare STDIN / STDOUT, funzioni / metodo con i parametri corretti e tipo di ritorno, programmi completi. La tua chiamata.
  • Sono vietate le scappatoie predefinite .
  • Se possibile, aggiungi un link con un test per il tuo codice (ad es. TIO ).
  • Inoltre, si consiglia vivamente di aggiungere una spiegazione per la risposta.


1
Il test case è 210 -> 2,1,0sbagliato (lo stesso con 0 -> 0)? Il task dice " i numeri secondari non possono contenere zeri iniziali ", zero è un caso speciale?
ბიმო

2
@BMO: beh, qui l'argomento è un po 'filosofico ...: D per me, 0 è un numero senza zero (inutile) che porta zero, quindi sì zero è un caso speciale
digEmAll

2
chiameresti questi ... numeri condiscendenti ? xD mi dispiace che non è stato nemmeno divertente
HyperNeutrino il

Siamo spiacenti, ho eliminato il mio commento in cui ho chiesto informazioni 212019. Sembra che non ho letto tutte le regole.
ciclista

Risposte:


6

Gelatina ,  15  9 byte

Bugfix grazie a Dennis

ŻṚẆDfŒṖẈṀ

Provalo online! (321impiegaanchemezzo minuto poiché il codice è almenoO(N2) )

Come?

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

Una porta della risposta Python di ArBo è significativamente più breve. Tuttavia, non riesce in alcuni casi di test a causa di troppa ricorsione.

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

Provalo online!


JavaScript (ES6), 66 byte

Accetta l'input come stringa.

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

Provalo online!

Commentate

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 byte implementando le modifiche al mio codice
ArBo

5

Perl 6 , 43 41 40 byte

-1 byte grazie a nwellnhof

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

Provalo online!

Soluzione basata su Regex. Sto cercando di trovare un modo migliore per abbinare da un elenco decrescente, ma Perl 6 non fa bene le partizioni

Spiegazione:

{                                        }  # 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 byte

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

Provalo online!

Codice iniziale non registrato:

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

Sembra che il secondo suggerimento non funzioni anche se non porterebbe nulla perché quindi hai bisogno di spazio per separare l'espressione if.
Nishioka,

Vero ... alternativa 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)

Provalo online!

-1 byte grazie ad Arnauld

Accetta l'input come stringa. Il programma si imbatte piuttosto rapidamente nel limite di profondità di ricorsione di Python, ma può finire la maggior parte dei casi di test.

Come funziona

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
Bella risposta! a+c+1può essere abbreviato in a-~c.
Arnauld

3

05AB1E , 10 byte

ÝRŒʒJQ}€gà

Estremamente lento, quindi il TIO di seguito funziona solo per casi di test inferiori a 750 ..

Provalo online .

Spiegazione:

Ý           # 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
Code golf: non vale la pena aggiungere 1 byte al programma da cui passare n!a n lg n.
corsiKa

3

Pyth, 16 byte

lef!.EhM.+vMT./z

Provalo online qui o verifica tutti i casi di test contemporaneamente qui .

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 byte

ŒṖḌ’Dɗ\ƑƇẈṀ

O(n0.3)

Provalo online!

Come funziona

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

Carbone , 26 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

F⊕Lθ

Passa ida 0 alla lunghezza dell'ingresso.

F⊕Lθ

Passa kda 0 alla lunghezza dell'ingresso.

⊞υ⭆κ⁻I…θ⊕ιλ

Calcola i primi knumeri nella sequenza decrescente a partire dal numero dato dalle prime icifre dell'input, concatenali e accumula ciascuna stringa risultante nell'elenco vuoto predefinito.

I﹪⌕υθ⊕Lθ

Trova la posizione della prima copia corrispondente dell'input e riduci il modulo 1 in più rispetto alla lunghezza dell'input.

Esempio: per un input delle 2019seguenti stringhe vengono generate:

 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 si trova quindi all'indice 12, che è ridotto modulo 5 per dare 2, la risposta desiderata.


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

L'input è un elenco di cifre.

Provalo online!

La funzione #crea un elenco di tutte le possibili divisioni osservandole entrambe

  • anteponendo il numero corrente aa tutte le suddivisioni restituite da una chiamata ricorsiva con il resto dell'input ( x<-b#c), ma solo se il numero successivo non è zero ( b>0) (o è l'ultimo numero nell'input ( c==[])) ed aè uno maggiore del primo numero della rispettiva divisione precedente x( a==x!!0+1).

e

  • aggiungendo la cifra successiva bdall'elenco di input al numero corrente ae proseguendo con il resto dell'input ( (10*a+b)#c)

Il caso base è quando l'elenco di input è vuoto (cioè non corrisponde al modello (b:c)). La ricorsione inizia con il numero corrente che aè 0( (0#)), che non raggiunge mai il primo ramo (anteponendo aa tutte le divisioni precedenti), perché non sarà mai maggiore di qualsiasi numero di divisioni.

Prendi la lunghezza di ogni divisione e trova il massimo ( maximum.map length).

Una variante con anche 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)]

che sostanzialmente funziona allo stesso modo, ma invece di mantenere l'intera divisione in un elenco, mantiene solo una coppia (r,x)della lunghezza della divisione re il primo numero nella divisione x.


3

Python 3 , 302 282 271 byte

-10 byte grazie alla punta di @ElPedro.

Accetta l'input come stringa. Fondamentalmente, ci vogliono sezioni sempre più grandi del numero da sinistra e vede se per quella fetta del numero si può formare una sequenza usando tutti i numeri.

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

Provalo online!


1
Dato che stai usando range3 volte puoi definire R=rangeal di fuori di entrambe le funzioni e quindi usare R(whatever)invece di range(whatever)salvare 4 byte.
ElPedro il

3

Japt , 27 byte

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

Provalo online! oppure Controlla la maggior parte dei casi di test

Questo non segna bene, ma utilizza un metodo unico e potrebbe esserci spazio per giocare a golf molto di più. Funziona anche abbastanza bene che tutti i casi di test oltre a 201200199198evitare il timeout.

Spiegazione:

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

Penso che questo funzioni per 27.
Shaggy


@Shaggy entrambi falliscono in input 21201perché non impongono che la fine della sequenza sia allineata correttamente (dalla mia versione originale la riga "termina con una virgola"). Questa o questa alternativa funziona.
Kamil Drakari,

Ah ok. In quel caso: 26 byte
Shaggy

@Shaggy Quello e le soluzioni a 28 byte non sono riuscito 210perché non c'è un delimitatore dopo 0. Ecco un 28 byte fisso che funziona.
Kamil Drakari il

2

Haskell, 65 byte

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

L'input è una stringa.

Provalo online!

Completamente diverso dall'altra mia risposta . Una forza bruta semplice che prova tutti gli elenchi di numeri discendenti consecutivi fino a quando non ne trova uno uguale all'elenco di input.

Se limitiamo il numero di input per interi a 64 bit, possiamo risparmiare 6 byte da loop yattraverso [1..19], perché il più grande intero a 64 bit dispone di 19 cifre e non c'è alcun bisogno di liste di test con più elementi.

Haskell, 59 byte

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

Provalo online!


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

Un'altra soluzione lenta a forza bruta.

Provalo online!


2

Dyalog APL, 138 byte

Un po 'boccone, ma funziona velocemente anche per grandi numeri. Se lo provi online , aggiungi il prefisso dfn ⎕←e inserisci un input a destra come un elenco di cifre.

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

Spiegazione

Innanzitutto, il dfn interno sulla destra che costruisce ricorsivamente un elenco di possibili modi per partizionare (con ) l'elenco delle cifre. Ad esempio, 1 0 1 0 ⊂ 2 0 1 9restituisce il vettore nidificato (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.

Usiamo 1,per aggiungere una colonna di 1s all'inizio e finiamo con una matrice di partizioni valide per ⍵.

Ora il treno di funzioni a sinistra tra parentesi. A causa dell'argomento sinistro del treno è la riga della matrice delle partizioni e l'argomento destro è l'input dell'utente. Il treno è un mucchio di forchette con una cima come il dente all'estrema sinistra.

((≢⊂)×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 la partizione crea una sequenza di numeri decrescenti, il treno restituisce la lunghezza della sequenza. Altrimenti zero.

⍤1⊢applica il treno di funzioni tra l'input dell'utente e ciascuna riga della matrice delle partizioni, restituendo un valore per ogni riga della matrice. è necessario chiarire tra operando e argomento rispetto alla funzione derivata di .

⌈/ trova il massimo.

Potrei trovare un algoritmo più breve ma volevo provare in questo modo quale è il più diretto e dichiarativo a cui potrei pensare.


Benvenuti in PPCG! Questo è un primo post impressionante!
Rɪᴋᴇʀ

1

TSQL, 169 byte

Nota: questo può essere eseguito solo quando l'input può essere convertito in un numero intero.

Sql ricorsivo utilizzato per il looping.

golfed:

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

Provalo


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}

Provalo online!

Sono trascorse più di 2 settimane senza alcuna risposta R, quindi ho deciso di pubblicare la mia :)

Il codice è piuttosto veloce poiché utilizza un approccio "limitato" alla forza bruta

Codice non spiegato e spiegazione:

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
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.