コード(ミニ)ゴルフ


50

ミニゴルフコースのサイドビューとスイングの力を考慮して、ボールがホールに進入するかどうかを判断します。


コースは次の形式になります。

      ____       ____ _   
   __/    \     /    U \  
__/        \   /        \_
            \_/           

ボールは左側の最初の地面の直前から始まり、ホール(U現在の地面レベルより下の大文字)に到達するまでコースの輪郭をたどります。穴に到達した場合、真実の値を出力します。スイングの力がボールの初速になります。ボールは各反復で右側の次のキャラクターに移動し、現在のキャラクターに応じて速度が変更されます。速度が0穴の前に到達するかそれ以下の場合、偽の値を出力します。

  • _ 速度を下げる 1
  • / 速度を下げる 5
  • \ 速度を上げる 4

オプションで、コースにスペースを埋め込むことができます。スイングの力は常に正の整数になります。

ボールが速すぎてホールに入るのを心配したり、後方に転がったり、丘を飛び降りたりすることを心配する必要はありません。

テストケース

Input: 27
      ____       ____ _   
   __/    \     /    U \  
__/        \   /        \_
            \_/           
Output: true

----------

Input: 26
      ____       ____ _   
   __/    \     /    U \  
__/        \   /        \_
            \_/           
Output: false

----------

Input: 1

U
Output: true

----------

Input: 1
_ 
 U
Output: false

----------

Input: 22

     /U
    /  
   /   
  /    
\/     
Output: true

----------

Input: 999
_       _
 \     / 
  \   /  
   \ /   
    U    
Output: true

----------

Input: 5
  /
/U 
Output: false

----------

Input: 9

/\/\/\/\/U
Output: false

----------

Input: 16

_/\                                         _
   \      __       /\/\/\                  / 
    \    /  \     /      \                /  
     \__/    \   /        \____________ _/   
              \_/                      U     

Output: true

これはコードミニゴルフで、バイト単位の最短回答が勝ちです!


1
言語に適切な配列が組み込まれている場合\_/は、次の手順で入力を操作のストリームに変換できます()。行の配列に分割、回転、フラット化、スペースを削除
チョイス

1
これは本当に多くの固定トラック機構のゴルフ場より:P
ザック・ゲイツ

24
\/\/\/\/\/はそれよりも効率的なコースが好きです__________
ezrast

2
それが私が考えていた4ダウン、5アップ、そして.5は平均でなければなりません。ああ、フラットは1ですか?
レイフウィラーツ

コース内の各行の長さは常に同じですか(後続のスペースが短い行の終わりを埋めます)?
SnoringFrog

回答:


17

Pyth、27バイト

.Am<sXsd"_\ /"[1_4Z5)Q._C.z

デモンストレーション

このコードは非常に巧妙な処理を行いますが、でタイプセーフではありませんX。以下をご覧ください。

説明:

.Am<sXsd"_\ /"[1_4Z5)Q._C.z
                               Implicit: Z = 0, Q = eval(input())
                               Q is the initial power.
                         .z    Take all input, as a list of lines.
                        C      Transpose, giving all columns.
                      ._       Form all prefixes.
  m                            Map over the prefixes.
      sd                       Concatenate the prefix.
     X  "_\ /"[1_4Z5)          Change '_' to 1, '\' to -4, ' ' to 0, and '/' to 5.
                               In particular, 'U' is left unchanged.
    s                          Reduce on addition.
                               If all elements were numbers,
                               this results in the total change in power.
                               If there was a 'U', it results in a string.
   <                 Q         If the previous result was a number, this compares
                               it with the initial input to see if the ball is
                               still rolling.
                               If the previous result was a string, this slices off
                               the first Q characters, which always has a truthy
                               result.
.A                             Test whether all of the prefixes mapped to a thruthy
                               result.

私は何かを見逃しているかもしれませんが、止まりQますか?つまり、最後の例はいくつかの問題を引き起こす可能性がありますか?
flindeberg

@flindebergそれはそれがどのように機能するかではありません。これ< ... Qは、スライスではなく、穴までの数値比較として機能します。ホールの後、重要なことは結果が真実であることだけです。
isaacg

14

Haskell、111 109バイト

import Data.List
g"_"=1
g"/"=5
g _= -4 
f n=all(>0).scanl(-)n.map g.fst.span(/="U").(>>=words).transpose.lines

使用例:

*Main> f 27 "      ____       ____ _   \n   __/    \\     /    U \\  \n__/        \\   /        \\_\n            \\_/           "
True
*Main> f 26 "      ____       ____ _   \n   __/    \\     /    U \\  \n__/        \\   /        \\_\n            \\_/           "
False

使い方:

                            lines  -- split into list of lines at nl
                       transpose   -- transpose
                  (>>=words)       -- turn each line into words (i.e. remove spaces)  
            fst.span(/="U")        -- take all words up to but excluding "U"
         map g                     -- turn each word into the speed modifier
    scanl(-)n                      -- build list of partial sums starting with n
                                   --   note: speed modifiers are negative so we
                                   --   use (-) with scanl to build sums 
all(>0)                            -- return true if all sums are greater than 0                                 

編集:@ user81655は保存する2バイトを見つけました。ありがとう!


7

ルビー、104 87文字

->s,t{t.lines.map(&:bytes).transpose.map{|o|(c=o.max)==85||s<0?break: s+=c*3%14-6}
s>0}

サンプル実行:

2.1.5 :001 > track = '      ____       ____ _   
2.1.5 :002'>    __/    \     /    U \  
2.1.5 :003'> __/        \   /        \_
2.1.5 :004'>             \_/           
2.1.5 :005'> '
 => "      ____       ____ _   \n   __/    \\     /    U \\  \n__/        \\   /        \\_\n            \\_/           \n" 

2.1.5 :006 > ->s,t{t.lines.map(&:bytes).transpose.map{|o|(c=o.max)==85||s<0?break: s+=c*3%14-6};s>0}[27, track]
 => true 

2.1.5 :007 > ->s,t{t.lines.map(&:bytes).transpose.map{|o|(c=o.max)==85||s<0?break: s+=c*3%14-6};s>0}[26, track]
 => false 

6

Japt、38バイト

Vz r"%s|U[^]*" ¬e@UµX¥'_?1:X¥'/?5:-4 ¬

Try it here!

CJamを破った!

説明

基本的に、文字列入力を受け取り、時計回りに90度回転し、スペースと改行を取り除き、穴とその後のすべてを削除し、文字に沿って分割します。次に、every関数を使用してボールがゼロ以下になるかどうかを確認します。


私は ''肯定的であるべきだ(説明が間違っているように見える)
isaacg

私はそれが機能するとは思わない。これを想像してください:一連のスロープはボールの速度を-2にしますが、その後ネット+4があります。合計は+2を反映するので、ボールはそれを作りました。実際には、ネガティブに達した後、ポジティブセクションに到達することはありません。
チョイス

私は問題を解決したと思います。
ママファンロール

それはクールなボタンです;)
Jアトキン

いいね!したがって、ゴルフ...二重のバックスラッシュはに置き換え可能であり%>0に置き換えることができます¬。これは、正でない数のsqrtは常に偽(0 -> 0-1 -> NaN)であるためです。
ETHproductions

6

CJam、40 39バイト

liqN/:.e>'U/0="\_/"[4W-5]er{1$+}/]:e<0>

入力の最初の行にパワーがあり、2行目から始まるコースがあります。出力は0または1です。

ここでテストしてください。

説明

li    e# Read power and convert to integer.
qN/   e# Read course and split into lines.
:.e>  e# Flatten course by folding maximum over columns.
'U/   e# Split around the hole.
0=    e# Keep the first chunk.
"\_/"[4W-5]er
      e# Replace \, _, / with 4, -1, 5, respectively.
{     e# For each of those costs...
  1$+ e#   Copy the previous power and add the cost.
}/    e# This leaves all partial sums on the stack.
]     e# Wrap them in an array.
:e<   e# Find the minimum.
0>    e# Check whether it's positive.

5

網膜、82 81 77 74 68 67 68バイト

+`(?<=(.)*) (?=.*¶(?<-1>.)*(.))
$2
\\
>>>>
+`>_|>{5}/|>¶

^>*U

オンラインで試す

  • 入力はn sのように単項ベースで表されます。>たとえば、4は>>>>\nです。(これは合法ですか?)
  • +`(?<=(.)*) (?=.*¶(?<-1>.)*(.)) $2 -コースを平らにします-スペースをその下の文字に置き換えます。

    この段階の後、データは次のようになります。

    >>>>>>>>>>>>>>>>>>>>>>>>>>
    __/__/____\\\_///____U_\\_
    __/__/    \\\_///    U \\_
    __/        \\_//        \_
                \_/           
    

    最初のもの以降はすべて無視するUことができますが、とにかくそこには到達しません。

  • > 許可されているステップ、または残りのエネルギーを表します。
  • それぞれ\を4つに置き換えます>-スロープは追加のエネルギーを与えます。
  • ループ:議論の余地なく削除する>_>>>>>/、何もなくなるまで。_sと/sはエネルギーを消費します。
  • 最後に、一致^>*Uするようにしてください- U正のエネルギー(またはエネルギーなし)で到達できるかどうかを確認してください。
    これにより、0またはが出力されます1

91 79バイトのもう1つのクローズオプションは次のとおりです。

+`(?<=¶(.)*) (?=.*¶(?<-1>.)*(.))
$2
^(>)+\n(?<-1>_|/(?<-1>){4}|\\(?<1>){5})+U

オンラインで試す

これは同じアプローチですが、論争の多い置き換えの代わりにバランスグループを使用します。

私はこれらの両方がさらにゴルフできると確信しているので、どちらかがより短くなるかもしれません。


1
はい、単項入力が合法である私はおそらく使用したいが、(挑戦指定する「小数」場合を除く)0または1その任意の追加のバイトが発生しない場合の数字として。
マーティンエンダー

1
PPCGへようこそ、ここでお会いできて本当に嬉しいです!:)(そしてRetinaも使用しています。)
マーティン・エンダー

承知しました!ホットな質問リストに載っていて、面白そうだった。私はそれを試してみたいと思った:-)
コビ

3

ES6、117バイト

(c,p)=>c.split`
`.map(s=>[...s.slice(0,c.match(/^.*U/m)[0].length-1)].map(c=>p+=c=='/'?-5:'    \\'.indexOf(c)))&&p>0

ゴルフをしていない:

function hole(course, power) {
    width = course.match(/^.*U/m)[0].length - 1; // calculate width to hole
    lines = course.split("\n");
    for (i = 0; i < lines.length; i++) {
        line = lines[i].slice(0, width); // ignore extraneous parts of the course
        for (j = 0; j < line.length; j++) {
            switch (line[j]) { // accumulate remaining power
            case '/': power -= 5; break;
            case '\\': power += 4; break;
            case ' ': break;
            default: power--; break;
            }
        }
    }
    return power > 0;
}

編集:ՊՓԼՃՐՊՃՈԲՍԼのおかげで4バイトを保存しました。


@ՊՓԼՃՐՊՃՈԲՍԼおかげで、速度を最適化しようとし続けています...-
ニール

3

JavaScriptの(ES6)、108の 107 106バイト

これが、チャレンジを作成したときに思いついたソリューションです。

(p,c)=>[...(l=c.split`
`)[w=0]].map((_,i)=>l.map(t=>(g=t[i])-1|p<=0?0:p-=g>"]"?1:g>"U"?-4:g>"/"?w=1:5))&&w

説明

力を数字として、コースを文字列として受け取ります。戻り値1のためtrue0についてfalse。コースにはスペースを埋め込む必要があります。

(p,c)=>
  [...(l=c.split`
`)                          // l = array of lines
  [w=0]]                    // w = true if the ball has entered the hole
.map((_,i)=>                // for each index i
  l.map(t=>                 // for each line t
    (g=t[i])                // g = the character at the current index
    -1|p<=0?0:              // do nothing if g is a space or the ball has no speed left
    p-=
      g>"]"?1               // case _: subtract 1 from p
      :g>"U"?-4             // case \: add 4 to p
      :g>"/"?w=1            // case U: set w to true (it doesn't matter what happens to p)
      :5                    // case /: subtract 5 from p
  )
)
&&w                         // return w

テスト

var solution = (p,c)=>[...(l=c.split`
`)[w=0]].map((_,i)=>l.map(t=>(g=t[i])-1|p<=0?0:p-=g>"]"?1:g>"U"?-4:g>"/"?w=1:5))&&w
Power = <input type="number" id="power" value="16" /><br />
<textarea id="course" rows="6" cols="50">_/\                                         _
   \      __       /\/\/\                  / 
    \    /  \     /      \                /  
     \__/    \   /        \____________ _/   
              \_/                      U     </textarea><br />
<button onclick="result.textContent=solution(+power.value,course.value)">Go</button>
<pre id="result"></pre>


3

Python(3.5)169160バイト

転置機能なしの再帰的ソリューション(zip)

def f(c,p):c=c.splitlines();l=len(c);f=lambda x,h,v:v if'U'==c[h][x]or v<1 else f(x+(h==l-1),(h+1)%l,v+{"_":-1,"\\":4,"/":-5," ":0}[c[h][x]]);return f(0,0,p)>0

非ゴルフ

cはもちろん、pは力、vは速度、hは高さ

def f(c,p):
    c=c.splitlines()
    l=len(c)
    tmp = {"_":-1,"\\":4,"/":-5," ":0}
    f=lambda x,h,v:v if'U'==c[h][x]or v<1 else f(x+(h==l-1),(h+1)%l,v+tmp[c[h][x]])
    return f(0,0,p)>0

使用法

f(16,"_/\                                         _\n   \      __       /\/\/\                  / \n    \    /  \     /      \                /  \n     \__/    \   /        \____________ _/   \n              \_/                      U     ")
f(9,"/\/\/\/\/U")

2

Pyth、35バイト

VC.z=-Q@(1_4 5)x"_\\/"JrN6IqJ\U>Q_5

説明

                                    - Autoassign Q = eval(input())
                                    - Autoassign .z = rest of input
VC.z                                - For N in zip(*.z)
    =-Q                             - Q -= ...
                      JrN6          - Autoassign J to N.strip() (get rid of spaces)
       @(1_4 5)x"_\\/"              - {"_":1, "\\": -4, "/": 5, "U":5}[J] ("U" isn't defined but that's what it is according to how str.index works)
                          IqJ\U     - If J == "U"
                               >Q_5 - print Q > -5 ()

1

ルビー、85文字

->i,s{s.lines.map(&:bytes).transpose.any?{|o|(c=o.max)==85||i<0||!(i+=c*3%14-6)};i>0}

@manatworkの回答を修正


1

JavaScriptの、266の 263 244バイト

(s,a)=>{var f=(e,x)=>{for(var i=1;D=e[i][x],i<e.length;i++)if(D!=" ")return D},o=a.split(`
`),l=o.reduce((a,b)=>Math.max(a.length||a,b.length)),b="";for(i=0;i<l;i)b+=f(o,i++);for(i=0;b[i]!="U"&&s>0;i++)s-=b[i]=="_"?1:b[i]=="/"?5:-4;return s>0}

非ゴルフ

(s,a)=>{
    var f=(e,x)=>{
        for(var i=1;D=e[i][x],i<e.length;i++)
            if(D!=" ")
                return D
    },
    o=a.split(`
`),
    l=o.reduce((a,b)=>Math.max(a.length||a,b.length)),
    b="";
    for(i=0;i<l;)
        b+=f(o,i++);
    for(i=0;b[i]!="U"&&s>0;i++)
        s-=b[i]=="_"?1:b[i]=="/"?5:-4;
    return s>0
}

使用法

var o = (s,a)=>{var f=(e,x)=>{for(var i=1;D=e[i][x],i<e.length;i++)if(D!=" ")return D},o=a.split(`
`),l=o.reduce((a,b)=>Math.max(a.length||a,b.length)),b="";for(i=0;i<l;)b+=f(o,i++);for(i=0;b[i]!="U"&&s>0;i++)s-=b[i]=="_"?1:b[i]=="/"?5:-4;return s>0}


o(27, `
      ____       ____ _   
   __/    \\     /    U \\  
__/        \\   /        \\_
            \\_/           `); // will return true

私の間違い; 最初の例で「27」を最初の引数としてコピーしたと思った。これを修正しました。ありがとうございました。
user49328

1

Java、219バイト

boolean p(int v,String c){int z=c.length(),f[]=new int[z],e,i,k;for(String r:c.split("\n"))for(i=-1;++i<r.length();)if((e=r.charAt(i))>32)f[i]=e;for(i=-1,e=0;++i<z&v>0;)v-=(k=f[i])>94?1:k>91?-4:k>84?(e=1):5;return 0<e;}
  • y座標は重要ではないため、コースを平坦化します。残念ながら、Javaには垂直トリムがありません。また、String-transposeもありません。

  • 平坦化されたコースを反復処理し、ボールの速度を追跡します。


1

オクターブ、111 110バイト

function g(v,s) A([95,47,92])=[1,5,-4];all(v>cumsum(A(m=max(cat(1,strsplit(s,'\n'){:}),[],1)))(1:find(m==85)))

説明:

  • 入力を改行で分割し、その迷惑なセル配列を行列に変換します
  • max各列を見つけることにより、マトリックスを平坦化します
  • 文字'_/\'をマップします[1, 5, -4]'_'マップされているよりも小さいすべての文字0
  • マップされた配列のすべての要素の累積合計を計算します
  • Trueコースの開始からカップまでのすべての累積合計が開始速度よりも小さい場合に出力されます(Falseそうでない場合)。

これは、@ Erwanが提案した2番目のテストケースに似た、既に開発したテストケースといくつかの結果です。

s9 =
   /\
  /  \
_/    \
       \
        \
         U

g(11,s9) %False
ans = 0
g(17,s9) %True
ans =  1

そして、これが最初のテストケースです:

s10 = 
  _
 / U\
/    \
      \
       \
        \
         \
          \_

>> g(11,s10)
ans = 0
>> g(12,s10)
ans =  1

コースが"//_U\\\\\\\_結果のように間違っていると思うのはU、ローカル最大値のようなコースがある場合、同じことの後にキャラクターを削除しないからです_//\\\\\U
-Erwan

@Erwanしかし、。の後の文字削除しUます。それがそう(1:find(m==85))です。最初のインデックスからの位置までサブ配列を取りますU。いくつかの開始速度でテストケースを確認し、ご連絡いたします。
ビーカー

私はあなたのソリューションを実行できませんでした(私はオクターブを持っていません)、なぜ私は尋ねるのですか...そして、私は他のPythonソリューションでローカルマキシマを持つISSUを見つけるため:)最終的にあなたのソリューションはcumsumを使用しているためローカルマキシマで動作します合計だけではありません(最初の読み物では見ないでください)
エルワン

@Erwanあなたが提案した2つのテストケースを追加しました。結果が期待どおりかどうかを確認してください。MATLABでこれを試している場合、Octaveでのみ機能するインデックスを使用するため、実行することはできません。の結果をcumsum中間変数に割り当て、それを最終比較に使用する必要がありall(v>tmp(1:find(m==85)))ます。
ビーカー

あなたのソリューションは、最初の読み取りで多くのことをうまく見逃します(Matlabで追加する中間変数が非常に多くテストされます)
-Erwan

0

C、629バイト

#include <string.h>
#include <stdlib.h>
#include <string.h>

bool swing(char *c, unsigned int p)
{
    char *olc = calloc(strlen(c), 1);
    int x = 0;
    char *n = c;

    while(1) {
        if(*n == '\0')  break;
        else if(*n == ' ') x += 1;
        else if(*n == '\n') x = 0;
        else {
            olc[x] = *n;
            x += 1;
        }
        n++;
    }

    int hd = 0;
    for(char *i = olc; i != strchr(olc, 'U'); i++) {
        if(*i == '_') hd += 1;
        else if(*i == '/') hd += 5;
        else hd -= 4;
    }

    free(olc);
    if(hd < p) return 1;
    return 0;
}

ゴルフをしていない:

bool swing(char *course, unsigned int power)
{
    const size_t course_len = strlen(course);
    char *one_line_course = calloc(course_len, sizeof(char));
    assert(one_line_course);
    int x_pos = 0;
    char *next = course;

    //Convert to one line representation
    while(1) {
        if(*next == '\0') {
            break;
        }
        else if(*next == ' ') {
            x_pos += 1;
        }
        else if((*next == '\n') || (*next == '\r')) {
            x_pos = 0;
        }
        else {
            one_line_course[x_pos] = *next;
            x_pos += 1;
        }
        next++;
    }

    //Calculate power vs distance
    const char *hole_location = strchr(one_line_course, 'U');
    int hole_distance = 0;
    for(char *i = one_line_course; i != hole_location; i++) {
        if(*i == '_') {
            hole_distance += 1;
        }
        else if(*i == '/') {
            hole_distance += 5;
        }
        else {
            hole_distance -= 4;
        }
    }

    free(one_line_course);
    if(hole_distance < power) {
        return true;
    }
    else {
        return false;
    }
}

基本的には、入力文字列を変換してすべてを1行に収めるために1回パスするだけです。


プログラミングパズルとコードゴルフへようこそ!ほとんどの空白を削除することにより、サイズを大幅に縮小することができます(また、そうすべきです)。if/ elseegの一部を減らすことができますx+=*n==' ')?1:*n=='\n'?-x:(olc[x]=*n,1。別のヒント:Cでは、すぐに4バイトを節約してunsigned int書くことができますunsigned
トビースパイト

0

Python、212 201 188 143バイト

このスクリプトのこの反復の功績の多くは@Erwanにあります。@ Erwanは、まったく異なるアプローチを試してみて、最終的に55バイトを節約したいくつかのヒントを与えてくれました。

再帰的ではないため、他のPythonソリューションとは大幅に異なる必要があります。

def g(c,p):
 o=[''.join(x).split()[0] for x in zip(*c.split('\n'))]
 t={"_":1,"/":5,"\\":-4}
 for v in o:
    if v=="U" or p<1:return p>0
    p-=t[v]

少しゴルフを解いた:

def g(course,power):
  course=course.split('\n') # split into lines
  course=zip(*course) 

  #transpose and flatten course, then remove spaces
  one_line_course=[''.join(x).split[0] for x in zip(*course)] 

  terrain_values={"_":1,"/":5,"\\":-4}
  for char in one_line_course:
    if char=="U" or power<1: 
      return power>0 # true when power remains, false otherwise
    power-=terrain_values[char]

より短いソリューションが必要な場合は、Cyoce tipを使用して、組み込みのトランスポーズ機能を使用できます。o=[''.join(x).split()[0] for x in zip(*c.split('\n'))]40バイトを勝ち取るようなもの
-Erwan

あなたも置き換えることができますbreakによってreturn p>0および削除if p...
エルワン

次のif"U"==v or p<1 ようなローカル最大値がある場合、条件を追加する必要があります_//\\\\\U
-Erwan

@Erwan最初のヒントは、行の長さがすべて同じではない場合は機能しません(短い行には、長い行と一致する後続スペースがあります)。投稿には「コースにオプションでスペースを埋め込むことができる」と書かれているので、それが正しいと仮定できるかどうかはわかりません。私はコメントでそれについて尋ねました。
SnoringFrog

はい私は多分私は私の解決策が悪いだと思うこの場合は間違っているすべての行が同じ長さ(空白でegalized)を持っていると仮定
エルワン・
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.