Trova il numero più fluido


59

La tua sfida è trovare il numero più regolare in un determinato intervallo. In altre parole, trova il numero il cui fattore primo più grande è il più piccolo.

Un numero regolare è uno il cui fattore primo più grande è piccolo. Numeri di questo tipo sono utili per l'algoritmo di trasformata di Fourier, la crittoanalisi e altre applicazioni veloci.

Ad esempio, nell'intervallo 5, 6, 7, 8, 9, 10, 8 è il numero più regolare, poiché il fattore primo più grande di 8 è 2, mentre tutti gli altri numeri hanno un fattore primo di 3 o maggiore.

Input: l'input sarà due numeri interi positivi, che definiscono un intervallo. L'intero minimo consentito nell'intervallo è 2. È possibile scegliere se l'intervallo è inclusivo, esclusivo, semi-esclusivo, ecc., Purché sia ​​possibile specificare un intervallo arbitrario entro i limiti della propria lingua. Puoi prendere i numeri tramite input di funzione, stdin, argomento della riga di comando o qualsiasi metodo equivalente per la tua lingua. Nessuna codifica di informazioni extra nell'input.

Output: restituisce, stampa o uno o più numeri interi equivalenti nell'intervallo di input che sono estremamente fluidi (fattore minimo minimo). La restituzione di più risultati è facoltativa, ma se si sceglie di farlo, i risultati devono essere chiaramente delimitati. Il formato di output nativo va bene per più risultati.

Indica nella tua risposta come stai prendendo input e dando output.

Punteggio: codice golf. Contare per carattere se scritto in ASCII o 8 * byte / 7 se non in ASCII.

Casi test:

Nota: si tratta di gamme in stile Python, compresa la fascia bassa ma non la fascia alta. Cambia in base al tuo programma. È necessario un solo risultato.

smooth_range(5,11)
8
smooth_range(9,16)
9, 12
smooth_range(9,17)
16
smooth_range(157, 249)
162, 192, 216, 243
smooth_range(2001, 2014)
2002

Gli intervalli specificati come (inizio, lunghezza) anziché (inizio, fine) sono accettabili?
Codici A Caos il

1
@CodesInChaos Certo. È coperto dalla clausola "o qualunque altra cosa".
isaacg,

3
Non vedo il punto nel penalizzare le risposte non ASCII. Sarebbe più semplice contare i byte in tutti i casi.
nyuszika7h

1
@ nyuszika7h Ascii è significativamente più piccolo di un byte - utilizza solo 7 bit. Pertanto, denoto un carattere di 7 bit e ridimensiono le altre lingue di conseguenza. Tuttavia, se la lingua non è ASCII ma può contenere tutti i suoi caratteri in 7 bit, non applicherò il supplemento. Vedi J / K vs. APL. tl; dr Bytes è più semplice, ma fornisce APL et. al. un vantaggio sottile ma ingiusto.
isaacg,

3
@isaacg stai incoraggiando la creazione di pseudo-lingue usando set di caratteri più piccoli. se calcoliamo set di caratteri a 7 bit diversi dai set di caratteri a 8 bit, qualcuno può impacchettare la maggior parte delle lingue moderne in 6 bit (64 caratteri ci danno AZ, 0-9, una manciata di spazi bianchi, 20 punteggiatura e alcuni di riserva) .
Sparr

Risposte:


99

CJam - 13

q~,>{mfW=}$0=

Provalo su http://cjam.aditsu.net/

Esempio di input: 2001 2014
Esempio di output:2002

Spiegazione:

q~legge e valuta l'input, spingendo i 2 numeri nello stack (diciamo min e max)
,crea un array [0 1 ... max-1]
>suddivide l'array a partire da min, risultando in [min ... max-1]
{…}$ordina l'array usando il blocco per calcolare la chiave di ordinamento
mfottiene un array con tutti i fattori primi di un numero, in modo da
W=ottenere l'ultimo elemento dell'array (W = -1), ottenendo così il fattore primo più grande da usare come la chiave di ordinamento
0=ottiene il primo elemento dell'array (ordinato)


38
Beh, immagino che sia quello.
Eric Tressler,

5
Ho bisogno di aggiungere una funzione di fattorizzazione a Pyth.
isaacg,

6
Questa lingua è magia.
Brobin,

8
Questo è il più vicino al solo tirare un po 'di HQ9 + s ** t come può essere senza diventare una scappatoia. Eccezionale!
Ingo Bürk,

25
ノ ༼ ຈ ل͜ ຈ ༽ ノmfWqualcuno l'ha risolto in 13 caratteri.
Internet è fatto di Catz il

66

Regex ( .NET PCRE flavour), 183 129 byte

Non provarlo a casa!

Questo non è davvero un contendente per la vittoria. Ma Eric Tressler ha suggerito di risolvere questo problema con nient'altro che una regex, e non ho potuto resistere a provarlo. Questo potrebbe essere possibile anche in PCRE (e anche più breve, vedi sotto), ma ho scelto .NET perché la mia soluzione ha bisogno di lookbehind di lunghezza arbitraria. Eccoci qui:

(?<=^(1+),.*)(?=\1)(?=((11+)(?=.*(?=\3$)(?!(11+?)\4+$))(?=\3+$)|(?!(11+)\5+$)1+))(?!.+(?=\1)(?:(?!\2)|(?=((11+)(?=.*(?=\7$)(?!(11+?)\8+$))(?=\7+$)|(?!(11+)\9+$)1+)).*(?=\2$)(?=\6)))1+

L'input è codificato come un intervallo separato da virgole, in cui entrambi i numeri sono indicati in notazione unaria usando 1s. La partita sarà il S1s finale dove Sè il numero più regolare nell'intervallo. I legami sono interrotti a favore del numero più piccolo.

Quindi il secondo esempio dalla domanda sarebbe la seguente stringa (corrispondenza sottolineata)

111111111,1111111111111111
                 =========

Si basa sulla regex (ormai piuttosto nota) del controllo di base , le cui varianti sono incorporate al suo interno ben 6 volte.

Ecco una versione che usa spaziatura libera e commenti per coloro che vogliono sapere cosa sta succedendo.

# Note that the beginning of the match we're looking for is somewhere
# in the second part of the input.
(?<=^(1+),.*)          # Pick up the minimum range MIN in group 1
(?=\1)                 # Make sure there are at least MIN 1s ahead

                       # Now there will be N 1s ahead of the cursor
                       # where MIN <= N <= MAX.


(?=(                   # Find the largest prime factor of this number
                       # store it in group 2.
  (11+)                # Capture a potential prime factor P in group 3
  (?=                  # Check that it's prime
    .*(?=\3$)          # Move to a position where there are exactly 
                       # P 1s ahead
    (?!(11+?)\4+$)     # Check that the remaining 1s are not composite
  )
  (?=\3+$)             # Now check that P is a divisor of N.
|                      # This does not work for prime N, so we need a 
                       # separate check
  (?!(11+)\5+$)        # Make sure that N is prime.
  1+                   # Match N
))

(?!                    # Now we need to make sure that here is not 
                       # another (smaller) number M with a smaller 
                       # largest prime factor

  .+                   # Backtrack through all remaining positions
  (?=\1)               # Make sure there are still MIN 1s ahead

  (?:
    (?!\2)             # If M is itself less than P we fail 
                       # unconditionally.
  |                    # Else we compare the largest prime factors.
    (?=(               # This is the same as above, but it puts the
                       # prime factor Q in group 6.
      (11+)
      (?=
        .*(?=\7$)
        (?!(11+?)\8+$)
      )
      (?=\7+$)
    |
      (?!(11+)\9+$)
      1+
    ))
    .*(?=\2$)          # Move to a position where there are exactly 
                       # P 1s ahead
    (?=\6)             # Try to still match Q (which means that Q is
                       # less than P)
  )
)
1+                     # Grab all digits for the match

Puoi provarlo online qui . Non provare input troppo grandi, tuttavia, non garantisco le prestazioni di questo mostro.

Modificare:

Ho finito per portarlo su PCRE (che richiede solo due passaggi) e accorciare la regex di quasi un terzo. Ecco la nuova versione:

^(1+),.*?\K(?=\1)(?=((11+)(?=.*(?=\3$)(?!(11+?)\4+$))(?=\3+$)|(?!(11+)\5+$)1+))(?!.+(?=\1)(?:(?!\2)|(?=((?2))).*(?=\2$)(?=\6)))1+

Questo è essenzialmente lo stesso, con due modifiche:

  • PCRE non supporta lookbehind di lunghezza arbitraria (che utilizzavo per MINinserire il gruppo 1). Tuttavia, PCREsupporta \Kche reimposta l'inizio della corrispondenza alla posizione corrente del cursore. Quindi (?<=^(1+),.*)diventa ^(1+),.*?\K, che salva già due byte.
  • I veri risparmi derivano dalla funzionalità di ricorsione di PCRE. In realtà non sto usando la ricorsione, ma è possibile utilizzare (?n)per abbinare nnuovamente il gruppo , simile a una chiamata di subroutine. Dato che il regex originale conteneva il codice per trovare due volte il primo fattore più grande di un numero, sono stato in grado di sostituire l'intero grosso del secondo con un semplice (?2).

37
Santa madre di Dio
Newb,

1
@Timwi Devo verificare che il più grande fattore primo (gruppo 3o 7) sia in realtà primo. Ciò richiede che ci sia un'altra copia del fattore dopo averlo catturato per la prima volta, il che non sarebbe il caso dei numeri primi. Mentre lavoro intorno a questo in .NET mettendo un lookbehind da qualche parte lì in modo che potessi tornare un po 'indietro per il controllo, questo non sarebbe possibile nella versione PCRE più corta a causa della mancanza di lookbehind di lunghezza variabile. Probabilmente è possibile accorciare quel po ', ma non penso solo che cambi +a *lavorare.
Martin Ender,

2
@MartinEnder Ciao! Immagino che tu abbia da tempo superato questa sfida, ma mi sono appena avvicinato, ho visto una soluzione regex e non ho potuto fare a meno di ignorare totalmente il tuo avvertimento in cima a questo post :) Trovo difficile golf il codice di altre persone, così dopo aver visto il tuo regex e essermi confuso, l'ho provato da zero e ho trovato questo: (.*),.*?\K(?=(..+)((?=((?(R)\6|\2))*$).*(?=\4$)(?!(..+)\5+$)))(?!.+(?=\1)(?=(..+)(?3)).*(?!\2)\6).+ 99 byte in PCRE. Inoltre, mi sono imbattuto in molti dei tuoi lavori su questo sito e sono un grande fan: D In attesa di una battaglia regex in futuro!
jaytea,

1
Stavo giocando a code golf con quel commento, quindi inserirò qui l'addendum: puoi eliminare 4b estraendo \4$il lookahead e attaccandolo dopo il lookahead negativo, ma questo ha un impatto grave sulle prestazioni (ogni sottogruppo di cifre <= \ 4 viene verificato per la composizione piuttosto che solo \ 4 stesso) e non riesce su input più lunghi.
jaytea,

1
@jaytea Ci scusiamo per il tempo impiegato per ricontattarti al riguardo. Dal momento che hai scritto la cosa da zero, penso che dovresti pubblicare una risposta separata. È un ottimo punteggio e te lo meriti. :)
Martin Ender,

16

Regex (sapore PCRE), 66 (65🐌) byte

Ispirato dal vedere che sia Martin Ender che jaytea , due geni della regex, scrissero soluzioni regex a questo codice golf, ne scrissi la mia da zero. Il famoso regex a controllo di prim'ordine non appare da nessuna parte nella mia soluzione.

Non leggerlo se non vuoi che qualche magia regex unaria venga rovinata per te. Se vuoi provare a capire da solo questa magia, ti consiglio vivamente di iniziare risolvendo alcuni problemi nella regex di ECMAScript:

  1. Abbina i numeri primi (se non hai già familiarità con questo in regex)
  2. Abbina poteri di 2 (se non l'hai già fatto). O semplicemente fatti strada attraverso Regex Golf , che include Prime e Powers. Assicurati di eseguire i set di problemi sia Classic che Teukon.
  3. Trova il modo più breve per abbinare i poteri di N dove N è una costante (cioè specificata nella regex, non nell'input) che può essere composita (ma non è richiesta). Ad esempio, abbina poteri di 6.

  4. Trova un modo per abbinare l'ennesimo potere, dove N è una costante> = 2. Ad esempio, abbina i quadrati perfetti. (Per un riscaldamento, abbina i poteri principali .)

  5. Abbina le dichiarazioni di moltiplicazione corrette. Abbina i numeri triangolari.

  6. Abbina i numeri di Fibonacci (se sei pazzo come me) o se vuoi attenersi a qualcosa di più breve, abbina le giuste dichiarazioni di esponenziazione (per un riscaldamento, ritorna come un logaritmo in base 2 di una potenza di 2 - bonus, fai lo stesso per qualsiasi numero, arrotondandolo come preferisci) o numeri fattoriali (per un riscaldamento, abbina i numeri primari ).

  7. Abbina numeri abbondanti (se sei pazzo come me)

  8. Calcola un numero irrazionale con la precisione richiesta (ad esempio dividi l'input per la radice quadrata di 2, restituendo il risultato arrotondato come una corrispondenza)

(Il motore regex che ho scritto può essere di aiuto, poiché è molto veloce nelle regex matematiche unarie e include una modalità numerica unaria che può testare intervalli di numeri naturali (ma ha anche una modalità stringhe che può valutare regex non unari o unaria con delimitatori). Per impostazione predefinita è compatibile con ECMAScript, ma ha estensioni opzionali (che possono aggiungere selettivamente sottoinsiemi di PCRE, o persino lookahead molecolare, qualcosa che nessun altro motore regex ha).)

Altrimenti, continua a leggere e leggi anche questo GitHub Gist (avvertimento, molti spoiler) che racconta il viaggio della spinta alla regex di ECMAScript per affrontare le funzioni numeriche naturali di crescente difficoltà (a partire dal set di puzzle di Teukon, non tutti matematici, che hanno scatenato questo viaggio).

Come con le altre soluzioni regex a questo problema, l'input è dato come due numeri in unario biiettivo, separati da una virgola, che rappresentano un intervallo inclusivo. Viene restituito un solo numero. La regex potrebbe essere modificata per restituire tutti i numeri che condividono lo stesso fattore primo più grande più piccolo, come corrispondenze separate, ma ciò richiederebbe un lookbebe a lunghezza variabile e inserendo \Kun lookahead o restituendo il risultato come una cattura anziché una corrispondenza.

La tecnica usata qui di ripetuta divisione implicita per il fattore primo più piccolo è identica a quella usata nelle stringhe Match la cui lunghezza è una quarta risposta di potenza che ho postato qualche tempo fa.

Senza ulteriori indugi: ((.+).*),(?!.*(?=\1)(((?=(..+)(\5+$))\6)*)(?!\2)).*(?=\1)\K(?3)\2$

Puoi provarlo qui.

E la versione a spaziatura libera, con commenti:

                        # No ^ anchor needed, because this algorithm always returns a
                        # match for valid input (in which the first number is less than
                        # or equal to the second number), and even in /g mode only one
                        # match can be returned. You can add an anchor to make it reject
                        # invalid ranges.

((.+).*),               # \1 = low end of range; \2 = conjectured number that is the
                        # smallest number in the set of the largest prime factor of each
                        # number in the range; note, it is only in subsequent tests that
                        # this is implicitly confined to being prime.
                        # We shall do the rest of our work inside the "high end of range"
                        # number.

(?!                     # Assert that there is no number in the range whose largest prime
                        # factor is smaller than \2.
  .*(?=\1)              # Cycle tail through all numbers in the range, starting with \1.

  (                     # Subroutine (?3):
                        # Find the largest prime factor of tail, and leave it in tail.
                        # It will both be evaluated here as-is, and later as an atomic
                        # subroutine call. As used here, it is not wrapped in an atomic
                        # group. Thus after the return from group 3, backtracking back
                        # into it can increase the value of tail – but this won't mess
                        # with the final result, because only making tail smaller could
                        # change a non-match into a match.

    (                   # Repeatedly divide tail by its smallest prime factor, leaving
                        # only the largest prime factor at the end.

      (?=(..+)(\5+$))   # \6 = tool to make tail = \5 = largest nontrivial factor of
                        # current tail, which is implicitly the result of dividing it
                        # by its smallest prime factor.
      \6                # tail = \5
    )*
  )
  (?!\2)                # matches iff tail < \ 2
)

# now, pick a number in the range whose largest prime factor is \2
.*(?=\1)                # Cycle tail through all numbers in the range, starting with \1.
\K                      # Set us up to return tail as the match.
(?3)                    # tail = largest prime factor of tail
\2$                     # Match iff tail == \2, then return the number whose largest
                        # prime factor is \2 as the match.

L'algoritmo può essere facilmente trasferito su ECMAScript sostituendo la chiamata della subroutine con una copia della subroutine e restituendo la corrispondenza come gruppo di acquisizione anziché utilizzare \ K. Il risultato è di 80 byte di lunghezza:

((x+)x*),(?!.*(?=\1)((?=(xx+)(\4+$))\5)*(?!\2)).*(?=\1)(((?=(xx+)(\8+$))\9)*\2$)

Provalo online!

Si noti che ((.+).*)può essere modificato in ((.+)+), diminuendo la dimensione di 1 byte (da 66 a 65 byte ) senza perdita della funzionalità corretta - ma il regex esplode esponenzialmente con lentezza.

Provalo online! (79 byte ECMAScript versione esponenziale-rallentamento)


11

Python 2, 95

i=input()
for a in range(*i):
 s=a;p=2
 while~-a:b=a%p<1;p+=1-b;a/=p**b
 if p<i:i=p;j=s                                        
print j

Trova la levigatezza dei numeri per divisione di prova fino a quando il numero è 1. imemorizza la levigatezza più piccola finora, jmemorizza il numero che ha dato quella levigatezza.

Grazie a @xnor per i golf.


1
Questo if/elseha ottenuto di essere accorciabile. Il mio primo pensiero è b=a%p<1;p+=1-b;a/=p**b. O un dirigente che esegue uno dei due in una stringa interfogliata. Inoltre, forse while~-afunziona.
xnor

isaacg - Adoro questa risposta! Che modo fantastico hai trovato per cercare il più grande fattore primo! Ho aggiornato la mia risposta per prendere in prestito il tuo metodo, con credito a te sul metodo.
Todd Lehman,

Ottima soluzione! Usando s,p=a,2, i,j=p,s, @ idee di XNOR, eliminando rientro ridondante e mettendo il blocco, mentre in uno dei rendimenti di linea 95 caratteri. Non sono sicuro di come ti sei inventato 98 ...
Falko,

questo codice è pieno di emoticon, :)
Rosenthal,

@Falko quei due cambiamenti non salvano caratteri. 7-> 7.
isaacg,

10

J, 22 20 19 caratteri

({.@/:{:@q:)@(}.i.)

Per esempio

   2001 ({.@/: {:@q:)@(}. i.) 2014
2002

(Le funzioni che accettano due argomenti sono infissi in J.)


Ho anche avuto una crepa, non è stata breve come questa risposta. Ancora:(#~ (= <./)@:(i:"1&1)@:*@:(_&q:))@:([ + i.@-~)
Augıʇǝɥʇuʎs

Qui {:è uguale >./e salva 1 byte.
randomra

@randomra Hai ragione, buona chiamata!
FireFly

Bellissimo. TIO se desideri aggiungerlo: provalo online!
Giona

9

Haskell, 96 94 93 86 80 caratteri

x%y|x<2=y|mod x y<1=div x y%y|0<1=x%(y+1)
a#b=snd$minimum$map(\x->(x%2,x))[a..b]

utilizzo tramite GHCi (una shell Haskell):

>5 # 9
8
>9 # 15
9

EDIT: ora un algoritmo molto più semplice.

questa soluzione include entrambi i numeri nell'intervallo (quindi 8 # 9e 7 # 8sono entrambi 8)

spiegazione:

la funzione (%) accetta due parametri, xey. quando y è 2, la funzione restituisce la levigatezza di x.

l'algoritmo da qui è semplice: ottieni l'elenco combinato di tutte le levigatezza dei numeri nell'input con ogni levigatezza che memorizza un riferimento al suo numero originale, ordina quindi per ottenere il più piccolo e restituisce il numero di riferimento.


ecco una versione javascript non golfata con lo stesso algoritmo:

function smoothness(n,p)
{
    p = p || 2
    if (x == 1)
        return p
    if (x % p == 0)
        return smoothness(x/p, p)
    else
        return smoothness(x,p+1);
}
function smoothnessRange(a, b)
{
    var minSmoothness = smoothness(a);
    var min=a;
    for(var i=a+1;i <= b;i++)
        if(minSmoothness > smoothness(i))
        {
            minSmoothness = smoothness(i)
            min = i
        }
    return min;
}

Sarebbe possibile alias minimo a qualcosa di più breve? Sembra che salverebbe alcuni personaggi.
isaacg,

L'ho provato, ma a causa della restrizione del monomorfismo, in realtà costa un personaggio
orgoglioso haskeller il

Non puoi semplicemente fare m = minimo? Haskell è ancora un mistero.
isaacg,

1
@isaacg Per aggirare la limitazione del monomorfismo si dovrebbe scriverem l=minimum l
orgoglioso haskeller il

2
Avevo intenzione di pubblicare una soluzione Haskell, fino a quando non ho visto la tua che batte anche la mia versione incompleta ... +1
nyuszika7h

9

Mathematica, 61 45 39 caratteri

Range@##~MinimalBy~Last@*FactorInteger&

Implementazione molto semplice della specifica come funzione senza nome.

  • Ottieni l'intervallo (incluso).
  • Fattorizza tutti i numeri interi.
  • Trova il minimo, ordinato per il fattore primo più grande.

8

Lua - 166 caratteri

Non avevo (ancora!) Una reputazione sufficiente per commentare la soluzione di AndoDaan , ma qui ci sono alcuni miglioramenti sul suo codice

a,b=io.read("*n","*n")s=b for i=a,b do f={}n=i d=2 while n>1 do while n%d<1 do f[#f+1]=d n=n/d end d=d+1 end p=math.max(unpack(f))if p<s then s=p c=i end end print(c)

I cambiamenti :

  • Il n%d==0by n%d<1che equivale in questo caso
  • Rimosso uno spazio
  • Sostituito table.insert(f,d)da f[#f+1]=d ( #fè il numero di elementi di f)

Ah, felice di aver dato un'occhiata qui. Ah, i primi due avrei dovuto controllare e catturare, ma il tuo terzo miglioramento è nuovo per me (intendo solo diverso da quello a cui sono abituato). Questo mi aiuterà molto qui e ancora su golf.shinh.com. Grazie!
AndoDaan,

8

Bash + coreutils, 56 byte

seq $@|factor|sed 's/:.* / /'|sort -nk2|sed '1s/ .*//;q'

L'input proviene da esattamente due argomenti della riga di comando (grazie @ nyuszika7h !!!). L'output è un risultato singolare stampato su STDOUT.

  • seq fornisce l'intervallo di numeri, uno per riga, dagli argomenti della riga di comando.
  • factorlegge quei numeri e genera ciascun numero seguito da due punti e dall'elenco ordinato dei fattori primi di quel numero. Quindi il fattore primo più grande si trova alla fine di ogni riga.
  • Il primo sedrimuove i due punti e tutti tranne l'ultimo / il più grande fattore primo, quindi lascia un elenco di ciascun numero (colonna 1) e il suo primo fattore più grande (colonna 2).
  • sort numericamente in ordine crescente dalla colonna 2.
  • La finale sedcorrisponde alla riga 1 (numero il cui fattore primo più grande è il più piccolo nell'elenco), rimuove tutto compreso e dopo il primo spazio, quindi si chiude. sedstampa automaticamente il risultato di questa sostituzione prima di uscire.

Produzione:

$ ./smooth.sh 9 15
12
$ ./smooth.sh 9 16
16
$ ./smooth.sh 157 249
162
$ ./smooth.sh 2001 2014
2002
$ 

Gli intervalli di note in questo contesto sono comprensivi di entrambi gli endpoint.


1
seq $@è 3 byte più corto, se si può presumere che ci siano solo due argomenti.
nyuszika7h,

@ nyuszika7h Bella idea - grazie!
Trauma digitale

5

Python 2, 67

f=lambda R,F=1,i=2:[n for n in range(*R)if F**n%n<1]or f(R,F*i,i+1)

Pensare a un altro golf mi ha dato l'idea di un nuovo algoritmo per controllare la scorrevolezza, da cui la risposta tardiva.

La fattorizzazione primaria del fattoriale i!include al massimo esattamente i numeri primi i. Quindi, se nè un prodotto di numeri primi distinti, la sua scorrevolezza (il fattore primo più grande) è il più piccolo iper il quale nè un divisore di i!. Per tenere conto di fattori primi ripetuti n, possiamo invece usare una potenza sufficientemente elevata di i!. In particolare, è (i!)**nsufficiente.

Il codice tenta di aumentare i fattoriali F=i!, aggiornati in modo ricorsivo. Filtriamo per i divisori di Fnell'intervallo di input e li emettiamo se ce ne sono, e altrimenti passiamo a (i+1)!.

Caso di prova:

>> f([157, 249])
[162, 192, 216, 243]

4

C,  149   95

Risposta modificata:

Non posso richiedere credito per questa soluzione. Questa risposta aggiornata prende in prestito il bellissimo metodo usato da isaacg nella sua soluzione Python. Volevo vedere se era possibile scriverlo in C come un annidato for/ whileloop senza parentesi graffe, e lo è!

R(a,b,n,q,p,m){for(;a<b;m=p<q?a:m,q=p<q?p:q,n=++a,p=2)while(n>1)if(n%p)p++;else n/=p;return m;}

Spiegazione:

  • Funzione R(a,b,n,q,p,m)esegue la scansione della gamma aper b-1e restituisce il numero primo più liscio trovato. Invocazione richiede l'aderenza alla seguente forma: R(a,b,a,b,2,0)in modo che le variabili all'interno della funzione sono effettivamente inizializzate come segue: n=a;q=b;p=2;m=0;.

Risposta originale :

Questa era la mia risposta originale ...

P(n,f,p){for(;++f<n;)p=p&&n%f;return p;}
G(n,f){for(;--f>1;)if(n%f==0&&P(f,1,1))return f;}
R(a,b,p,n){for(;++p;)for(n=a;n<b;n++)if(G(n,n)==p)return n;}

Spiegazione:

  • La funzione P(n,f,p)verifica il valore nper la primalità e restituisce true n(diverso da zero) se è primo o falso (zero) se nnon è primo. fe pdevono essere entrambi passati come 1.
  • La funzione G(n,f)restituisce il massimo fattore primo di n. fdeve essere passato come n.
  • Funzione R(a,b,p,n)esegue la scansione della gamma aper b-1e restituisce il numero primo più liscio trovato. pdeve essere passato come 1. npuò essere qualsiasi valore.

Test driver:

test(a,b){printf("smooth_range(%d, %d)\n%d\n",a,b,S(a,b,1,0));}
main(){test(5,11);test(9,16);test(9,17);test(157,249);test(2001,2014);}

Produzione:

smooth_range(5, 11)
8
smooth_range(9, 16)
9
smooth_range(9, 17)
16
smooth_range(157, 249)
162
smooth_range(2001, 2014)
2002

Direi che ciò cade nella clausola "Nessuna codifica di informazioni extra nell'input".
Alchymist,

@Alchymist - Forse hai ragione ... ma non credo che ci siano informazioni aggiuntive reali negli pseudo-argomenti. Almeno non tutte le informazioni che sono di qualsiasi tipo di indizio sulla risposta.
Todd Lehman,

4

Haskell - 120

import Data.List
import Data.Ord
x!y=(minimumBy(comparing(%2)))[x..y]
x%y|x<y=y|x`mod`y==0=(x`div`y)%y|otherwise=x%(y+1)

Esempio di utilizzo:

> 5 ! 10
8
> 9 ! 15
9
> 9 ! 16
16
> 157 ! 248
162
> 2001 ! 2013
2002

1
Non potresti usare al <1posto di ==0?
dfeuer

Sì, sarebbe un bel miglioramento. Ci sono molte piccole cose che potrebbero essere fatte meglio. Fortunatamente questa risposta fa già tutti loro: codegolf.stackexchange.com/a/36461
Taylor Fausak il

4

Q, 91 caratteri K, 78 caratteri

{(x+{where x=min x}{(-2#{x div 2+(where 0=x mod 2_til x)@0}\[{x>0};x])@0}'[(x)_til y+1])@0}

k probabilmente raderebbe una dozzina di caratteri

modifica: infatti, trattando il limite superiore come non inclusivo questa volta

{*:x+{&:x=min x}{*:-2#{6h$x%2+*:&:x={y*6h$x%y}[x]'[2_!x]}\[{x>0};x]}'[(x)_!y]}

4

Nota: questa risposta non è consentita.

Questa risposta utilizza più funzionalità di Pyth aggiunte dopo la richiesta della sfida.

Ho aggiunto un'altra nuova funzionalità, chiamando l'intervallo unario su una tupla a 2 elementi, che accorcia la soluzione di due caratteri, a questo:

Pyth , 7

hoePNUQ

L'input è ora preso separato da virgole. Il riposo è lo stesso.


Questa risposta utilizza una funzionalità di Pyth che è stata aggiunta dopo che questa domanda è stata posta, in particolare dopo aver visto la meravigliosa soluzione CJam di @aditsu. Detto questo, volevo dimostrare cosa ha reso possibile l'aggiunta di quella funzione. La funzione è P, che è una funzione arity-1 che sull'input intero restituisce un elenco di tutti i fattori primi dell'input, ordinati dal più piccolo al più grande.

Pyth , 9

hoePNrQvw

Utilizza intervalli in stile Python, newline separati su STDIN. Invia la soluzione più piccola a STDOUT.

Spiegazione:

      Q = eval(input())                         Implicit, because Q is present.
h     head(                                     First element of
 o         order_by(                            Sort, using lambda expression as key.
                    lambda N:                   Implicit in o
  e                          end(               Last element of
   PN                            pfact(N)),     List containing all prime factors of N.
  r                 range(                      Python-style range, lower inc, upper exc.
   Q                      Q,                    A variable, initialized as shown above.
   vw                     eval(input()))))      The second entry of the range, same way.

test:

$ newline='
'

$ echo "9${newline}16" | ./pyth.py -c 'hoePNrQvw'
9

$ echo "9${newline}17" | ./pyth.py -c 'hoePNrQvw'
16

$ echo "157${newline}249" | ./pyth.py -c 'hoePNrQvw'
162

$ echo "2001${newline}2014" | ./pyth.py -c 'hoePNrQvw'
2002

@ MartinBüttner Sì, come suggerito dal suo commento sulla soluzione
CJam

@ MartinBüttner Sì, P, è la nuova funzionalità. Lo inserirò nella risposta.
isaacg,

1
Consentito o no, non solo mi piace, ma penso anche che quei brevi "macronutrienti" siano leggibili se presti attenzione - dopo tutto si convertono in Python semplice. Qualcosa da dire per un linguaggio di golf che è buono per il golf ma non necessariamente offuscante.
Kuba Ober,

@KubaOber Grazie, Kuba. È sempre stata mia intenzione scrivere Pyth, per renderlo il più possibile giocabile e leggibile. Sono contento che funzioni.
isaacg,

3

Lua - 176 caratteri

a,b=io.read("*n","*n")s=b for i=a,b do f={}n=i d=2 while n>1 do while n%d==0 do table.insert(f, d)n=n/d end d=d+1 end p=math.max(unpack(f))if p<s then s=p c=i end end print(c)

Dovrei davvero smettere di giocare a golf a Lua. Non ha senso.


14
IMHO, il golf del codice è come la boxe: ci sono classi di peso. Una determinata lingua potrebbe non vincere del tutto, ma è divertente e illuminante giocare a golf in quella classe / lingua.
Michael Easter,

3

Clojure - 173 170 caratteri

Sono un principiante Clojure. golfed:

(defn g[x,d](if(and(= 0(mod x d))(.isProbablePrime(biginteger d) 1))d 0))(defn f[i](apply max-key(partial g i)(range 2(inc i))))(defn s[a,b](first(sort-by f(range a b))))

Esecuzioni campione:

Gli intervalli includono la fascia bassa, esclude la fascia alta: [a, b) Stampa solo uno dei numeri più lisci, se si verificano più numeri.

(println (s 5 11))
(println (s 9 16))
(println (s 9 17))
(println (s 157, 249))
(println (s 2001, 2014))

rendimenti:

bash$ java -jar clojure-1.6.0.jar range.clj
8
9
16
192
2002

Ungolfed:

(defn g [x,d] (if (and (= 0(mod x d)) (.isProbablePrime (biginteger d) 1)) d 0))
(defn f [i] (apply max-key (partial g i) (range 2 (inc i))))
(defn s [a,b] (first (sort-by f (range a b))))

1
Un intervallo che include la fascia bassa ed esclude la fascia alta viene solitamente scritto [a, b).
murgatroid99,

sì, grazie per la nota
Michael Easter,

3

Rubino, 65 62

require'prime'
s=->a,b{(a..b).min_by{|x|x.prime_division[-1]}}

Ci scusiamo con https://codegolf.stackexchange.com/a/36484/6828 , questa è la versione giocata a golf (e leggermente semplificata). Utilizza un intervallo inclusivo poiché è un personaggio più breve.

1.9.3-p327 :004 > s[157,249]
 => 192 
1.9.3-p327 :005 > s[5,11]
 => 8 
1.9.3-p327 :006 > s[9,15]
 => 12 
1.9.3-p327 :007 > s[9,16]
 => 16 

E grazie a YenTheFirst per aver salvato tre personaggi.


1
Puoi effettivamente scappare senza lo [0], poiché il confronto di array darà comunque la priorità al primo elemento. Ciò darà risultati diversi, ma ancora corretti.
YenTheFirst

3

C # LINQ: 317 303 289 262

using System.Linq;class P{static void Main(string[]a){System.Console.Write(Enumerable.Range(int.Parse(a[0]),int.Parse(a[1])).Select(i=>new{i,F=F(i)}).Aggregate((i,j)=>i.F<j.F?i:j).i);}static int F(int a){int b=1;for(;a>1;)if(a%++b<1)while(a%b<1)a/=b;return b;}}

Ungolfed:

using System.Linq;

class P
{
  static void Main(string[]a)
  {
    System.Console.Write(
      Enumerable.Range(int.Parse(a[0]), int.Parse(a[1])) //create an enumerable of numbers containing our range (start, length)
        .Select(i => new { i, F = F(i) }) //make a sort of key value pair, with the key (i) being the number in question and the value (F) being the lowest prime factor
        .Aggregate((i, j) => i.F < j.F ? i : j).i); //somehow sort the array, I'm still not entirely sure how this works
  }
  static int F(int a)
  {
    int b=1;
    for(;a>1;)
      if(a%++b<1)
        while(a%b<1)
          a/=b;
    return b;
  }
}

Prende l'inizio e la lunghezza dalla riga di comando e restituirà il numero più grande liscio.

Ho usato le risposte da qui e qui per fare la mia risposta.

Grazie a VisualMelon per averlo modificato e rasato 12 byte! Mi sono anche sbarazzato delle parentesi graffe nel salvataggio di 2 byte e CodeInChaos ha sottolineato alcune cose ovvie che mi mancavano (grazie ancora).


Coppia di piccole cose per scopi generici, è possibile salvare 4 byte Fdefinendo int baccanto a m. In un paio di posti che si esegue il confronto a%b==0, e ae bsono sempre positivi si può tagliare un byte per ogni controllando se è inferiore a 1 a%b<1. Puoi anche salvare un byte incrementando bla condizione if a%++b<0anziché in for inizializzandolo su 1. Penso anche che in questo caso sia più economico qualificarsi completamente System.Console.WriteLineed evitare la namespaceclausola.
VisualMelon,

@VisualMelon Grazie, aggiornato con le tue idee :)
ldam

La m=...:m;cosa non rientra nel ciclo while. Pertanto, è possibile eliminare m=0,e sostituire return m;con return m=b>m?b:m;. Quindi, puoi rilasciare il m=...:m;tutto.
tomsmeding,

Può sembrare strano, ma questo per me è meno ridimensionabile di CJam e J. Immagino che C # sia stato progettato per essere prolisso e cerchi di renderlo meno così da renderlo illeggibile? Hmm ....
Kuba Ober,

No, sono d'accordo, LINQ sembra un demone quando lo vedi qua e là e non ci giochi mai da solo. Una volta che lo afferrate, è davvero bello :) Detto questo, non capisco ancora come Aggregatefunziona, l'ho provato dopo averlo visto in un'altra risposta per arrivare al mio nuovo oggetto invece di un solo campo al suo interno, e ha funzionato perfettamente :)
ldam,

2

R, 83

library(gmp)
n=a:b
n[which.min(lapply(lapply(lapply(n,factorize),max),as.numeric))]

dove viene assegnata la parte inferiore dell'intervallo di input ae la parte superiore ( compresa ) a b.

gmpè un pacchetto disponibile su CRAN. Mi è sembrato sporco finché non ho visto quella mffunzione assurda in CJam. Installa digitando install.packages("gmp")nella console.


1
Se lo stai usando lapply3 volte, potresti volerlo alias (cioè l=lapplye poi usare l(...). Allo stesso modo poiché factorizeè l'unica funzione che si utilizza dal pacchetto, gmpè possibile utilizzare gmp::factorizeinvece di caricare la libreria e quindi utilizzare factorize. Il codice diventerebbe quindi l=lapply;n=a:b;n[which.min(l(l(l(n,gmp::factorize),max),as.numeric))]69 byte.
plannapus,

2

PowerShell - 85

($args[0]..$args[1]|sort{$d=2
while($_-gt1){while(!($_%$d)){$m=$d;$_/=$d}$d++}$m})[0]

Questo ordinerà un intervallo di numeri (inclusi) in base al fattore primo massimo di ciascun numero. Restituisce l'elemento ordinato più basso.

> smooth 5 10
8
> smooth 9 15
12
> smooth 9 16
16
> smooth 157 248
243
> smooth 2001 2013
2002

2

J - 16 caratteri

Utilizzando lo stile ( inizio , lunghezza ) dell'intervallo, come consentito dai commenti.

(0{+/:{:@q:@+)i.

Da usare come verbo diadico: l'argomento left è start , right è length .

   5 (+)i. 6              NB. range
5 6 7 8 9 10
   5 (q:@+)i. 6           NB. prime factorizations
5 0 0
2 3 0
7 0 0
2 2 2
3 3 0
2 5 0
   5 ({:@q:@+)i. 6        NB. largest prime factors
5 3 7 2 3 5
   5 (+/:{:@q:@+)i. 6     NB. sort range by smallest factors
8 6 9 5 10 7
   5 (0{+/:{:@q:@+)i. 6   NB. take first entry
8
   f=:(0{+/:{:@q:@+)i.    NB. can also be named
   2001 f 13
2002

Una soluzione ( inizio , fine ) è +2 caratteri ed esclude la fine; compresa la fine è +2 in più. Ma il lato positivo è piuttosto carino dato che abbiniamo tutti i {parentesi graffe}.

(0{}./:{:@q:@}.)i.    NB. excluding
(0{}./:{:@q:@}.)1+i.  NB. including

2

Scherzi a parte, 8 * 14/7 = 16 (non competitivo)

,x;`yM`M;m@í@E

Seriamente è stato creato dopo questa sfida, ma volevo pubblicare questa risposta perché esemplifica il tipo di sfide Seriamente è bravo.

Provalo online!

Spiegazione:

,x;`yM`M;m@í@E
,x;             make two copies of range(a,b) (a,b = input())
   `  `M;       make two copies of the result of the map:
    yM            push maximum prime factor
         m@í    push index of minimum element from prime factors
            @E  push element from range with given index

2

Pyth , 7 byte

.mePbrF

Provalo qui!

[a,b)[a,b]}r

.mePbrF – Full program with arguments a and b.
     rF – Fold by half-inclusive range. Yields the integers in [a, b).
.m      – Values b in that list which give minimal results when applied f.
  ePb   – function / block f. 
   Pb   – Prime factors of b.
  e     – Last element. This is guaranteed to yield the largest, as they're sorted.

1

Cobra - 150

def f(r as vari int)
    x,y=r
    c,o=y,0
    for n in x:y,for m in n:0:-1
        p=1
        for l in 2:m,if m%l<1,p=0
        if n%m<=0<p
            if m<c,c,o=m,n
            break
    print o

Non sono nemmeno sicuro del motivo per cui mi sono preoccupato, il cobra non può competere qui.


1
Cobra sembra identico a Python ... Quali sono le differenze?
Decadimento beta

@BetaDecay Cobra è ciò che accade quando si dà a C # la sintassi di Python. Il sito web di Cobra
Augurous

1

Rubino - 113 caratteri

Utilizzando lo stdlib. Restituisce un risultato. Testato su rubino 2.1.2.

require 'prime'
def smooth_range(a,b)
  (a...b).sort_by{|e|e.prime_division.flat_map{|f,p|[f]*p}.uniq.max}[0]
end

1
Benvenuto in Programmazione di puzzle e scambio di code stack di golf. Grazie per aver pubblicato il tuo risultato. Dal momento che questa è una domanda di code-golf, includi il numero dei tuoi personaggi nella tua risposta. Puoi usare uno strumento come questo: javascriptkit.com/script/script2/charcount.shtml
isaacg

1

Perl (5.10+), 83

for(<>..<>){$n=$_;$p=2;$_%$p&&$p++or$_/=$p while$_>1;$m=$p,$r=$n if$p<$m||!$m}
say$r

(l'interruzione di riga può essere rimossa). Prende due endpoint di un intervallo inclusivo su due linee di stdin (perché <>è più economico dell'accesso ARGV) e trasmette il più fluido allo stdout. Se c'è una cravatta per il più liscio, stampa il più piccolo. Potrebbe stampare il più grande al costo di un personaggio.

L'algoritmo è fondamentalmente il modo di isaacg di trovare il più grande fattore primo, anche se l'abbiamo trovato in modo indipendente. Quella parte gioca magnificamente fino a una singola affermazione in perl, il resto ha più spese generali di quanto mi piacerebbe però.

Dovrebbe essere eseguito sotto perl -Eo con un use 5.012preambolo. Se non riesci a farlo, sostituiscilo say$rcon print$r,$/.


1

Python 2 (84)

f=lambda n,p=2:n>1and f(n/p**(n%p<1),p+(n%p>0))or p
print min(range(*input()),key=f)

La soluzione di @ isaacg , ma con un mintasto funzione al posto di esplicita ricerca min e una funzione ricorsiva che svolge il ruolo dell'iterazione.

Esegui in Stackless Python per evitare i limiti di ricorsione.

Sembra inutile usare la condizione paresizzata (n%p<1), quindi ripetere la sua negazione anche nelle paratie (n%p>0), ma è stato il migliore che ho ottenuto. Ho provato un sacco di cose, ma sono andate peggio.

f(n/p**(n%p<1),p+(n%p>0))     # Current for comparison
f(*[n/p,n,p,p+1][n%p>0::2])
n%p and f(n,p+1)or f(n/p,p)
f(*n%p and[n,p+1]or[n/p,p])

Accolgo con favore qualsiasi miglioramento tu possa pensare.


1

Java 8 - 422 454 caratteri

Sto imparando Java 8 e volevo dare una possibilità a questo riguardo a Java (o anche ai flussi Java 8).

Rispetto ad altre lingue, questo è un esercizio brutale ma interessante.

golfed:

import java.util.stream.*;import java.math.*;
class F{int v;int i;public int getV() { return v; }
F(int i){this.i = i;v=IntStream.range(2,i+1).map(j->((i%j==0)&&new BigInteger(""+j).isProbablePrime(1))?j:0).max().getAsInt();}}
public class T{
int s(int a, int b){return IntStream.range(a,b+1).boxed().map(F::new).sorted(java.util.Comparator.comparingInt(F::getV)).collect(java.util.stream.Collectors.toList()).get(0).i;}}

Ungolfed:

import java.util.stream.*;
import java.math.*;

class F {
    int v;
    int i;
    public int getV() { return v; }
    F (int i) { 
        this.i = i;
        v = IntStream.range(2,i+1)
                     .map( j -> ((i%j==0) && 
                           new BigInteger(""+j).isProbablePrime(1))?j:0)
                     .max()
                     .getAsInt();
    }
}

public class T {
    int s(int a, int b) {
        return IntStream.range(a,b+1)
                    .boxed()
                    .map(F::new)
                    .sorted(java.util.Comparator.comparingInt(F::getV))
                    .collect(java.util.stream.Collectors.toList())
                    .get(0).i;
    }
}

esempio eseguito usando:

public static void main(String[] s) {
    System.out.println(new T().s(157,249));
}

192

1

MATL ( non competitivo ), 20 byte

Questo linguaggio è stato progettato dopo la sfida

La gamma è inclusiva ad entrambe le estremità. I numeri sono considerati come due ingressi separati.

2$:t[]w"@YfX>v]4#X<)

Provalo online!

Spiegazione

2$:          % implicitly input two numbers. Inclusive range
t            % duplicate                      
[]           % empty array
w            % swap elements in stack         
"            % for each                  
  @          %   push loop variable
  Yf         %   prime factors                  
  X>         %   maximum value
  v          %   vertical concatenation         
]            % end for each                         
4#X<         % arg min 
)            % index with this arg min into initial range of numbers

Immagino che oggi questo sarebbe di 17 byte &:[]y"@YfX>h]&X<)o forse 16 :[]y"@YfX>h]&X<). È &stata davvero una grande idea (e immagino che ynon fosse disponibile allora?).
domenica

E sembra che la trasmissione Yfcon 1 con prefisso sarebbe stata utile anche qui, ma probabilmente non è abbastanza per decidere che è una buona idea in generale. :)
domenica

Sì, questo è stato l'inizio, quindi no yo &. Ringraziamo Suever per l'utilissima semantica di quest'ultimo (la mia idea iniziale era far sì che significasse "un input in più rispetto al default"). Se vediamo più casi in cui Yfcon l'aggiunta di quelli sarebbe utile, potrebbe davvero valere la pena aggiungere quella funzione. Il problema è che ci sono circa 34 risposte che usano Yf(secondo questo script ), quindi è difficile da dire
Luis Mendo,

1

Gelatina , 7 byte, punteggio = 7 ÷ 7 × 8 = 8, sfida postdatati lingua

rÆfṀ$ÐṂ

Provalo online!

Accetta gli endpoint inferiore e superiore come due argomenti separati. Emette un elenco di tutti i numeri più fluidi nell'intervallo. (Questo può essere visto come una funzione, nel qual caso l'output è un elenco Jelly, o come un programma completo, nel qual caso l'output utilizza la stessa rappresentazione dell'elenco che JSON fa.)

Spiegazione

Quelle volte in cui il tuo programma Jelly è solo una traduzione letterale delle specifiche ...

rÆfṀ$ÐṂ
r        Range from {first argument} to {second argument}
     ÐṂ  Return the elements which have the minimum
   Ṁ$      largest
 Æf          prime factor
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.