> <> Su Dışı


20

> <> (Ezoterik bir programlama dili) kodu ile yüzen sevgili balık , doğal ortamından çıkarıldı. Bu değişiklik onu alıştığı şekilde hareket ettiremedi: toroidal hareket eskisi soldan sağa hareketle sınırlıydı. Ancak, programlar hala balıklar kendi aralarında hareket edebiliyormuş gibi yazılıyor. Göreviniz, sevgili programcı, bir programı <<> doğrusallaştırmak için bir program yazmak. Ve mümkün olduğunca az bayt ile yapın; balıkların çok büyük anıları yoktur.

Hareket <>

> Hareket, toroidal ve her seferinde bir karakterdir. Bu, balığın (işaretçi) bir çizginin sonundan başlangıcına "sarılabileceği" anlamına gelir. Balıklar, çoğu işaretçinin hareket etme biçiminin aksine, yukarıdan aşağıya, aşağıdan yukarıya ve sağdan sola hareket edebilir. Dolayısıyla bu hareket paterni geçerli olacaktır:

>>>^  >>>v
   >>>^  v

ve sonsuz bir döngü ile sona erer (en alttan sonsuza kadar geçtiğinde üst çizgiye geri dönerek).

Balık, maksimum (sıra uzunluğu) eşit uzunlukta bir ızgarada ve sıra sayısına eşit yükseklikte bir ızgarada hareket eder.

Balıkların hangi yönde hareket ettiğini nasıl anlarsınız? Bu komutlar hareketin yön vektörünü değiştirir (örneğin (-1,0)sağdan sola anlamına gelir):

Command | Direction Change
---------------------------
   >    | (1,0) (default)
   <    | (-1,0)
   ^    | (0,1)
   v    | (0,-1)
   /    | (x,y) -> (y,x)
   \    | (x,y) -> (-y,-x)
   |    | (x,y) -> (-x,y)
   _    | (x,y) -> (x,-y)
   #    | (x,y) -> (-x,-y)
   ;    | (0,0)

Belirtildiği gibi, balık soldan sağa, yani yön vektörü ile hareket etmeye başlar (1,0) . Balık, gördüğü ilk komuttan başlayarak komutları ayrıştırmaya başlar ve bir komut yukarıda belirtilen yön değiştiricilerden biriyle eşleşirse yönünü değiştirir.

Balık ;, programı gördüğünde ve programı sonlandırdığında durur .

Giriş

Girdi, STDIN aracılığıyla verilen geçerli bir program (örn. Sonsuz döngüsüz) olacaktır. İsterseniz bir dosyayı da okuyabilirsiniz. Her programın çizgileri olacaktır olup zorunlu olarak aynı uzunlukta olması.

Girdi, programdaki her satırı ayıran yeni satırlar içeren bir dize olarak verilir.

Programlar döngü yapmaz, bu da her zaman a ile sonlanacakları anlamına gelir ;.

Çıktı

Çıktı doğrusallaştırılmış program olacaktır. Yani, balığın programı "normal" olarak çalıştırıp çalıştırmadığını göreceği tüm karakterleri (yön değiştiriciler dahil) döndürmelisiniz. Bu yoldaki tüm karakterler; .

Giriş eşit olmayan uzunluktaki çizgilere sahipse ve balıklar en uzun çizginin uzunluğundan daha kısa bir çizgi boyunca hareket ederse, balıklar bir alanın üzerinde hareket ediyormuş gibi davranmalısınız (test durumlarına bakın).

> <> Konusuna aşina olanlar, yön değiştiricilerin içinde hareket yapmanın tek yolu olmadığını bileceklerdir, ancak basitlik uğruna girdiye hareketi etkilemenin tek yolu gibi davranırlar .

kurallar

  1. Standart boşluklar geçerlidir
  2. Tam bir program veya işlev yazabilirsiniz
  3. Girdi, STDIN veya dosya ile satırsonu ( \n) ile ayrılmış program satırlarını içeren bir dize olarak sağlanır
    • Girdiyi farklı nedenlerle aklınızda tutabilirsiniz (aklınızda belirli bir girdi olup olmadığını sormaktan çekinmeyin). Girişi satır boşluklarıyla eşleşecek şekilde boşluklarla dolduramazsınız.
    • Esnek girdi ile ilgili bu meta gönderiye bakın . Gönderi anlamına geldiği için, genel fikir birliği akıl içinde olabildiğince esnek olmalıdır.
  4. Çıktı STDOUT aracılığıyla tek bir dizedir veya işlev tarafından döndürülür (ne yapmayı seçtiğinize bağlı olarak, Kural 2'ye bakın)

Test Durumları

v     >v
>abcv//;
gfed<^ih

v>abcv<defghi^//>v;



v     >v
>abcv//;
gfed<^

v>abcv<defg  ^//>v;


abcdef;

abcdef;


abcd|;

abcd|dcba;


abcd#;

abcd#dcba;


abcd\;
    _

abcd\_\dcba;


^;
>abcde/
 ^jihg<

^ >abcde/ <ghij^a;


;

;

2
Girdiyi bir dizi dizisi olarak alabilir miyiz?
Luke

2
İlk karakterin (sol üstteki) noktalı virgül olmayacağını varsayabilir miyiz?
Kritixi Lithos

1
@KritixiLithos iyi soru, bunu kabul edemeyeceğini söyleyeceğim. Bir test senaryosu ekleyeceğim.
Cole

1
Dizelerin bir dizi olarak girdi alabilir @Luke eğer giriş biçimi çalışmasına ya da çok zor veya imkansız olduğu (çizgilerle dize yeni satır ile ayrılmış). Şimdi eklenen Kural 3'e bakın
cole

Yanıtlar:


13

Röda , 405 393 392 391 371 366 361 236 234 232 230 223 200 bayt

F f{L=f()|[#_]|sort|tail
c=""x=0
y=0
X=1
Y=0{l=f[y]l.=[" "]*(L-#l)c=l[x]a=X
[c]
C=indexOf(c,`><v^/\|_#`)X=[1,-1,0,0,-Y,Y,-X,X,-X,X][C]Y=[0,0,1,-1,-a,a,Y,-Y,-Y,Y][C]x+=X
x=x%L
y+=Y
y=y%#f}until[c=";"]}

Çevrimiçi deneyin!

Çıkışları kontrol edin!

Açıklama (modası geçmiş)

F f{                          /* Declares a function F with parameter f */
                              /* Takes a 2D array of single-char Strings as f */
L =                           /* L contains the value of the length of the longest line*/
    f()                       /* Push the contents each element of f to the stream; this pushes each line*/
        | [#_]                /* Pull a line and push its length to the stream*/
               |sort|tail     /* Sort it and get the last value (the largest one) */
c=""                          /* c contains the value of the current char that is being processed */
x=0; y=0                      /* x and y contain the position of the fish */
X=1; Y=0                      /* X and Y contain the direction of the fish */
{ ... }while [c != ";"]       /* While c is not `;` do: */
l=f[y]                        /*  l is the line (row) the fish is at */
c=" " if [x >= #l]            /*  If x is more than or equal to the line's length, set c to a space (so that we don't need to pad spaces to the array at the beginning)*/
else c = l[x]                 /*  Else set c to the character a position x of l*/
[c]                           /*  Push c to the output stream; ie prints c without a trailing newline*/
a = X                         /*  a preserves the value of X before analysing c */
C = indexOf(c,`><v^/\|_#`)    /*  Simple enough */
X=[1,-1,0,0,-Y,Y,-X,X,-X,X][C]/*  Map each value of C to their respective X-direction in the array */
                              /*  If c cannot be found in `><v^/\|_#` then it will be given the value of -1, or in other words, the -1th element of an array its last element */
Y=[0,0,1,-1,-a,a,Y,-Y,-Y,Y][C]/*  Do the same thing for Y */
x += X                        /*  Change the x-pos by the X-direction */
x = x%L                       /*  Wrap around the right edge */
y += Y                        /*  Do the same for y */
y=y%#f                        /*  But wrap around the bottom instead */
x+=L if[x<0]                  /*  Wrap around the left */
y+=#f if[y<0]                 /*  Wrap around the top */
}

Düzenlemeler

  • @Fergusq sayesinde %x veya y'nin sınırların üstünde olup olmadığını kontrol etmek yerine 10 bayt tasarruf etti , bu da 2 tane daha yol açtı!
  • Yerine `\`kullanılır"\\"
  • c=""İkinci satıra taşındı ve ardından satırsonu kaldırıldı
  • Satırların tek karakterli diziye dönüştürülmesini başlangıçta değil döngülere taşıdı (Python cevabından esinlenerek)
  • whileKüme ayracı sözdizimini kullandı (bunu tespit etmek için @fergusq'a teşekkürler)
  • İf a=Xifadelerinin dışına taşındı
  • En uzun hattın uzunluğunu bulmanın daha kısa bir yolunu bulmak için @fergusq'a teşekkürler
  • Tonlarca bayt kaydetmek için if ifadeleri (Python yanıtı gibi) yerine dizi sözdizimi kullanıldı
  • Boşlukları dolduran kod kaldırıldı, bunun yerine> <> ilerledikçe boşluklar eklendi
  • @Fergusq sayesinde bir hata düzeltildi ve bir karakter golf oynadı
  • Kaldırılan +1sonunda indexOf2 bayt kaydetmek ve yeniden kod
  • Bir şeyleri hareket ettirerek 2 bayt tasarruf etti (tekrar @fergusq sayesinde)
  • @Fergusq sayesinde farklı bir dolgu alanı yöntemi kullanarak 1 bayt kaydedildi
  • Kullanılarak 1 bayt kaydedilen until[c=";"]yerinewhile[c!=";"]
  • @Fergusq'tan bir ipucu sayesinde, boşlukları dolduran döngüyü kaldırdım ve onunla değiştirdim l.=[" "]*L
  • Sonunda programı sol ve üst kenarlara saran if ifadelerini kaldırarak 20 baytın üzerinde kaydedildi

Bunun x=((x+X)%#l)yerine kullanarak birkaç bayt tasarruf edebileceğinizi düşünüyorum x+=X. Ne yazık ki, (-1)%#lhala geri dönüyor -1.
fergusq

@fergusq Önerilerinizi
golf etti

Sen ile kullanabilirsiniz yçok: y=y%#f.
fergusq

@fergusq Bunu eklemek
üzereydi

Bunu daha çok düşündüm, işte diğer iki golf ipucu: keyyerine cmpkullanmak ve kullanmak {...}while[...]yerine while[...]do ... done.
fergusq

10

Python 2, 262 243 237 235 234 233 231 221 219 218 217 bayt

Girdiyi şu şekilde alır ['<line_1>', '<line_2>', ...]

i=input()
q=max(map(len,i))
i=[k+' '*q for k in i]
x=y=k=0
j=1
o=''
while';'not in o:r=[1,-1,-j,-k,0,0];o+=i[y][x];l='><#\\v^/|_'.find(o[-1]);a=(r+[k,-j,j])[l];k=([k,-k,k,j]+r)[~l];j=a;x=(x+j)%q;y=(y-k)%len(i)
print o

Çevrimiçi deneyin!

@Math_junkie sayesinde -19 bayt @ThisGuy sayesinde
-6 bayt
ayıklayarakmax(map(L,i)) bir değişkene (teorik olarak iki kez kullanıldığı için).
-1 bayt i[y][x]gösterme sayısını azaltır .
-1 bayt kullanarak çıkış- 2 bayt bir kısmını '\x00'yapmak zorunda değilim -10 bayt yerine kullanarak @KritixiLithos sayesinde sağ taraftaki istediğim kadar yastık olabilir çünkü Ekstre edilen değişken döngü -2 bayt dışında olduğu için (bayt değişikliği yok) sabit hata yok sayılır , çünkü şimdi sadece 2 kez kullanıyorum, bu yüzden yeniden atamak yerine 2 ek bayt -2 bayt alır .[1:]o[1:]
\0\x00


len
while';'not in owhile o[-1]!=';'ve o=''yerine o='\0'. Bu sadece 2 bayt tasarrufu sağlamakla kalmaz, aynı zamanda teknik olarak gerçekten geçerli olmayan önde gelen boş bayttan da kurtulur.

açıklama

i = input()                       # Takes input as an array of strings
q = max(map(len,i))               # Finds the width of the longest line
i = [k + ' ' * q for k in i]      # Makes sure everything is at least that width
x = y = k = 0                     # Set the point to (0, 0). Set the vertical motion to 0
j = 1                             # Set the horizontal motion to 1
o = '\0'                          # Initialize the output to a null byte (this is output as nothing, so it doesn't actually affect output)
while o[-1] != ';':               # While the last character in the output is not ';' (this is why the output needs to be initialized with something, otherwise o[-1] gives an index error)
    r = [1,-1,-j,-k,0,0]          # Some of the vertical and horizontal coordinates correspond in opposite order
    o += i[y][x]                  # Add the current character to the output
    l = '><#\\v^/|_'.find(o[-1])  # Find the index of the current character here (or -1 if it's just a regular character)
    a = (r + [k, -j, j])[l]       # The fancy array contains the horizontal movement for each control character
    k = ([k, -k, k, j] + r)[~l]   # The fancy array contains the vertical movement for each control character. Using ~l to get the right index, because r has the values backwards
    j = a                         # a was a placeholder because otherwise k would not be correct
    x = (x + j) % q               # Adjust the pointer position
    y = (y - k) % len(i)          # Adjust the pointer position
print o                           # Print the output after the loop is finished

Eğer bulamazsanız bu tryyana finddöner golf -1: TIO
matematik bağımlısı

Oh tamam, teşekkürler!
HyperNeutrino

lenÇok değişkenli Latamayı 01 satıra değiştirerek, örneğin 3 bayt ve başka bir 4 kaydetmek için bir değişkene atayabilirsiniz x=y=k=0.
17:31 de caird coinheringaahing

@ThisGuy Teşekkürler!
HyperNeutrino

2
@Cole Suggeted golf, her dizinin sonuna j ve k ekledim. Bu, yön korunur
matematik bağımlısı

5

Yakut, 274 , 200 187 183

Momentum dizisini bırakarak sadece birkaç karakter daha traş oldu d.

Bununla gurur duyuyorum. Bu komikti! Bir dizi dizeyi alır ve uygun dizeyi döndürür.

->a{o,x,y='',-1,0
b,m=1,0
(o+=n=a[y=(y+m)%a.size][x=(x+b)%(a.map &:size).max]||' '
b,m=([1]+[0,-1,0]*2+[1,-m]+[-b,m,b]*2+[-m,-b,-m,b,m])[2*('><^v/\\|_#'.index(n)||9),2])until o[?;]
o}

Aşağıda yorum yaptı.

->a{
    o,x,y='',-1,0  # o is the output string, x and y are the positions in the array
    b,m=1,0          # b and m are the direction of momentum
    until o[?;] # until o contains a semicolon
        w=(a.map &:size).max # w is the max width of the arrays
        h=a.size    # h is the height of arrays
        x=x+b % w   # increment cursor position
        y=y+m % h
        o+=n=a[y][x]||' ' # add the new char (or " ") to o
        ix=2*('><^v/\\|_#'.index(n)||9) # find the index new char in the string
        b,m=([1]+[0,-1,0]*2+[1,-m]+[-b,m,b]*2+[-m,-b,-m,b,m])[ix,2] # set momentum to its new value
    end
    o # return output string
}

1

PHP 7, 291 260 bayt

for($m=max(array_map(strlen,$z=explode("
",$argv[1]))),$y=0,$r=count($z)-$v=1;';'!=$c;[$v,$w]=[[$v,1,-1,0,0,-$w,$w,-$v,$v,-$v][$o=strpos(' ><^v/\|_#',$c)],[$w,0,0,-1,1,-$v,$v,$w,-$w,-$w][$o]],$x+=$m+$v,$x%=$m,$y=0<=($y+=$w)?$r<$y?:$y:$r)echo$c=$z[$y][$x]??' ';

291 bayt / karakter sayıyorum.
HyperNeutrino

Doğru, görünüşe göre sayma başarısız = P
chocochaos

Hah Endişelenme, ben de yaptım.
HyperNeutrino

Golf için bazı şeyler buldum, bunu% 25 azaltarak 218 bayta indirdim. Test edilmedi, ama kesinlikle bir göz atmaya değer .
Titus

2
benim golf birinde bir kusur ve altı bayt golf : güncellenen golf listesi .
Titus

1

JavaScript, 242 236 235 231 220 bayt

a=>{n=a.length;m=x=y=p=0;a.map(g=>m=(w=g.length)<m?m:w);q=1,o="";while((t=a[y][x]||" ")!=";")o+=t,h=q,q=[q,1,0,p,-q][(s=">v\\| <^/_#".indexOf(t)+1)%5]*(r=s>5?-1:1),p=[p,0,1,h,p][s%5]*r,x=(x+q+m)%m,y=(y+p+n)%n;return o+t}

Çevrimiçi deneyin!


dizeyi dizi olarak alırsanız 13 karakter kaydedebilirsiniz. Teknik özellikler değiştirildi.
Charles
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.