Ogni possibile durata del ciclo


21

Si può dire che una funzione (o programma) che accetta input e fornisce output abbia un ciclo se chiamare la funzione sul proprio output alla fine raggiunge ripetutamente il numero originale. Ad esempio, prendi la seguente funzione:

Input:  n    1 2 3 4 5 6
Output: f(n) 5 7 1 3 4 9

Se cominciamo con n=1, f(n)=5, f(f(n))=f(5)=4, f(f(f(n)))=f(4)=3, f(f(f(f(n))))=f(3)=1.

Questo è scritto (1 5 4 3). Poiché ci sono 4 numeri univoci in questo ciclo, questo è un ciclo di lunghezza 4.


La tua sfida è scrivere un programma o una funzione che abbia cicli di ogni possibile lunghezza. Cioè, ci deve essere un ciclo di lunghezza 1, di lunghezza 2 e così via.

Inoltre, la tua funzione / programma deve essere dagli interi positivi agli interi positivi e deve essere biiettiva , il che significa che deve esserci esattamente un valore di input per ogni possibile valore di output, su tutti i numeri interi positivi. Per dirla in altro modo, la funzione / programma deve calcolare una permutaione degli interi positivi.


Dettagli: è consentito qualsiasi sistema di input / output standard, inclusi STDIN, STDOUT, argomento della funzione, ritorno, ecc. Sono vietate le scappatoie standard.

Non è necessario preoccuparsi delle limitazioni dei tipi di dati: le proprietà sopra riportate devono essere valide solo supponendo che un into floatpossa contenere qualsiasi valore, ad esempio.

Non ci sono restrizioni sul comportamento della funzione sugli ingressi che non sono numeri interi positivi e tali ingressi / uscite verranno ignorati.


Il punteggio è il golf del codice in byte, il codice più corto vince.


"deve esserci un ciclo di lunghezza 1, di lunghezza 2 e così via" Dovrebbe essere interpretato come "deve esserci almeno un ciclo di lunghezza 1, almeno uno di lunghezza 2 e così via" o " essere esattamente un ciclo di lunghezza 1, uno di lunghezza 2 e così via ".
Bakuriu,

@Bakuriu Almeno un ciclo per ogni lunghezza positiva.
isaacg,

Risposte:


11

Pyth, 11 8 byte

.<W-0zz1

Molto più noioso della mia precedente risposta.

Ogni numero che contiene una cifra 0 viene mappato su se stesso. Qualsiasi altro numero è associato al numero con le cifre ruotate di 1. Quindi, ad esempio:

1 -> 1
10 -> 10
15 -> 51 -> 15
104 -> 104
123 -> 231 -> 312 -> 123

8

Python 2, 56 55 54 byte

n=input()
a=b=1
while a+b<=n:a+=b;b+=1
print(n+~a)%b+a

Ecco le prime 21 uscite:

[1, 3, 2, 6, 4, 5, 10, 7, 8, 9, 15, 11, 12, 13, 14, 21, 16, 17, 18, 19, 20]

Lo schema è ovvio se suddividiamo l'elenco in pezzi in questo modo:

 1    2  3    4  5  6    7  8  9  10    11  12  13  14  15    16  17  18  19  20  21
[1]  [3, 2]  [6, 4, 5]  [10, 7, 8, 9]  [15, 11, 12, 13, 14]  [21, 16, 17, 18, 19, 20]

Accidenti, questo è lo schema che stavo anche cercando, ma con una forma chiusa.
orlp,

1
Interessante .. i valori a seguono la sequenza A000124 . Ma immagino lo sapessi già: P
Kade,

Nota che questa sequenza è oeis.org/A066182 .
orlp,

8

Pyth, 25 byte

+hK/*J/h@h*8tQ2 2tJ2%-QKJ

Questa è la stessa sequenza di @ Sp3000, ma con un modulo chiuso. Il modulo chiuso è:

M (n) = piano ((1 + sqrt (1 + 8 * (n - 1))) / 2) B (n) = M (n) * (M (n) - 1) / 2 f (n) = B (n) + ((n - B (n) + 1) mod M (n))


5

Python3, 40 byte

n=input();print([n[1:]+n[0],n]['0'in n])

Ogni numero che contiene una cifra 0 viene mappato su se stesso. Qualsiasi altro numero è associato al numero con le cifre ruotate di 1. Quindi, ad esempio:

1 -> 1
10 -> 10
15 -> 51 -> 15
104 -> 104
123 -> 231 -> 312 -> 123

1
Già visto! Fantastico vederlo in due lingue!
Denham Coote,

3

Rubino, 22 + 1 = 23

Con flag della riga di comando -p, eseguire

~/(.)(.?)/
$_=$1+$'+$2

Quando viene fornita come input una rappresentazione in forma di stringa di un numero (senza nuova riga finale), mantiene costante la prima cifra, quindi ruota il resto a sinistra, quindi 1234diventa 1342.

Questo può essere ridotto a 21 caratteri con $_=$1+$'+$2if/(.)(.)/, ma stampa un avviso.


3

Rubino, 16 + 1 = 17

Con flag della riga di comando -p, eseguire

$_=$_[/.0*$/]+$`

Questa è una funzione più complicata dell'altra mia risposta, ma sembra essere più giocabile (e tollerante nei confronti delle nuove linee). Prende l'ultima cifra diversa da zero dell'input, più eventuali zero finali e la sposta all'inizio del numero. Così 9010300diventa 3009010. Qualsiasi numero con n cifre non zero farà parte di un ciclo di lunghezza n.

L'input è una stringa in qualsiasi base tramite STDIN, l'output è una stringa in quella base.


2

Python, 43

L' inverso della funzione di Sp3000 , implementata in modo ricorsivo.

f=lambda n,k=1:n>k and k+f(n-k,k+1)or n%k+1

La funzione è un ciclo seguito da un due cicli seguito da un tre cicli, ...

(1)(2 3)(4 5 6)(7 8 9 10)(11 12 13 14 15)...

L'operazione n%k+1funge da kciclo sui numeri 1..k. Per trovare l'appropriato kda usare, sposta tutto verso il basso di k=1, quindi k=2e così via, fino a quando n<=k.


2

Pyth, 15 byte

La risposta più breve finora che utilizza operazioni numeriche anziché operazioni di stringa.

.|.&Q_=.&_=x/Q2

    Q                input
            /Q2      input div 2
           x   Q     that XOR input
          =          assign that to Q
         _           negate that
       .&       Q    that AND Q
      =              assign that to Q
     _               negate that
  .&                 input AND that
.|               Q   that OR Q

L'effetto di questa funzione sulla rappresentazione binaria è di estendere il blocco più a destra di 1s al prossimo 0; o se non c'è 0, per reimpostarlo su un singolo 1:

10010110100000 ↦  
10010110110000 ↦  
10010110111000 ↦  
10010110111100 ↦  
10010110111110 ↦  
10010110111111 ↦
10010110100000  

Pyth, 26 byte, variante divertente

.|.&Q_h.&/Q2+Qy=.&/Q2_h.|y

    Q                           input
         /Q2                    input div 2
             Q                  input
                  /Q2           input div 2
                         yQ     twice input
                       .|  Q    that OR input
                     _h         NOT that
                .&              (input div 2) AND that
               =                assign that to Q
              y                 twice that
            +                   input plus that
       .&                       (input div 2) AND that
     _h                         NOT that
  .&                            input AND that
.|                          Q   that OR Q

Esegue l'operazione sopra descritta simultaneamente a tutti i blocchi di 1s, non solo quello più a destra, usando comunque solo operazioni bit per bit e aritmetiche.

1000010001001 ↦
1100011001101 ↦
1110011101001 ↦
1111010001101 ↦
1000011001001 ↦
1100011101101 ↦
1110010001001 ↦
1111011001101 ↦
1000011101001 ↦
1100010001101 ↦
1110011001001 ↦
1111011101101 ↦
1000010001001

1

Swift 1.2, 66 byte

func a(b:Int){var c=0,t=1,n=b
while n>c{n-=c;t+=c++}
print(n%c+t)}
Input:  1,   2, 3,  4, 5, 6,   7, 8, 9, 10,   11, 12, 13, 14, 15
Output: 1,   3, 2,  5, 6, 4,   8, 9, 10, 7,   12, 13, 14, 15, 11

1

Brachylog , 5 byte

∋0&|↺

Provalo online!

Porta della risposta Pyth di @orlp. Viene semplice e pulito:

∋0    % If input contains a 0 (since input is a single number, "contains" ∋ treats it as an array 
      %   of its digits, so this means "if any of input's digits are 0")
&     % Then output is the input
|     % Otherwise
↺     % Circularly shift the input once, and unify that with the output

Inizialmente volevo portare la soluzione Python di @ Sp3000, ma ci sono voluti ben 23 byte :

⟧∋B-₁⟦++₁A≤?;A--₁;B%;A+

Provalo online!


0

JavaScript (ES6), 43 byte

f=(n,i=1,j=1)=>n>j?f(n,++i,j+i):n++<j?n:n-i

0

Matlab (189)

  function u=f(n),if(~n|n==1)u=n;else,u=n;y=factor(n);z=y(y~=2);if ~isempty(z),t=y(y~=max(y));if isempty(t),u=y(end)*2^(nnz(y)-1);else,g=max(t);e=primes(g*2);u=n/g*e(find(e==g)+1);end,end,end

  • La funzione:

    Mappa qualsiasi numero intero in base ai suoi fattori primi, se il numero è zero o fattorizzato in 2 o 1, il numero viene mappato su se stesso, altrimenti scegliamo il fattore primo più grande di questo numero, quindi incrementiamo i diversi fattori primi rimanenti del più vicino fattore primo più grande fino a quando non raggiungiamo il numero in biggest_prime^ncui nè la somma di tutti gli esponenti di tutti i fattori, una volta raggiunto tale importo, ci rivolgiamo a max_prime*2^(n-1)e riproduciamo nuovamente lo stesso ciclo.


0

Matlab (137)

  function u=h(n),if(~n|n==1)u=n;else,u=n;y=factor(n);z=y(y~=2);if~isempty(z),e=nnz(y);f=nnz(z);if(~mod(e,f)&e-f)u=n/2^(e-f);else,u=u*2;end

  • Un approccio leggermente simile, moltiplicando gradualmente qualsiasi numero non uguale a {0,1,2 ^ n} 2fino a quando non ci imbattiamo in un esponente di 2cui è divisibile per somma di esponenti di altri fattori primi. poi ci spostiamo all'inizio del ciclo dividendo per 2^(sum of exponents of other primes). gli altri numeri sono associati a se stessi.
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.