Tutto su binario di base


29

Per favore, scusa il titolo punny.

Questa è una domanda ispirata a A Curious Property of 82000 . In esso, l'autore sottolinea che il numero 82000 è binario nelle basi 2, 3, 4 e 5. Il post pone quindi la domanda "c'è un numero che è binario nelle basi 2, 3, 4, 5 e 6 "? (Per i curiosi, ho controllato i valori fino a 10 ^ 1.000.000 e finora la risposta è no.)

Questo mi ha fatto pensare: dato un numero, in quali basi è binario?

Il nostro curioso numero, 82000, è in realtà binario in sei basi:

Base 2 = 10100000001010000
Base 3 = 11011111001
Base 4 = 110001100
Base 5 = 10111000
Base 81999 = 11
Base 82000 = 10

Non tutti i numeri avranno basi binarie sequenziali. Considera il numero 83521. È binario nelle basi 2, 17, 289, 83520 e 83521.

La tua sfida è determinare e visualizzare in quali basi è binario un numero.

Regole

  • Un numero è considerato "binario" in una data base se la sua rappresentazione in quella base è composta solo da zero e uno. 110110è un valore binario, mentre 12345non lo A380Fè , sicuramente no.
  • Il tuo numero verrà fornito su input standard. Sarà un valore intero compreso tra 2 e 2 ^ 32-1 inclusi e verrà fornito nel formato base-10.
  • In ordine crescente, visualizzare ogni base maggiore di una in cui il numero è binario. Ogni base deve essere sulla propria riga. Se includi il valore binario in quella base (vedi il punteggio bonus sotto), separa la base e il valore binario con uno spazio. Verrà giudicato solo l'output allo standard out, l'errore standard e le altre fonti verranno ignorate.

punteggio

Il tuo punteggio è la dimensione del programma in byte. Più basso è il punteggio, meglio è.

Bonus :
se il tuo programma emette anche i valori binari nelle basi trovate, moltiplica il tuo punteggio per 0,75
Il valore binario visualizzato non dovrebbe avere punteggiatura aggiuntiva, zero zero estranei, punti decimali, solo zero e uno.

Esempi

Ingresso:

82000

Uscita (riceve bonus):

2 10100000001010000
3 11011111001
4 110001100
5 10111000
81999 11
82000 10

Ingresso:

1234321

Uscita (nessun bonus):

2
1111
1234320
1234321

L'input può terminare con una nuova riga?
LegionMammal978,

@ LegionMammal978 - Uhhh ... sicuro? Il mio intento era che dovresti essere in grado di ottenere il numero di input con un semplice budget, readline o qualcosa di simile.
Mr. Llama,

1
In generale, nè sempre almeno binario in basi 1(non conteggiati) 2, n-1e n.
mbomb007,

1
Quando dici "il tuo numero verrà fornito sull'input standard", intendi solo STDIN o possiamo in alternativa accettare il numero come argomento di funzione come è standard per il sito?
Alex A.

La rappresentazione binaria (nella parte bonus) dovrebbe avere un determinato formato? In particolare sarebbe [1, 0, 1, 1, 0]ok, o i numeri devono essere uniti come 10110?
Jakube,

Risposte:


14

Pyth, 14 13

jbf!-jQTU2tSQ

Grazie a Jakube per aver sottolineato la nuova Sfunzione.

Provalo qui.

La versione online è troppo lenta per farlo 1234321. Questo semplicemente converte l'input per ogni base da 2 a se stesso e scarta i risultati che contengono valori diversi da 0 e 1.

Spiegazione:

                           : Q=eval(input) (implicit)
jb                         : join on newlines the list...
  f!                       : filter away nonempty values (impliticly named T)
    -jQTU2                 : sewtise difference of number converted to base and range(2)
     jQT                   : convert Q to base T
        U2                 : range(2)
          tSQ              : over the range [2 Q+1)

Inoltre, questa è una versione bonus ( non ben giocata, ora ben giocata, sempre grazie a Jakube) (20 * .75 = 15):

VQI!-JjQK+2NU2pdKjkJ

Provalo qui


Pyth è appena stato aggiornato. Quindi puoi collegarti a soluzioni reali.
Jakube

Ed ecco una soluzione 20 * 0.75 = 15: VQI!-JjQK+2NU2pdKjkJ volte la programmazione funzionale non è l'approccio migliore.
Jakube,

10

Julia, 72 70 byte

In realtà è più lungo con il bonus, quindi nessun bonus qui.

n=int(readline());for j=2:n all(i->i0:1,digits(n,j))&&println(j)end

Questo legge una riga da STDIN, la converte in un numero intero e stampa il risultato. Nonostante sia un metodo di forza bruta, l'ingresso 1234321 ha impiegato meno di 1 secondo per me.

Ungolfed + spiegazione:

# Read n from STDIN and convert to integer
n = int(readline())

# For every potential base from 2 to n
for j = 2:n
    # If all digits of n in base j are 0 or 1
    if all(i -> i0:1, digits(n, j))
        # Print the base on its own line
        println(j)
    end
end

Esempi:

julia> n=int(readline());for j=2:n all(i->i0:1,digits(n,j))&&println(j)end
1234321
2
1111
1234320
1234321

julia> n=int(readline());for j=2:n all(i->i0:1,digits(n,j))&&println(j)end
82000
2
3
4
5
81999
82000

NOTA : se l'input può essere preso come argomento di funzione piuttosto che da STDIN (in attesa di conferma dall'OP), la soluzione è di 55 byte.


7

CJam, 20 byte (o 27 byte * 0,75 = 20,25)

Ecco la versione senza bonus, 20 byte:

ri:X,2f+{X\b2,-!},N*

Prova qui.

Solo per divertimento, ecco la versione bonus, 27 byte:

ri:X{X\)b2,-!},1>{)SX2$bN}/

Provalo online qui


Sicuro. Una volta ho finito di giocare a golf.
Ottimizzatore

1
ri_,f{2+S@2$bN}4/{2=2,-!},(19,5 byte)
Dennis

7

Mathematica, 59 byte

Print/@Select[1+Range[n=Input[]],Max@IntegerDigits[n,#]<2&]

Ugh ... IntegerDigitsD:

Non c'è molto da spiegare sul codice ... 12 byte sono sprecati dal requisito per l'utilizzo di STDIN e STDOUT.

Non credo di poter richiedere il bonus. Il migliore che ho è 84 byte (che produce un punteggio superiore a 60):

Print@@@Select[{b=#+1," ",##&@@n~IntegerDigits~b}&/@Range[n=Input[]],Max@##3<2&@@#&]

7

Python 2, 88 86 80

Abbastanza semplice, nessun bonus. Python è simpatico e indulgente con le variabili globali.

N=input();g=lambda n:n<1or(n%b<2)*g(n/b)
for b in range(2,N+1):
 if g(N):print b

Il migliore che sono riuscito a ottenere per il bonus è 118 * .75 = 87.75 :

N=input();g=lambda n:0**n*" "or" "*(n%b<2)and(g(n/b)+`n%b`)*(g(n/b)>'')
for b in range(2,N+1):
 if g(N):print`b`+g(N)

Bella soluzione, battimi con un codice molto più breve.
Kade,

Sarebbe più breve da fare g(N)invece che n=N.
feersum

@feersum Oh yeah (è usato per essere g(N,b)così la virgola fatto la due uguali), ma ciò che vuoi dire non avrei bisogno di una variabile per N?
KSab il

@KSab Ho cancellato quella seconda parte; non importa.
feersum

Posso sbagliarmi, ma non sono riuscito a ottenere il bonus, semplicemente cambiando g(n/b)per (g(n/b)+'n%b')cui 'rappresenta un apice inverso?
feersum,

4

Python 2, 90 * 0,75 = 67,5

n=input();b=1
while b<n:
 b+=1;s="";c=k=n
 while k:s=`k%b`+s;c*=k%b<2;k/=b
 if c:print b,s

Approccio iterativo piuttosto semplice.

Senza il bonus, si tratta di 73 byte:

n=input();b=1
while b<n:
 b+=1;c=k=n
 while k:c*=k%b<2;k/=b
 if c:print b

4

SQL (PostgreSQL), 247,5 255 230.25 (307 * .75)

Dato che SQL è noto per essere meraviglioso in questo tipo di sfide, ho pensato di metterlo insieme :) Il bonus è stato davvero utile per questo.
Dovrebbe essere conforme alle specifiche, ma non ho un modo semplice per testare la COPIA I DA STDIN .
Modifica ordine fisso. Modificato il modo in cui la colonna R viene gestita per utilizzare un array.

CREATE TABLE IF NOT EXISTS I(I INT);TRUNCATE TABLE I;COPY I FROM STDIN;WITH RECURSIVE R AS(SELECT n,I/n I,ARRAY[I%n] R FROM generate_series(2,(SELECT I FROM I))g(n),(SELECT I FROM I)I(I)UNION ALL SELECT n,I/n,I%n||R FROM R WHERE I>0)SELECT n||' '||array_to_string(R,'')FROM R WHERE 2>ALL(R)and i=0ORDER BY n

Come test ho usato solo inserti dritti nella Itabella. Esecuzione del test estesa e commentata.

-- Create the table to accept the input from the copy command
CREATE TABLE IF NOT EXISTS I(I INT);
-- Make sure that it is empty
TRUNCATE TABLE I;
-- Popoulate it with a value from STDIN
--COPY I FROM STDIN;
INSERT INTO I VALUES(82000); -- Testing
--Using a recursive CTE query
WITH RECURSIVE R AS (
    -- Recursive anchor
    SELECT n,                -- base for the row
       I/n I,                -- integer division
       ARRAY[I%n] R   -- put mod value in an array
    FROM generate_series(2,(SELECT I FROM I))g(n), -- series for the bases
         (SELECT I FROM I)I(I) -- Cross joined with I,  saves a few characters
    UNION ALL 
    -- for each row from r recursively repeat the division and mod until i is 0
    SELECT n,
        I/n,
        I%n||R -- Append mod to beginning of the array
    FROM R WHERE I>0
    )
-- return from r where i=0 and r has 1's and 0's only
SELECT n||' '||array_to_string(R,'')
FROM R 
WHERE 2 > ALL(R)and i=0
ORDER BY n -- Ensure correct order

2 10100000001010000
3
11011111001 4 110001100
5 10111000
81999 11
82000 10


Così vicino! Le basi di output devono essere in ordine crescente. +1 per l'utilizzo di un linguaggio non convenzionale però.
Mr. Llama,

@ Mr.Llama risolto con un order by. Ora per vedere se riesco a riavere quei personaggi
MickyT

3

Haskell 109 * 0,75 = 81,75 byte

0#x=[]
n#x=n`mod`x:div n x#x 
f n=[show x++' ':(n#x>>=show)|x<-[2..n+1],all(<2)$n#x]
p=interact$unlines.f.read

Esempio di utilizzo (nota: i valori binari sono prima lsb):

p 82000

2 00001010000000101
3 10011111011
4 001100011
5 00011101
81999 11
82000 01

Senza restrizioni di input / output, ovvero input tramite argomento della funzione, output in formato nativo tramite REPL):

Haskell, 67 * 0,75 = 50,25 byte

0#x=[]
n#x=n`mod`x:div n x#x
f n=[(x,n#x)|x<-[2..n+1],all(<2)$n#x]

Restituisce un elenco di coppie (base, valore). I valori sono prima lsb, ad es. (Nuove righe / spazi aggiunti per una migliore visualizzazione):

 f 82000
 [ (2,[0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,1]),
   (3,[1,0,0,1,1,1,1,1,0,1,1]),
   (4,[0,0,1,1,0,0,0,1,1]),
   (5,[0,0,0,1,1,1,0,1]),
   (81999,[1,1]),
   (82000,[0,1]) ] 

2

R, 111

Probabilmente un sacco di spazio per migliorare questo al momento

i=scan();b=2:i;R=i%%b;I=rep(i,i-1);while(any(I<-I%/%b))R=cbind(I%%b,R);for(x in b)if(all(R[x-1,]<2))cat(x,'\n')

Funziona con avvisi

> i=scan();b=2:i;R=i%%b;I=rep(i,i-1);while(any(I<-I%/%b))R=cbind(I%%b,R);for(x in b)if(all(R[x-1,]<2))cat(x,'\n')
1: 82000
2: 
Read 1 item
There were 17 warnings (use warnings() to see them)
2 
3 
4 
5 
81999 
82000
>

@AlexA. Avvertenze causate dalla forzatura I%/%bdi un logico nella any()clausola. `
MickyT

2

Java, 181 155,25 (207 * .75) 151,5 (202 * .75) byte

class I{public static void main(String[]a){a:for(long b=new java.util.Scanner(System.in).nextLong(),c,d=1;d++<b;){String e="";for(c=b;c>0;e=c%d+e,c/=d)if(c%d>1)continue a;System.out.println(d+" "+e);}}}

Ampliato con spiegazione:

class I {
    public static void main(String[]a){
        a:for(long b=new java.util.Scanner(System.in).nextLong(),c,d=1; //b = input(), d = base
              d++<b;) {                                           //For all bases in range(2,b+1)
            String e="";
            for(c = b;c > 0; e = c % d + e,c /= d)                //Test all digits of base-d of b
                           //e = c % d + e                        //Append digits to string
                if (c % d > 1)                                    //Reject base if the digit is greater than 1
                    continue a;
            System.out.println(d+" "+e);                          //Print base and digits.
        }
    }
}

Originale (senza bonus):

class I{public static void main(String[]a){long b=new java.util.Scanner(System.in).nextLong(),c,d=1;a:for(;d++<b;){c=b;while(c>0){if(c%d>1)continue a;c/=d;}System.out.println(d);}}}

3,75 byte grazie a Ypnypn :)


2

R, 94 83 79

n=scan();cat((2:n)[!sapply(2:n,function(x){while(n&n%%x<2)n=n%/%x;n})],sep="\n")

Uso:

> n=scan();cat((2:n)[!sapply(2:n,function(x){while(n&n%%x<2)n=n%/%x;n})],sep="\n")
1: 82000
2: 
Read 1 item
2
3
4
5
81999
82000
> n=scan();cat((2:n)[!sapply(2:n,function(x){while(n&n%%x<2)n=n%/%x;n})],sep="\n")
1: 1234321
2: 
Read 1 item
2
1111
1234320
1234321

Il nucleo della funzione è !sapply(2:n,function(x){while(n&n%%x<2)n=n%/%x;n}) che, per ogni base x da 2 a n, mantiene il quoziente n / x fintanto che il resto è 0 e 1. Emette quindi il risultato (che è 0 se tutti i resti erano 1 o 0) e lo nega (0 nega a VERO, tutto il resto nega a FALSO). Grazie all'ambito delle funzioni, non è necessario creare una variabile fittizia per n. Il vettore risultante di booleani viene quindi utilizzato per indicizzare 2:ne quindi genera solo le basi per cui ha funzionato.


1

TI-Basic, 45 byte

Input N
For(B,2,N
If prod(seq(BfPart(iPart(N/B^X)/B),X,0,log(N)/log(B))<2
Disp B
End

Spiegazione

  • Ingresso n
  • Per ogni B da 2 a N
    • Se N è solo 0 e 1 nella base B
      • Display B
  • End loop

La parte complicata

La seconda riga funziona come segue:

  • Per ogni X da 0 a registro B N
  • B × fPart (iPart (N / B X ) / B) è l'ennesima cifra nella base B, contando all'indietro
  • Considera questo come un elenco
  • Per ogni elemento, se la cifra è inferiore a 2, produce 1 (vero), altrimenti 0 (falso)
  • Prendi il prodotto: 1 se tutti gli elementi sono 1

Nota

Il programma funziona in modo significativamente più veloce se )viene posizionata una parentesi di chiusura alla fine della seconda riga. Vedi qui per ulteriori informazioni al riguardo.


1

TI-BASIC, 31 29

For(B,2,Ans
If 2>round(Bmax(fPart(Ans/B^randIntNoRep(1,32
Disp B
End

Questo è probabilmente ottimale per TI-BASIC.

Spiegazione:

randIntNoRep(1,32)restituisce una permutazione casuale dei numeri da 1 a 32 (Tutto ciò di cui abbiamo bisogno è quei numeri in un certo ordine; TI-BASIC non ha niente come il comando iota di APL). 32 elementi sono sufficienti perché la base più piccola possibile è 2 e il numero più grande è 2 ^ 32-1. B^randIntNoRep(1,31)eleva quella lista alla potenza Bth, che risulta nella lista che contiene tuttoB^1,B^2,...,B^32 (in un certo ordine).

Quindi l'input (nella Ansvariabile wer, che viene immesso nel modulo [number]:[program name]) viene diviso per quel numero. Se il tuo input è 42 e la base è 2, il risultato sarà l'elenco21,10.5,5.25,...,42/32,42/64,[lots of numbers less than 1/2] , sempre in un certo ordine.

Prendendo la parte frazionaria e moltiplicando il numero per la base, si ottiene la cifra in quella posizione nella rappresentazione base-b. Se tutte le cifre sono inferiori a 2, la cifra più grande sarà inferiore a 2.

Come affermato da Ypnypn, una parentesi chiusa sull'istruzione Foraccelera questo a causa di un bug del parser.

31-> 31: salvato un byte ma risolti errori di arrotondamento che hanno aggiunto nuovamente il byte.

31-> 29: salvato due byte utilizzando RandIntNoRep()invece di cumSum(binomcdf()).


TI-BASIC ha una funzione di sequenza?
Mr. Llama,

Sì, il comando è seq(expression, variable, start, end[, step]). Se non viene fornito alcun passaggio, il valore predefinito è 1. Tuttavia, cumSum(binomcdf(31,0è 8 byte mentre seq(X,X,1,32è 9 byte.
lirtosiast,

Ah, questo lo spiega. Non ho familiarità con le opere di punteggio in TI-Basic.
Mr. Llama,

1

Gelatina , 9 byte

³bṀỊµÐfḊY

Provalo online!

Fatto insieme a caird coinheringaahing in chat .

Come funziona

³bṀỊµÐfḊY Programma completo.

     Ðf Filtra l'intervallo generato implicitamente [1, input].
    µ Avvia una nuova catena monadica.
³b Converte l'input alla base del numero corrente, come un elenco.
  Ṁ massimo.
   Ị Insignificante. Verifica se abs (Z) ≤ 1.
       Ḋ Dequeue; Rimuove il primo elemento dell'elenco (per eliminare la base 1).
        Y Partecipa per newline.

0

Javascript, ES6, 118 * .75 = 88.5 110 * .75 = 82.5

f=x=>{res={};for(b=2;b<=x;++b)if(!+(res[b]=(c=x=>x%b<2?x?c(x/b|0)+""+x%b:"":"*")(x)))delete res[b];return res}

Versione precedente:

f=x=>{res={};for(q=2;q<=x;++q)if(!+(res[q]=(c=(x,b)=>x%b<2?x?c(x/b|0,b)+""+x%b:"":"*")(x,q)))delete res[q];return res}

Dai un'occhiata:

f(82000)
Object { 2: "10100000001010000", 3: "11011111001", 4: "110001100", 5: "10111000", 81999: "11", 82000: "10" }

Qui non hai input e output.
edc65,

0

JavaScript ( ES6 ) 65

68 byte per una funzione con un parametro e un output console.

f=n=>{s=n=>n%b>1||b<n&&s(n/b|0);for(b=1;b++<n;)s(n)||console.log(b)}

65 byte con I / O tramite popup

n=prompt(s=n=>n%b>1||b<n&&s(n/b|0));for(b=1;b++<n;)s(n)||alert(b)

Richiesta del bonus: 88 * 0,75 => 66

n=prompt(s=n=>n%b>1?9:(b<=n?s(n/b|0):'')+n%b);for(b=1;b++<n;)s(n)<'9'&&alert(b+' '+s(n))

0

Mathematica, 76 * 0.75 = 57

n=Input[];G=#~IntegerDigits~b&;If[Max@G@n<2,Print[b," ",Row@G@n]]~Do~{b,2,n}

Inizialmente dimenticato i requisiti di input ... Fortunatamente, quelli non hanno aggiunto troppo.



0

Perl 5 , 63 byte

map{$t=$n;1while($f=$t%$_<2)&&($t=int$t/$_);say if$f}2..($n=<>)

Provalo online!

Nessun bonus su questo perché segna un punteggio leggermente migliore rispetto alla mia versione con il bonus:

Perl 5 , 85 byte * 0,75 = 63,75

map{my$r;$t=$n;$r=$/.$r while($/=$t%$_)<2&&($t=int$t/$_);say"$_ 1$r"if$/<2}2..($n=<>)

Provalo online!

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.