Numeri super pieghevoli


10

Abbiamo già definito un numero pieghevole qui .

Ma ora definiremo un numero super pieghevole. Un numero Super Folding è un numero che se piegato abbastanza volte alla fine raggiungerà uno in meno di una potenza di due. Il metodo di piegatura è leggermente diverso rispetto alla domanda sul numero di piegatura.

L'algoritmo pieghevole è il seguente:

  • Prendi la rappresentazione binaria

    ad es. 5882

    1011011111010
    
  • Distribuito in tre partizioni. Prima metà, ultima metà e cifra centrale (se ha un numero dispari di cifre)

    101101 1 111010
    
  • Se la cifra centrale è zero, questo numero non può essere piegato

  • Invertire la seconda metà e sovrapporre la prima metà

    010111
    101101
    
  • Aggiungi le cifre sul posto

    111212
    
  • Se nel risultato ci sono 2 secondi, il numero non può essere piegato altrimenti il ​​nuovo numero è il risultato dell'algoritmo di piegatura.

Un numero è un numero Super Folding se può essere piegato in una stringa continua di quelli. (Tutti i numeri pieghevoli sono anche numeri super pieghevoli)

Il tuo compito è di scrivere un codice che accetta un numero e genera un valore di verità se il numero è un numero Super Folding e falsa in caso contrario. Sarai segnato sulla dimensione del tuo programma.

Esempi

5200

Converti in binario:

1010001010000

Dividi a metà:

101000 1 010000

Il mezzo è uno quindi continuiamo a sovrapporre le metà:

000010
101000

Li ho aggiunti:

101010

No due quindi continuiamo a dividere a metà:

101 010

Fold:

010
101

111

Il risultato è 111(7 in decimale) quindi questo è un numero super pieghevole.

Casi test

I primi 100 numeri super pieghevoli sono:

[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
A meno che non mi sbagli, come si è 3insinuato di nuovo nei casi di test? Non riesco a vedere come può essere piegato, dal momento che si divide 1 1, dando immediatamente un 2. O stai dicendo che ripiegarlo zero volte conta anche?
Geobits il

@geobits 3 dovrebbe essere lì. Ho controllato questa volta;). Tre è 11, quindi arriva solo a quelli con zero file
Ad Hoc Garf Hunter il

Penso che valga la pena mettere una nota proprio in alto, subito dopo aver collegato l'altra domanda sul numero di piegatura che sottolinea che le singole pieghe in questa domanda useranno un metodo diverso.
Jonathan Allan,

Risposte:


9

Ecco il mio primo colpo in assoluto al code golf:

Python 3, 167 byte

167 byte se per l'indentazione vengono utilizzate schede o spazi singoli

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

Modifica: grazie all'aiuto di tutti sotto, il codice sopra è stato ridotto da una dimensione originale di 232 byte!


1
Benvenuti in PPCG! È possibile salvare un sacco di byte rimuovendo gli spazi dopo la :s, e ritornando 0e 1invece di Truee False.
Steven H.

Grazie Steven. Inoltre, non sono sicuro al 100% di aver contato correttamente la lunghezza del byte.
Kapocsi,

1
Sto vedendo 232 byte. Dammi un secondo e posso provare a giocarci ancora un po '.
Steven H.

Ho usato questo per misurare: bytesizematters.com
Kapocsi

1
@Kapocsi, bytesizematters.com conta le righe errate. Confronta con mothereff.in , 5 cifre e 5 newline dovrebbero essere 10 byte, non i 14 che ho ottenuto per dimensione byte ... è 232.
Linus

5

Java 7, 202 byte

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

Ci è voluto un po 'di sforzo per rendere ripetibile la vecchia funzione di piegatura, ma eccola qui. È brutto come il peccato, a dire il vero. Dovrò dare un'occhiata al mattino per vedere se riesco a golf ulteriormente, dal momento che riesco a malapena a guardarlo in questo momento.

Con interruzioni di riga:

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 byte

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

Provalo online! o generare un elenco di numeri super pieghevoli fino a un determinato numero.
I tentativi di golf possono essere visti qui .


Il codice si suddivide nelle seguenti fasi:

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: questa versione più o meno adotta un approccio De Morgan's Law alla versione precedente.

* Il problema con l'esecuzione su singletons è che restiamo bloccati con una stringa vuota dopo lo slice.

** Se un numero binario è super pieghevole, la sua immagine speculare (con 0 iniziali se necessario) è. Ciò consente di risparmiare un byte nel prendere la metà giusta.


2

JavaScript, 149 byte

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``+"")

Definisce una funzione ricorsiva.

Spiegazione:

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)(O affettare la stringa invertita). Penso che se si cambiano i casi di fallimento e successo, è possibile utilizzare /0/.test(n)?f(...):1.
Neil,

2

JavaScript (ES6), 113 109 108 byte

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

Formattato e commentato

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

dimostrazione

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 byte

Include +1 per -p

Indicare il numero su STDIN

superfolding.pl:

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

1

Python 2, 151 byte

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

Ideone

Una funzione doppiamente ricorsiva che accetta un numero intero n, e restituisce 0o 1.

Viene rmantenuta una variabile per consentire sia il risultato della piegatura sia per sapere se attualmente: abbiamo un numero intero (solo primo); avere una nuova stringa binaria per provare a piegare (esterno); o stanno piegando (interno).

Al primo passaggio n è e intero, che è <''in Python 2, quindi la ricorsione inizia colando su una stringa binaria.

L'esecuzione successiva ha r=''e quindi il test {'1'}==set(n)viene eseguito per verificare la presenza di una stringa continua di 1s (l'RHS non può essere {n}poiché potremmo aver bisogno di passare questo punto in seguito con r=''e un vuoton quando quello sarebbe un dizionario che non sarà uguale {'1'}, un insieme).

Se questo non è soddisfatto, vengono testati i criteri della coda interna (anche se non necessari): se n in'1'valuterà True quando nè una stringa vuota o una singola 1, al che una nuova ricorsione esterna viene iniziata posizionando r, con la stringa binaria poi piegata in ne ''in r. Il letterale2 viene aggiunto al risultato di questa chiamata di funzione per consentire di non passare alla parte successiva (a destra di una logica or) che viene corretta in seguito.

Se questo non è un valore di verità (tutti i numeri interi diversi da zero sono veritieri in Python) vengono testati i criteri di ricorsione della coda esterna: n!=0esclude il caso con un centro 0e vengono testati i due caratteri esterni che non si sommano alla 2concatenazione di stringhe '11'!=n[0]+n[-1]; se entrambi sono veri, i bit esterni vengono scartati da ncon n[1:-1], e quindi 1viene aggiunto a rse ce n'è uno all'esterno altrimenti lo 0è, usando il fatto che '1'>'0'in Python con max(n[0],n[-1]).

Infine, l'aggiunta di 2ad ogni ricorsione interna viene corretta con %2.


0

PHP, 113 byte

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

esce con errore (codice 1) se l'argomento non è super-pieghevole, codice 0else. Corri con -r.
L'input 0restituirà true (codice 0).

abbattersi

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 byte

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

allargato

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

Valori reali <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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.