> <>水不足


20

> <>(難解なプログラミング言語)のコードを泳ぐ愛する魚は、その自然環境から取り出されました。この変更により、従来の方法で動き回ることができなくなりました。トロイダル運動であったものは、単純な左から右への動きに制限されていました。しかし、> <>プログラムは、魚がそれらの中を移動できるように書かれています。親愛なるプログラマーの仕事は、プログラムを書いて> <>プログラムを線形化することです。そして、できるだけ少ないバイトでそれを行います。魚にはあまり大きな記憶がありません。

> <>での移動

> <>では、動きはトロイダルで、一度に1つのキャラクターになります。これは、魚(ポインター)が行の終わりから先頭まで「ラップ」できることを意味します。> <>では、ほとんどのポインターの動きとは対照的に、魚は上から下、下から上、および右から左に移動することもできます。したがって、この移動パターンは有効です。

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

そして、それは無限ループで終了します(底部を無限に通過すると、最上部のラインに戻ります)。

魚は、max(row length)に等しい長さと、行の数に等しい高さのグリッドで移動します。

魚がどのように動くかをどのように把握しますか?これらのコマンドは、移動の方向ベクトルを変更します(たとえば(-1,0)、右から左を意味します)。

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)

前述のように、魚は左から右へ、つまり方向ベクトルで動き始め(1,0)ます。魚は、コマンドが最初のコマンドから解析を開始し、コマンドが前述の方向変換器のいずれかに一致した場合、その方向を変更します。

それを見る;と魚は動きを止め、プログラムを終了します。

入力

入力は、STDINで指定された有効な(無限ループではない)プログラムになります。必要に応じてファイルを読み取ることもできます。各プログラムの行は、必ずしも同じ長さではありません

入力は文字列として与えられ、プログラム内の各行は改行で区切られます。

プログラムはループしません;。つまり、プログラムは常にで終了します。

出力

出力は線形化されたプログラムになります。つまり、プログラムが「正常に」実行された場合に魚が見るすべてのキャラクター(方向転換器を含む)を返す必要があります。これは、へのパス内のすべての文字;です。

入力に不等長のラインがあり、魚が最長ラインの長さよりも短いラインに沿って移動する場合、魚がスペース上を移動しているかのように扱う必要があります(テストケースを参照)。

> <>に精通している人は、方向変更器がその中で移動を行う唯一の方法ではないことを知っていますが、簡単にするために、入力を移動に影響する唯一の方法として扱います。

ルール

  1. 標準的な抜け穴が適用されます
  2. 完全なプログラムまたは機能を書くことができます
  3. 入力は、STDINまたはファイルを介して、改行(\n)で 区切られたプログラム行を含む文字列として提供されます
    • 理由の範囲内で、入力を異なる方法で受け取ることができます(特定の種類の入力を念頭に置いているかどうか、お気軽にお問い合わせください)。行の長さが一致するように入力にスペースを埋め込むことはできません。
    • 柔軟な入力については、このメタ投稿を参照しください。投稿の略であるため、一般的なコンセンサスは、理にかなった範囲で可能な限り柔軟にすることです。
  4. 出力は、STDOUTを介した単一の文字列であるか、関数によって返されます(選択内容に応じて、ルール2を参照)

テストケース

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
入力を文字列の配列として取得できますか?
ルーク

2
最初の文字(左上の文字)がセミコロンではないと仮定できますか?
クリチキシリトス

1
@KritixiLithos良い質問です、私はあなたがそれを仮定できないと言うつもりです。テストケースを追加します。
コール

1
@Luke は、入力形式(改行で区切られた行を含む文字列)での操作が非常に困難または不可能な場合、入力を文字列の配列として受け取ることができます。追加されたルール3を参照してください
コール

回答:


13

ローダ405 393 392 391 371 366 361 236 234 232 230 223 200バイト

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=";"]}

オンラインでお試しください!

出力を確認してください!

説明(古い)

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 */
}

編集

  • @fergusqのおかげで、%xまたはyが境界を越えているかどうかをチェックする代わりに使用することで10バイト節約され、さらに2つの道が開けました!
  • `\`代わりに使用"\\"
  • c=""2行目に移動し、その後の改行を削除しました
  • 行の単一文字配列への変換を先頭ではなくループに移動しました(Pythonの回答に触発されました)
  • 中括弧構文を使用しましたwhile(@potgusqに感謝します)
  • a=Xifステートメントの外に移動しました
  • 最も長い行の長さを見つけるより短い方法を見つけてくれた@fergusqに感謝します
  • 大量のバイトを節約するために、if文(Pythonの回答など)の代わりに配列構文を使用しました
  • スペースを埋めるコードを削除し、代わりに> <>が移動するとスペースが追加されます
  • バグの感謝を修正し、@ fergusqのおかげで1人のキャラクターをゴルフしました
  • +1末尾のindexOfコードを削除し、2バイトを節約するためにコードを再構築しました
  • 物事を移動して2バイトを節約しました(再び@fergusqに感謝)
  • スペースを埋める別の方法を使用して、@ fergusqのおかげで1バイト節約
  • until[c=";"]代わりにを使用して1バイトを保存しましたwhile[c!=";"]
  • @fergusqからのヒントのおかげで、スペースを埋めるループを削除して、 l.=[" "]*L
  • プログラムの左端と上端をラップするif文を最後に削除することにより、20バイト以上節約しました。

x=((x+X)%#l)代わりにを使用すると、数バイト節約できると思いますx+=X。残念ながら、(-1)%#lまだが返されます-1
fergusq

@fergusqあなたの提案をゴルフ:)
Kritixi Lithos

以下yでも使用できますy=y%#f
fergusq

@fergusqはちょうどそれを追加しようとしていた:)
Kritixi Lithos

私はこれについてさらに考えました、ここに2つの他のゴルフのヒントがあります:のkey代わりにcmp使用するとの{...}while[...]代わりに使用するwhile[...]do ... done
-fergusq

10

パイソン2、262 243 237 235 234 233の 231 221 219 218 217バイト

入力を受け取ります ['<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

オンラインでお試しください!

@math_junkieのおかげで-19バイト@ThisGuyのおかげで
-6バイト変数に
抽出するmax(map(L,i))ことで-2バイト(理論的には2回使用されるため)
回数を減らすことで-1バイトがi[y][x]表示されます。
使用'\x00'することで-1バイトなので、出力の[1:]一部を行う必要はありません -10バイトの代わりに 使用することで-2バイト- 右側に必要なだけパディングできることを実現するために@KritixiLithosのおかげで余分無視されます (何バイト変化)で抽出変数がループの外側にあったので、バグを修正し 、今私は使用しているため-2バイトこれは、2つの追加バイトかかる再割り当てするように2回 使用して-2バイトの代わりにo[1:]
\0\x00


len
while';'not in owhile o[-1]!=';'、およびのo=''代わりに使用しますo='\0'。これは2バイトを節約するだけでなく、技術的には実際には有効ではなかった先頭のヌルバイトも取り除きます。

説明

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

次のことができますオフゴルフtryので、findリターン-1が見つからない場合:TIO
数学中毒

@math_junkieああ大丈夫、ありがとう!
ハイパーニュートリノ

lenたとえばL、複数行の割り当てを01行に変更することで、3バイトと別の4バイトを節約するために、変数に割り当てることができますx=y=k=0
コイナーリンガーをケアします。

@ThisGuyありがとう!
ハイパーニュートリノ

2
@Cole提案されたゴルフでは、各配列の最後にjとkを追加しました。これにより、方向が維持されます
数学中毒者

5

ルビー、274 200 187 183

運動量配列を削除することにより、さらに数文字を削り落としましたd

私はこれをかなり誇りに思っています。これは楽しかった!文字列の配列を受け取り、適切な文字列を返します。

->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{
    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バイト

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バイト/文字をカウントします。
ハイパーニュートリノ

あなたは正しい、私はどうやら= P
chocochaosの

心配しないで、私もやった。
ハイパーニュートリノ

私はゴルフにいくつかのものを見つけ、これを25%削減して218バイトにしました。テストされていませんが、間違いなく一見の価値があります
タイタス

2
私のゴルフの1つに欠陥があり、さらに6バイトのゴルフが行われました:更新されたゴルフリスト
タイタス

1

JavaScript、242 236 235 231 220バイト

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}

オンラインでお試しください!


文字列を配列として取り込むと、13文字を節約できます。仕様が変更されました。
はないチャールズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.