Hardcoding di sbirri e ladri (ladri)


12

Questa è una sfida per . Il thread della polizia per questa sfida è qui

Una domanda interessante a cui pensare è la seguente:

Se ho una sequenza di numeri quanti ne devo fornire prima che sia chiaro di quale sequenza sto parlando?

Ad esempio, se voglio parlare degli interi positivi in ​​ordine a partire da , potrei dire , ma è davvero abbastanza?1 , 2 , 3 , ...11,2,3,

Ho un modo per rispondere a questa domanda, ed essere un giocatore di codice coinvolge il gioco di codice. Hai fornito abbastanza termini di una sequenza se il codice più breve che produce quei termini produce tutti i termini della sequenza. Se pensiamo a questo in termini di code-golf, ciò significherebbe che hai fornito un numero sufficiente di casi di test in modo tale che il codice più breve che supera i casi di test faccia il compito desiderato.

Sfida

Questa sfida è una sfida per . In cui i poliziotti presenteranno casi di test e i ladri dovranno trovare un modo più breve per falsificare i casi di test diversi dalla sequenza prevista. Gli sbirri presenteranno le seguenti cose:

  • Un pezzo di codice che accetta un intero positivo come input e produce un numero intero come output. Questo codice può essere zero o uno indicizzato ma dovrebbe essere chiaro quale sia l'indicizzazione. Questo codice definirà la sequenza.

  • Qualsiasi piattaforma pertinente o requisiti linguistici che potrebbero influire sull'output, ad esempio la dimensione del longint.

  • Un numero , insieme ai primi termini della sequenza calcolati dal codice. Questi fungeranno da "casi di test".nnn

I ladri troveranno un programma nella stessa lingua che è più breve di quello presentato e supera tutti i casi di test (produce lo stesso output per i primi input del codice del poliziotto). Il codice del ladro deve anche differire nell'output dal programma del poliziotto per un numero maggiore di .nnn

punteggio

I ladri saranno segnati nel numero di crepe che trovano, con più crepe migliori. Una risposta può essere decifrata trovando una risposta valida più breve della crepa originale. Se una risposta viene decifrata una seconda volta, viene dato il punto al secondo cracker anziché al primo.


2
Non stiamo permettendo ai ladri di picchiarsi a vicenda per aver infranto una risposta (ovvero il crack più breve nella lingua vincente)
fəˈnɛtɪk,

@ fəˈnɛtɪk Suoni, bene l'ho aggiunto.
Ad Hoc Garf Hunter,

Risposte:



5

JavaScript, la risposta di fəˈnɛtɪk (17 byte)

x=>"11237"[x]||22

Beh, è ​​stato facile codificare per ottenere un punteggio molto più basso ... Differisce dall'implementazione di riferimento per qualsiasi voce , 0-indicizzata. Questo utilizza un trucco golf JS molto noto: l'indicizzazione in una sequenza con un numero intero che ne supera i limiti restituisce un valore errato ( ), quindi può essere semplicemente forzato a un valore predefinito utilizzando OR logico ( ), in questo caso , gestendo l'ultimo termine della sequenza ma anche quelli da seguire.x6undefined||22

analisi

let f=x=>"11237"[x]||22

for (x of [1,2,3,4,5,6,7]) {
  console.log(x + ' -> ' + f(x))
}

In alternativa, provalo online!


4

Haskell , la risposta di Laikoni , 15 byte

b n=n*div(n+1)2

Provalo online!

Di solito indicherei qualcosa del genere in un commento, ma poi ho pensato che poliziotti e ladri sono un po 'più spietati.

Questa è solo la risposta di BMO meno il caso speciale per b 42. Poiché l'originale di Laikoni passa in virgola mobile, non è necessario: basta trovare un numero abbastanza grande da dare errori di arrotondamento in questo, ma non Integernell'aritmetica esatta . Per esempio:

a 100000000000000000000000 = 4999999999999999580569600000000000000000000000
b 100000000000000000000000 = 5000000000000000000000000000000000000000000000

Ho pensato che questo potesse essere possibile (quindi ho scritto che può essere riscritto per i termini richiesti) ma non ho trovato un valore per il quale funziona .. Ben fatto!
ბიმო

4

Python 2 , risposta di xnor , 43 byte

La prima differenza si verifica per :n=69

f=lambda n,p=2:n<1or-~f(n-(~-2**p%p<2),p+1)

Provalo online!

Titoli di coda

Gran parte del merito di questo crack deve andare a @ Mr.Xcoder che per primo ha pubblicato un commento su un possibile attacco usando questo metodo, e a @PoonLevi che ha trovato una soluzione a 44 byte.

Come?

Teoria

Il crack si basa sul piccolo teorema di Fermat che afferma che se è primo e e sono relativamente primi, allora:a ppap

(1)ap11(modp)

In particolare, per :a=2

2p11(modp)

Quindi esiste un intero positivo tale che:k

2p1=kp+1

Che porta a:

2p=2kp+2
2p1=2kp+1
(2)2p11(modp)

Quest'ultima formula è quella da cui deriva il codice Python e ora vale per , anche se non è relativamente primo con se stesso.p=22

Ora, per la parte più importante: il contrario del piccolo teorema di Fermat non è vero. Potremmo avere per un numero composto . Tali numeri sono chiamati pseudoprimi di Fermat per basare . Gli pseudoprimi di Fermat alla base 2 sono anche noti come numeri di Poulet .an11(modn)na

Il primo pseudoprime di Fermat alla base (o primo numero di Poulet) è , per il quale abbiamo:n = 341 = 11 × 312n=341=11×31

2 341 - 1 1

234111(mod341)
234111(mod341)

Ciò significa che il nostro algoritmo restituirà invece del previsto 69 ° primo .347341347

Implementazione

@PoonLevi ha trovato la seguente soluzione a 44 byte, che si basa direttamente su :(2)

f=lambda n,p=1:n and-~f(n-(~-2**p%p==1),p+1)

Usando <2invece di ==1, salviamo 1 byte ma introduciamo nella sequenza, perché :2 1 - 1 012110(mod1)

f=lambda n,p=1:n and-~f(n-(~-2**p%p<2),p+1)

Provalo online!

Iniziando con , otteniamo i termini previsti di 1 perché eseguiamo una iterazione in meno:p=2

f=lambda n,p=2:n and-~f(n-(~-2**p%p<2),p+1)

Provalo online!

L'ultimo trucco è usare n<1orinvece di n and. Questo è altrettanto lungo, ma fa sì che l'ultima iterazione ritorni su Vero anziché su 0 , aggiungendo quindi l'offset mancante a ciascun termine.


Congratulazioni a tutti voi! Questa è la soluzione che avevo in mente. Penso che sia divertente che, dalla motivazione della sfida "Se ho una sequenza di numeri quanti ne devo fornire prima che sia chiaro di quale sequenza sto parlando?", I primi 50 numeri primi apparentemente non sono sufficienti - un alieno che gioca a golf in Python presumerebbe che tu stia parlando di una sequenza diversa.
xnor

@xnor I love the idea of ​​a "Python-golfing alien"
dylnan,

3

Python 3 , crashoz , 45 byte

lambda n:int(60*math.sin(n/10-2))
import math

Provalo online!

L'espressione x*60-x**3*10+x**5/2-x**7/84è la serie di Taylor per fino al termine , moltiplicato per 60. Questo è abbastanza accurato sugli input utilizzati, ma per valori più alti, i due divergeranno man mano che i termini troncati diventano più rilevanti.x 7sin(x)x7



2

Haskell , la risposta di Laikoni , 26 22 byte

-4 byte non usando infix div, grazie a Laikoni !

b 42=0;b n=n*div(n+1)2

Provalo online!

Spiegazione

Per il termine può essere riscritto in quanto ci dà abbastanza byte per la corrispondenza del modello su un che porta a una crepa entro 28 byte:n > 200n20ceiling(realToFrac n/2)div(n+1)2n>20

b 42=0

Ah, non ci ho pensato. Ho un approccio diverso che porta a una crepa di 20 byte nel caso in cui tu voglia enigma un po 'di più. Anche ((n+1)`div`2)-> div(n+1)2.
Laikoni,

@Laikoni: Sì, non rivelarlo ancora! Oopsies, sì, è passato un po 'di tempo da quando ho giocato a golf, lo aggiornerò.
ბიმო

2

> <> , risposta di crashoz 203 byte

:l2-$g:0=?;n:





M
-
B
"
BM
",
7M
!"
BBM
!",
7CM
!"-
BBBM
!!",
7BBMM
!!,,
7BBBMM
!!,,
7BBBMM
!!!,,
7BBBBMM
!!!,,
7BBBBMM
!!!!,,
7BBBBBMM
!!!!,,
7BBBBBMM
!!!!!,,
7BBBBBBMM

Provalo online!

Stavo per fare qualcosa di intelligente con il fatto che i numeri pari / dispari sopra n=20erano gli stessi, tranne per un elemento ripetuto al centro, ma era più semplice programmare semplicemente ogni elemento.

L'ingresso è tramite la -vbandiera. Non stampa nulla per elementi superiori a 34.


2

Pascal (FPC) , risposta di AlexRacer , 80 byte

var n,m:word;begin read(n);while n<>0 do begin n:=n div 2;m:=m+n;end;write(m)end.

Provalo online!

Quando le uscite sono identiche, ma quando il codice sopra emette , mentre il codice di AlexRacer genera .n = 128 127 1260n120n=128127126

Questa sembra una risposta tardiva, ma grazie @AlexRacer per un buon puzzle!


1
Wow, questo è ancora più breve di quello che avevo. Benvenuti in PPCG!
AlexRacer,


1

JavaScript, la risposta di fəˈnɛtɪk (17 byte)

È possibile vedere nel collegamento TIO o nel risultato dello snippet dello stack che non riesce per le voci superiori a .15

x=>2.7182819**x|1

Se l'accuratezza fosse richiesta solo per (i primi valori), funzionerebbe anche per 16 byte.15n1415x=>Math.exp(x)|1

analisi

f=x=>2.7182819**x|1
g=x=>(3-(5/63)**.5)**x|1

tmp=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]
console.log(tmp.map(f).join(","))
console.log(tmp.map(g).join(","))

In alternativa, provalo online!


1

Husk , cracking 5 byte di BMO con  3  2 byte

-1 grazie a BMO ( LdΣ-> poiché, quando viene dato un Tnum, Lesegue "lunghezza della rappresentazione della stringa")

Provalo online!

La lunghezza digitale dei numeri triangolari * corrisponde quindi differisce da a ... quando si ottiene mentre si ottiene .a ( 24 ) 3 4a(0)a(23)a(24)
3←d+164

* Dove ha una lunghezza digitale di (non )1 0T(0)=010


Congratulazioni, questa è stata la mia soluzione esatta! Comunque ho appena notato che per TNum s Le Ld sono equivalenti risparmio voi un byte;)
ბიმო

Ah, ho cercato "digit" nel wiki per cercare di trovare la lunghezza digitale, ma non ho notato che si Lsostituisce a "lunghezza della rappresentazione della stringa" per Tnum.
Jonathan Allan,

(Si noti che sono equivalenti solo per numeri interi non negativi - abbastanza buono per questo.)
Jonathan Allan


0

JavaScript, la risposta di fəˈnɛtɪk , 23 byte

Restituisce per .n 140n14

x=>14-`${73211e9}`[x]|0

Provalo online!

Come?

L'espressione si `${73211e9}`espande nella stringa "73211000000000", fornendo una tabella di ricerca di 14 valori sottratti da 14, che fornisce la sequenza prevista.

Per , il risultato è:n14

(14 - undefined) | 0
=== NaN | 0
=== 0

21 byte

Restituisce NaNper , che può o non può essere considerato un output valido.n14

x=>14-`${73211e9}`[x]

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.