Dennis numeri 2.0


54

Utente PPCG e mod eletto, @Dennis è appena diventato il secondo utente in assoluto a guadagnare oltre 100.000 rappresentanti!

inserisci qui la descrizione dell'immagine

Questa è un'idea totalmente originale, che non ho ricevuto da nessun altro , ma facciamo una sfida in base al suo ID utente, 12012come omaggio!

Guardandolo, noterai che ci sono due "sezioni" distinte nel suo ID.

12

e

012

Entrambe queste sezioni si sommano a 3. Questa è una proprietà piuttosto interessante.

Definiamo un "numero Dennis 2.0" come qualsiasi numero intero positivo in cui ogni sottosequenza massima di cifre strettamente crescenti si somma allo stesso numero. Per esempio,

123

è un numero Dennis 2.0 perché esiste solo un elenco secondario massimo di cifre in costante aumento, e somma a 6. Inoltre, 2.846.145 è anche un numero Dennis 2.0 perché i tre elenchi massimi di cifre in aumento, vale a dire

28
46
145

Tutto sommato a 10. Inoltre, i numeri che ripetono la stessa cifra devono essere numeri Dennis 2.0 perché, ad esempio, 777possono essere suddivisi in

7
7
7

che chiaramente tutto sommano a sette.

Un numero come non42 è un numero Dennis 2.0, poiché è suddiviso in

4
2

che chiaramente non si sommano allo stesso numero.

La sfida

È necessario scrivere un programma o una funzione per determinare se un determinato numero è un numero Dennis 2.0 o meno. Puoi prendere input e output in qualsiasi formato di input ragionevole, ad esempio come una stringa, come un numero, da un file, argomenti di funtion / return, da STDIN / STDOUT, ecc. E quindi restituire un valore di verità se questo numero è un Dennis 2.0 numero e un valore falso se non lo è. Per riferimento, ecco tutti i numeri Dennis 2.0 fino a 1.000:

1
2
3
4
5
6
7
8
9
11
12
13
14
15
16
17
18
19
22
23
24
25
26
27
28
29
33
34
35
36
37
38
39
44
45
46
47
48
49
55
56
57
58
59
66
67
68
69
77
78
79
88
89
99
101
111
123
124
125
126
127
128
129
134
135
136
137
138
139
145
146
147
148
149
156
157
158
159
167
168
169
178
179
189
202
222
234
235
236
237
238
239
245
246
247
248
249
256
257
258
259
267
268
269
278
279
289
303
312
333
345
346
347
348
349
356
357
358
359
367
368
369
378
379
389
404
413
444
456
457
458
459
467
468
469
478
479
489
505
514
523
555
567
568
569
578
579
589
606
615
624
666
678
679
689
707
716
725
734
777
789
808
817
826
835
888
909
918
927
936
945
999

Si applicano scappatoie standard e vince la risposta più breve misurata in byte!


1
Solo per riferimento, Martin Ender è stato il primo a ottenere sempre 100.000 rappresentanti.
Erik the Outgolfer,

1
12366 è un numero 2.0 valido? (123 | 6 | 6 vs. 1236 | 6)
Sp3000,

2
@ sp3000 Questo non è un numero Dennis. Sarebbe1236|6
DJMcMayhem

Posso prendere ogni cifra poiché è una rappresentazione unaria con una ,tra di loro? Questo probabilmente lo sta allungando molto.
Riley,

13
Ho paura che Dennis ci distruggerà tutti in questa sfida
downrep_nation

Risposte:


15

Gelatina, 13 12 byte

1 byte grazie a @Dennis.

DIṠ’0;œṗDS€E

Provalo online!

Spiegazione

DIṠ’0;œṗDS€E    Main link. Argument: N
D               Convert N to its digits.
 I              Find the differences between the elements.
  Ṡ             Find the sign of each difference. This yields 1 for locations where the
                list is strictly increasing and 0 or -1 elsewhere.
   ’            Decrement. This yields 0 for locations where the list is strictly
                increasing and -1 or -2 elsewhere.
    0;          Prepend a 0.
        D       Get another list of digits.
      œṗ        Split the list of digits at truthy positions, i.e. the -1s and -2s.
         S€     Sum each sublist.
           E    Check if all values are equal.

16

JavaScript (ES6), 72 70 byte

Accetta una stringa come input. Restituisce falso o un valore di verità (che può essere un numero).

Sta usando un'espressione regolare per trasformare una stringa di input come "2846145"in:

"(a=2+8)&&(a==4+6)&&(a==1+4+5)"

Quindi chiama eval()questa espressione.

let f =

n=>eval(n.replace(/./g,(v,i)=>(v>n[i-1]?'+':i?')&&(a==':'(a=')+v)+')')

console.log(f("101"));
console.log(f("102"));
console.log(f("777"));
console.log(f("2846145"));


Bello, è un'idea davvero intelligente. :-)
ETHproductions

Ti piace anche quell'idea! Ma questo non funziona: console.log (f ("2011")); // false console.log (f ("189")); // 18
user470370,

3
@ user470370 - Penso che sia effettivamente corretto. La definizione indica " sottosequenze di numeri strettamente crescenti" , quindi si 2011divide come 2 / 01 / 1e non è un numero D2.0. Per quanto riguarda 189, è un numero D2.0 ed 18è un valore veritiero.
Arnauld,

Ups 😳 Certo, hai ragione. Non l'avevo capito prima. Penso che devo rielaborare la mia soluzione: D
user470370,

15

Python, 50 byte

r='0'
for d in input():r=d+'=+'[r<d]*2+r
1/eval(r)

Si aspetta input()che valuti una stringa, quindi l'input ha bisogno delle virgolette circostanti in Python 2. L'output è tramite il codice di uscita , dove 0 indica il successo (verità) e 1 indica il fallimento (falsa).

Provalo su Ideone .

Come funziona

Inizializziamo r sulla stringa 0 e ripetiamo su tutte le cifre d nell'input.

  • Se d è maggiore della prima cifra del r (inizialmente 0 , quindi uguale al valore precedente di d ), r<drestituisce vero e '=+'[r<d]*2rendimenti ++.

  • Se d è più piccolo della prima cifra di r , '=+'[r<d]*2produce ==.

  • Se d è uguale alla prima cifra di r , r sarà più lungo della stringa singleton d , quindi '=+'[r<d]*2cede ancora una volta ==.

In tutti i casi, la cifra d e i due caratteri generati vengono anteposti a r .

Una volta elaborate tutte le cifre di input, eval(r)valuta l'espressione generata.

  • Se l'input è costituito da una singola sequenza strettamente crescente di cifre (positive), l'espressione valuta la loro somma.

    Ad esempio, l'intero 12345 risulta nell'espressione 5++4++3++2++1++0, che restituisce 15 quando viene valutata. Si noti che ogni secondo + è un vantaggio unario , quindi non influisce sul risultato. La divisione 1 per 15 è valida (il risultato non è importante); il programma esce normalmente.

  • Se l'input è costituito da due sequenze di cifre strettamente crescenti, l'espressione consiste in un semplice confronto.

    Ad esempio, l'intero 12012 risulta nell'espressione 2++1++0==2++1++0, che restituisce True quando valutata poiché entrambi i termini hanno la somma 3 . La divisione 1 per True ( 1 ) è valida (il risultato non è importante); il programma esce normalmente.

    D'altra parte, il numero intero 12366 risulta nell'espressione 6==6++3++2++1++0, che produce Falso quando valutato poiché i termini hanno somme 6 e 12 . Dividendo 1 per False ( 0 ) genera un ZeroDivisionError ; il programma si chiude con un errore.

  • Se l'input è costituito da tre o più sequenze di cifre strettamente crescenti, l'espressione consiste in un confronto concatenato , che restituisce True se e solo se tutti i confronti coinvolti restituiscono True .

    Ad esempio, il numero intero 94536 risulta nell'espressione 6++3==5++4==9++0, che restituisce True quando viene valutata poiché tutti i termini hanno la somma 9 . Come prima, il programma si chiude normalmente.

    D'altra parte, il numero intero 17263 risulta nell'espressione 3==6++2==7++1++0, che produce Falso quando valutato poiché i termini hanno somme 3 , 8 e 8 . Come prima, il programma si chiude con un errore.


11
A proposito di tempo ho pubblicato una presentazione per questa sfida ...
Dennis

7

Brachylog , 13 byte

~c@e:{<+}a!#=

Provalo online!

Spiegazione

~c               Find a list of integers which when concatenated result in the Input
  @e             Split the integers into lists of digits
    :{<+}a       Each list of digit is stricly increasing, and compute its sum
          !      Discard all other choice points (prevents backtracking for smaller sublists)
           #=    All sums must be equal

~c prima si unificheranno con le liste più grandi.


6

Pyke, 18 byte

mb$1m>0R+fMbms}lt!

Provalo qui!

mb                 -         map(int, input)
  $                -        delta(^)
   1m>             -       map(^, 1>i)
      0R+          -      [0]+^
         f         -     input.split_at(^) 
          Mb       -    deep_map(int, ^)
            ms     -   map(sum, ^)
              }    -  uniquify(^)
               lt! - len(^) == 1

6

PowerShell v2 +, 100 64 61 byte

-join([char[]]$args[0]|%{("+$_","-eq$_")[$_-le$i];$i=$_})|iex

Un vero e proprio transatlantico, poiché questa è tutta una pipeline. Accetta l'input come stringa $args[0]. charPassa attraverso di esso come una matrice, ogni iterazione posiziona l'elemento corrente con a +o -eqdavanti a esso sulla pipeline in base al fatto che il valore corrente sia -lessenziale rispetto eal valore precedente $i. Tali stringhe vengono -joineditate insieme e reindirizzate a iex(abbreviazione di Invoke-Expressione simili a eval. Ad esempio, per l'input 2846145questo verrà valutato come +2+8-eq4+6-eq1+4+5, ovvero True.

Quel booleano viene lasciato sulla pipeline e True/ Falseè implicitamente scritto al completamento del programma.

NB: per l'immissione di una sola cifra, la cifra risultante viene lasciata sulla pipeline, che è un valore veritiero in PowerShell.

Esempi

PS C:\Tools\Scripts\golfing> 2846145,681,777,12366,2|%{"$_ -> "+(.\dennis-number-20.ps1 "$_")}
2846145 -> True
681 -> False
777 -> True
12366 -> False
2 -> 2

6

GNU sed 217 o 115

Entrambi includono +1 per -r

217:

s/./&,/g;s/^/,/g;:;s,0,,;s,2,11,;s,3,21,;s,4,31,;s,5,41,;s,6,51,
s,7,61,;s,8,71,;s,9,81,;t;s/(,1*)(1*)\1,/\1\2X\1,/;t;s/,//g
s,1X1(1*),X\1a,;t;/^1.*X/c0
/Xa*$/s,a*$,,;y,a,1,;/1X1/b;/1X|X1/c0
c1

Accetta l'input in decimale normale

Provalo online!


115:

s/^|$/,/g;:;s/(,1*)(1*)\1,/\1\2X\1,/;t;s/,//g
s,1X1(1*),X\1a,;t;/^1.*X/c0
/Xa*$/s,a*$,,;y,a,1,;/1X1/b;/1X|X1/c0
c1

Prende l'input come elenco separato da virgole delle cifre dei numeri in unario. per esempio 123sarebbe1,11,111

Provalo online!


5

Perl, 38 + 3 ( -p) = 41 byte

-9 byte grazie a @Ton Hospel !

s%.%2x$&.(~$&le~$')%eg;$_=/^(2+1)\1*$/

Poiché esiste un $', il codice deve essere contenuto in un file per essere eseguito. Quindi -pconta per 3 byte. Emette 1 se il numero è un numero Dennis 2.0 o una stringa vuota in caso contrario:

$ cat dennis_numbers.pl
s%.%2x$&.(~$&le~$')%eg;$_=/^(2+1)\1*$/
$ perl -p dennis_numbers.pl <<< "1
10
12315
12314"

1
Penso che questo sia probabilmente il miglior approccio in perl, ma puoi s%.%2x$&.($&.O ge$')%eg;$_=/^(2+1)\1*$/-p$'
giocarlo

In effetti, usare il risultato del confronto anziché quello casuale Aè molto meglio! Grazie! Non capisco .Operò ... Senza di essa, in alcuni casi fallisce, ma non riesco a capire perché.
Dada,

$'è la cifra successiva e tutte quelle successive. Quindi, ad esempio, 778si confronta 7con 78quale ltsembra una sequenza crescente. Le Orotture che e mette a confronto 7Oa 78 (qualsiasi cosa sopra 9in opere ASCII)
Ton Hospel

Oh giusto, è carino! Ho cercato un modo per usare $' or $`al posto dei miei gruppi di acquisizione, ma non sono riuscito a trovarlo, a causa di quello" e di tutti quelli che lo seguono ". Grazie per il consiglio!
Dada,

Mmm, ~$&le~$'dovrebbe essere 1 più corto
Ton Hospel

5

JavaScript (ES6), 66 65 63 byte

Salvato 2 byte grazie a @ edc65

x=>[...x,p=t=z=0].every(c=>p>=(t+=+p,p=c)?(z?z==t:z=t)+(t=0):1)

Accetta l'input come stringa. Vecchia versione (funziona solo con Firefox 30+):

x=>[for(c of(p=t=0,x))if(p>=(t+=+p,p=c))t+(t=0)].every(q=>q==+p+t)

Suggerimento: [...x,0]->[...x,p=t=z=0]
edc65,

@ edc65 Grazie, non ci avevo pensato!
ETHproductions

3

Mathematica, 38 byte

Equal@@Tr/@IntegerDigits@#~Split~Less&

Funzione anonima. Accetta un numero come input e restituisce Trueo Falsecome output.


3

Brachylog 2, 10 byte, sfida postdatati in lingua

ẹ~c<₁ᵐ!+ᵐ=

Provalo online!

Questo è fondamentalmente lo stesso algoritmo della risposta di @ Fatalize (che non ho visto fino a dopo averlo scritto), ma riorganizzato in qualche modo per renderlo più golfoso nella sintassi di Brachylog 2.

È un programma completo, che ritorna false.se non è un numero Dennis 2.0 o truese lo è.

Spiegazione

ẹ~c<₁ᵐ!+ᵐ=
ẹ           Interpret the input number as a list of digits
      !     Find the first (in default order)
 ~c           partition of the digits
   <₁ᵐ        such that each is in strictly increasing order
         =  Assert that the following are all equal:
       +ᵐ     the sums of each partition

Come al solito per un programma completo di Brachylog, se tutte le affermazioni possono essere soddisfatte contemporaneamente, otteniamo un ritorno sincero, altrimenti false. L'ordine predefinito per ~cè ordinare prima le partizioni con meno elementi più lunghi, e in Prolog (quindi Brachylog), l'ordine predefinito è definito dal primo predicato nel programma (usando il secondo come tiebreak, e così via; qui ~cdomina, perché è deterministico e quindi non ha nulla da ordinare).


2

MATL, 24 23 20 18 16 byte

Tjdl<vYsG!UlXQ&=

Restituisce una verità di matrice di falsità

Provalo online!

Inoltre, complimenti @Dennis!

Spiegazione

T       % Push a literal TRUE to the stack
        %   STACK: {1}
j       % Explicitly grab the input as a string
        %   STACK: {1, '2846145'}
d       % Compute the difference between successive ASCII codes
        %   STACK: {1, [6 -4 2 -5 3 1]}
l<      % Find where that difference is less than 1
        %   STACK: {1, [0 1 0 1 0 0]}
v       % Prepend the TRUE value we pushed previously
        %   STACK: {[1 0 1 0 1 0 0]}
Ys      % Compute the cumulative sum. This assigns a unique integer label to
        % each set of increasing numbers
        %   STACK: {[1 1 2 2 3 3 3]}
G!U     % Grab the input as numeric digits
        %   STACK: {[1 1 2 2 3 3 3], [2 8 4 6 1 4 5]}
lXQ     % Compute the sum of each group of increasing digits
        %   STACK: {[10 10 10]}
&=      % Computes element-wise equality (automatically broadcasts). A
        % truthy value in MATL is a matrix of all ones which is only the case
        % when all elements are equal:
        %   STACK: {[1 1 1
        %            1 1 1
        %            1 1 1]}
        % Implicitly display the result

Bel uso di &=!
Luis Mendo,

2

PHP, 108 105 92 byte

$p=-1;foreach(str_split("$argv[1].")as$d)$p>=$d?$r&&$s-$r?die(1):($r=$s)&$s=$p=$d:$s+=$p=$d;

accetta input dall'argomento, esce con 0per il numero Dennis-2.0, con 1else.

abbattersi

$p=-1;                              // init $p(revious digit) to -1
foreach(str_split("$argv[1].")as$d) // loop $d(igit) through input characters
                                    // (plus a dot, to catch the final sum)
    $p>=$d                              // if not ascending:
        ?$r                             // do we have a sum remembered 
        &&$s-$r                         // and does it differ from the current sum?
                ?die(1)                     // then exit with failure
                :($r=$s)&$s=$p=$d           // remember sum, set sum to digit, remember digit
        :$s+=$p=$d                      // ascending: increase sum, remember digit
    ;
// 

2

05AB1E , 18 byte

SD¥X‹X¸«DgL*ꥣOÙg

Spiegazione

N = 12012 usato come esempio.

                    # implicit input N = 12012
S                   # split input number to list of digits  
                    # STACK: [1,2,0,1,2]
 D                  # duplicate
                    # STACK: [1,2,0,1,2], [1,2,0,1,2]
  ¥                 # reduce by subtraction
                    # STACK: [1,2,0,1,2], [1,-2,1,1]
   X‹               # is less than 1
                    # STACK: [1,2,0,1,2], [0,1,0,0]
     X¸«            # append 1
                    # STACK: [1,2,0,1,2], [0,1,0,0,1]
        DgL*        # multiply by index (1-indexed)
                    # STACK: [1,2,0,1,2], [0,2,0,0,5]
            ê       # sorted unique
                    # STACK: [1,2,0,1,2], [0,2,5]
             ¥      # reduce by subtraction
                    # STACK: [1,2,0,1,2], [2,3]
              £     # split into chunks
                    # STACK: [[1,2],[0,1,2]]
               O    # sum each
                    # STACK: [3,3]
                Ù   # unique
                    # STACK: [3]
                 g  # length, 1 is true in 05AB1E
                    # STACK: 1

Provalo online!


2

Ruby 2.3, 56 byte

p !gets.chars.chunk_while(&:<).map{|a|eval a*?+}.uniq[1]

Quasi certamente non è il modo più golfoso per farlo, ma mostra alcune belle caratteristiche linguistiche.

(Non tollerante la newline, quindi esegui come ruby dennis2.rb <<< '12012')


1

PHP, 144 byte

<?php preg_match_all("/0?1?2?3?4?5?6?7?8?9?/",$argv[1],$n);foreach($n[0]as$i)if(strlen($i)&&($a=array_sum(str_split($i)))!=$s=$s??$a)die;echo 1;

Sono sicuro che esiste un modo molto più intelligente (e più breve) per farlo, ma lo farà per ora.


1

Python 2, 69 byte

Accetta l'input come stringa.

lambda I:len(set(eval(reduce(lambda x,y:x+',+'[y>x[-1]]+y,I+' '))))<2

Spiegazione:

ex 1201212012

Converte in elenco di somme:

1+2,0+1+2,1+2,0+1+2,

Valuta e converte per impostare.

set([3])

Se la lunghezza del set è 1, tutte le somme sono uguali.


1

JavaScript (ES6), 58

s=>![...s,z=x=p=0].some(c=>[c>p?0:z-=(x=x||z),z-=p=c][0])

Applicazione del mio consiglio raramente utile https://codegolf.stackexchange.com/a/49967/21348

Esegue la scansione del carattere stringa per carattere identificando la sequenza di caratteri ascendenti, alla fine di ogni rum controlla se la somma è sempre la stessa

  • c: carattere attuale
  • p: carattere precedente
  • z: somma corrente, alla fine di una corsa verrà confrontata con ...
  • x: somma da confrontare, alla prima esecuzione viene semplicemente reso uguale a z

Test

f=
s=>![...s,z=x=p=0].some(c=>[c>p?0:z-=(x=x||z),z-=p=c][0])

function run()
{
  var i=I.value
  O.textContent = i + ' -> ' + f(i)
}

run()

test=`1 2 3 4 5 6 7 8 9 11 12 13 14 15 16 17 18 19 22 23 24 25 26 27 28 29 33 34 35 36 37 38 39 44 45 46 47 48 49 55 56 57 58 59 66 67 68 69 77 78 79 88 89 99 101 111 123 124 125 126 127 128 129 134 135 136 137 138 139 145 146 147 148 149 156 157 158 159 167 168 169 178 179 189 202 222 234 235 236 237 238 239 245 246 247 248 249 256 257 258 259 267 268 269 278 279 289 303 312 333 345 346 347 348 349 356 357 358 359 367 368 369 378 379 389 404 413 444 456 457 458 459 467 468 469 478 479 489 505 514 523 555 567 568 569 578 579 589 606 615 624 666 678 679 689 707 716 725 734 777 789 808 817 826 835 888 909 918 927 936 945 999`.split` `

numerr=0
for(i=1; i<1000; i++)
{
  v = i + '';
  r = f(v);
  ok = r == (test.indexOf(v) >= 0)
  if (!ok) console.log('Error',++numerr, v)
}  
if(!numerr) console.log('All test 1..999 ok')
<input id=I value=612324 type=number oninput='run()'>
<pre id=O>



0

Rubino, 117 105 85 byte

# original (117):
j,k=0,?0;"#{i}".chars.group_by{|n|n>k||j=j+1;k=n;j}.values.map{|a|a.map(&:to_i).reduce(&:+)}.reduce{|m,n|n==m ?m:nil}

# inspired by PHP regexp approach (105):
"#{i}".scan(/0?1?2?3?4?5?6?7?8?9?/).map{|a|a.chars.map(&:to_i).reduce(&:+)}.reduce{|m,n|!n||n==m ?m:nil}

# some number comparison simplification (85):
!"#{i}".scan(/0?1?2?3?4?5?6?7?8?9?/).map{|a|a.chars.map(&:to_i).reduce(&:+)}.uniq[1]

Ciò restituirebbe l'intero di questo numero di dennis o nilse non un numero di dennis. Tutti i numeri interi saranno considerati veri anche nel rubino e saranno nilconsiderati falsi. iè il numero intero che viene verificato.

La terza versione effettivamente ritorna truee false.

PS testato per restituire 172 numeri interi da 1 a 1000 come nella risposta.


0

APL, 23 byte

{1=≢∪+/↑N⊂⍨1,2>/N←⍎¨⍕⍵}

Spiegazione:

  • N←⍎¨⍕⍵: ottenere le singole cifre nell'input, memorizzare N
  • N⊂⍨1,2>/N: trova le liste di numeri strettamente crescenti in N
  • +/↑: somma ogni lista secondaria
  • 1=≢∪: verifica se l'elenco risultante ha un solo elemento univoco

0

Aggiungi ++ , 109 byte

D,g,@@#,BF1_B
D,k,@@#,bR$d@$!Q@BFB
D,f,@,BDdVÑ_€?1€_0b]$+€?dbLRBcB*BZB]GbL1+b]+qG€gd€bLÑ_0b]$+BcB]£k€¦+Ñ=1$ª=

Provalo online!

Come funziona

fgkf

f(x)

x1[4,4,4]0110A010

[1,2,...length(A)]0AAAAA

ggA

g(x,y)

g(x,y)x:=[1,2,0,1,2]y=33AA10x=12012A=[3,6]3A6x

g([1,2,0,1,2],3)[1 2 0 1 2 2][1,2]g

g(x,y)yAx:=12012g

[[[1 2] [1 2 0 1 2]]]

[2,5]A10[0,3]gB

k(x,n)

k[[1,2],[3,4],[5,6]]

[[[1,2],0],[[1,2,0,1,2],3]]kk([1,2,0,1,2],3)

k(x,n)gn=0[n,x,n]n=0[[2,1,0,1,2],3]nxxB

[0,1,2][2,1,0]

k(x,n)(x,n)B1

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.