丹尼斯数字2.0


54

PPCG用户和当选mod,@ Dennis成为有史以来第二个收入超过10万的用户!

在此处输入图片说明

这是一个完全原始的想法,我没有从其他任何人那里得到,但是让我们根据他的用户ID进行挑战,12012以示敬意!

查看它,您会注意到他的ID有两个不同的“部分”。

12

012

这两个部分的总和为3。这是一个非常有趣的属性。

让我们将“ Dennis 2.0数字”定义为任何正整数,其中严格增加的数字的每个最大子序列加总为相同的数字。例如,

123

是Dennis 2.0的数字,因为只有一个严格增加数字的最大子列表,它的总和为6。另外,2,846,145也是Dennis 2.0的数字,因为三个增加的数字最大子列表,即

28
46
145

总计为10。此外,仅重复相同数字的数字必须是Dennis 2.0数字,因为例如777可以细分为

7
7
7

其中明确所有总和为7。

一些诸如42一个丹尼斯2.0数量,因为它被分解成

4
2

显然,它们的总和并不相同。

挑战

您必须编写程序或函数来确定给定数字是否为Dennis 2.0数字。您可以采用任何合理的输入格式进行输入和输出,例如从文件,函数参数/返回,STDIN / STDOUT等中以字符串,数字形式输入,然后如果该数字是Dennis 2.0 ,则返回真实值。数字,如果不是,则为假值。作为参考,以下是每个Dennis 2.0编号(最多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

存在标准漏洞,以字节为单位的最短答案为胜!


1
仅供参考,马丁·恩德(Martin Ender)是第一个获得10万名的代表。
Erik the Outgolfer

1
12366是有效的2.0数字吗?(123 | 6 | 6 vs. 1236 | 6)
Sp3000

2
@ sp3000这不是丹尼斯号码。它将是1236|6
DJMcMayhem

我可以将每个数字作为一元表示形式使用,它们之间的一个数字吗?这可能会延长很多时间。
莱利

13
我害怕丹尼斯仍然会在这场挑战中摧毁我们所有人
downrep_nation

Answers:


15

果冻,13 12字节

1个字节感谢@Dennis。

DIṠ’0;œṗDS€E

在线尝试!

说明

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字节

将字符串作为输入。返回false或true值(可以是数字)。

它使用正则表达式将输入字符串"2846145"转换为:

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

然后调用eval()此表达式。

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


很好,这是一个非常聪明的主意。:-)
ETHproductions's

也喜欢这个想法!但这不起作用:console.log(f(“ 2011”)); //错误的console.log(f(“ 189”)); // 18
user470370

3
@ user470370-我认为这是正确的。定义指出“严格增加数字的子序列”,因此2011拆分为 2 / 01 / 1D2.0而不是D2.0。至于189,它是一个D2.0数字,18是一个真实值。
阿尔诺

Ups😳当然,您是对的。以前没听懂 我认为,我必须重新设计自己的解决方案:D
user470370

15

Python,50个字节

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

期望input()对字符串求值,因此输入需要在Python 2 中用引号引起来。输出通过退出代码,其中0表示成功(真),1表示失败(虚假)。

Ideone上进行测试

这个怎么运作

我们将r初始化为字符串0,然后遍历输入中的所有数字d

  • 如果d大于r的第一个数字(最初为0,则等于d的先前值),则r<d求值为True'=+'[r<d]*2得出++

  • 如果d小于r的第一个数字,则'=+'[r<d]*2产生==

  • 如果ð等于第一位[R [R会比单身的字符串长ð,所以'=+'[r<d]*2收益率再次==

在所有情况下,数字d和两个生成的字符都放在r之前

处理eval(r)完所有输入数字后,对生成的表达式求值。

  • 如果输入由(正)数字的一个严格递增的序列组成,则表达式将求和它们的和。

    例如,整数12345导致表达式5++4++3++2++1++0,计算时得出15。请注意,秒+是一加号,因此不会影响结果。除以115是有效的(结果并不重要); 程序正常退出。

  • 如果输入包含两个严格增加的数字序列,则表达式包含一个简单的比较。

    例如,整数12012导致表达式2++1++0==2++1++0,由于两个项的总和为3,因此在求值时得出True。将1除以True1)是有效的(结果并不重要);程序正常退出。

    另一方面,整数12366导致表达式6==6++3++2++1++0,由于各项之和为612,因此在求值时会生成False。将1除以False0)会引发ZeroDivisionError ; 程序退出并出现错误。

  • 如果输入由三个或更多个严格递增的数字序列,表达由一个的链式比较,它返回当且仅当所有涉及的比较返回

    例如,整数94536导致表达式6++3==5++4==9++0,由于所有项的总和为9,因此在求值时会得出True。和以前一样,程序正常退出。

    在另一方面,整数17263所导致表达3==6++2==7++1++0,这产生时评价由于术语具有总和38,和8。和以前一样,程序退出并出现错误。


11
大约我发布了一份关于这一挑战的论文……
丹尼斯

7

Brachylog,13个字节

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

在线尝试!

说明

~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 将首先与最大的子列表结合。


6

Pyke,18个字节

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

在这里尝试!

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字节

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

一个真正的单线,因为这就是所有管道。将输入作为字符串$args[0]。将其作为char-array 循环遍历,每次迭代都根据当前值是否大于或等于前一个值将当前元素+或带有a 或-eq位于其前面的元素放置到管道上。这些字符串被ed在一起,并通过管道传递到(缩写和类似。例如,对于输入,它将被评估为,即。-le$i-joiniexInvoke-Expressioneval2846145+2+8-eq4+6-eq1+4+5True

该布尔值留在管道上,并且True/ False在程序完成时隐式写入。

注意:对于一位数字输入,结果数字留在管道上,这是PowerShell中的真实值。

例子

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或115

两者都包含-r的+1

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

以普通十进制输入

在线尝试!


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

将输入作为一元数字的逗号分隔列表。例如1231,11,111

在线尝试!


5

Perl,38 + 3(-p)= 41字节

-9个字节,感谢@Ton Hospel

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

由于存在$',因此代码必须在文件中才能运行。因此-p计数为3个字节。如果数字是Dennis 2.0的数字,则输出1,否则输出空字符串:

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

1
我想这大概是在Perl的最佳方法,但你可以打高尔夫球它归结为42:s%.%2x$&.($&.O ge$')%eg;$_=/^(2+1)\1*$/-p选项(+3,因为代码中有$'
吨Hospel

确实,使用比较的结果而不是随机A数会更好!谢谢!我不明白,.O但是……没有它,它在某些情况下会失败,但是我不明白为什么。
达达

$'是下一个数字及其后的所有数字。所以在例如778它比较778其中lt的样子上升序列。O7O789
与之

哦,对,太好了!我正在寻找一种使用$' or $`而不是捕获组的方法,但由于“及其后的所有”原因而找不到它。谢谢你的提示!
达达

嗯,~$&le~$'应该短1点
Ton Hospel

5

JavaScript(ES6),66 65 63字节

@ edc65节省了2个字节

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

将输入作为字符串。旧版本(仅适用于Firefox 30+):

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

提示:[...x,0]->[...x,p=t=z=0]
edc65 '16

@ edc65谢谢,我还没想到!
ETHproductions

3

Mathematica,38个字节

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

匿名函数。将数字作为输入,然后返回TrueFalse作为输出。


3

Brachylog 2,10字节,语言日期挑战

ẹ~c<₁ᵐ!+ᵐ=

在线尝试!

这基本上与@Fatalize的答案使用相同的算法(直到写完这篇文章后我才看到),但是在Brachylog 2的语法下进行了一些重新排列以使其更具高尔夫球手感。

这是一个完整的程序,false.如果不是Dennis 2.0数字,true则返回该数字。

说明

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

与Brachylog完整程序一样,如果所有断言可以同时满足,我们将得到真实的回报,否则返回错误。默认顺序为~c是用较少的分区,更长的元件第一排序,并在Prolog中(因此Brachylog),(默认顺序的通过在程序中的第一谓词所定义使用所述第二作为抢七,等等;在这里,~c占主导地位,因为是确定性的,因此无序。


2

MATL,24 23 20 18 16字节

Tjdl<vYsG!UlXQ&=

返回真假矩阵

在线尝试!

另外,恭喜@Dennis!

说明

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

很好用&=
路易斯·门多

2

PHP,108个 105 92字节

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

从参数接受输入,以0Dennis-2.0数字退出,以1else 退出。

分解

$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个字节

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

说明

N = 12012 用作示例。

                    # 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

在线尝试!


2

Ruby 2.3,56个字节

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

几乎可以肯定,这不是最简单的方法,但是它展示了一些不错的语言功能。

(不兼容换行符,因此运行类似ruby dennis2.rb <<< '12012'


1

PHP,144字节

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

我敢肯定,有一种更聪明(更短)的方法可以做到这一点,但它现在就可以了。


1

Python 2,69个字节

将输入作为字符串。

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

说明:

1201212012

转换为总和列表:

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

求值并转换为set。

set([3])

如果集合的长度为1,则所有总和都是相同的。


1

JavaScript(ES6),58

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

应用我很少有用的技巧https://codegolf.stackexchange.com/a/49967/21348

它按char扫描字符串char,以识别升序char的运行,在每个朗姆酒的末尾检查总和是否始终相同

  • c:当前字符
  • p:前一个字符
  • z:运行总和,运行结束时将与...
  • x:要比较的总和,在第一次运行时就简单地等于z

测试

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

红宝石, 117 105 85字节

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

这将返回该丹尼斯数字的整数,nil如果不是,则返回一个丹尼斯数字。所有整数在红宝石中都将被视为真,也将nil被视为假。i是要检查的整数。

第三版实际返回truefalse

PS已测试返回1到1000之间的172个整数,如答案所示。


0

APL,23个字节

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

说明:

  • N←⍎¨⍕⍵:获取输入中的各个数字,并存储在 N
  • N⊂⍨1,2>/N:在中找到数量严格增加的子列表 N
  • +/↑:对每个子列表求和
  • 1=≢∪:查看结果列表中是否只有一个唯一元素

0

加++,109字节

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

在线尝试!

这个怎么运作

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.