La sfida dell'errore fatale


20

Obbiettivo

Scrivere una routine che accetta una stringa di caratteri ASCII stampabili, s , e restituisce una stringa contenente gli stessi caratteri s , riordinate in modo che non ci sono due caratteri sottostringa appare più di una volta. Il programma deve elaborare tutte le stringhe di benchmark (vedi sotto) in meno di un minuto ciascuna su un computer moderno . Assegnerò anche un bonus speciale di 50 ripetitori alla risposta con il punteggio più basso che elabora qualsiasi stringa valida di 30 caratteri in meno di un minuto.

Ad esempio, dato l'input Mississippi, un output valido sarebbe issiMspiips(nessuna sottostringa a due caratteri appare due volte), mentre un output non valido sarebbe ipMsispiiss(poiché la sottostringa isappare due volte).

La routine può assumere la forma di:

  • un programma completo che legge dalla stdin(o equivalente) o dalla riga di comando e che emette stdout(o equivalente)
  • una funzione che accetta un singolo argomento stringa e restituisce una stringa

Si può presumere che la stringa di input ammetta sempre almeno un output valido.

La sfida

La routine deve comprendere 5 o più righe di codice separate da newline. Le righe vuote (che includono righe contenenti solo spazi bianchi) vengono ignorate in tutti i contesti e non vengono conteggiate nel conteggio totale delle righe.

Lo scambio di due righe qualsiasi nel codice sorgente deve produrre un errore irreversibile. Per "errore fatale", ci riferiamo a una delle seguenti condizioni:

  • la compilazione del codice sorgente non riesce, con il compilatore / interprete che dichiara un errore fatale
  • la routine si interrompe con un errore irreversibile di runtime o un'eccezione di runtime non gestita
  • la routine viene forzata in una chiusura improvvisa e anormale del programma che non produce alcun output di alcun tipo se non per un possibile messaggio di errore e / o dump dello stack

In alternativa , al posto delle righe possono essere utilizzati blocchi di codice contigui che non contengono caratteri di nuova riga. Ciascuno di questi blocchi dovrebbe essere visualizzato sulla propria riga nel file sorgente, con la consapevolezza che le nuove righe vengono rimosse prima che il codice sorgente venga compilato / interpretato.

Ad esempio, il codice

aaaa
bbbb
cccc

si condenserebbe

aaaabbbbcccc

prima di essere valutato.

In questa modalità, la condizione di errore irreversibile si applica allo scambio di due blocchi di codice (e quindi allo scambio di righe nel codice sorgente prima che vengano rimosse le nuove righe). Quindi nell'esempio sopra le routine aaaaccccbbbb, bbbbaaaacccce ccccbbbbaaaadevono tutti produrre errori fatali, sia in fase di compilazione che in fase di esecuzione.

Gli invii che utilizzano questa modalità alternativa devono dichiararne l'utilizzo.

punteggio

Sia n il numero di righe di testo non vuote nel file di origine, con n ≥ 5. Sia c il numero di byte compreso dalla riga di testo più lunga (in base alla lunghezza dei byte) nel file di origine, senza contare alcuna riga successiva.

Il punteggio di un invio è dato da c ( n + 10).

La presentazione con il punteggio più basso è il vincitore.

Buona fortuna. ;)

Stringhe di benchmark

Abracadabra Alacazam
Is Miss. Mississauga Missing?
Ask Alaska's Alaskans
GGGGAAAATTTTCCCCgggaaatttccc
A Man A Plan A Canal Panama

Le lettere maiuscole sono diverse dalle lettere minuscole? cioè l'ingresso è CooliO, l'uscita oOoCli?
FryAmTheEggman,

@FryAmTheEggman: Sì. Le lettere maiuscole differiscono dalle lettere minuscole. In generale, considerare solo i valori del codice ASCII dei caratteri.
COTO

Le ripetizioni si limitano alle coppie di lettere che compaiono nell'input? Ad esempio, è Mspiisiipssvalido poiché l'unica ripetizione è in iicui non si verifica Mississippi?
TwiNight,

@TwiNight: non sono consentite nemmeno sottostringhe ripetute che non compaiono nella stringa originale.
COTO,

Posso assumere qualcosa sulla lunghezza dell'input? (sfondo: un'idea geniale per una soluzione BF)
PurkkaKoodari,

Risposte:


6

PHP, punteggio = 289 (17 × (7 + 10))

Le funzioni integrate di PHP rendono abbastanza facile farlo male. Il codice seguente mescola semplicemente la stringa fino ad ottenere un risultato valido:

function f($s){
while(preg_match(
'/(..).*?\1/',$s)
+preg_match('/(.'
.')\1\1/',$s))$s=
str_shuffle(
$s);return $s;}

Punti di riferimenti

Tempi medi e massimi di esecuzione calcolati utilizzando il seguente codice:

$s = 'Mississippi';
$t_total = 0;
$t_max = 0;
for ($i=0; $i<10; $i++) {
  $t0 = microtime(true);
  echo f($s);
  $t = microtime(true) - $t0;
  printf("  %10.7f\n",$t);
  $t_total += $t;
  if ($t > $t_max) $t_max = $t;
}
printf("Avg: %10.7f secs; Max: %10.7f secs\n",$t_total/$i, $t_max);

risultati:

  • Mississippi: media: 0.0002460 sec; Max: 0.0005491 sec
  • Anticonstitutionnellement: Average: 0.0001470 sec; Max: 0.0002971 sec
  • Pneumonoultramicroscopicsilicovolcanoconiosis: media: 0,0587177 secondi; Max: 0,1668079 secondi
  • Donaudampfschiffahrtselektrizitatenhauptbetriebswerkbauunterbeamtengesellschaft * : media: 9.5642390 sec; Max: 34.9904099 sec
  • baaacadaeafbbcbdbebfccdcecfdde : media: 5.0858626 secondi; Max: 9,8927171 secondi

* Ho cambiato äper aevitare problemi multi-byte
† Questa era la stringa di 30 caratteri più difficile che potessi inventare. In realtà sono i primi 30 caratteri della sequenza di De Bruijn per k = 'abcdef' e n = 2, con la prima 'b' spostata per evitare una corrispondenza istantanea.


5
Ciò non soddisfa > Il programma deve elaborare una stringa valida di 30 caratteri in meno di un minuto su un computer moderno. , considerando il runtime potenzialmente infinito.
Bob,

@Bob Ho aggiunto alcuni parametri di riferimento alla risposta. Il codice può essere inefficiente, ma la probabilità che impieghi più di un minuto per elaborare una stringa di 30 caratteri è, a mio avviso, davvero molto piccola.
ossifrage schifoso

5

Dyalog APL (11 (5 + 10) = 165)

f←{a←{⍴⍵}
b←a⌸2,/⍵
c←b⊢⍵[?⍨a⍵]
1∨.≠b:∇c⋄⍵
}

Prova:

  • Le righe 1 e 5 hanno associato la funzione. Lo scambio di qualsiasi riga con quelli comporterebbe il verificarsi al di fuori di una funzione, che è a SYNTAX ERROR.
  • La linea 2 definisce b, quindi non può essere scambiata con linee 3o 4, da cui dipendono b. Ci sarebbe un VALUE ERROR. (E ovviamente non può essere scambiato 1né con 5nessuno dei due.)
  • La linea 3 definisce c, quindi non può essere scambiata con la linea 4, da cui dipende c. (E abbiamo già dimostrato che nessun'altra linea può essere scambiata con la linea 3.)
  • La riga 4 dipende dalle variabili dalle righe 2 e 3 e deve quindi essere l'ultima.

3
+1. Ma che cosa fa tutto media ??
ossifrage schifoso

4

APL (Dyalog), 6 (5 + 10) = 90

{1∧.=
+/∘.≡⍨
2,/⍵:⍵
⋄∇⍵[
?⍨⍴⍵]}

Sto usando l'alternativa, quindi:

{1∧.=+/∘.≡⍨2,/⍵:⍵⋄∇⍵[?⍨⍴⍵]}

Questo è lo stesso vecchio algoritmo.


La spiegazione
2,/⍵ fornisce una matrice di coppie di caratteri nella stringa di input
+/∘.≡⍨genera una matrice numerica di quante coppie ogni coppia è uguale (incluso se stessa)
1∧.=controlla se ogni elemento di quella matrice è uguale a 1 e logico AND i risultati insieme

:⍵Se questo è true ( 1), restituisce la stringa di input

∇⍵[?⍨⍴⍵] altrimenti rimescola la stringa di input ed effettua una chiamata ricorsiva


Swapping

Se la riga 1 viene scambiata con la riga 2, si finisce con +/∘.≡⍨{...}quale è solo un casino di funzioni e operatori che danno SYNTAX ERROR.
Se la riga 1 viene scambiata con la riga 3 o 4, allora hai una definizione di funzione esterna, e questo è un SYNTAX ERROR.
Se la riga 1 viene scambiata con la riga 5, solo le parentesi sbilanciate potrebbero causare SYNTAX ERROR, quindi non preoccuparti degli altri 4 errori di sintassi.

Se la riga 5 viene scambiata con la riga 2/3/4, si ha di nuovo una definizione di funzione esterna. ( SYNTAX ERROR)

Se la riga 2 viene scambiata con la riga 3, si finisce con 1∧.=2,/⍵:⍵. Questa sintassi è chiamata guardia (pensala come un condizionale). La condizione di guardia deve valutare in 0o 1o un array di 1 elemento di 0o 1. Qui, valuta qualcosa di più complesso di quello (uno scalare contenente un array di 2 elementi). Quindi questo è un DOMAIN ERROR.
Se la riga 2 viene scambiata con la riga 4, si ottiene l'istruzione 1∧.=, che tenta di applicare la funzione ∧.=senza l'argomento sinistro richiesto. ( SYNTAX ERROR).

Se la riga 3 viene scambiata con la riga 4, di nuovo si ottiene un casino di funzioni e operatori ( 1∧.=+/∘.≡⍨) in modo da ottenere SYNTAX ERROR.


Benchmark
(numeri in millisecondi)

Abracadabra Alacazam
11 1 3 5 2
Avg: 4.4

Is Miss. Mississauga Missing?
1260 2000 222 117 111
Avg: 742

Ask Alaska's Alaskans
7 2 3 3 4
Avg: 3.8

GGGGAAAATTTTCCCCgggaaatttccc
31 15 24 13 11
Avg: 18.8

A Man A Plan A Canal Panama
377 2562 23 301 49
Avg: 662.4

Sto ancora pensando a diverse divisioni. Inoltre ho un modo deterministico e sistematico di svolgere il compito. Non riesco proprio a trasformarlo in un algoritmo (togli la parte creativa del "rendere i numeri giusti") e non posso assicurarmi che funzioni ogni volta.


0

Haskell, 129 = 3x (33 + 10)

questo utilizza la modalità alternativa.

imp
ort
 Da
ta.
Lis
t;a
%[]
=[[
]];
a%s
=[x
:j|
x<-
s,n
ot$
isI
nfi
xOf
[la
st 
a,x
]a,
j<-
(a+
+[x
])%
(s\
\[x
])]
;g 
s=[
]%s
!!0

o in una forma leggibile:

import Data.List
a%[]=[[]]
a%s=[x:j|x<-s,not$isInfixOf[last a,x]a,j<-(a++[x])%(s\\[x])]
g s=[]%s!!0

Haskell è un linguaggio molto rigoroso. per esempio, il importprimo deve venire; le definizioni di smust si fondono; tutti i tipi devono essere d'accordo e non c'è modo di lanciarsi tra di loro, e così via. questo porta ad avere un errore non fatale quasi impossibile. infatti, avere un errore fatale durante il runtime è quasi quasi impossibile.

si noti che if gè una funzione valida ma ha un tipo errato (qualsiasi tipo diverso allora [a]->[a]o String -> Stringe simili) di questo è un errore fatale perché è impossibile applicare gagli input.

uscite:

Abracadabar Alaazcma
Is Miss. iMsiasusgsa sMniig?s
Ask Alasak's lAaankss
GGAGTGCAATACTTCCggagtaacttcc
A Man AP la nAC  aalnnaPama
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.