Luồng dữ liệu không đáng tin cậy


8

Thử thách của bạn là chơi một chương trình bắt chước luồng truyền dữ liệu. Chương trình của bạn nên đọc đầu vào từ stdin và xuất trực tiếp ra thiết bị xuất chuẩn. Để làm cho vấn đề trở nên thú vị hơn, luồng đầu ra là 'bị lỗi' và phải đáp ứng một số yêu cầu:

  1. Cần có 10% cơ hội mỗi ký tự được chuyển +1 mã ascii (ví dụ 'a' trở thành 'b', '9' trở thành ':'), v.v.
  2. Đầu vào và đầu ra chỉ nên bao gồm các giá trị ascii có thể in được ('!' Đến '~', thập phân 33 đến thập phân 126, đã bao gồm). Nếu +1 ngẫu nhiên xảy ra trên '~' (số thập phân 126), thì '!' (thập phân 33) nên được đầu ra thay thế.
  3. Nếu ba ký tự được thay đổi ngẫu nhiên liên tiếp, chương trình sẽ xuất ra "MÃ LRI 4625: LRI KHÔNG GIỚI HẠN, XIN VUI LÒNG LIÊN HỆ HỆ THỐNG QUẢN LÝ HỆ THỐNG CỦA BẠN" (theo dõi dòng mới tùy chọn) và tạm dừng thực thi.

Để đơn giản hóa vấn đề, đây là một vài tiêu chí khác:

  1. Bạn có thể cho rằng đầu vào sẽ luôn hợp lệ; nghĩa là, nó sẽ chỉ chứa các giá trị '!' thông qua '~'.
  2. Chương trình nên tiếp tục cho đến khi ba ký tự được thay đổi ngẫu nhiên liên tiếp; Sẽ an toàn khi cho rằng EOF sẽ không bao giờ xảy ra.
  3. Sự ngẫu nhiên phải khác nhau giữa các lần chạy; nếu trình tạo số ngẫu nhiên của bạn cần được tạo mầm để có kết quả duy nhất cho mỗi lần chạy, thì mã của bạn cần phải gieo nó.
  4. Bạn phải viết một chương trình, không phải là một chức năng.
  5. Bạn phải lấy đầu vào từ stdin và ghi đầu ra vào thiết bị xuất chuẩn.
  6. Bạn không được sử dụng bất kỳ thư viện hoặc tài nguyên bên ngoài.
  7. Mã của bạn phải có một trình biên dịch hoặc trình biên dịch có sẵn miễn phí.

Luật golf tiêu chuẩn được áp dụng. Người chiến thắng là bất cứ ai có chương trình ngắn nhất được đăng hai tuần kể từ bây giờ (Thứ năm, ngày 20 tháng 2 năm 2014).


Bạn có thể cho rằng sẽ có EOF không? Cụ thể, tôi có thể đọc tất cả đầu vào vào bộ nhớ trước khi tạo bất kỳ đầu ra nào không, như GolfScript thường không?
Ilmari Karonen

@IlmariKaronen có lẽ không; không thể đảm bảo đủ đầu vào cho RNG của bạn để mắc 3 lỗi liên tiếp.
TypeIA

1
@IlmariKaronen theo thông số kỹ thuật, EOF sẽ không bao giờ xảy ra. Điều kiện thoát duy nhất là ba ký tự lật liên tiếp.
Josh

Câu trả lời:


4

Befunge-98, 166 159 156 155 148

Điều này cải thiện câu trả lời Befunge tuyệt vời khác với xác suất chính xác (1/10) và nhỏ gọn hơn một chút:

~>?#v?1+\1>+\:'~1+-4k#x07_$'!>,:3-!#v_
>#?>>>\$\0^>
^<<
A"##  "CT YOUR SYSTEM ADMINISTRATOR"<@,kM'"ERROR CODE 4625: UNRECOVERABLE ERROR, PLEASE CONT

Một số ý kiến ​​thực hiện: xđược sử dụng ở hai nơi dưới dạng "goto." Gói cạnh là (ab) được sử dụng rộng rãi, bao gồm kiểm soát chảy qua khoảng cách giữa ASECONTACT. Bộ đếm "3 liên tiếp" được giữ ở dưới cùng của ngăn xếp; dấu gạch chéo ngược được sử dụng để trao đổi và truy cập nó khi cần thiết.
TypeIA

1
Đây là chất lượng befunge ngay tại đây. Tôi thực sự thích những gì bạn đã làm với chuỗi ở cuối, để cho phép điểm vào nơi bạn cần nó
Cruncher

Tôi đã thử rất nhiều thứ vào cuối tuần này để giảm bớt điều này và tôi không thể, thậm chí chỉ bằng một nhân vật. Nhưng tôi đã không từ bỏ! :)
TypeIA

1
Tái cấu trúc khối RNG chỉ sử dụng ba ?hướng dẫn (một trong số đó bị tấn công bởi hai đường dẫn, do đó xác suất vẫn chính xác là 1/10) và thực hiện một số điều chỉnh nhỏ khác để loại bỏ 7 ký tự nữa!
TypeIA

Chúc mừng chiến thắng!
Josh

4

C, 168 ký tự

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");}

Việc gieo hạt PRNG của giải pháp này lợi dụng thực tế là các HĐH hiện đại thay đổi vị trí của ngăn xếp trong bộ nhớ trên mỗi lần chạy, như một biện pháp cơ bản chống lại các khai thác ngăn xếp.


Bạn có thể loại bỏ choàn toàn biến bằng cách chuyển getchar()cuộc gọi vào putchar()và sử dụng một số phép toán lạ mắt ...
Josh

Tôi tin rằng bạn vẫn cần phải có cđể bạn có thể kiểm tra getchar()giá trị của nó so với 126 ngoài việc chuyển nó tới putchar().
hộp bánh mì

Do đó toán học ưa thích ... Tôi tin rằng putchar((getchar()-33+(rand()%10?i=0:1))%94+33))nên làm việc. Sử dụng giải pháp của bạn làm cơ sở, nó giúp tôi giảm xuống còn 165 ký tự.
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'

Bạn có thể giải thích đó là :3whilegì?
Uri Agassi

@UriAgassi :3thực sự là kết thúc của câu lệnh này: e=r>0?e-r :3nó đặt giá trị của e (số lỗi liên tiếp còn lại trước khi chúng tôi hủy bỏ) dựa trên r (1 nếu ký tự cuối được xử lý là lỗi, 0 nếu không). Nó chỉ được đẩy lên so với thời gian để tiết kiệm không gian:>
Paul Prestidge

1
Và ruby ​​nhận ra whilekhông có khoảng trống trước nó? Điều đó thật mơ hồ và không thể đọc được! ;)
Uri Agassi

2

Mẻ - 359

Mở để đề xuất để làm cho nó hoàn toàn tuân thủ các quy tắc thách thức.

Tôi sẽ làm việc để làm cho nó nhỏ hơn / tốt hơn - tôi muốn đăng nó trong khi nó hoạt động, trước khi tôi phá vỡ nó.

@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%

Chắc chắn có khá nhiều cách để chơi golf.

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

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

Không chơi gôn -

@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%

2

Befunge-93 (206)

Nó có 142 ký tự không phải khoảng trắng. Về mặt kỹ thuật, nó không tuân thủ, vì nó có xác suất 1/9 chứ không phải 1/10 để xảy ra lỗi.

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    %"
   >   ^^<

Chạy như cat /dev/urandom | tr -dc '!-~' | ./befungee.py -c 100 ../rand.

Với đầu vào này, !!!!aaaaaaa~~~~~~~~~~chúng tôi nhận được đầu ra !"!!aabaaba~~~!~~~~!!chỉ ra rằng các lỗi được xử lý chính xác.


Để có được 10% cơ hội sẽ khá khó khăn. Mỗi người trong số 9 người của bạn sẽ phải chia thành 2 người khác (ném lại người thứ ba). Sau đó, 8 trong số 18 phải quay trở lại từ đầu
Cruncher

@Cruncher tương tự như cách tiếp cận tôi đã sử dụng trong bài nộp Befunge của mình, có xác suất chính xác. Bốn? Được sử dụng và một số đường dẫn mã quay trở lại đầu RNG dưới dạng "nops".
TypeIA

1

PHP 190

đó là xa hơn tôi có thể chơi nó, nhưng tôi nghĩ nó khá tốt khi nó ít hơn 100 ký tự từ hàng đầu

<? 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;}

1

C # - 346 330 313 309 297 288 278 274

Kinda dài nhưng làm công việc.

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");}}

1
c=n==0?c+1:0ngắn hơn c+=(n==0?1:-c)...
Timwi

1
(n==1?1:0)được ngắn hơn (n==1?n--:(--n-n))(và sau đó dĩ nhiên thay đổi sau n==0để n==1)
Timwi

Cảm ơn rất nhiều, bạn gần như đã viết lại toàn bộ chương trình!
dùng3188175

Bạn thật tuyệt vời.
dùng3188175

Hừm, tại sao (false)? Nếu bất cứ điều gì, bạn không muốn (true)?
Timwi

1

sh bash, trên 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

Hơi tốt hơn 10% vì ngẫu nhiên sẽ tạo ra các số trong khoảng từ 0 đến 32767, do đó, thực sự là 3,277 trong 32,768 tỷ lệ cược (10.0006%).

Cảm ơn, @Gilles (nhưng không chắc ý của bạn về việc tái cấu trúc. Cũng có một số ý tưởng khác khi tắm.


Vì bạn đang sử dụng tính năng bash (vì vậy đây là một giải pháp bash, thực sự), bạn có thể rút ngắn [ $RANDOM -gt 3276 ]tới ((RANDOM>3276))[ $[t++] -eq 2 ]đến ((t++==2)). Tôi nghĩ bạn cũng có thể lưu một vài nhân vật bằng cách tái cấu trúc như while read -n1 a;((RANDOM>3276))&&….
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles Cảm ơn. Bạn có ý nghĩa gì về while read...phần này?
Không phải Charles

Xin lỗi, tôi cắt ở sai chỗ. Tạo vòng lặp while …;do :;donehoặc until …;do :;done, bạn sẽ có thể cạo một vài ký tự.
Gilles 'SO- ngừng trở thành ác quỷ'

1

C, 260 257 237 225 189 174

Golf đầu tiên của tôi, đề nghị đánh giá cao.

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 là rất ngẫu nhiên.

Biên dịch sẽ cung cấp cho bạn cảnh báo.

Cảm ơn sự giúp đỡ từ Breadbox và Josh.


1
Gợi ý ban đầu: Rời khỏi #include; C sẽ chấp nhận (có cảnh báo) các cuộc gọi đến các chức năng chưa được khai báo (trong giới hạn). Sử dụng các biến toàn cục để có được khởi tạo không tự động. Tìm cách sử dụng toán tử ternary thay vì if/ elsestatement. Việc sử dụng forthay thế whilemang lại nhiều cơ hội hơn cho việc giảm số lượng báo cáo cấp cao nhất và bỏ qua các dấu ngoặc quanh thân vòng lặp. Nhiều hơn nữa có thể được đề cập: kiểm tra các giải pháp C khác trên trang web này.
hộp bánh mì

Cảm ơn những lời đề nghị - Tôi nghĩ gcc sẽ phàn nàn mà không ít nhất là stdio, nhưng rõ ràng nó rất tuyệt. Tôi cũng có một biến ngớ ngẩn vẫn được đặt tên là 'đếm'. Có vẻ như vòng lặp for cũng bị cắt giảm rất nhiều.
millinon

Bạn có thể khai báo ncở phạm vi toàn cầu. Điều này sẽ cho phép bạn bỏ intkhai báo cũng như để việc khởi tạo về không là tự động.
Josh

Tôi quyết định sử dụng cgiá trị chưa được khởi tạo trong srand. Tôi đoán tôi có thể sử dụng &choặc &nthay vào đó, đó là những gì mà hộp bánh mì đã sử dụng.
millinon

Tôi thích thủ thuật mà bạn nghĩ ra để loại bỏ sự cần thiết cho biến thứ hai của bạn!
Josh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.