Dennis números 2.0


54

Usuario PPCG y mod elegido, @Dennis se convirtió en el segundo usuario en ganar más de 100k rep.

ingrese la descripción de la imagen aquí

Esta es una idea totalmente original, que no obtuve de nadie más , ¡pero hagamos un desafío basado en su ID de usuario, 12012como tributo!

Al mirarlo, notará que hay dos "secciones" distintas en su ID.

12

y

012

Ambas secciones suman un 3. Esa es una propiedad bastante interesante.

Definamos un "número Dennis 2.0" como cualquier número entero positivo donde cada subsecuencia máxima de dígitos estrictamente crecientes suma al mismo número. Por ejemplo,

123

es un número de Dennis 2.0 porque solo hay una sublista máxima de dígitos estrictamente crecientes, y suma 6. Además, 2.846.145 también es un número de Dennis 2.0 porque las tres sublistas máximas de dígitos crecientes, a saber

28
46
145

Todo suma a 10. Además, los números que solo repiten el mismo dígito deben ser números de Dennis 2.0 porque, por ejemplo, 777se pueden dividir en

7
7
7

que claramente todos suman siete.

Un número como no42 es un número Dennis 2.0, ya que se divide en

4
2

que claramente no suman el mismo número.

El reto

Debe escribir un programa o función para determinar si un número dado es un número Dennis 2.0 o no. Puede tomar entradas y salidas en cualquier formato de entrada razonable, por ejemplo, como una cadena, como un número, de un archivo, argumentos de función / retorno, de STDIN / STDOUT, etc. y luego devolver un valor verdadero si este número es un Dennis 2.0 número y un valor falso si no lo es. Como referencia, aquí está cada número Dennis 2.0 hasta 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

Se aplican las lagunas estándar, ¡y gana la respuesta más corta medida en bytes!


1
Solo como referencia, Martin Ender fue el primero en obtener 100k rep.
Erik the Outgolfer

1
¿12366 es un número 2.0 válido? (123 | 6 | 6 vs. 1236 | 6)
Sp3000

2
@ sp3000 Ese no es un número de Dennis. Sería1236|6
DJMcMayhem

¿Puedo tomar cada dígito como representación unaria con un ,entre ellos? Esto probablemente lo está estirando mucho.
Riley

13
No
obstante

Respuestas:


15

Jalea, 13 12 bytes

1 byte gracias a @Dennis.

DIṠ’0;œṗDS€E

Pruébalo en línea!

Explicación

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 bytes

Toma una cadena como entrada. Devuelve un valor falso o verdadero (que puede ser un número).

Está utilizando una expresión regular para transformar una cadena de entrada como "2846145"en:

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

Luego invoca eval()esta expresión.

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"));


Bien, esa es una idea muy inteligente. :-)
ETHproductions

¡Me gusta esa idea también! Pero esto no funciona: console.log (f ("2011")); // false console.log (f ("189")); // 18
usuario470370

3
@ user470370 - Creo que eso es realmente correcto. La definición establece "subsecuencias de números estrictamente crecientes" , por lo que se 2011divide como 2 / 01 / 1y no es un número D2.0. En cuanto a 189, es un número D2.0 y 18es un valor verdadero.
Arnauld

Ups 😳 Por supuesto, tienes razón. No entendí eso antes. Creo que tengo que reelaborar mi propia solución: D
user470370

15

Python, 50 bytes

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

Espera input()evaluar a una cadena, por lo que la entrada necesita comillas circundantes en Python 2. La salida es a través del código de salida , donde 0 indica éxito (verdad) y 1 indica falla (falsedad).

Pruébalo en Ideone .

Cómo funciona

Inicializamos r en la cadena 0 e iteramos sobre todos los dígitos d en la entrada.

  • Si d es mayor que el primer dígito de r (inicialmente 0 , luego igual al valor anterior de d ), se r<devalúa como Verdadero y '=+'[r<d]*2produce ++.

  • Si d es menor que el primer dígito de r , los '=+'[r<d]*2rendimientos ==.

  • Si d es igual al primer dígito de r , r será más largo que la cadena de un solo tono d , por lo que se '=+'[r<d]*2obtiene una vez más ==.

En todos los casos, el dígito d y los dos caracteres generados se anteponen a r .

Una vez que se han procesado todos los dígitos de entrada, eval(r)evalúa la expresión generada.

  • Si la entrada consiste en una única secuencia estrictamente creciente de dígitos (positivos), la expresión se evalúa como su suma.

    Por ejemplo, el entero 12345 da como resultado la expresión 5++4++3++2++1++0, que produce 15 cuando se evalúa. Tenga en cuenta que cada segundo + es un plus unario , por lo que no afecta el resultado. Dividir 1 entre 15 es válido (el resultado no es importante); el programa sale normalmente.

  • Si la entrada consta de dos secuencias estrictamente crecientes de dígitos, la expresión consiste en una comparación simple.

    Por ejemplo, el entero 12012 da como resultado la expresión 2++1++0==2++1++0, que produce Verdadero cuando se evalúa ya que ambos términos tienen suma 3 . Dividir 1 entre Verdadero ( 1 ) es válido (el resultado no es importante); el programa sale normalmente.

    Por otro lado, el entero 12366 da como resultado la expresión 6==6++3++2++1++0, que produce False cuando se evalúa ya que los términos tienen las sumas 6 y 12 . Dividir 1 por False ( 0 ) genera un ZeroDivisionError ; el programa sale con un error.

  • Si la entrada consta de tres o más secuencias de dígitos estrictamente crecientes, la expresión consiste en una comparación encadenada , que devuelve True si y solo si todas las comparaciones involucradas devuelven True .

    Por ejemplo, el entero 94536 da como resultado la expresión 6++3==5++4==9++0, que produce Verdadero cuando se evalúa ya que todos los términos tienen la suma 9 . Como antes, el programa sale normalmente.

    Por otro lado, el entero 17263 da como resultado la expresión 3==6++2==7++1++0, que produce False cuando se evalúa ya que los términos tienen sumas 3 , 8 y 8 . Como antes, el programa sale con un error.


11
Ya es hora de que publique una presentación para este desafío ...
Dennis

7

Brachylog , 13 bytes

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

Pruébalo en línea!

Explicación

~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 se unificará con las sublistas más grandes primero.


6

Pyke, 18 bytes

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

Pruébalo aquí!

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 bytes

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

Una línea literal, ya que esta es toda una tubería. Toma la entrada como una cadena $args[0]. Lo recorre en bucle como una charmatriz, cada iteración coloca el elemento actual con +o -eqdelante de él en la tubería en función de si el valor actual es -less-than-or- equal al valor anterior $i. Esas cadenas se -joineditan juntas y se canalizan a iex(abreviatura Invoke-Expressiony similar a eval. Por ejemplo, para la entrada 2846145esto se evaluará como +2+8-eq4+6-eq1+4+5, que es True.

Ese booleano se deja en la tubería y True/ Falsese escribe implícitamente al finalizar el programa.

NB: para la entrada de un solo dígito, el dígito resultante se deja en la tubería, que es un valor verdadero en PowerShell.

Ejemplos

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

Ambos incluyen +1 para -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

Toma entrada en decimal normal

Pruébalo en línea!


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

Toma la entrada como una lista separada por comas de los dígitos de números en unario. por ejemplo 123sería1,11,111

Pruébalo en línea!


5

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

-9 bytes gracias a @Ton Hospel !

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

Como hay un $', el código debe estar en un archivo para ejecutarse. Entonces -pcuenta para 3 bytes. Salidas 1 si el número es un número Dennis 2.0, o una cadena vacía de lo contrario:

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

1
Creo que este es probablemente el mejor enfoque en perl, pero puede s%.%2x$&.($&.O ge$')%eg;$_=/^(2+1)\1*$/-p$'
reducirlo

De hecho, ¡usar el resultado de la comparación en lugar de ese azar Aes mucho mejor! ¡Gracias! .OSin embargo, no entiendo ... Sin esto, falla en algunos casos, pero no puedo ver por qué.
Dada

$'es el siguiente dígito y todos los siguientes. Entonces, por ejemplo, 778se compara 7a 78cuál ltparece una secuencia ascendente. Lo Orompe y se compara 7Ocon 78 (todo lo anterior 9en ASCII funciona)
Ton Hospel

Oh cierto, eso es bueno! Busqué una forma de usar $' or $`en lugar de mis grupos de captura, pero no pude encontrarlo, por eso" y todos los que están después ". ¡Gracias por el consejo!
Dada

Mmm, ~$&le~$'debería ser 1 más corto
Ton Hospel

5

JavaScript (ES6), 66 65 63 bytes

Guardado 2 bytes gracias a @ edc65

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

Toma la entrada como una cadena. Versión anterior (solo funciona en Firefox 30+):

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

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

@ edc65 ¡Gracias, no había pensado en eso!
ETHproductions

3

Mathematica, 38 bytes

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

Función anónima. Toma un número como entrada y devuelve Trueo Falsecomo salida.


3

Brachylog 2, 10 bytes, desafío de fechas posteriores al idioma

ẹ~c<₁ᵐ!+ᵐ=

Pruébalo en línea!

Este es básicamente el mismo algoritmo que la respuesta de @ Fatalize (que no vi hasta después de escribir esto), pero se reorganizó un poco para que sea más golf bajo la sintaxis de Brachylog 2.

Es un programa completo, que regresa false.si no es un número Dennis 2.0, o truesi lo es.

Explicación

ẹ~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

Como de costumbre para un programa completo de Brachylog, si todas las afirmaciones pueden cumplirse simultáneamente, obtenemos un verdadero retorno, de lo contrario falsey. El orden predeterminado para ~ces ordenar las particiones con menos elementos más largos primero, y en Prolog (por lo tanto, Brachylog), el orden predeterminado definido por el primer predicado en el programa (usando el segundo como un desempate, y así sucesivamente; aquí, ~cdomina, porque es determinista y por lo tanto no tiene nada que ordenar).


2

MATL, 24 23 20 18 16 bytes

Tjdl<vYsG!UlXQ&=

Devuelve una verdad de la matriz de Falsey

Pruébalo en línea!

Además, felicidades @Dennis!

Explicación

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

Buen uso de &=!
Luis Mendo

2

PHP, 108 105 92 bytes

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

toma la entrada del argumento, sale con el 0número Dennis-2.0, con 1else.

Descompostura

$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 bytes

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

Explicación

N = 12012 usado como ejemplo.

                    # 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

Pruébalo en línea!


2

Ruby 2.3, 56 bytes

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

Ciertamente, no es la mejor forma de hacer esto, pero muestra algunas características agradables del lenguaje.

(No tolera la nueva línea, así que corre como ruby dennis2.rb <<< '12012')


1

PHP, 144 bytes

<?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;

Estoy seguro de que hay una forma mucho más inteligente (y más corta) de hacerlo, pero lo hará por ahora.


1

Python 2, 69 bytes

Toma la entrada como una cadena.

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

Explicación:

ex 1201212012

Convierte a la lista de sumas:

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

Evalúa y convierte a conjunto.

set([3])

Si la longitud del conjunto es 1, todas las sumas son iguales.


1

JavaScript (ES6), 58

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

Aplicando mi consejo raramente útil https://codegolf.stackexchange.com/a/49967/21348

Escanea el string char por char identificando la ejecución de caracteres ascendentes, al final de cada ron comprueba si la suma es siempre la misma

  • c: char actual
  • p: char anterior
  • z: suma de ejecución, al final de una ejecución se comparará con ...
  • x: suma para comparar, en la primera ejecución simplemente se hace igual a z

Prueba

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

Rubí, 117 105 85 bytes

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

Esto devolvería el número entero de este número dennis o, nilsi no, un número dennis. Todos los enteros se considerarán verdaderos en ruby ​​y también nilse considerarán falsos. ies el entero que se está comprobando.

La tercera versión en realidad regresa truey false.

PS probó para devolver 172 enteros de 1 a 1000 como en la respuesta.


0

APL, 23 bytes

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

Explicación:

  • N←⍎¨⍕⍵: obtener los dígitos individuales en la entrada, almacenar en N
  • N⊂⍨1,2>/N: encuentre las sublistas de números estrictamente crecientes en N
  • +/↑: suma cada sublista
  • 1=≢∪: ver si la lista resultante tiene solo un elemento único

0

Añadir ++ , 109 bytes

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$ª=

Pruébalo en línea!

Cómo funciona

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.