Aliran data tidak dapat diandalkan

8

Tantangan Anda adalah bermain golf program yang meniru aliran transmisi data. Program Anda harus membaca input dari stdin dan mengeluarkannya langsung ke stdout. Untuk membuat masalah lebih menarik, aliran output 'salah', dan harus memenuhi beberapa persyaratan:

  1. Seharusnya ada peluang 10% bahwa setiap karakter digeser +1 kode ascii (ex 'a' menjadi 'b', '9' menjadi ':'), dll.
  2. Input dan output hanya mencakup nilai ascii yang dapat dicetak ('!' Hingga '~', desimal 33 hingga desimal 126, inklusif). Jika +1 acak terjadi pada '~' (desimal 126), a '!' (desimal 33) yang seharusnya menjadi keluaran.
  3. Jika tiga karakter digeser secara acak berturut-turut, program harus menampilkan "ERROR CODE 4625: ERROR YANG TIDAK DAPAT DIKECUALIKAN, SILAHKAN HUBUNGI ADMINISTRATOR SISTEM ANDA" (mengikuti baris baru opsional) dan menghentikan eksekusi.

Untuk menyederhanakan masalah, berikut adalah beberapa kriteria lain:

  1. Anda dapat berasumsi bahwa input akan selalu valid; artinya, itu hanya akan berisi nilai '!' melalui '~'.
  2. Program harus berlanjut sampai tiga karakter secara acak bergeser dalam satu baris; aman untuk mengasumsikan bahwa EOF tidak akan pernah terjadi.
  3. Keacakan harus berbeda di seluruh proses; jika generator nomor acak Anda perlu diunggulkan untuk mendapatkan hasil yang unik setiap kali dijalankan, maka kode Anda perlu diunggulkan.
  4. Anda harus menulis sebuah program, bukan fungsi.
  5. Anda harus mengambil input dari stdin dan menulis output ke stdout.
  6. Anda tidak boleh menggunakan perpustakaan atau sumber daya eksternal apa pun.
  7. Kode Anda harus memiliki intrepreter atau kompiler yang tersedia secara bebas dan berfungsi.

Aturan standar kode-golf berlaku. Pemenang adalah siapa pun yang memposting program terpendek dua minggu dari sekarang (Kamis, 20 Februari, 2014).

Josh
sumber
Apakah boleh untuk menganggap bahwa akan ada EOF? Secara khusus, dapatkah saya membaca semua input ke dalam memori sebelum menghasilkan output apa pun, seperti yang biasanya dilakukan GolfScript?
Ilmari Karonen
@IlmariKaronen mungkin tidak; tidak mungkin untuk menjamin input yang cukup untuk RNG Anda untuk membuat 3 kesalahan berturut-turut.
TypeIA
1
@IlmariKaronen sesuai spesifikasi, EOF tidak akan pernah terjadi. Satu-satunya syarat keluar adalah tiga karakter membalik secara berurutan.
Josh

Jawaban:

4

Befunge-98, 166 159 156 155 148

Yang ini meningkatkan jawaban Befunge luar biasa lainnya dengan probabilitas yang benar (1/10) dan sedikit lebih kompak:

~>?#v?1+\1>+\:'~1+-4k#x07_$'!>,:3-!#v_
>#?>>>\$\0^>
^<<
A"##  "CT YOUR SYSTEM ADMINISTRATOR"<@,kM'"ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONT
TypeIA
sumber
Beberapa komentar implementasi: xdigunakan di dua tempat sebagai "goto." Pembungkus tepi (ab) digunakan secara luas, termasuk kontrol yang mengalir melalui celah ruang antara ASEdan CONTACT. Penghitung "3-in-a-row" disimpan di bagian bawah tumpukan; backslash digunakan untuk bertukar dan mengaksesnya di mana diperlukan.
TypeIA
1
Ini adalah befunge berkualitas di sini. Saya sangat menyukai apa yang Anda lakukan dengan string pada akhirnya, untuk memungkinkan titik masuk di mana Anda membutuhkannya
Cruncher
Saya mencoba banyak hal akhir pekan ini untuk mengurangi ini dan saya tidak bisa, bahkan dengan satu karakter. Tapi saya belum menyerah! :)
TypeIA
1
Merestrukturisasi blok RNG untuk menggunakan hanya tiga ?instruksi (salah satunya dihantam oleh dua jalur, sehingga kemungkinan masih tepat 1/10) dan membuat beberapa penyesuaian kecil lainnya untuk mengurangi 7 karakter lagi!
TypeIA
Selamat atas kemenangan!
Josh
4

C, 168 karakter

i;main(c){for(srand(&c);i++<3;putchar(rand()%10?i=0,c:c-126?c+1:33))c=getchar();
puts("ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONTACT YOUR SYSTEM ADMINISTRATOR");}

Penyemaian solusi PRNG ini mengambil keuntungan dari kenyataan bahwa OS modern mengubah lokasi stack dalam memori pada setiap run, sebagai langkah dasar terhadap eksploitasi stack-smashing.

kotak roti
sumber
Anda dapat menyingkirkan variabel csepenuhnya dengan memindahkan getchar()panggilan ke putchar()dan menggunakan beberapa matematika mewah ...
Josh
Saya yakin Anda masih perlu memiliki csehingga Anda dapat menguji getchar()nilai terhadap 126 selain meneruskannya putchar().
kotak roti
Oleh karena itu matematika mewah ... Saya percaya putchar((getchar()-33+(rand()%10?i=0:1))%94+33))harus bekerja. Menggunakan solusi Anda sebagai basis, itu membuat saya turun hingga 165 karakter.
Josh
2

Ruby, 156

e=3
putc(($_.ord-33+r=rand(10)/9)%94+33)/e=r>0?e-r :3while gets(1)rescue$><<'ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONTACT YOUR SYSTEM ADMINISTRATOR'
Paul Prestidge
sumber
Bisakah Anda menjelaskan apa itu :3while?
Uri Agassi
@UriAgassi the :3sebenarnya adalah akhir dari pernyataan ini: e=r>0?e-r :3yang menetapkan nilai e (jumlah kesalahan berurutan yang tersisa sebelum kita batalkan) berdasarkan r (1 jika karakter terakhir yang diproses adalah kesalahan, 0 jika tidak). Ini hanya didorong melawan sementara untuk menghemat ruang:>
Paul Prestidge
1
Dan ruby ​​mengenali whiletanpa ruang sebelumnya? Itu sangat tidak jelas dan tidak bisa dibaca! ;)
Uri Agassi
2

Gelombang - 359

Terbuka untuk saran agar sepenuhnya mematuhi aturan tantangan.

Saya akan berusaha membuatnya lebih kecil / lebih baik - saya ingin mempostingnya ketika sedang bekerja, sebelum saya istirahat.

@echo off&setLocal enableDelayedExpansion&for /L %%a in (33,1,126)do cmd/cexit %%a&set %%a=!=exitcodeAscii!
set a=%~1
:l
if defined a (
set c=!a:~0,1!&set a=!a:~1!&set b=0&set/ar=%RANDOM%*10/32768+1
if !r!==1 for /L %%b in (33,1,126)do (
if !b!==1 echo !%%b!>>f
if "!c!"=="!%%b!" set b=1
)
if !b!==1 set/pc=<f&del f
set o=%o%!c!&goto l
) 
echo %o%

Pasti ada beberapa cara untuk menurunkannya.

h:\uprof>UDS.bat "test ing"
tesu inh

h:\uprof>UDS.bat "test ing"
tfsu ing

Tidak golf -

@echo off
setLocal enableDelayedExpansion
for /L %%a in (33,1,126) do (
    cmd /c exit %%a
    set %%a=!=exitcodeAscii!
)
set a=%~1
:l
if defined a (
    set c=!a:~0,1!
    set a=!a:~1!
    set b=0
    set /a r=%RANDOM%*10/32768+1
    if !r!==1 for /L %%b in (33,1,126) do (
        if !b!==1  echo !%%b!>>f
        if "!c!"=="!%%b!" set b=1
    )
    if !b!==1 set /p c=<f& del f
    set o=%o%!c!
    goto l
) 
echo %o%
hapus clemeat
sumber
2

Befunge-93 (206)

Ini memiliki 142 karakter non-spasi. Secara teknis itu tidak sesuai, karena memiliki probabilitas 1/9 bukan 1/10 untuk kesalahan.

v$,_\1+:4-v
~> ^1:  <v_$$"ROTARTSINIMDA METSYS RUOY TCATNOC ESAELP ,RORRE ELBAREVOCERNU :5264 EDOC RORRE">:#,_@
 ^ < < < \
   1     "
 ^0?2^
   ^ 3  +"
> >?>?4^"-
   v 5  !"
 ^8?6> ^"^
   7    %"
   >   ^^<

Jalankan sebagai cat /dev/urandom | tr -dc '!-~' | ./befungee.py -c 100 ../rand.

Dengan input ini, !!!!aaaaaaa~~~~~~~~~~kami mendapatkan output yang !"!!aabaaba~~~!~~~~!!mengindikasikan bahwa kesalahan ditangani dengan benar.

Joel Bosveld
sumber
Untuk mendapatkan peluang 10% akan agak sulit. Masing-masing dari 9 Anda harus dibagi menjadi 2 lainnya (melemparkan yang ketiga kembali) Kemudian 8 dari 18 harus kembali ke awal
Cruncher
@Cruncher yang mirip dengan pendekatan yang saya gunakan dalam pengiriman Befunge saya, yang memiliki probabilitas yang benar. Empat digunakan dan beberapa jalur kode memberi umpan balik ke awal RNG sebagai "nops."
TypeIA
1

PHP 190

itu semakin jauh saya bisa golf itu, tetapi saya pikir itu cukup bagus bahwa itu kurang dari 100 karakter dari yang terkemuka

<? while($a=fread(STDIN,1)){if(!rand(0,9)){$a=$a=='~'?'!':chr(ord($a)+1);@$i+=1;$i>2&&die("ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONTACT YOUR SYSTEM ADMINISTRATOR");}else$i=0;echo$a;}
Einacio
sumber
1

C # - 346 330 313 309 297 288 278 274

Agak lama tetapi melakukan pekerjaan.

using System;class m{static void Main(){int c=0;var r=new Random();while(c<3){int n=r.Next(10);var j=Console.In.Read();Console.Write((char)(n<1?j>'}'?'!':++j:j));c=n<1?c+1:0;}Console.Write("ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONTACT YOUR SYSTEM ADMINISTRATOR");}}
pengguna3188175
sumber
1
c=n==0?c+1:0lebih pendek dari c+=(n==0?1:-c)...
Timwi
1
(n==1?1:0)lebih pendek dari (n==1?n--:(--n-n))(dan tentu saja kemudian berubah n==0menjadi n==1)
Timwi
Terima kasih banyak, Anda hampir menulis ulang seluruh program!
user3188175
Anda menakjubkan.
user3188175
Hm, mengapa (false)? Jika ada, bukankah Anda mau (true)?
Timwi
1

sh bash, di OSX, 211 , 208 , 203 , 200 , 196 , 185

IFS=
while read -n1 a;do
((RANDOM>3276))&&echo $a&&t=0||{
tr !-}~ \"-~!<<<$a
((t++==2))&&echo ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONTACT YOUR SYSTEM ADMINISTRATOR&&exit
}
done

Sedikit lebih baik dari 10% karena acak akan menghasilkan angka antara 0 dan 32767, jadi benar-benar 3,277 dalam peluang 32,768 (10.0006%).

Terima kasih, @Gilles (tetapi tidak yakin apa yang Anda maksud tentang restrukturisasi sementara. Ada beberapa ide lain di kamar mandi juga.

Bukan itu Charles
sumber
Karena Anda menggunakan fitur bash (jadi ini solusi bash, sebenarnya), Anda dapat menyingkat [ $RANDOM -gt 3276 ]menjadi ((RANDOM>3276))dan [ $[t++] -eq 2 ]ke ((t++==2)). Saya pikir Anda juga dapat menyimpan beberapa karakter dengan menata ulang sebagai while read -n1 a;((RANDOM>3276))&&….
Gilles 'SO- stop being evil'
@Gilles Terima kasih. Apa maksudmu tentang while read...bagian itu?
Bukan karena Charles
Maaf, saya terpotong di tempat yang salah. Buat lingkaran while …;do :;doneatau until …;do :;done, Anda harus dapat mencukur beberapa karakter.
Gilles 'SO- stop being evil'
1

C, 260 257 237 225 189 174

Golf pertama saya, saran sangat dihargai.

n;main(){for(srand(&n);n!=3;putchar((getchar()+(rand()%10==7?!!++n:(n=0))-33%94)+33));puts("ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONTACT YOUR SYSTEM ADMINISTRATOR");}

7 sangat acak.

Kompilasi akan memberi Anda peringatan.

Terima kasih atas bantuan dari kotak roti dan Josh.

milinon
sumber
1
Saran awal: Tinggalkan #include; C akan menerima (dengan peringatan) panggilan ke fungsi yang tidak dideklarasikan (dalam batas). Gunakan variabel global untuk mendapatkan inisialisasi nol otomatis. Temukan cara untuk menggunakan operator ternary alih-alih if/ elsepernyataan. Menggunakan fordi tempat whilememberi lebih banyak peluang untuk mengurangi jumlah pernyataan tingkat atas dan menghilangkan tanda kurung di sekitar badan loop. Banyak lagi yang bisa disebutkan: periksa solusi C lain di situs ini.
kotak roti
Terima kasih atas sarannya - saya pikir gcc akan mengeluh tanpa setidaknya stdio, tapi ternyata itu keren. Saya juga punya variabel konyol yang masih bernama 'count'. Sepertinya for loop mengurangi banyak juga.
milinon
Anda dapat mendeklarasikan ndan cpada lingkup global. Ini akan memungkinkan Anda untuk menjatuhkan intdeklarasi serta membiarkan inisialisasi menjadi nol secara otomatis.
Josh
Saya memutuskan untuk menggunakan cnilai yang tidak diinisialisasi di srand. Saya kira saya bisa menggunakan &catau &nsebagai gantinya, itulah kotak roti yang digunakan.
milinon
Saya suka trik yang Anda buat untuk menghilangkan kebutuhan variabel kedua Anda!
Josh