Numeri split, flip e ricombine


16

sfondo

È ben noto in matematica che gli interi possono essere messi in una corrispondenza uno a uno con coppie di interi. Ci sono molti modi possibili per farlo, e in questa sfida, implementerai uno di essi e la sua operazione inversa.

L'obiettivo

Il tuo input è un numero intero positivo n > 0. È noto che esistono numeri interi non negativi univoci a, b ≥ 0tali . Il tuo output è la "versione capovolta" di , il numero intero positivo .n == 2a * (2*b + 1)n2b * (2*a + 1)

Puoi presumere che l'input e l'output si adattino al tipo di dati intero senza segno standard della tua lingua.

Regole e punteggio

È possibile scrivere un programma completo o una funzione. Vince il conteggio di byte più basso e non sono consentite scappatoie standard.

Casi test

Questi sono indicati nel formato in <-> out, poiché la funzione da implementare è la sua inversa: se gli restituisci l'output, dovresti ottenere l'input originale.

1 <-> 1
2 <-> 3
4 <-> 5
6 <-> 6
7 <-> 8
9 <-> 16
10 <-> 12
11 <-> 32
13 <-> 64
14 <-> 24
15 <-> 128
17 <-> 256
18 <-> 48
19 <-> 512
20 <-> 20
28 <-> 40
30 <-> 384
56 <-> 56
88 <-> 224
89 <-> 17592186044416

Classifica

Ecco uno snippet di stack per generare sia una classifica regolare che una panoramica dei vincitori per lingua. Per assicurarti che la tua risposta venga visualizzata, ti preghiamo di iniziare la risposta con un titolo, usando il seguente modello Markdown:

## Language Name, N bytes

dov'è Nla dimensione del tuo invio. Se si migliora il punteggio, è possibile mantenere i vecchi punteggi nel titolo, colpendoli. Per esempio:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Se si desidera includere più numeri nell'intestazione (ad es. Perché il punteggio è la somma di due file o si desidera elencare separatamente le penalità del flag dell'interprete), assicurarsi che il punteggio effettivo sia l' ultimo numero nell'intestazione:

## Perl, 43 + 2 (-p flag) = 45 bytes

Puoi anche rendere il nome della lingua un collegamento che verrà quindi visualizzato nello snippet della classifica:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


1
Divertente, questo problema è stato pubblicato su anarchy golf la scorsa settimana
febbraio

@feersum Oh, non ne ero a conoscenza. Che coincidenza.
Zgarb,

2
Obbligatorio xkcd.com/153
corsiKa

Risposte:


11

Gelatina , 17 16 15 byte

BUi1µ2*³:2*×Ḥ’$

Provalo online!

Come funziona

BUi1µ2*³:2*×Ḥ’$    Main link. Input: n

B                  Convert n to base 2.
 U                 Reverse the array of binary digits.
  i1               Get the first index (1-based) of 1.
                   This yields a + 1.
    µ              Begin a new, monadic chain. Argument: a + 1
     2*            Compute 2 ** (a+1).
       ³:          Divide n (input) by 2 ** (a+1).
                   : performs integer division, so this yields b.
         2*        Compute 2 ** b.
              $    Combine the two preceding atoms.
            Ḥ      Double; yield 2a + 2.
             ’     Decrement to yield 2a + 1.
           ×       Fork; multiply the results to the left and to the right.

Aspetta, stai implementando operatori in Jelly per soddisfare il problema? In quel caso LOL
Alexander Torstling,

Io non sono. L' unico impegno con Jelly dopo che questa sfida è stata pubblicata è stato un aggiornamento della documentazione e tutto l'operatore utilizzato in questa risposta è stato implementato per almeno un mese. Sentiti libero di verificare
Dennis,

Non preoccuparti, non ho familiarità con le regole o altro, ho solo pensato che fosse bello che il golf fosse arrivato alle persone che inventavano le loro lingue!
Alexander Torstling,


10

Pyth, 16 15 byte

*hyJ/PQ2^2.>QhJ

1 byte grazie a Dennis

Suite di test

Spiegazione:

*hyJ/PQ2^2.>QhJ
                    Implicit: Q = eval(input())
     PQ             Take the prime factorization of Q.
    /  2            Count how many 2s appear. This is a.
   J                Save it to J.
  y                 Double.
 h                  +1.
          .>QhJ     Shift Q right by J + 1, giving b.
        ^2          Compute 2 ** b.
*                   Multiply the above together, and print implicitly.

7

MATL , 22 byte

Yft2=XK~)pq2/2w^Ks2*Q*

Provalo online!

Spiegazione

Yf      % factor
t       % duplicate
2=      % compare to 2 (yields a logical array)
XK      % save a copy of that to variable K
~)      % keep only values != 2 in the factors array
p       % multiply that factors
q2/     % product - 1 / 2
2w^     % 2^x

K       % load variable K (the logical array)
s       % sum (yields the number of 2s)
2*Q     % count * 2 + 1

*       % multiply both values

Molto bella! È possibile utilizzare Qper 1+(questo è stato introdotto di recente) e qper 1-. Ciò consente anche di risparmiare uno spazio (che è possibile salvare Hcomunque). Vedi qui
Luis Mendo,

@LuisMendo Grazie. Non conoscevo quella funzione.
Rainer P.

5
Ben fatto battere Luis usando MATL!
Stewie Griffin,

6

Python 2, 39 byte

lambda n:2*len(bin(n&-n))-5<<n/2/(n&-n)

n & -ndà la potenza maggiore di 2 che divide n. Funziona perché in complemento a due aritmetica, -n == ~n + 1. Se nha k zeri finali, prendere il suo complemento farà sì che abbia k trailing. Quindi l'aggiunta di 1 cambierà tutti quelli finali in zero e cambierà il bit 2 ^ k da 0 a 1. Quindi -ntermina con un 1 seguito da k 0 (proprio come n), pur avendo il bit opposto nin tutti i punti più alti.


puoi spiegare brevemente come n&-nfunziona? vedo cosa fa questo trucco ma non come :(
Erwan,

n&-nrestituisce la massima potenza di 2 che si divide n.
Neil,

@Erwan ho spiegato n & -n.
feersum

Avevo ottenuto il programma corrispondente sul golf Anarchy n=1;exec"c=n&-n;print n,':',2*len(bin(c))-5<<n/2/c;n+=1;"*100, ma sono due caratteri dietro la migliore soluzione.
xnor

@xnor Suggerimento: la soluzione a 59 byte (beh, almeno la mia) non funziona per tutti i valori di n.
feersum

6

MATL , 25 26 byte

:qt2w^w!2*Q*G=2#f2*q2bq^*

Questo usa attuale versione (10.2.1) del linguaggio / compilatore.

Provalo online!

Spiegazione

Abbastanza semplice, basato sulla forza bruta. Prova tutte le combinazioni di un e b , seleziona quella appropriata e fa il calcolo richiesto.

:q          % implicit input "n". Generate row vector [0,1,...,n-1], say "x"
t2w^        % duplicate and compute 2^x element-wise
w!2*Q       % swap, transpose to column vector, compute 2*x+1
*           % compute all combinations of products. Gives 2D array
G=2#f       % find indices where that array equals n
2*q2bq^*    % apply operation to flipped values

1
Hah! :-P Hai battuto nella tua lingua ... la prima volta?
Stewie Griffin,

@StewieGriffin Yep! Un bel traguardo :-)
Luis Mendo il

5

Julia, 41 byte

n->2^(n>>(a=get(factor(n),2,0)+1))*(2a-1)

Questa è una funzione anonima che accetta un numero intero e restituisce un numero intero. Per chiamarlo, assegnarlo a una variabile.

Definiamo a1 + l'esponente di 2 nella scomposizione in fattori primi di n. Dal momento che factori rendimenti di una Dict, siamo in grado di utilizzare getcon un valore predefinito di 0 nel caso in cui la fattorizzazione primo non contiene 2. spostamento a destra po ' nda a, e prendere 2 a questo potere. Moltipliciamo questo 2a-1per ottenere il risultato.


4

Perl 5, 40 byte

38 byte più 2 per -p

$i++,$_/=2until$_%2;$_=2*$i+1<<$_/2-.5

-plegge lo STDIN nella variabile $_.

$i++,$_/=2until$_%2incrementi $i(che inizia da 0) e si dimezza $_fino a quando $_non è diverso da zero 2. Successivamente, $_è il fattore dispari del numero originale ed $iè l'esponente di 2.

$_=2*$i+1<<$_/2-.5- Il lato destro di =è solo la formula per il numero cercato: {1 più del doppio dell'esponente di 2} volte {2 alla potenza di {metà del fattore dispari meno una metà}}. Ma "times {2 alla potenza di ...}" viene giocato come "spostato verso sinistra da ...". E quel lato destro è assegnato a$_ .

E -pstampe $_.



2

JavaScript ES6, 36 33 byte

n=>63-2*Math.clz32(b=n&-n)<<n/b/2

La mia comprensione è che Math.clz32sarà più breve che armeggiare toString(2).length.

Modifica: salvato 3 byte grazie a @ user81655.


Bello. È inoltre possibile salvare alcuni byte impostando n&-nuna variabile:n=>63-2*Math.clz32(x=n&-n)<<n/x/2
user81655

@ user81655 Grazie; Vorrei solo che avrei potuto usare n&=-n, ma ho bisogno di nnuovo ...
Neil,

1

PARI / GP , 38 byte

f(n)=k=valuation(n,2);(2*k+1)<<(n>>k\2)

Si noti che >>e \hanno la stessa precedenza e sono calcolati da sinistra a destra, quindi l'ultima parte può essere n>>k\2piuttosto che (n>>k)\2. La versione ungolf avrebbe reso klessicale con my:

f(n)=
{
  my(k=valuation(n,2));
  (2*k+1) << ((n>>k)\2);
}
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.