Va via! No-1 è qui!


16

Stavo giocando con alcuni numeri e ho trovato una sequenza che, ovviamente, è su OEIS. È A005823 : numeri la cui espansione ternaria non contiene 1 . Va:

a (2n) = 3 * a (n) +2

a (2n + 1) = 3 * a (n + 1)

a (1) = 0

a = 0,2,6,8,18,20,24,26,54 ....

Ho scritto un programma CJam che genera la prima n di questi numeri convertendo l'indice in binario, sostituendo 1 con 2 e convertendo da ternario a decimale.

Ho anche notato che qualsiasi numero pari può essere ottenuto prendendo la somma di due numeri nella sequenza (a volte il numero con se stesso).

La sfida:

Dato qualsiasi numero pari non negativo come input, genera gli indici di due numeri nella sequenza che lo sommano. (Nota che a volte sono possibili più coppie.)

Le regole:

  • Specifica se stai utilizzando l'indicizzazione 0 o 1.
  • Se stai producendo una stringa, inserisci un delimitatore tra i due indici.
  • È possibile eseguire l'output come numero complesso.
  • Se lo desideri, puoi generare ogni coppia valida.
  • Codice Golf: vince la risposta più breve

Casi test

Uso l'indicizzazione 0. Qui elencherò ogni possibile output per ogni input, ma è necessario solo emetterne uno.

0:       [0 0]
 2:       [1 0]
 4:       [1 1]
 6:       [2 0]
 8:       [2 1] [3 0]
 10:      [3 1]
 12:      [2 2]
 14:      [3 2]
 16:      [3 3]
 18:      [4 0]
 30:      [6 2]
 32:      [6 3] [7 2]
 46:      [7 5]
 50:      [7 6]
 120:     [10 10]
 338:     [19 18]
 428:     [30 23] [31 22]
 712:     [33 27] [35 25] [41 19] [43 17] [49 11] [51 9] [57 3] [59 1]
 1016:    [38 37] [39 36]
Grazie a @Luis Mendo per l'aiuto nel caso di test.

Correlati: è all'interno del set Cantor?


Possiamo emettere un numero complesso dei due valori? Possiamo fornire due funzioni, una che dà ciascun valore?
xnor

2
Possiamo produrre tutti i possibili valori o va oltre la sfida?
Cole

@cole Sì, va bene.
geokavel,

Sembra che a Sloane piacciano molto le sue sequenze numeriche. "C'è una sequenza per questo" (TM)
Pharap

1
Dal momento che ci sono diverse soluzioni per alcuni input, sarebbe bello includere tutte le soluzioni nei casi di test. Questo programma mostra tutte le coppie di soluzioni per ciascun caso di test, nello stesso formato del testo della sfida (basato su 0, ciascuna coppia ordinata in modo crescente)
Luis Mendo,

Risposte:


10

Husk , 21 14 13 byte

-7 byte, grazie a @ Neil's risposta JS di

-1 byte ispirato a betaveros risposta betaveros

Utilizza l'indicizzazione 0

mḋTmMo±>ḋ2B3½

Provalo online!

Spiegazione

            ½    Half the input
          B3     Convert to Base 3
   m             Map over the list
    Mo±>ḋ2       Function such that: 0 -> [0,0], 1 -> [0,1], 2 -> [1,1]
        ḋ2       Binary 2, [1,0]
    M            For each in that list
     o±>         check if the argument is greater than it
  T              Transpose
mḋ               Convert each from binary

Soluzione precedente a 21 byte

La prima volta che ho visto un uso per ».

mḋT»o%2+ȯ?´eḋε%3`-0B3

Provalo online!

Più a lungo, mentre mi occupavo di trasporta


8

JavaScript (ES6), 75 71 byte

f=
n=>[1,0].map(i=>parseInt((n/2).toString(3).replace(/./g,c=>+c+i>>1),2))
<input type=number min=0 step=2 oninput=o.textContent=this.value%2?``:f(this.value)><pre id=o>

Spiegazione: Dividere l'input e gli elementi di A005823 per 2 non modifica il problema, tuttavia rende la soluzione più semplice poiché le rappresentazioni ternarie ora usano solo 0 e 1 e quindi non c'è nulla da considerare. Inoltre, salva un passaggio durante la conversione dall'elemento al suo indice (il ternario di ogni elemento è il doppio del binario del suo indice). Esempi:

                 A005823
                  halved
            n in  values A005823
   n n/2  base 3  base 3 indices
   0   0       0   0   0   0   0  
   2   1       1   1   0   1   0
   4   2       2   1   1   1   1
   6   3      10  10   0   2   0
   8   4      11  11   0   3   0
  10   5      12  11   1   3   1
  12   6      20  10  10   2   2
  14   7      21  11  10   3   2
  16   8      22  11  11   3   3
  18   9     100 100   0   4   0
  30  15     120 110  10   6   2
  32  16     121 111  10   7   2
  46  23     212 111 101   7   5
  50  25     221 111 110   7   6

6

Gelatina , 26, 22 , 21 byte

ḶBḤḅ3
ÇŒcS=¥Ðf⁸ḢiЀÇT

Provalo online!

Un byte salvato grazie a @JonathanAllan!

Spiegazione:

                # Helper link: A005823 to *N* terms
Ḷ               # Lowered range(N)
 B              # Converted to binary
  Ḥ             # Double each digit
   ḅ3           # Converted from base 3 to decimal
                # Main link
Ç               # Last link
 Œc             # All combinations of 2 items (with replacement)
      Ðf        # Remove every combination where this isn't true:
   S=¥          #   The sum of the two items is equal to N
        ⁸Ḣ      # Take the first combination left
          i     # Index of
           Ѐ   # Each element of the combination
             Ç  # In the sequence
              T # Return the truthy indices

1
@JonathanAllan Oh, bello da sapere Œc. E sì, Dennis mi ha spiegato il problema S=¥.
DJMcMayhem

Sembra che tu debba aggiungere la gestione dei casi limite per zero a proposito :(
Jonathan Allan

Sembra che questo sia basato su 1; forse varrebbe la pena dichiararlo nella risposta
Luis Mendo,


3

Python 2 , 51 byte

f=lambda n:[n and(n/2%3>r)+2*f(n/3)[r]for r in 0,1]

Provalo online!

L'attività può essere eseguita in questo modo:

  1. Dimezza l'input
  2. Converti in elenco ternario
  3. Dividilo in due elenchi binari che sommano elementally ad esso
  4. Converti tali elenchi da binari

Possiamo dividere in (3) convertendo 0->0,1->1,2->1per un elenco e 0->0,1->0,2->1per l'altro. Cioè, controllando è che il valore è sopra una soglia di 0 o 1.

I due valori possono essere trovati dalle rispettive funzioni ricorsive:

p=lambda n:n and(n/2%3>0)+2*p(n/3)
q=lambda n:n and(n/2%3>1)+2*q(n/3)

La funzione f combina questi due aspetti in una comprensione dell'elenco. Ciò lo rende inefficiente a causa della ramificazione esponenziale.

Se fossero emessi numeri complessi, potremmo salvare 10 byte con:

f=lambda n:n and(n%6>1)+n%6/4*1j+2*f(n/3)

Immagino che numeri complessi siano ok.
geokavel,

3

J, 35 32 byte

($#:I.@,)@(=[:+/~3#.+:@#:@i.@>:)

Provalo online!

0-indicizzato e l'input è dato monadicamente. Restituisce tutte le possibili sommazioni al valore (tratta a be b acome diverse possibili sommazioni).

La conversione da una matrice booleana in indici richiede molto codice ...

Vorrei anche rimuovere il fork a sinistra, quindi non devo usare tante parentesi e @-at, ma non riesco a trovare un buon modo per farlo (il mio approccio alternativo non salva alcun byte ).

Spiegazione

Ai fini della spiegazione e della nongolfing, considera i seguenti componenti della funzione principale

valid_nums      =. = [: +/~ 3 #. +:@#:@i.@>:
indices_of_ones =. $ #: I.@,

valid_nums produce una matrice booleana in cui gli indici sono gli indici dei valori di sequenza sommati. Se ce n'è uno in quegli indici, significa che i due numeri si sommano al valore di input.

indices_of_ones è un linguaggio J per le coordinate di quelle in una matrice booleana di rango arbitrario

La funzione principale è composta semplicemente come

indices_of_ones@valid_nums

valid_nums

= [: +/~ 3 #. +:@#:@i.@>:  Input is n
                 #:@i.@>:  Binary numbers in range [0,n]
              +:           Doubled
         3 #.              Interpreted as ternary
     +/~                   Addition table with self (sum all possible pairs)
=                          Equate to n

indices_of_ones

$ #: I.@,
        ,  Ravel matrix into a single list
     I.    Find the indices of ones in that list
  #:       Convert to the base given by
$          The shape of the matrix

,-ravel funziona in questo caso unendo ciascuna riga alla successiva.

   i.3 3
0 1 2
3 4 5
6 7 8
   , i.3 3
0 1 2 3 4 5 6 7 8

Possiamo vedere che se questa fosse una matrice booleana, le coordinate di esse possono essere trovate interpretando gli indici della matrice sfilacciata come numeri nella base della forma di quella matrice usando quante più frasi preposizionali possibile per aiutare a confondere il povero lettore .


1
i tuoi output ridondanti sono ok.
geokavel,

3

MATL , 22 21 19 17 byte

tQ:qBEI_ZA&+=R&fh

L'output è basato su 1. Il programma produce tutte le coppie di soluzioni. Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

t      % Implicit input: n. Duplicate
Q:q    % Range [0 1 ... n]
B      % Convert to binary. Gives a matrix where each row corresponds to a number
E      % Multiply each entry by 2
I_ZA   % Convert each row from ternary to a number
&+     % Matrix of all pair-wise additions
=      % Does each entry equal n?
R      % Upper triangular matrix
&f     % Push row and column indices of nonzero entries
h      % Concatenate horizontally. Implicit didsplay

OP ha dichiarato che la produzione di tutte le soluzioni era OK nei commenti
H.Pwiz

@ H.PWiz Grazie! Non l'avevo visto
Luis Mendo il

2

Pyth , 37 byte

0-indicizzato

Certamente non golfizzato come potrebbe essere.

KUQJmi:.Bd\1\23KhfqQ+@JeT@JhTsmm,dkKK

Provalo online!


1
34 byte: hfqQ+@Jmi:.Bd\1\23QeT@JhTsmm,dkUQU. Può sicuramente essere giocato a golf
Mr. Xcoder

1
33 byte:hfqQ+@Jmi:.Bd\1\23QeT@JhTsmm,dkUQ
Mr. Xcoder

2

Pyth , 29 byte

Questo restituisce tutte le possibili coppie di indici.

fqQ+@Kmi:.Bd\1\23QhT@KeT.cUQ2

Provalo qui.

Pyth , 30 byte

hfqQ+@Kmi:.Bd\1\23QhT@KeT.cUQ2

Provalo qui.

Questo restituisce le coppie di indici come [LowerIndex, HigherIndex] .


Come funziona?

hfqQ+@Kmi:.Bd\1\23QhT@KeT.cUQ2   Full Program. Q means input throughout the whole explanation.

       m          Q               Map over the range [0, Q) with a variable d.
          .Bd                     Convert to binary.
         :   \1\2                 Replace 1 with 2.
        i        3                Convert it from base 3 to integer.
      K                           Assign the mapped range to a variable K.
                         .cUQ2    All possible two-element combinations of the range [0...Q).
    +@             hT@KeT         Sum of the integers on positions in K of the two-element
                                  combination.
 fqQ                              Filter those that equal the input.
h                                 Optional: Head. Take the first element.
                                  Print the result, implicitly. 

2

Paradoc (v0.2.10), 11 byte (CP-1252)

½3B2>_B™2Bv

Provalo online!

Algoritmicamente è proprio come la risposta ES6 di Neil . A un livello inferiore, anche sorprendentemente simile alla risposta Husk di H.PWiz . Sono divertito dal fatto che dobbiamo usare tutti e tre i sovraccarichi di B.

Prende un numero intero nello stack, lascia un elenco di due numeri interi nello stack.

Spiegazione:

½           .. Halve input
 3B         .. Convert to ternary
   2        .. 2, which will get implicitly coerced to [0,1]
    >_      .. Greater than, as a block
      B     .. "Bimap": take the block and map it over the Cartesian
            .. product of the last two lists to get a matrix
       ™    .. Transpose
        2Bv .. Convert each row from binary

1

Python 3 , 122 120 byte

-2 byte grazie a Mr. Xcoder!

0-indicizzato

def f(a):r=range(a);s=[int(bin(x)[2:].replace(*'12'),3)for x in r];return[(i,j)for i in r for j in r if s[i]+s[j]==a][0]

Ungolfed:

def f(a):
    r=range(a)
    s=[int(bin(x)[2:].replace(*'12'),3)for x in r]
    return[(i,j)for i in r for j in r if s[i]+s[j]==a][0]

Provalo online!


1
Spero non ti importi. Ho aggiunto un link TiO.
Mr. Xcoder,

1

Mathematica, 94 byte

(w=#;Position[s,#]&/@#&@@(k=Select)[Tuples[s=k[Range@w,DigitCount[#,3,1]==0&],{2}],Tr@#==w&])& 


1-indicizzato


1

JavaScript, 120 101 byte

n=>[(A=[...Array(n+1)].map(Z=(a,b=a)=>b&&3*Z(b/2|0)+b%2*2))[F='findIndex'](a=>z=~A[F](b=>a+b==n)),~z]

Provalo online!

0-indicizzati.
Restituisce la coppia di indici in cui un indice è il più piccolo possibile (ad esempio nel caso in 428cui ritorni 22,31).


1

Brain-Flak , 220 166 byte

-54 byte cercando la funzione modulo sul wiki, consentendo alcune modifiche strutturali

({()<({}[()()])>}{}){({}(<>))<>(()()())({()<(({})){({}[()])<>}{}>}{}<><([{}()]{})>[()])}([]){{}<>(({}){})<>(({}){}{()<({}[()]){<>({}())<>(<{}>)}>}{})([][()])}({}{}<>)

Provalo online!

0-indicizzati.

Spiegazione

Come molte altre soluzioni, questo calcola l'espansione ternaria n/2e la converte in due numeri binari.

Passaggio 1: dividere l'input per 2

({()<({}[()()])>}{})

 {              }     until number becomes zero:
     ({}[()()])       subtract two
( ()<          > {})  push number of iterations

Passaggio 2: calcolare l'espansione ternaria

{({}(<>))<>(()()())({()<(({})){({}[()])<>}{}>}{}<><([{}()]{})>[()])}

 ({}(<>))<>         {   (({})){({}[()])<>}{} }{}<> ([{}()]{})         modulo (from wiki)
           (()()())                                                   use 3 as base
                     ()<                    >                         evaluate as 1 every time the 3 rolls over
                   (                              <          >[()])   push number of rollovers (function is now division with remainder)
{                                                                  }  repeat until quotient is zero, leaving all remainders on stack

Passaggio 3: convertire in soluzione

([]){{}<>(({}){})<>(({}){}{()<({}[()]){<>({}())<>(<{}>)}>}{})([][()])}({}{}<>)

([]){{}                                                      ([][()])}           repeat while stack height > 1:
                                                                                 (loop happens once when initial stack height is 1, but that's fine)
       <>(({}){})                                                                double smaller output number
                 <>(({}){}                                  )                    double larger output number
                          {                              }{}                     if digit in ternary expansion is nonzero:
                           ()<                          >                        add 1 to larger output number
                              ({}[()]){                }                         if digit is 2:
                                       <>({}())<>(<{}>)                          add 1 to smaller output number

0

JavaScript (ES6), 70 72 byte

n=>[6,4].map(x=>parseInt((n/2).toString(3).replace(/./g,d=>x>>d&1),2)) // thanks @Neil
n=>[0,1].map(x=>parseInt((n/2).toString(3).replace(/1|2/g,d=>~-d||x),2))

(Indicizzato 0 e apparentemente quasi la stessa soluzione di @Neil anche se non avevo visto la sua risposta)

Ho iniziato con il recupero dell'indice da un numero usando il contrario del processo: stringify con base 3, sostituisci ogni 2con 1, analizza con base 2.

Per ottenere due numeri, e quello per ogni pari, abbiamo solo la metà dell'input, ma ora 1possono verificarsi anche cifre. Quindi lo sostituiamo con a 0in un numero e a 2in un altro numero, che non modifica la somma dei due, prima del passaggio di sostituzione e analisi. Ecco cosa mi è venuto in mente (facendo i due rimpiazzi, 1-> 0-o-2 e 2-> 1in un solo passaggio):

n=>["001","011"].map(x=>parseInt((n/2).toString(3).replace(/./g,d=>x[d]),2))

Naturalmente le due mappe sostitutive (stringhe) differiscono solo per un indice, quindi dovremmo essere in grado di accorciare letteralmente l'array sostituendo 1e 2con d == 2 ? 1 : x. Or d-1 || x. Dove -1fa lo stesso dei due operatori unari - ma sembrano più spaventosi :-)

Cercando di evitare la matrice letterale e la parentesi intorno n/2ho anche escogitato

n=>Array.from(parseInt,(h=n/2,i)=>parseInt(h.toString(3).replace(/1|2/g,d=>~-d||i),2))

ma non è risultato fruttuoso.


Ho iniziato anche con la ["001","011"]versione (beh, i nomi delle mie variabili erano diversi)
Neil

Penso che .replace(/./g,d=>d>>1|x)salva 2 byte.
Neil,

@Neil Purtroppo non funziona d="0"e x=1- la cifra dovrebbe rimanere0
Bergi

Sì, l'ho appena risolto dopo aver provato alcuni altri casi di test. (E da allora ho escogitato un'altra variante, ma questo sta andando nella mia risposta, temo.)
Neil

1
Oh, molto carino, e pensavo di essere intelligente per battere la tua versione precedente ...
Neil,

0

Pyth, 22 byte

J.m}1jb3hQxLJhfqsTQ^J2

Provalo online: dimostrazione

Spiegazione:

J.m}1jb3hQxLJhfqsTQ^J2
        hQ                input + 1 
 .m                       find all values of [0, 1, 2, ..., input], where
     jb3                     value converted to base 3
   }1                        check if it contains the digit 1
                          this boolean ^ is false
J                         store this list in variable J

                   ^J2    every pair of J
              f           filter for pairs with
                sT           sum of pair
               q             equal
                  Q          the input
             h            take the first of these pairs
          xLJ             and find the corresponding indices of J
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.