| Bytes | Lang | Time | Link |
|---|---|---|---|
| 081 | JavaScript Node.js | 250329T040828Z | l4m2 |
| 095 | JavaScript Node.js | 250328T130844Z | Steve Be |
| 047 | J | 200918T063717Z | Jonah |
| 068 | Retina | 160121T142615Z | Kobi |
| 143 | Python | 160122T162950Z | SnoringF |
| 629 | C | 160125T213404Z | samt1903 |
| 110 | Octave | 160122T201054Z | beaker |
| 160 | Python 3.5 | 160120T135230Z | Erwan |
| 219 | Java | 160122T083621Z | ECS |
| 039 | CJam | 160120T080543Z | Martin E |
| 106 | JavaScript ES6 | 160121T074045Z | user8165 |
| 117 | ES6 | 160120T214634Z | Neil |
| 038 | Japt | 160120T051041Z | Mama Fun |
| 244 | JavaScript | 160120T182437Z | user4932 |
| 085 | Ruby | 160120T210609Z | Connor C |
| 087 | Ruby | 160120T135520Z | manatwor |
| 035 | Pyth | 160120T133605Z | Blue |
| 027 | Pyth | 160120T063211Z | isaacg |
| 109 | Haskell | 160120T000323Z | nimi |
JavaScript (Node.js), 81 bytes
s=>t=>t[0].some((_,i)=>t.some(r=>(s-={'\\':-4,'/':5,'_':1,'U':-1/0}[r[i]]||0)<1))
The hole provide infinite extra speed, and test if it reach the end
JavaScript (Node.js), 95 bytes
(s,t)=>{for(i in t[0])for(r of t){s-=~~{'\\':-4,'/':5,'_':1}[c=r[i]]
if(c=='U'|s<1)return s>0}}
Takes an array of strings that equal in length (right-padded). Works from left to right, then top to bottom, stopping when speed hits 0 or the hole is found.
JavaScript (Node.js), 119 bytes
(t,s=l=0)=>s.replace(/U|(.)|$/mg,(m,c,d)=>{l=m?l:d
if(d-/^.*U/m.exec(s)[0].length<l)t-=~~{'\\':-4,'/':5,'_':1}[c]})|t>0
Retina, 82 81 77 74 68 67 68 bytes
+`(?<=(.)*) (?=.*¶(?<-1>.)*(.))
$2
\\
>>>>
+`>_|>{5}/|>¶
^>*U
- Input is represented in unary base, as n
>s - for example, 4 is>>>>\n. (is this legal?) +`(?<=(.)*) (?=.*¶(?<-1>.)*(.))$2- flatten the course - replace spaces with the character below them.After this stage the data will look like this:
>>>>>>>>>>>>>>>>>>>>>>>>>> __/__/____\\\_///____U_\\_ __/__/ \\\_/// U \\_ __/ \\_// \_ \_/We can just ignore everything after the first
U, we will not reach there anyway.>represent a step we are allowed to make, or the remaining energy.- Replace each
\with four>- a slope gives us additional energy. - Loop: contentiously remove
>_or>>>>>/until there are none left._s and/s consume energy. - Finally, try to match
^>*U- check if we can reachUwith positive energy (or no energy).
This will output0or1.
Another close option with 91 79 bytes is:
+`(?<=¶(.)*) (?=.*¶(?<-1>.)*(.))
$2
^(>)+\n(?<-1>_|/(?<-1>){4}|\\(?<1>){5})+U
This is the same approach but with a balancing group instead of a contentious replace.
I'm sure both of these can be golfed further, so any one of them may end up shorter.
Python, 212 201 188 143 bytes
Much of the credit for this iteration of this script goes to @Erwan, who gave me an entirely different approach to try and some tips that saved me 55 bytes in the end.
Not recursive, so should be substantially different from the other python solution.
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]
Ungolfed a bit:
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]
C, 629 Bytes
#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;
}
Ungolfed:
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;
}
}
Basically I just make one pass to convert the input string to fit everything in one line, then
Octave, 111 110 bytes
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)))
Explanation:
- Split the input on newlines and convert that annoying cell array to a matrix
- Flatten the matrix by finding the
maxfor each column - Map the characters
'_/\'to[1, 5, -4](all other characters less than'_'are mapped to0) - Calculate the cumulative sum of all elements of the mapped array
- Output
Trueif all cumulative sums from the beginning of the course to the cup are less than the start velocity (Falseotherwise).
Here is a test case that I had already developed similar to the second one proposed by @Erwan and a couple of results:
s9 =
/\
/ \
_/ \
\
\
U
g(11,s9) %False
ans = 0
g(17,s9) %True
ans = 1
And here's the first test case:
s10 =
_
/ U\
/ \
\
\
\
\
\_
>> g(11,s10)
ans = 0
>> g(12,s10)
ans = 1
Python (3.5) 169 160 bytes
A recursive solution without the transpose function (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
Ungolfed
c for course, p for power, v for speed, h for height
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
Usage
f(16,"_/\ _\n \ __ /\/\/\ / \n \ / \ / \ / \n \__/ \ / \____________ _/ \n \_/ U ")
f(9,"/\/\/\/\/U")
Java, 219 Bytes
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;}
Flatten the course, because the y-coordinate doesn't matter, unfortunately Java doesn't have a vertical trim. It also doesn't have a String-transpose.
Iterate over the flattened course and keep track of the ball speed.
CJam, 40 39 bytes
liqN/:.e>'U/0="\_/"[4W-5]er{1$+}/]:e<0>
Input has the power on the first line and the course starting on the second line. Output is 0 or 1.
Explanation
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.
JavaScript (ES6), 108 107 106 bytes
This is the solution I came up with when I created the challenge.
(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
Explanation
Takes the power as a number and the course as a string. Returns 1 for true or 0 for false. The course must be padded with spaces.
(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
Test
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>
ES6, 117 bytes
(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
Ungolfed:
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;
}
Edit: Saved 4 bytes thanks to ՊՓԼՃՐՊՃՈԲՍԼ.
Japt, 38 bytes
Vz r"%s|U[^]*" ¬e@UµX¥'_?1:X¥'/?5:-4 ¬
Beating CJam!
Explanation
Basically takes the string input, rotates it 90deg clockwise, strips out spaces and newlines, removes the hole and everything after it, and splits along chars. Then checks if ball ever gets to zero or below using the every function.
JavaScript, 266 263 244 bytes
(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}
Ungolfed
(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
}
Usage
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
Ruby, 85 characters
->i,s{s.lines.map(&:bytes).transpose.any?{|o|(c=o.max)==85||i<0||!(i+=c*3%14-6)};i>0}
Adapted @manatwork's answer
Ruby, 104 87 characters
->s,t{t.lines.map(&:bytes).transpose.map{|o|(c=o.max)==85||s<0?break: s+=c*3%14-6}
s>0}
Sample run:
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
Pyth, 35 bytes
VC.z=-Q@(1_4 5)x"_\\/"JrN6IqJ\U>Q_5
Explanation
- 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 ()
Pyth, 27 bytes
.Am<sXsd"_\ /"[1_4Z5)Q._C.z
This code does something very clever and not at all type-safe with X. Check it out below.
Explanation:
.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.
Haskell, 111 109 bytes
import Data.List
g"_"=1
g"/"=5
g _= -4
f n=all(>0).scanl(-)n.map g.fst.span(/="U").(>>=words).transpose.lines
Usage example:
*Main> f 27 " ____ ____ _ \n __/ \\ / U \\ \n__/ \\ / \\_\n \\_/ "
True
*Main> f 26 " ____ ____ _ \n __/ \\ / U \\ \n__/ \\ / \\_\n \\_/ "
False
How it works:
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
Edit: @user81655 found 2 bytes to save. Thanks!