Денис номера 2.0

54

Пользователь PPCG и избранный мод @Dennis стали вторым пользователем, заработавшим более 100 тысяч повторений!

введите описание изображения здесь

Это совершенно оригинальная идея, которую я не получил ни от кого другого , но давайте сделаем вызов на основе его идентификатора пользователя, 12012как дань уважения!

Глядя на это, вы заметите, что есть два отдельных «раздела» его идентификатора.

12

а также

012

Оба этих раздела в сумме дают 3. Это довольно интересное свойство.

Давайте определим «число Денниса 2.0» как любое положительное целое число, где каждая максимальная подпоследовательность строго возрастающих цифр суммируется с одним и тем же числом. Например,

123

является числом Денниса 2.0, потому что существует только один максимальный подсписок строго возрастающих цифр, и его сумма равна 6. Кроме того, 2846145 также является числом Денниса 2.0, потому что три максимальных подсписка возрастающих цифр, а именно

28
46
145

Вся сумма до 10. Кроме того, числа, которые просто повторяют одну и ту же цифру, должны быть числами Денниса 2.0, потому что, например, 777их можно разбить на

7
7
7

которые явно все сумма до семи.

Ряд таких , как 42это не число Дэннис 2.0, так как оно разбивается на

4
2

которые явно не суммируются к одному и тому же числу.

Соревнование

Вы должны написать программу или функцию, чтобы определить, является ли данное число номером Дениса 2.0 или нет. Вы можете взять ввод и вывод в любом приемлемом формате ввода, например, в виде строки, в виде числа, из файла, аргументов / возврата функции, из STDIN / STDOUT и т. Д., А затем вернуть истинное значение, если это число является Денисом 2.0. число и ложное значение, если это не так. Для справки, вот каждый номер Dennis 2.0 до 1000:

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

Применяются стандартные лазейки, и выигрывает самый короткий ответ, измеряемый в байтах!

DJMcMayhem
источник
1
Просто для справки, Мартин Эндер был первым, кто получил 100 000 представителей.
Эрик Outgolfer
1
Является ли 12366 действительным номером 2.0? (123 | 6 | 6 против 1236 | 6)
Sp3000
2
@ sp3000 Это не номер Денниса. Это было бы1236|6
DJMcMayhem
Могу ли я взять каждую цифру в виде одинарного представления ,между ними? Это, вероятно, сильно растягивает.
Райли
13
Я боюсь, что Денис уничтожит всех нас в этом вызове
downrep_nation

Ответы:

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.
PurkkaKoodari
источник
16

JavaScript (ES6), 72 70 байт

Принимает строку в качестве ввода. Возвращает либо ложное, либо истинное значение (которое может быть числом).

Он использует регулярное выражение для преобразования входной строки, такой как "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"));

Arnauld
источник
Хорошо, это действительно умная идея. :-)
ETHproductions
Понравилась и эта идея! Но это не работает: console.log (f ("2011")); // false console.log (f ("189")); // 18
user470370
3
@ user470370 - Я думаю, это действительно правильно. Определение гласит «подпоследовательности строго возрастающих чисел» , поэтому 2011разделяется, как 2 / 01 / 1и не является числом D2.0. Что касается 189, это число D2.0 и 18является истинным значением.
Арно
Упс 😳 Конечно, вы правы. Не получил это раньше. Я думаю, я должен переделать свое собственное решение: 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выдает ==.

  • Если d равно первой цифре r , r будет длиннее, чем одиночная строка d , поэтому '=+'[r<d]*2возвращается снова ==.

Во всех случаях цифра d и два сгенерированных символа добавляются к r .

Как только все входные цифры были обработаны, eval(r)оценивается сгенерированное выражение.

  • Если входные данные состоят из одной строго возрастающей последовательности (положительных) цифр, выражение оценивается как их сумма.

    Например, целое число 12345 приводит к выражению 5++4++3++2++1++0, которое дает 15 при оценке. Обратите внимание, что каждая секунда + является унарным плюсом, поэтому она не влияет на результат. Деление 1 на 15 является действительным (результат не важен); программа выходит нормально.

  • Если входные данные состоят из двух строго возрастающих последовательностей цифр, выражение состоит из простого сравнения.

    Например, целое число 12012 приводит к выражению 2++1++0==2++1++0, которое возвращает True, когда вычисляется, поскольку оба члена имеют сумму 3 . Деление 1 на True ( 1 ) действительно (результат не важен); программа выходит нормально.

    С другой стороны, целое число 12366 приводит к выражению 6==6++3++2++1++0, которое выдает False при оценке, поскольку термины имеют суммы 6 и 12 . При делении 1 на False ( 0 ) возникает ошибка ZeroDivisionError ; программа завершается с ошибкой.

  • Если входные данные состоят из трех или более строго возрастающих последовательностей цифр, выражение состоит из цепочечного сравнения , которое возвращает True, если и только если все участвующие сравнения возвращают True .

    Например, целое число 94536 приводит к выражению 6++3==5++4==9++0, которое возвращает True при оценке, так как все члены имеют сумму 9 . Как и прежде, программа выходит нормально.

    С другой стороны, целое число 17263 приводит к выражению 3==6++2==7++1++0, которое выдает False при оценке, поскольку термины имеют суммы 3 , 8 и 8 . Как и прежде, программа завершает работу с ошибкой.

Деннис
источник
11
О времени я отправил представление на этот вызов ...
Деннис
7

Брахилог , 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 сначала объединится с самыми большими списками.

Fatalize
источник
6

Пайк, 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, каждая итерация помещает либо текущий элемент с +или -eqперед ним в конвейер, основываясь на том, является ли текущее значение -less-than-or- equal для предыдущего значения $i. Эти строки -joinредактируются вместе и передаются по каналу iex(сокращенно Invoke-Expressionи аналогично eval. Например, для ввода 2846145это будет оцениваться как +2+8-eq4+6-eq1+4+5, то есть True.

Это логическое значение остается в конвейере и 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
AdmBorkBork
источник
6

GNU sed 217 или 115

Оба включают +1 для -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

Принимает ввод в нормальном десятичном формате

Попробуйте онлайн!


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

Принимает ввод как разделенный запятыми список чисел в унарном формате. например 123, будет1,11,111

Попробуйте онлайн!

Райли
источник
5

Perl, 38 + 3 ( -p) = 41 байт

-9 байт благодаря @Ton Hospel !

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

Поскольку существует $', код должен быть в файле для запуска. Так что -pсчитается за 3 байта. Выводит 1, если число является числом Дениса 2.0, или пустой строкой в ​​противном случае:

$ 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, потому что код имеет $')
Ton Hospel
Действительно, Aлучше использовать результат сравнения вместо случайного ! Спасибо! .OХотя я не понимаю ... Без этого в некоторых случаях это не помогает, но я не понимаю, почему.
Дада
$'следующая цифра и все после нее. Так, например, 778он сравнивается 7с тем, 78что ltвыглядит как восходящая последовательность. В Oперерывы , которые и сравнивает 7Oс 78 (что - либо выше 9в ASCII работ)
Тон Hospel
Ах да, это мило! Я искал способ использовать $' or $`вместо своих групп захвата, но не смог его найти, из-за этого" и всех тех, кто после него ". Спасибо за чаевые!
Дада
Ммм, ~$&le~$'должно быть на 1 короче
Тон Хоспел
5

JavaScript (ES6), 66 65 63 байта

Сохранено 2 байта благодаря @ edc65

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)
ETHproductions
источник
Подсказка: [...x,0]->[...x,p=t=z=0]
edc65
@ edc65 Спасибо, я не думал об этом!
ETHproductions
3

Mathematica, 38 байт

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

Анонимная функция. Принимает число как ввод и возвращает Trueили Falseкак вывод.

LegionMammal978
источник
3

Brachylog 2, 10 байт, языковые проблемы

ẹ~c<₁ᵐ!+ᵐ=

Попробуйте онлайн!

По сути, это тот же алгоритм, что и в ответе @ Fatalize (которого я не видел, пока не написал), но он несколько перестроен, чтобы сделать его более подходящим для синтаксиса Brachylog 2.

Это полная программа, возвращающая, false.если это не номер Дениса 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
Suever
источник
Хорошее использование &=!
Луис Мендо
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;

принимает входные данные из аргумента, завершает работу с 0номером Dennis-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
    ;
// 
Titus
источник
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

Попробуйте онлайн!

Emigna
источник
2

Ruby 2.3, 56 байт

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

Почти наверняка это не самый лучший способ сделать это, но он демонстрирует некоторые приятные языковые особенности.

(Не переносит перевод строки, поэтому бегите как ruby dennis2.rb <<< '12012')

histocrat
источник
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;

Я уверен, что есть гораздо более умный (и более короткий) способ сделать это, но пока он подойдет.

user59178
источник
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([3])

Если длина набора равна 1, все суммы одинаковы.

TFeld
источник
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, идентифицирующего пробег восходящих символов, в конце каждого рома он проверяет, всегда ли сумма одинакова

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

edc65
источник
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если не номер Дениса. Все целые числа будут считаться истинными в ruby, а также nilсчитается ложным. iцелое число, которое проверяется.

Третья версия на самом деле возвращается trueи false.

PS проверено, чтобы вернуть 172 целых числа от 1 до 1000, как в ответе.

akostadinov
источник
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


источник