Trova il primo più piccolo da una sottostringa


17

Nel 1946 Erdos e Copeland dimostrarono che un certo numero è un numero normale , cioè le cifre nella sua espansione decimale sono distribuite uniformemente.

Gli utenti inseriranno una sequenza di cifre e troverai il primo più piccolo che contiene quella stringa nella base 10.

Esempio:

input   -> output
"10"    -> 101
"03"    -> 103
"222"   -> 2221
"98765" -> 987659

Vince il codice più breve in byte . So che alcune lingue (matematica, sage, pari-gp ...) sono dotate di funzioni integrate relative ai numeri primi. -50 byte se il programma non si basa su tali funzioni. Non cercare di tradire, per favore, se la tua lingua ha già un enorme vantaggio, non richiedere il bonus.

modificare

Secondo alcuni commenti qui sotto, il numero primo più piccolo che contiene "03" è 3. Questo fa davvero la differenza? L'unica cosa che mi viene in mente è che forse i numeri sono più facili da gestire delle stringhe.

In casi come "03" l'output preferito sarebbe 103. Tuttavia, non considero la parte fondamentale del tuo programma, quindi sei libero di ignorare qualsiasi zero iniziale se ti concede un conteggio di byte inferiore.


5
Sembra una buona base per un compito di Project Euler
John Dvorak,

Il primo più piccolo contenente "03" è 03. Forse dovresti aggiungere una regola che chiarisca che l'input può contenere zeri iniziali ma l'output potrebbe non esserlo.
Level River St

2
@steveverrill non esiste un numero come 03. Se volevi dire 3, allora non contiene "03".
John Dvorak,

3
@JanDvorak 03 è una rappresentazione valida del numero 3. (2.9 ... ricorrendo all'infinito, equivalente a 2 + 9/9, è anche considerato da alcuni una rappresentazione valida.) Capisco dall'esempio dato che 03 non è accettabile rappresentazione per questa domanda. Questo è un punto importante, ma dato il solito abuso delle regole, penso che valga la pena farlo.
Level River St

1
Penso che il modo migliore per formulare una frase sarebbe quello di trovare il numero più piccolo che, convertito in una stringa, contenga "03".
Thebluefish

Risposte:


13

Golfscipt, 33 32 byte = -18 punti

2{:x,2>{x\%!},!!x`3$?)!|}{)}/;;x

Spiegazione:

  • 2{...}{)}/- a partire da 2, mentre qualcosa è vero, incrementa la parte superiore dello stack
  • ;;x- scartare i valori intermedi raccolti da {}{}/e l'input, quindi inserire l'ultimo valore testato lì

  • :x,2>- memorizza il valore come x, quindi produce un elenco da 2ax-1

  • {x\%!},!!- mantieni quelli che xsono divisibili per, poi costringili a booleani (non vuoti)
  • x`3?)!- cerca l'input sotto forma di testo x( -1se non trovato), incrementa, annulla.
  • | - o

7

Programma Haskell, 97 caratteri = 47 punti

main=getLine>>= \i->print$head$[x|x<-[2..],all((/=0).mod x)[2..x-1],i`Data.List.isInfixOf`show x]

Funzione Haskell, 75 caratteri = 25 punti

p i=head$[x|x<-[2..],all((/=0).mod x)[2..x-1],i`Data.List.isInfixOf`show x]

il tipo di pè (Integral a, Show a) => [Char] -> a. Se si fornisce il proprio tipo integrale, è possibile cercare per infisso nella propria rappresentazione di tali valori. Lo standard Integerutilizza la notazione decimale prevista per gli interi.

Non molto veloce Quadratico nel valore (non dimensione) dell'output.

versione non golfata:

import Data.List
leastPrime infix = head $ filter prime' [2..]
  where prime' x  = all (\n-> x`mod`n /= 0) [2..x-1]
                 && i `isInfixOf` show x
main = print . leastPrime =<< getLine

esempio:

Prelude> let p i=head$[x|x<-[2..],all((/=0).mod x)[2..x-1],i`Data.List.isInfixOf`show x]
Prelude> p "0"
101
Prelude> p "00"
1009
Prelude> p "000" -- long pause
10007

3

Java - 175 caratteri.

class s{public static void main(String[]a){int i,n=2,p;for(;;){p=1;for(i=3;i<n;i++)if(n%i==0)p=0;if((n==2||p>0)&&(""+n).indexOf(a[0])>=0) {System.out.println(n);break;}n++;}}}

Puoi salvare 1 personaggio facendo cadere lo spazio tra indexOf(a[0])>=0)e {System.out.println(n).
Programma FOX

@ProgramFOX Grazie.
jolly

Penso che puoi facilmente salvare (circa 8) personaggi sostituendoli boolean p=truecon qualcosa di simile int p=1e così via.
florian h

dichiarando tutti i tuoi ints contemporaneamente ridurrai ulteriormente le dimensioni del tuo programma.
Olivier Grégoire,

3

Mathematica 58

(n=1;While[StringCases[ToString[p=Prime@n],#]=={},n++];p)&

Tempi relativi sul mio Mac (2,6 GHz i7 con 8 GB di memoria).

Trova il primo più piccolo contenente "01".

AbsoluteTiming[(n = 1; While[StringCases[ToString[p = Prime@n], #] == {}, n++]; p) &["01"]]

{0.000217, 101}


Trova il primo più piccolo contenente "012345".

AbsoluteTiming[(n = 1; While[StringCases[ToString[p = Prime@n], #] == {}, n++]; p) &["012345"]]

{5.021915, 10123457}


Trova il numero primo più piccolo contenente "0123456".

AbsoluteTiming[(n = 1; While[StringCases[ToString[p = Prime@n], #] == {}, n++]; p) &["0123456"]]

{87.056245, 201234563}


Puoi usarlo StringFreeQper ridurlo.
alephalpha

2

Salvia , 72

Viene eseguito nel prompt interattivo

a=raw_input()
i=0
p=2
while a not in str(p):i+=1;p=Primes().unrank(i)
p

Primes().unrank(i)dà il inumero primo primo, con il primo numero primo 2.


2

R, 56chars -50 = 6

k=2;n=scan(,"");while(!grepl(n,k)|sum(!k%%2:k)>1)k=k+1;k

Prendi input come stdin. Incrementa k fino a quando k è un numero primo (testato sommando le istanze per cui k mod da 2 a k sono zero, quindi FALSO poiché 0 trasformato in un logico è FALSO) e contiene la stringa fornita come input (testata con un semplice grep, qui grepl dal momento che vogliamo un risultato logico).

Uso:

> k=2;n=scan(,"");while(!grepl(n,k)|sum(!k%%2:k)>1)k=k+1;k
1: "03"
2: 
Read 1 item
[1] 103
> k=2;n=scan(,"");while(!grepl(n,k)|sum(!k%%2:k)>1)k=k+1;k
1: "003"
2: 
Read 1 item
[1] 2003

2

shell oneliner (coreutils): 45chars

Non definendo una funzione qui ... solo un oneliner che accetta un argomento $ne scansiona l'intervallo intero (in realtà un po 'di più per rendere il codice più breve). La versione da 55 caratteri:

seq 5e9|grep $n|factor|awk '{if(NF==2)print $2}'|head -n1

Non è nemmeno troppo lento. Per n=0123456ritorna 201234563in 81.715s. È incredibilmente veloce per una lunga pipeline con due processori di stringhe.

Rimuovendo due caratteri (fino a 53) e una pipe, possiamo farlo funzionare ancora più velocemente:

seq 5e9|grep $n|factor|awk '{if(NF==2){print $2;exit}}'

E infine, alcuni sedmaghi per ridurlo a 45 caratteri , anche se la stampa è brutta:

seq 5e9|grep $n|factor|sed -n '/: \w*$/{p;q}'

n = 000 -> 10007: 10007 (utente 0,017 s)

n = 012345 -> 10123457: 10123457 (utente 7.11s)

n = 0123456 -> 201234563: 201234563 (utente 66,8 s)


2

J - 38 caratteri -50 = -12 punti

Normalmente in J, useresti i builtin molto ottimizzati dedicati ai numeri primi, quindi non mi scuserò per la lentezza nell'esecuzione.

>:@]^:(>./@(E.":)*:]=*/@(+.i.)@])^:_&2

Ha spiegato:

  • >:@]^:(...)^:_&2- A partire da 2, incrementa fino a quando non (...)restituisce false.
  • (+.i.)@]- Prendi il GCD del contatore con ogni numero intero più piccolo di esso. (Usiamo la convenzione GCD (X, 0) = X.)
  • ]=*/@- Prendi il prodotto di tutti questi numeri e verifica l'uguaglianza al banco. Se il contatore è primo, l'elenco era tutto 1s, tranne il GCD con 0; altrimenti ci sarà almeno un GCD che è maggiore di 1, quindi il prodotto sarà maggiore del contatore.
  • >./@(E.":)- Verifica se la rappresentazione di stringa del contatore ( ":) contiene la stringa ( E.) in qualsiasi momento. >./è la funzione max e la usiamo perché E.restituisce un vettore booleano con un 1 ogni volta che la sottostringa inizia nella stringa principale.
  • *:- Logica NAND i risultati insieme. Questo sarà falso solo se entrambi gli input fossero veri, cioè se il contatore fosse entrambi primo e contenesse la sottostringa.

Uso:

   >:@]^:(>./@(E.":)*:]=*/@(+.i.)@])^:_&2 '03'
103
   >:@]^:(>./@(E.":)*:]=*/@(+.i.)@])^:_&2 '713'
2713

Per i posteri, ecco la versione che usa l'integrato prime (lungo 30 caratteri, ma senza bonus):

>:@]^:(>./@(E.":)*:1 p:])^:_&2

1 p:] testa il contatore per la primalità, invece del trucco GCD.


2

Brachylog (v2), 3 byte nella codifica di Brachylog

ṗ≜s

Provalo online!

Invio di funzioni, prendendo input dall'argomento di destra, dando output mutando l'argomento di sinistra. (Questo è l'opposto della normale convenzione di Brachylog; vedere questo meta post per ulteriori discussioni. Lo scambio degli argomenti nell'ordine più normale costerebbe tre byte.) Il collegamento TIO ha un wrapper che chiama la funzione con la convenzione di chiamata appropriata e stampa il risultato.

Spiegazione

ṗ≜s
 ≜   Find the integer closest to zero
ṗ      which is prime {implicit: and output it via the left argument}
  s    and which is a substring of the {right argument}

Purtroppo, Brachylog è così appropriato per questo problema che, secondo le regole del problema, non posso nemmeno tentare di ottenere il bonus (il che significa ironicamente che non è in grado di vincere).

Uno dei motivi per cui mi piace così tanto Brachylog è che la programmazione è una comunicazione tra uomo e computer, e quindi un linguaggio "perfetto" ti permetterebbe di tradurre direttamente le specifiche del problema in inglese; le idee attraverso le quali è stato affermato il problema e tramite le quali è stato scritto il programma sarebbero le stesse. Brachylog può colpire questo ideale sorprendentemente spesso; la domanda qui è "trova il primo più piccolo contenente una determinata sottostringa", e posso letteralmente mettere insieme i concetti di "più piccolo, primo, contenente la sottostringa" nell'ordine corretto e avere un programma di lavoro. Come tale, Brachylog dice molto di più sulla natura della comunicazione rispetto a un linguaggio in cui dovresti specificare esplicitamente un algoritmo per risolvere il problema; a volte quando si parla con altri umani, proviamo a spiegare un problema spiegando i passi che faresti per risolverlo, ma è raro. Quindi perché le nostre lingue dovrebbero essere diverse?


1

JavaScript 83 byte = 33 punteggio

golfed:

for(s=prompt(n=x=0);!n;x++)for(n=(''+x).match(s)?2:0;n&&n<x;n=x%n?n+1:0);alert(x-1)

Ungolfed (un po '):

s=prompt() // get the input
n = 0
for(x=0;!n;x++) // stop when n is non-zero
    if ((''+x).match(s)) { // if x matches the pattern, check if x is prime
        for(n=2;n&&n<x;)
            n = (x%n == 0) ? 0 : n+1; // if x%n is zero, x is not prime so set n=0
        // if n is non-zero here, x is prime and matches the pattern
    }
alert(x-1)

0

Javascript (Node.JS) - 93 byte = 43 punti

l:for(i=x=process.argv[2];j=i;i++){while(--j>2)if(!(i%j*(""+i).match(x)))continue l
throw i}

In forma estratta con nomi di variabili sensibili:

outerLoop:for (currentTry=inputNumber=process.argv[2]; primeIterator=currentTry; currentTry++ ) {
    while (--primeIterator > 2) 
        if(!(currentTry % primeIterator * (""+currentTry).match(inputNumber)))
            continue outerLoop;
    throw i
}

0

Ruggine 0,9 136 byte = 86 punti

fn main(){
   let mut n:u32=2;
   while n.to_str().find_str(std::os::args()[1])==None ||
         range(2,n).find(|&x|n%x==0)!=None {
      n=n+1;
   }
   print!("{}",n);
}

Molto esplicito nonostante la compattezza. Troppo spazio speso nella ricerca della stringa. :(

Qui la versione senza spazi bianchi (136 caratteri)

fn main(){let mut n:u32=2;while n.to_str().find_str(std::os::args()[1])==None||range(2,n).find(|&x|n%x==0)!=None{n=n+1;}print!("{}",n);}



0

Perl 6 , 36 - 50 = -14 punti

{$^a;first {/$a/&&$_%%one ^$_},2..*}

Provalo online!

Considerare che $_%%one ^$_è solo 2 byte più piccolo di.is-prime , penso che ne valga la pena per il bonus. Questo è scaduto per l'ultimo caso di test.

Spiegazione:

{                                  }  # Anonymous code block
 $^a;                                 # Assign input to $a
     first                    ,2..*   # Find the first number
           {                 }        # Which
            /$a/                        # Contains the input
                &&                      # And
                  $_%%one ^$_           # Is prime

2 byte più piccoli?
ASCII il

lol @ la parte nella domanda che dice "Non provare a tradire questo per favore, se la tua lingua ha già un enorme vantaggio non richiedere il bonus".
ASCII il

@ Solo ASCII Beh, sono ancora battuto da GolfScript, quindi ...:$
Jo King

0

Python 3 , 80 79 byte - 50 = 30 29 punti

-1 byte grazie all'uso creativo di @ ASCII %sinvece distr

Il test case "98765" non è stato ancora confermato a causa del tempo impiegato per il test. Confermato per il test case "98765" dopo un paio d'ore, ma con un approccio simile che utilizza la valutazione del corto circuito per evitare alcuni test di primalità, funziona più veloce. In alternativa, questo può essere ~ 2x più veloce se sappiamo che "2" non è un input (possiamo evitare di controllare i numeri pari per la primalità) impostando i=3inizialmente e i+=2nel ciclo, senza costi di byte aggiuntivi.

def f(x):
 i=2
 while(x in"%s"%i)*all(i%j for j in range(2,i))-1:i+=1
 return i

Provalo online!

Spiegazione della whilecondizione ( (x in"%s"%i)*all(i%j for j in range(2,i))-1):

(x in"%s"%i): True/ 1se il contatore corrente contiene al suo interno la sequenza di numeri desiderata; False/ 0Altrimenti.

all(i%j for j in range(2,i)): True/ 1se il contatore corrente ha sempre un resto quando diviso per qualsiasi numero intero da 2 (compreso) a se stesso (esclusivo), ovvero è primo; False/0 Altrimenti.

I *moltiplica le due condizioni insieme, e agisce come un andoperatore - il prodotto è True/ 1se e solo se entrambe le condizioni sono True/1 .

La -1agisce come notesercente: False/ 0- 1 risultati in -1, che è considerato vero, che True/ 1- 1 risultati in0 , che è considerato falso. Pertanto, il ciclo continua mentre il numero o non contiene la sequenza di numeri desiderata o non è un numero primo.

Sostituisci *con ande aggiungi parentesi intorno a tutto tranne che a-1 per una soluzione equivalente molto più veloce (che è leggermente più lunga).

Una soluzione a 76 byte - 50 = 26 in Python 2 data solo da @ ASCII (utilizza ``invece di str(),

def f(x):
 i=2
 while(x in`i`)*all(i%j for j in range(2,i))-1:i+=1
 return i

Provalo online!



@ ASCII-only Non ho usato molto Python 2 e uso principalmente Python 3, quindi è quello che gioco a golf. Anche se sembra che la maggior parte delle volte Python 2 finisca per essere più corto ...
Neil A.

Hai fatto un refuso, nel primo che haireturn I
solo ASCII il


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.