Денніс числа 2.0


54

Користувач PPCG та обраний мод, @Dennis просто став другим користувачем, який заробив понад 100 тис. Реп!

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

Це абсолютно оригінальна ідея, яку я не отримав від когось іншого , але давайте зробимо виклик, виходячи з його ідентифікатора користувача, 12012як данина!

Дивлячись на це, ви помітите, що до його посвідчення особи є два чіткі "секції".

12

і

012

Обидва ці розділи складають до 3. Це досить цікава властивість.

Давайте визначимо "число Денніса 2.0" як будь-яке додатне ціле число, де кожне максимальне подання суворо зростаючих цифр дорівнює одному і тому ж номеру. Наприклад,

123

є числом Dennis 2.0, оскільки існує лише один максимальний підпис під суттєво зростаючими цифрами, і він дорівнює 6. Крім того, 2846,145 також є числом Dennis 2.0, оскільки три максимальні підписи збільшуваних цифр, а саме

28
46
145

Усі суми до 10. Крім того, числа, які просто повторюють одну і ту ж цифру, повинні бути числами Dennis 2.0, оскільки, наприклад, 777їх можна розбити на

7
7
7

що, очевидно, все становить сім.

Таке число, як 42це не номер Dennis 2.0, оскільки воно розбито на

4
2

які явно не підсумовують однакову кількість.

Змагання

Ви повинні написати програму чи функцію, щоб визначити, чи є це число Dennis 2.0 чи ні. Ви можете приймати введення та вихід у будь-якому розумному форматі введення, наприклад, у вигляді рядка, у вигляді числа, з файлу, аргументів функцій / повернення, зі STDIN / STDOUT тощо, а потім повернути триєдне значення, якщо це число Dennis 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

Застосовуються стандартні лазівки, і найкоротша відповідь, виміряна в байтах, виграє!


1
Для довідки, Мартін Ендер був першим, хто отримав 100 тис. Респ
Ерік Аутгольфер

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.

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


Приємно, це дійсно розумна ідея. :-)
ETHproductions

Як і ця ідея! Але це не працює: console.log (f ("2011")); // false false console.log (f ("189")); // 18
user470370

3
@ user470370 - Я думаю, що це насправді правильно. Визначення вказує на "послідовності суворо зростаючих чисел" , тому 2011розбивається як 2 / 01 / 1і не є числом D2.0. Що стосується 189, це число D2.0 і 18є правдоподібним значенням.
Арнольд

Ups 😳 Звичайно, ви праві. Не розуміли цього раніше. Думаю, я повинен переробити власне рішення: D
user470370

15

Пітон, 50 байт

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

Розраховує input()оцінити рядок, тому вхід потребує оточуючих лапок в Python 2. Вихід здійснюється за допомогою коду виходу , де 0 вказує на успіх (truthy), а 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, який дає помилкове значення при оцінці, оскільки умови мають суми 6 та 12 . Поділ 1 на False ( 0 ) викликає ZeroDivisionError ; програма виходить із помилкою.

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

    Наприклад, ціле число 94536 приводить до виразу 6++3==5++4==9++0, який дає значення True при оцінці, оскільки всі доданки мають суму 9 . Як і раніше, програма виходить нормально.

    З іншого боку, ціле число 17263 приводить до виразу 3==6++2==7++1++0, який дає помилкове значення при оцінці, оскільки умови мають суми 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 спочатку об’єднається з найбільшими сублістами.


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Проводиться через нього як- масив, кожна ітерація розміщуючи поточний елемент з a +або -eqперед ним на трубопроводі, виходячи з того, чи є поточне значення -less- or-qual eвід попереднього значення $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

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, якщо число - це номер Dennis 2.0 або порожній рядок інакше:

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

1
Я думаю, що це, мабуть, найкращий підхід у perl, але ви можете s%.%2x$&.($&.O ge$')%eg;$_=/^(2+1)\1*$/-p$'
пограти в

Дійсно, використовувати результат порівняння замість цього випадкового 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)

Підказка: [...x,0]->[...x,p=t=z=0]
edc65

@ edc65 Спасибі, я про це не думав!
ETHproductions

3

Математика, 38 байт

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

Анонімна функція. Приймає число як вхід, а повертає Trueабо Falseяк вихід.


3

Брахілог 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) порядок за замовчуванням визначається першим предикатом у програмі (використовуючи другий як tiebreak тощо), тут ~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;

приймає дані з аргументу, виходить з 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
    ;
// 

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

Рубін 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,

Evals і перетворює на встановлення.

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, визначаючи пробіг висхідних знаків, в кінці кожного рому перевіряє, чи сума завжди однакова

  • c: поточний знак
  • p: попереднє char
  • 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]

Це поверне ціле число цього числа dennis або nilякщо не число dennis. Всі цілі числа вважатимуться істинними в рубіні, а nilтакож вважаються помилковими. iце ціле число, яке перевіряється.

Третя версія фактично повертає trueі false.

PS перевірено, щоб повернути 172 цілі числа від 1 до 1000, як у відповіді.


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

Далі ми використовуємо функцію helper. Як діадічно (приймає 2 аргументу), він веде себе трохи по- іншому , коли в парі з кожним оператором, . Діадичні функції виводять значення зі стека і прив'язують це значення як їх правильний аргумент для створення часткової монадичної функції. Потім ця часткова функція відображається над кожним елементом аргументу. Тут зв'язаним правим аргументом є цифри введення, а часткова функція відображається на .g A ggA

g(x,y)

Давайте розглянемо лише одну ітерацію де і . Зауважте, що - перший показник уx : = [ 1 , 2 , 0 , 1 , 2 ] y = 3 3g(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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.