代码(迷你)高尔夫


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
如果您的语言具有良好的内置数组,则可以\_/通过以下步骤将输入转换为操作流():拆分为行数组,旋转,展平,去除空格。
Cyoce

1
实际上,这比高尔夫球场更像是固定轨道的机制:P
Zach Gates

24
我喜欢那\/\/\/\/\/是比的更有效的课程__________
ezrast

2
这就是我的想法,下降4点,上升5点,然后.5必须是平均水平。哦,单位是1?
Leif Willerts '16

路线中的每一行都将保持相同的长度(短行尾填充尾随空格)吗?
SnoringFrog

Answers:


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 '16

@flindeberg那不是它的工作原理。该< ... Q工程作为一个数字比较起来,直到孔,而不是一个切片。在漏洞之后,重要的是结果是真实的。
isaacg '16

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

Ruby,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!

击败果酱!

说明

基本上接受字符串输入,将其顺时针旋转90度,去除空格和换行符,删除孔及其后的所有内容,然后沿字符拆分。然后使用该every功能检查球是否达到零或以下。


我认为“应该是积极的(描述看起来有误)
isaacg

我认为那行不通。想象一下:一系列的坡度使球的速度变为-2,但随后的净值为+4。总和将反映为+2,所以球成功了。实际上,到达负数之后再也不会到达正数了。
Cyoce

我想我解决了这个问题。
Mama Fun Roll

那是个很棒的按钮;)
J Atkin

真好!因此,打高尔夫球...双反斜杠可以替换为%>0也可以替换为¬,因为非正数的平方根始终为假(0 -> 0-1 -> NaN)。
ETHproductions 2016年

6

CJam,40 39字节

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

输入在第一行有电源,而课程在第二行开始。输出为01

在这里测试。

说明

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

Retina,82 81 77 74 68 67 68字节

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

^>*U

在线尝试

  • 输入以一进制为单位表示,例如n >s,例如4 is >>>>\n。(这合法吗?)
  • +`(?<=(.)*) (?=.*¶(?<-1>.)*(.)) $2 -弄平路线-用下方的字符替换空格。

    在此阶段之后,数据将如下所示:

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

    我们只能在第一个之后忽略所有内容U,无论如何我们都不会到达那里。

  • > 代表我们被允许迈出的一步或剩余的能量。
  • \用四个替换每个>-倾斜会给我们带来额外的能量。
  • 循环:有争议地删除>_>>>>>/直到没有剩余。_s和/s 消耗能量。
  • 最后,尝试匹配^>*U-检查我们是否可以达到U正能量(或没有能量)。
    这将输出01

具有91 79个字节的另一个关闭选项是:

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

在线尝试

这是相同的方法,但是使用平衡组而不是有争议的替换。

我确信这两个都可以打得更远,所以它们中的任何一个都可能变短。


1
是的,一元输入是合法的(除非挑战指定“十进制”),但是如果不引起任何额外的字节,我可能会使用01作为数字。
Martin Ender

1
也欢迎来到PPCG,很高兴在这里见到您!:)(以及使用视网膜)
。–马丁·恩德

当然!它在热门问题列表上,看起来很有趣。我以为可以试试看:-)
Kobi

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

编辑:感谢Save,保存了4个字节。


@ՊՓԼՃՐՊՃՈԲՍԼ谢谢,我一直在努力优化速度...
Neil

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

说明

将幂作为数字,将过程作为字符串。返回1true0false。课程必须用空格填充。

(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

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 '16

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没有垂直修剪。它也没有字符串转置。

  • 遍历平坦的路线并跟踪球速。


1

八度,111110字节

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提出的第二个用例,并产生了一些结果:

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。我将以几个初始速度来检查您的测试用例,然后再与您联系。
烧杯

我不能运行您的解决方案(我没有Octave),这就是为什么我只是问...,因为我在另一个python解决方案中找到了带有局部极大值的issu :)最后,因为您使用了cumsum,所以您的解决方案可以与局部极大值一起工作而不是总和(初读时看不到)
Erwan

@Erwan我已经添加了您建议的两个测试用例。请看一下结果是否符合您的期望。如果您在MATLAB中尝试此操作,那么您将无法运行它,因为它使用的某些索引仅在Octave中有效。您将必须将结果分配给cumsum中间变量,然后将其用于最终比较all(v>tmp(1:find(m==85)))
烧杯

您的解决方案在第一次阅读时就很好地解决了很多问题(只是在Matlab中测试,所以要添加许多中间变量)
Erwan 2016年

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

基本上,我只需要经过一遍就可以将输入字符串转换为适合一行的所有内容,然后


欢迎来到编程难题和代码高尔夫球!您可以(并且应该)能够通过消除大多数空白来大幅减小尺寸;你可以减少一些if/ else例如x+=*n==' ')?1:*n=='\n'?-x:(olc[x]=*n,1。另一个技巧:在C中,unsigned int可以被写入unsigned,立即节省4个字节。
Toby Speight

0

Python中,212个 201 188 143字节

此脚本的这次迭代的大部分功劳归功于@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笔尖并使用移调内置函数。o=[''.join(x).split()[0] for x in zip(*c.split('\n'))]我认为这样 可以赢得40个字节
Erwan 2016年

你也可以更换breakreturn p>0,并删除if p...
二万

如果需要if"U"==v or p<1 局部最大值,则需要添加一个条件,例如_//\\\\\U
Erwan

@Erwan如果行的长度不一样(短行的尾部空格匹配长行),则第一个技巧不起作用。由于帖子中说“课程可以有选择地用空格填充”,所以我不确定我们可以假设这是真的。我已经在评论中问过这个问题。
SnoringFrog

是的,我承担所有线具有相同的长度(以空格egalized)也许我错在这种情况下,我认为我的解决方案是坏的
二万
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.