Супер складаються номери


10

Ми вже визначили ряд складаний тут .

Але тепер ми будемо визначати Суперскладний номер. Суперскладне число - це число, яке, якщо складеться достатньо разів, в кінцевому підсумку досягне одного менше, ніж потужність у два. Метод складання дещо інший, ніж у питанні про складне число.

Алгоритм складання складається так:

  • Візьміть бінарне подання

    наприклад 5882

    1011011111010
    
  • Розлили його на три перегородки. Перша половина, остання половина та середня цифра (якщо вона має непарну кількість цифр)

    101101 1 111010
    
  • Якщо середня цифра дорівнює нулю, це число неможливо скласти

  • Переверніть другу половину і накладіть на першу половину

    010111
    101101
    
  • Додайте цифри на місці

    111212
    
  • Якщо в результаті є 2s, число не можна скласти, інакше нове число є результатом алгоритму складання.

Число - це суперскладне число, якщо його можна скласти до суцільного рядка з них. (Усі номери складання також є Super Folding Numbers)

Ваше завдання полягає в тому, щоб записати код, який приймає число, і виводить триєдне значення, якщо число є Super Folding числом, а в іншому випадку помилковим. Вам буде набрано розмір вашої програми.

Приклади

5200

Перетворити у двійкове:

1010001010000

Розділіть навпіл:

101000 1 010000

Середина одна, і ми продовжуємо Накладати половинки:

000010
101000

Додано їх:

101010

Немає двох, тому ми продовжуємо Спліт навпіл:

101 010

Складіть:

010
101

111

Результат 111(7 у десятковій частині), тож це суперскладне число.

Випробування

Першими 100 супер складаними номерами є:

[1, 2, 3, 6, 7, 8, 10, 12, 15, 20, 22, 28, 31, 34, 38, 42, 48, 52, 56, 63, 74, 78, 90, 104, 108, 120, 127, 128, 130, 132, 142, 150, 160, 170, 178, 192, 204, 212, 232, 240, 255, 272, 274, 276, 286, 310, 336, 346, 370, 400, 412, 436, 472, 496, 511, 516, 518, 524, 542, 558, 580, 598, 614, 640, 642, 648, 666, 682, 704, 722, 738, 772, 796, 812, 852, 868, 896, 920, 936, 976, 992, 1023, 1060, 1062, 1068, 1086, 1134, 1188, 1206, 1254, 1312, 1314, 1320, 1338, 1386, 1440, 1458, 1506, 1572, 1596]

2
Якщо я не помиляюся, як я знову 3проник у тестові справи? Я не бачу, як його можна скласти, оскільки він розпадається 1 1, одразу ж даючи 2. Або ви хочете сказати, що складання його в нуль разів теж вважається?
Геобіц

@geobits 3, як передбачається, буде там. Я перевірив цього разу;). Три - це 11, тож вони дістаються лише до нульових файлів
Ad Hoc Garf Hunter

Я думаю, що варто було б помістити примітку прямо вгорі, одразу після того, як ви посилаєтесь на інше запитання про номер складання, яке вказує на те, що окремі складки в цьому запитанні будуть використовувати інший метод.
Джонатан Аллан

Відповіді:


9

Ось мій перший в історії вистрілений гольф з кодом:

Python 3, 167 байт

167 байт, якщо для відступу використовуються вкладки або одинарні пробіли

def f(n):
 B=bin(n)[2:];L=len(B);M=L//2
 if'1'*L==B:return 1
 S=str(int(B[:M])+int(B[:-M-1:-1]))
 return 0if(~L%2==0and'0'==B[M])or'2'in S else{S}=={'1'}or f(int(S,2))

Редагувати: Завдяки допомозі кожного, наведеному нижче, код вище було зменшено з початкового розміру 232 байт!


1
Ласкаво просимо до PPCG! Ви можете зберегти купу байтів, видаливши пробіли після :s, а також повернувшись 0і 1замість Trueі False.
Стівен Х.

Дякую, Стівен Також я не на 100% впевнений, що правильно порахував довжину байтів.
Капочсі

1
Я бачу 232 байти. Дайте мені секунду, і я можу спробувати пограти в неї трохи далі.
Стівен Х.

Я використовував це для вимірювання: bytesizematters.com
Kapocsi

1
@Kapocsi, bytesizematters.com неправильно вважає нові рядки. Порівняйте з mothereff.in , 5 цифр і 5 нових рядків мають бути 10 байтами, а не 14, що я отримав на байтазі ... його 232.
Лінус

5

Java 7, 202 байти

boolean g(Integer a){byte[]b=a.toString(a,2).getBytes();int i=0,l=b.length,o=0,c,z=(a+1&a)==0?-1:1;for(;i<l/2&z>0;o+=o+c*2,z*=c>1|(l%2>0&b[l/2]<49)?0:1)c=b[i]+b[l-++i]-96;return z<0?1>0:z<1?0>1:g(o/2);}

Потрібно було трохи зусиль, щоб стара функція складання повторювалась, але ось вона. Чесно, як гріх, якщо чесно. Мені доведеться поглянути вранці, щоб побачити, чи зможу я далі пограти в гольф, оскільки я ледве витримую, щоб подивитися на це зараз.

З розривами рядків:

boolean g(Integer a){
    byte[]b=a.toString(a,2).getBytes();
    int i=0,l=b.length,o=0,c,z=(a+1&a)==0?-1:1;
    for(;i<l/2&z>0;o+=o+c*2,z*=c>1|(l%2>0&b[l/2]<49)?0:1)
        c=b[i]+b[l-++i]-96;
    return z<0?1>0:z<1?0>1:g(o/2);
}

3

CJam , 47 44 байт

ri2b{_W%.+__0e=)\_,1>\0-X+:*3<*&}{_,2/<}w2-!

Спробуйте в Інтернеті! або генерувати список надскладних чисел до заданого числа.
Спроби гольфу можна побачити тут .


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

ri2b                e# get input in binary
{                   e# While fold is legal
 _W%.+_             e#   "fold" the whole number onto itself
 _0e=)\             e#   count zeros and add 1 (I)
 _,1>\              e#   size check, leave 0 if singleton (II)*
 0-X+:*3<           e#   product of 2s, leave 0 if too many (III)
 *&                 e#   (II AND III) AND parity of I
}{                  e# Do
 _,2/<              e#   slice opposite to the actual fold**
}w                  e# End while
2-!                 e# return 1 if "fold" ended in all 2s

EDIT: Ця версія більш-менш використовує підхід Закону Де Моргана до попередньої версії.

* Проблема із запуском на одиночних кнопках полягає в тому, що ми застрягли з порожнім рядком після фрагмента.

** Якщо двійкове число є надзвичайно складним, його дзеркальне зображення (при необхідності провідні 0). Це економить байт над захопленням правої половини.


2

JavaScript, 149 байт

f=(i,n=i.toString(2),l=n.length,m=l/2|0)=>/^1*$/.test(n)?1:/[^01]/.test(n)|!+n[m]&l?0:f(0,+n.slice(0,m)+ +n.slice(m+l%2).split``.reverse().join``+"")

Визначає рекурсивну функцію.

Пояснення:

f=(i                       //Defines the function: i is input
,n=i.toString(2)           //n is the current number
,l=n.length                //l is the length of the number,
,m=l/2|0)=>                //m is the index of the center character
/^1*$/.test(n)?1:          //returns 1 if the number is all ones
/[^01]/.test(n)            //returns 0 if the number has any chars other than 0 or 1
|!+n[m]&l?0:               //or if the middle char is 0
f(0,+n.slice(0,m)+ +n.slice(m+l%2).split``.reverse().join``+"")
                           //otherwise recurses using the first half of the number plus the second half

m=l>>1, /2/.test(n), n.slice(l-m)(Або скибочку перевернуте рядок). Я думаю, що якщо ви переключите випадки відмови та успіху, ви можете використовувати /0/.test(n)?f(...):1.
Ніл

2

JavaScript (ES6), 113 109 108 байт

f=(n,[h,...r]=n.toString(2),b='')=>++n&-n-n?h?f(2,r,r[0]?b+(h- -r.pop()):+h?b:2):!isNaN(n=+('0b'+b))&&f(n):1

Відформатовано та прокоментовано

f = (                               // given:
  n,                                // - n = integer to process
  [h, ...r] = n.toString(2),        // - h = highest bit, r = remaining low bits
  b = ''                            // - b = folded binary string
) =>                                //
  ++n & -n - n ?                    // if n is not of the form 2^N - 1:
    h ?                             //   if there's still at least one bit to process:
      f(                            //     do a recursive call with:
        2,                          //     - n = 2 to make the 2^N - 1 test fail
        r,                          //     - r = remaining bits
        r[0] ?                      //     - if there's at least one remaining low bit:
          b + (h - -r.pop())        //       append sum of highest bit + lowest bit to b
        : +h ? b : 2                //       else, h is the middle bit: let b unchanged
      )                             //       if it is set or force error if it's not
    : !isNaN(n = +('0b' + b)) &&    //   else, if b is a valid binary string:
      f(n)                          //     relaunch the entire process on it
  : 1                               // else: n is a super folding number -> success

Демо

f=(n,[h,...r]=n.toString(2),b='')=>++n&-n-n?h?f(2,r,r[0]?b+(h- -r.pop()):+h?b:2):!isNaN(n=+('0b'+b))&&f(n):1

// testing integers in [1 .. 99]
for(var i = 1; i < 100; i++) {
  f(i) && console.log(i);
}

// testing integers in [1500 .. 1599]
for(var i = 1500; i < 1600; i++) {
  f(i) && console.log(i);
}


2

Perl, 71 70 байт

Включає +1 для -p

Наведіть номер на STDIN

superfolding.pl:

#!/usr/bin/perl -p
$_=sprintf"%b",$_;s%.%/\G0$/?2:/.\B/g&&$&+chop%eg while/0/>/2/;$_=!$&

1

Python 2, 151 байт

f=lambda n,r=0:f(bin(n)[2:],'')if r<''else(r==''and{'1'}==set(n)or(n in'1'and f(r,'')+2)or n!='0'and'11'!=n[0]+n[-1]and f(n[1:-1],r+max(n[0],n[-1])))%2

ідеоне

Подвійно-рекурсивна функція, яка приймає ціле число n, і повертає 0або 1.

Змінна rпідтримується, щоб дозволити як результат складання, так і знати, чи є ми в даний час: маємо ціле число (лише перше); мати новий двійковий рядок, який слід спробувати скласти (зовнішній); або складаються (внутрішні).

На першому проході nє і ціле число, яке знаходиться <''в Python 2, тому рекурсія починається з переведення на бінарний рядок.

Наступне виконання має r=''і тому тест {'1'}==set(n)виконується, щоб перевірити наявність суцільної рядки 1s (RHS не може бути, {n}як нам може знадобитися передати цю точку пізніше r=''і порожнім, nколи це буде словник, який звичайно рівний {'1'}, безліч).

Якщо цього не виконано, внутрішні хвістні критерії перевіряються на (навіть якщо вони не потрібні): якщо n in'1'буде оцінено на Істинне, коли nце порожній рядок або одиничний 1, після чого починається нова зовнішня рекурсія, розміщуючи r, потім складений, двійковий рядок у nі ''в r. Літерал 2додається в результат цього виклику функції, щоб не допустити проникнення до наступної частини (праворуч від логічної or), яка буде виправлена ​​пізніше.

Якщо це не значення truthy (усі ненульові цілі числа є truthy у Python), критерії рекурсії зовнішнього хвоста перевіряються на: n!=0виключається випадок із серединою, 0а зовнішні два символи перевіряються, вони не підсумовуються 2шляхом конкатенації рядків '11'!=n[0]+n[-1]; якщо вони і справедливі зовнішні біти видаляються з nс n[1:-1], а потім 1додаються , rякщо є один на зовнішній стороні в іншому випадку 0це, використовуючи той факт , що '1'>'0'в Python з max(n[0],n[-1]).

Нарешті доповнення 2при кожній внутрішній рекурсії виправляється за допомогою %2.


0

PHP, 113 байт

for($n=$argv[1];$n!=$c;$n=($a=$n>>.5+$e)|($b=$n&$c=(1<<$e/=2)-1))if($a&$b||($e=1+log($n,2))&!(1&$n>>$e/2))die(1);

виходить з помилкою (кодом 1), якщо аргумент не надто складний, код 0інший Бігайте з -r.
Введення 0поверне вірно (код 0).

зламатися

for($n=$argv[1];            
    $n!=$c;                 // loop while $n is != mask
                            // (first iteration: $c is null)
    $n=                     // add left half and right half to new number
        ($a=$n>>.5+$e)      // 7. $a=left half
        |
        ($b=$n&             // 6. $b=right half
            $c=(1<<$e/=2)-1 // 5. $c=mask for right half
        )
)
    if($a&$b                // 1. if any bit is set in both halves
                            // (first iteration: $a and $b are null -> no bits set)
        ||                  // or
        ($e=1+log($n,2))    // 2. get length of number
        &
        !(1&$n>>$e/2)       // 3. if the middle bit is not set -> 1
                            // 4. tests bit 0 in length --> and if length is odd
    )
    die(1);                 // -- exit with error

0

PHP, 197 байт

function f($b){if(!$b)return;if(!strpos($b,"0"))return 1;for($n="",$i=0;$i<($l=strlen($b))>>1;)$n.=$b[$i]+$b[$l-++$i];if($l%2&&!$b[$i]||strstr($n,"2"))return;return f($n);}echo f(decbin($argv[1]));

Розширено

function f($b){
    if(!$b)return; # remove 0
    if(!strpos($b,"0"))return 1; # say okay alternative preg_match("#^1+$#",$b)
    for($n="",$i=0;$i<($l=strlen($b))>>1;)$n.=$b[$i]+$b[$l-++$i]; #add first half and second reverse
    if($l%2&&!$b[$i]||strstr($n,"2"))return; #if middle == zero or in new string is a 2 then it's not a number that we search
    return f($n); #recursive beginning
}
echo f(decbin($argv[1]));

Справжні значення <10000

1, 2, 3, 6, 7, 8, 10, 12, 15, 20, 22, 28, 31, 34, 38, 42, 48, 52, 56, 63, 74, 78, 90, 104, 108, 120, 127, 128, 130, 132, 142, 150, 160, 170, 178, 192, 204, 212, 232, 240, 255, 272, 274, 276, 286, 310, 336, 346, 370, 400, 412, 436, 472, 496, 511, 516, 518, 524, 542, 558, 580, 598, 614, 640, 642, 648, 666, 682, 704, 722, 738, 772, 796, 812, 852, 868, 896, 920, 936, 976, 992, 1023, 1060, 1062, 1068, 1086, 1134, 1188, 1206, 1254, 1312, 1314, 1320, 1338, 1386, 1440, 1458, 1506, 1572, 1596, 1644, 1716, 1764, 1824, 1848, 1896, 1968, 2016, 2047, 2050, 2054, 2058, 2064, 2068, 2072, 2110, 2142, 2176, 2180, 2184, 2222, 2254, 2306, 2320, 2358, 2390, 2432, 2470, 2502, 2562, 2576, 2618, 2650, 2688, 2730, 2762, 2866, 2898, 2978, 3010, 3072, 3076, 3080, 3132, 3164, 3244, 3276, 3328, 3380, 3412, 3492, 3524, 3584, 3640, 3672, 3752, 3784, 3888, 3920, 4000, 4032,4095, 4162, 4166, 4170, 4176, 4180, 4184, 4222, 4318, 4416, 4420, 4424, 4462, 4558, 4674, 4688, 4726, 4822, 4928, 4966, 5062, 5186, 5200, 5242, 5338, 5440, 5482, 5578, 5746, 5842, 5986, 6082, 6208, 6212, 6216, 6268, 6364, 6508, 6604, 6720, 6772, 6868, 7012, 7108, 7232, 7288, 7384, 7528, 7624, 7792, 7888, 8032, 8128, 8191, 8202, 8206, 8218, 8232, 8236, 8248, 8318, 8382, 8456, 8460, 8472, 8542, 8606, 8714, 8744, 8814, 8878, 8968, 9038, 9102, 9218, 9222, 9234, 9248, 9252, 9264, 9334, 9398, 9472, 9476, 9488, 9558, 9622, 9730, 9760, 9830, 9894, 99848128, 8191, 8202, 8206, 8218, 8232, 8236, 8248, 8318, 8382, 8456, 8460, 8472, 8542, 8606, 8714, 8744, 8814, 8878, 8968, 9038, 9102, 9218, 9222, 9234, 9248, 9252, 9264, 9334, 9398, 9472, 9476, 9488, 9558, 9622, 9730, 9760, 9830, 9894, 99848128, 8191, 8202, 8206, 8218, 8232, 8236, 8248, 8318, 8382, 8456, 8460, 8472, 8542, 8606, 8714, 8744, 8814, 8878, 8968, 9038, 9102, 9218, 9222, 9234, 9248, 9252, 9264, 9334, 9398, 9472, 9476, 9488, 9558, 9622, 9730, 9760, 9830, 9894, 9984

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