Tantangan Kesalahan Fatal

20

Objektif

Tulis rutin yang menerima string karakter ASCII yang dapat dicetak, s , dan mengembalikan string yang berisi karakter yang sama dengan s , disusun ulang sehingga tidak ada substring dua karakter yang muncul lebih dari satu kali. Program harus memproses semua string benchmark (lihat di bawah) masing-masing dalam waktu kurang dari satu menit pada komputer modern . Saya juga akan penghargaan bonus khusus dari 50 rep untuk jawaban skor terendah yang memproses setiap string yang 30-karakter yang valid di dalam satu menit.

Misalnya, dengan diberi input Mississippi, output yang valid adalah issiMspiips(tidak ada substring dua karakter yang muncul dua kali), sedangkan output yang tidak valid adalah ipMsispiiss(karena substring ismuncul dua kali).

Rutin dapat berupa:

  • pembacaan program lengkap dari stdin(atau setara) atau baris perintah, dan keluaran ke stdout(atau setara)
  • sebuah fungsi yang menerima argumen string tunggal dan mengembalikan string

Anda dapat mengasumsikan bahwa string input selalu mengakui setidaknya satu output yang valid.

Tantangan

Rutin Anda harus terdiri dari 5 atau lebih baris kode yang dipisahkan oleh baris baru. Baris kosong (yang termasuk baris yang hanya berisi spasi putih) diabaikan dalam semua konteks dan tidak dihitung terhadap jumlah baris total.

Mengganti dua baris dalam kode sumber Anda harus menghasilkan kesalahan fatal. Dengan "kesalahan fatal", kami merujuk ke salah satu kondisi berikut:

  • kode sumber gagal dikompilasi, dengan kompiler / juru bahasa menyatakan kesalahan fatal
  • aborsi rutin dengan kesalahan fatal runtime atau pengecualian runtime tidak tertangani
  • rutin dipaksa menjadi penghentian tiba-tiba, program abnormal yang tidak menghasilkan output apa pun kecuali untuk pesan kesalahan yang mungkin dan / atau tumpukan dump

Atau , blok kode yang berdekatan yang tidak mengandung karakter baris baru dapat digunakan sebagai ganti baris. Blok-blok ini masing-masing harus ditampilkan pada baris mereka sendiri di file sumber, dengan pemahaman bahwa baris baru dihapus sebelum kode sumber dikompilasi / ditafsirkan.

Misalnya kodenya

aaaa
bbbb
cccc

akan mengembun

aaaabbbbcccc

sebelum dievaluasi.

Dalam mode ini, kondisi kesalahan fatal berlaku untuk menukar dua blok kode apa pun (dan dengan demikian untuk menukar baris dalam kode sumber sebelum baris baru dihapus). Oleh karena itu dalam contoh di atas rutinitas aaaaccccbbbb, bbbbaaaaccccdan ccccbbbbaaaasemua harus menghasilkan kesalahan fatal, baik di compiletime atau runtime.

Pengajuan yang menggunakan mode alternatif ini harus menyatakan penggunaannya.

Mencetak gol

Biarkan n menjadi jumlah baris teks tidak kosong dalam file sumber Anda, dengan n ≥ 5. Biarkan c menjadi jumlah byte yang terdiri dari baris teks terpanjang (dengan panjang byte) dalam file sumber Anda, tidak termasuk baris baru yang tertinggal.

Skor pengajuan diberikan oleh c ( n + 10).

Pengajuan dengan skor terendah adalah pemenang.

Semoga berhasil. ;)

String Tolok Ukur

Abracadabra Alacazam
Is Miss. Mississauga Missing?
Ask Alaska's Alaskans
GGGGAAAATTTTCCCCgggaaatttccc
A Man A Plan A Canal Panama
COTO
sumber
Apakah huruf kapital berbeda dari huruf kecil? yaitu input CooliO, output oOoCli?
FryAmTheEggman
@FryAmTheEggman: Ya. Huruf kapital berbeda dari huruf kecil. Secara umum, pertimbangkan hanya nilai kode ASCII dari karakter.
COTO
Apakah pengulangan membatasi pasangan surat yang muncul di input? Misalnya, Mspiisiipssvalid karena satu-satunya pengulangan iiyang tidak terjadi Mississippi?
TwiNight
@Wiwi: Substring berulang yang tidak muncul di string asli tidak diperbolehkan
COTO
Bolehkah saya berasumsi tentang panjang input? (latar belakang: mendapat ide cemerlang untuk solusi BF)
PurkkaKoodari

Jawaban:

6

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

Fungsi bawaan PHP membuatnya mudah untuk melakukan hal ini dengan buruk. Kode berikut hanya mengacak string hingga hasil yang valid diperoleh:

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

Tingkatan yang dicapai

Rata-rata dan waktu eksekusi maksimum dihitung menggunakan kode berikut:

$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);

Hasil:

  • Mississippi: Rata-rata: 0,0002460 detik; Maks: 0,0005491 dtk
  • Anticonstitusinellement: Rata-rata: 0,0001470 detik; Maks: 0,0002971 dtk
  • Pneumonoultramicroscopicsilicovolcanoconiosis: Rata-rata: 0,0587177 detik; Maks: 0,1668079 detik
  • Donaudampfschiffahrtselektrizitatenhauptbetriebswerkbauunterbeamtengesellschaft * : Harga rata-rata: 9.5642390 dtk; Maks: 34,9904099 dtk
  • baaacadaeafbbcbdbebfccdcecfdde : Rata-rata: 5.0858626 detik; Maks: 9.8927171 detik

* Saya mengubah äuntuk amenghindari masalah multi-byte
† Ini adalah string 30-karakter tersulit yang dapat saya buat. Ini sebenarnya 30 karakter pertama dari urutan De Bruijn untuk k = 'abcdef' dan n = 2, dengan 'b' pertama dipindahkan untuk menghindari pertandingan instan.

osifrque melengking
sumber
5
Ini tidak terlalu memuaskan > Program harus memproses string 30 karakter yang valid dalam waktu kurang dari satu menit pada komputer modern. , mengingat kemungkinan runtime yang tak terbatas.
Bob
@ Bob Saya telah menambahkan beberapa tolok ukur untuk jawabannya. Kode mungkin tidak efisien, tetapi kemungkinan butuh lebih dari satu menit untuk memproses string 30 karakter, saya pikir, memang sangat kecil.
Lubang keras mual
5

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

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

Bukti:

  • Baris 1 dan 5 mengikat fungsi. Menukar setiap baris dengan yang akan menghasilkan terjadi di luar fungsi, yaitu a SYNTAX ERROR.
  • Baris 2 mendefinisikan b, sehingga tidak dapat ditukar dengan garis 3atau 4, yang bergantung pada b. Akan ada a VALUE ERROR. (Dan itu jelas tidak bisa ditukar dengan 1atau 5salah.)
  • Baris 3 mendefinisikan c, sehingga tidak dapat ditukar dengan jalur 4, yang tergantung pada c. (Dan kami sudah membuktikan tidak ada jalur lain yang bisa ditukar dengan garis 3.)
  • Baris 4 tergantung pada variabel dari baris 2 dan 3 dan karena itu harus menjadi yang terakhir.
marinus
sumber
3
+1. Tapi apa itu semua berarti ??
Lubang keras mual
4

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

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

Saya menggunakan alternatif, jadi:

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

Ini adalah algoritma lama yang sama.


Penjelasan
2,/⍵ memberikan array pasangan karakter dalam string input
+/∘.≡⍨menghasilkan array numerik dari berapa pasangan yang masing-masing pasangan sama (termasuk dirinya sendiri)
1∧.= memeriksa apakah setiap elemen array itu sama dengan 1, dan logis DAN hasilnya bersamaan

:⍵ Jika itu benar (1 ), kembalikan string input

∇⍵[?⍨⍴⍵] lain mengacak string input dan melakukan panggilan rekursif


Bertukar

Jika saluran 1 bertukar dengan saluran 2, maka Anda akan berakhir dengan +/∘.≡⍨{...}kekacauan fungsi dan operator yang memberi SYNTAX ERROR.
Jika baris 1 bertukar dengan baris 3 atau 4, maka Anda memiliki di luar definisi fungsi, dan itu a SYNTAX ERROR.
Jika baris 1 ditukar dengan baris 5, kawat gigi yang tidak seimbang sendiri akan menyebabkan SYNTAX ERROR, jadi jangan khawatir tentang 4 kesalahan sintaks lainnya.

Jika baris 5 ditukar dengan baris 2/3/4, sekali lagi Anda memiliki di luar definisi fungsi. ( SYNTAX ERROR)

Jika jalur 2 ditukar dengan jalur 3, Anda berakhir dengan 1∧.=2,/⍵:⍵. Sintaks ini disebut pelindung (anggap sebagai kondisional). Kondisi penjaga harus mengevaluasi ke 0atau 1atau array 1 elemen dari 0atau 1. Di sini, ia mengevaluasi sesuatu yang lebih kompleks dari itu (skalar yang mengandung array 2-elemen). Jadi ini a DOMAIN ERROR.
Jika baris 2 ditukar dengan baris 4, Anda mendapatkan pernyataan 1∧.=, yang mencoba menerapkan fungsi∧.= tanpa argumen kiri yang diperlukan. ( SYNTAX ERROR).

Jika saluran 3 bertukar dengan saluran 4, sekali lagi Anda mendapatkan banyak fungsi dan operator ( 1∧.=+/∘.≡⍨) sehingga Anda dapat SYNTAX ERROR.


Benchmark
(angka dalam milidetik)

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

Saya masih berpikir tentang perpecahan yang berbeda. Saya juga memiliki cara yang deterministik dan sistematis untuk melakukan tugas itu. Saya tidak bisa membuatnya menjadi sebuah algoritma (menghilangkan bagian kreatif dari "membuat angka-angka yang benar") dan tidak dapat memastikan itu berfungsi setiap saat.

TwiNight
sumber
0

Haskell, 129 = 3x (33 + 10)

ini menggunakan mode alternatif.

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

atau dalam bentuk yang dapat dibaca:

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 adalah bahasa yang sangat ketat. misalnya, importharus didahulukan; definisis harus bersatu; semua tipe harus setuju dan tidak ada cara untuk memilih di antara mereka, dan sebagainya. ini menyebabkan kesalahan tidak fatal hampir tidak mungkin terjadi. pada kenyataannya, memiliki kesalahan fatal runtime terlalu hampir mustahil.

perhatikan bahwa jika gfungsi yang valid tetapi memiliki jenis yang salah (semua jenis berbeda maka [a]->[a]atau String -> Stringdan sejenisnya) daripada ini adalah kesalahan fatal karena tidak mungkin untuk menerapkang pada input.

output:

Abracadabar Alaazcma
Is Miss. iMsiasusgsa sMniig?s
Ask Alasak's lAaankss
GGAGTGCAATACTTCCggagtaacttcc
A Man AP la nAC  aalnnaPama
haskeller bangga
sumber