Code (Mini) Golf


50

Compte tenu de la vue de côté d'un parcours de mini-golf et de la puissance de l'élan, déterminez si la balle parviendra dans le trou.


Un cours sera dans ce format:

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

La balle commence juste avant le premier terrain à gauche et suit le contour du parcours jusqu'à atteindre le trou (majuscule au- Udessous du niveau actuel du sol). S'il atteint le trou, affichez une valeur de vérité. La puissance du swing sera la vitesse initiale de la balle. La balle se déplace vers le personnage suivant à droite à chaque itération, puis la vitesse change en fonction du personnage sur lequel elle se trouve. Si la vitesse atteint 0ou moins avant le trou, donnez une valeur de falsey.

  • _ diminue la vitesse de 1
  • / diminue la vitesse de 5
  • \ augmente la vitesse de 4

Les cours peuvent éventuellement être complétés par des espaces. La puissance du swing sera toujours un entier positif.

Vous n'avez pas à craindre que la balle aille trop vite pour entrer dans le trou, rouler en arrière ou sauter / rebondir sur les collines.

Cas de test

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

C'est le code mini-golf, la réponse la plus courte en octets gagne!


1
Si votre langue comporte de bons tableaux intégrés, vous pouvez alors transformer l’entrée en un flux d’opérations ( \_/) en procédant comme suit: scission en tableau de lignes, rotation, aplatissement, bandes d’espace.
Cyoce

1
C'est vraiment plus un mécanisme à voie fixe qu'un terrain de golf: P
Zach Gates

24
J'aime que ce \/\/\/\/\/soit un cours plus efficace que __________.
Ezrast

2
C'est ce que je pensais, 4 bas, 5 en haut, alors .5 doit être moyenne. Oh, plat c'est 1?
Leif Willerts

Chaque ligne d'un parcours aura-t-elle toujours la même longueur (avec des espaces finaux remplissant les extrémités des lignes plus courtes)?
SnoringFrog

Réponses:


17

Pyth, 27 octets

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

Manifestation

Ce code fait quelque chose de très intelligent et pas du tout sûr avec le type X. Vérifiez ci-dessous.

Explication:

.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.

Il se peut que je manque quelque chose, mais est-ce que ça s'arrête à Q? C'est-à-dire que le dernier exemple pourrait causer des problèmes?
Flindeberg

@ Flindeberg Ce n'est pas comme ça que ça marche. Le < ... Qfonctionne comme une comparaison numérique jusqu'au trou, pas une tranche. Après le trou, tout ce qui compte est que le résultat soit la vérité.
isaacg

14

Haskell, 111 109 octets

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

Exemple d'utilisation:

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

Comment ça fonctionne:

                            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 a trouvé 2 octets à sauvegarder. Merci!


7

Ruby, 104 87 caractères

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

Échantillon échantillon:

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 octets

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

Try it here!

Battre CJam!

Explication

Fondamentalement, saisit la chaîne, la fait pivoter de 90 degrés dans le sens des aiguilles d'une montre, supprime les espaces et les nouvelles lignes, supprime le trou et tout ce qui suit, et se scinde le long des caractères. Puis vérifie si la balle arrive à zéro ou en dessous en utilisant la everyfonction.


Je pense que `` devrait être positif (la description semble fausse)
isaacg

Je ne pense pas que ça marche. Imaginez ceci: une série de pentes donne la vitesse de la balle à -2, mais il y a ensuite un filet de +4. La somme refléterait +2 alors la balle a réussi. En réalité, il n’arriverait jamais à la section positive après avoir atteint les négatifs.
Cyoce

Je pense avoir résolu le problème.
Mama Fun Roll

C'est un bouton cool;)
J Atkin

Agréable! Donc, jouer au golf ... La double barre oblique inversée est remplaçable par %et >0peut être remplacée par ¬, puisque le carré d'un nombre non positif est toujours faux ( 0 -> 0, -1 -> NaN).
ETHproductions

6

CJam, 40 39 octets

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

L'entrée a le pouvoir sur la première ligne et le parcours commence sur la deuxième ligne. La sortie est 0ou 1.

Testez-le ici.

Explication

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 octets

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

^>*U

Essayez-le en ligne

  • L'entrée est représentée dans une base unaire , comme n >s - par exemple, 4 l'est >>>>\n. (est-ce légal?)
  • +`(?<=(.)*) (?=.*¶(?<-1>.)*(.)) $2 - aplatissez le parcours - remplacez les espaces par le caractère situé en dessous d'eux.

    Après cette étape, les données ressembleront à ceci:

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

    Nous pouvons simplement tout ignorer après le premier U, nous n'y arriverons pas de toute façon.

  • > représentent une étape que nous sommes autorisés à faire, ou l'énergie restante.
  • Remplacez-les \par quatre >: une pente nous donne une énergie supplémentaire.
  • Boucle: supprimer de manière contentieuse >_ou >>>>>/jusqu'à ce qu'il n'en reste plus. _s et /s consomment de l' énergie.
  • Enfin, essayez de faire correspondre ^>*U- vérifiez si nous pouvons atteindre Uavec une énergie positive (ou aucune énergie).
    Cela produira 0ou 1.

Une autre option proche avec 91 79 octets est:

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

Essayez-le en ligne

C'est la même approche mais avec un groupe d'équilibrage au lieu d'un substitut litigieux.

Je suis sûr que les deux peuvent être joués plus loin, donc l’un d’eux peut être plus court.


1
Oui, entrée unaire est légitime ( à moins que le défi spécifie « décimales »), bien que je serais probablement utiliser 0ou 1que le chiffre si cela ne comporte pas de tout octets supplémentaires.
Martin Ender

1
Aussi, bienvenue à PPCG, je suis vraiment content de vous voir ici! :) (Et j'utilise aussi Retina.)
Martin Ender

Sûr! C'était sur la liste des questions chaudes et avait l'air amusant. Je pensais que j'allais l'essayer :-)
Kobi

3

ES6, 117 octets

(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: Sauvegardé 4 octets grâce à.


@ ՊՓԼՃՐՊՃՈԲՍԼ Merci, je continue d'essayer d'optimiser la vitesse ...
Neil

3

JavaScript (ES6), 108 107 106 octets

C’est la solution que j’ai trouvée lorsque j’ai créé le défi.

(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

Explication

Prend le pouvoir en tant que nombre et le cours en tant que chaîne. Retours 1pour trueou 0pour false. Le parcours doit être complété par des espaces.

(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

Tester

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) 169 160 octets

Une solution récursive sans la fonction de transposition (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 pour le parcours, p pour la puissance, v pour la vitesse, h pour la hauteur

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")

2

Pyth, 35 octets

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

Explication

                                    - 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

Ruby, 85 caractères

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

Réponse adaptée de @ manatwork


1

JavaScript, 266 263 244 octets

(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

Mon erreur; Je pensais avoir copié dans le premier exemple avec "27" comme premier argument. J'ai corrigé cela. Je vous remercie.
user49328

1

Java, 219 octets

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;}
  • Aplatissez le parcours, car la coordonnée y importe peu. Malheureusement, Java n’a pas d’ajustement vertical. Il n'a pas non plus de String-transpose.

  • Parcourez le parcours aplati et gardez une trace de la vitesse de la balle.


1

Octave, 111 à 110 octets

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)))

Explication:

  • Fractionner l'entrée sur les nouvelles lignes et convertir ce tableau de cellules gênant en matrice
  • Aplatir la matrice en recherchant le maxpour chaque colonne
  • Mappe les caractères '_/\'sur [1, 5, -4](tous les autres caractères inférieurs à ceux '_'mappés sur 0)
  • Calculer la somme cumulée de tous les éléments du tableau mappé
  • Sortie Truesi toutes les sommes cumulées depuis le début du parcours dans la coupe sont inférieures à la vitesse de départ ( Falsesinon).

Voici un cas test que j'avais déjà développé similaire au second proposé par @Erwan et quelques résultats:

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

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

Et voici le premier cas de test:

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

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

Je pense que si le cours est comme "//_U\\\\\\\_le résultat est incorrect puisque vous ne supprimez pas le caractère après les Umêmes choses si vous avez un cours avec un maximum local comme_//\\\\\U
Erwan

@Erwan Mais je ne supprimer les caractères après U. C'est ce que (1:find(m==85))fait le il faut sous-tableau du premier index à l’emplacement du fichier U. Je vais vérifier votre cas de test avec quelques vitesses de départ et vous contacter.
Bécher

Je ne pouvais pas exécuter votre solution (je n'ai pas Octave), c'est pourquoi je pose juste la question ... et parce que je trouve l'émission avec des maxima locaux dans l'autre solution python :) Enfin, votre solution fonctionne avec des maxima locaux puisque vous utilisez cumsum. et pas seulement la somme (ne voyez pas cela à la première lecture)
Erwan

@Erwan J'ai ajouté les deux cas de test que vous avez suggérés. S'il vous plaît jeter un oeil et voir si les résultats sont ce que vous attendez. Si vous essayez cela dans MATLAB, vous ne pourrez pas l'exécuter car il utilise une indexation qui ne fonctionne que dans Octave. Vous devez affecter le résultat de cumsumà une variable intermédiaire, puis l’utiliser pour la comparaison finale all(v>tmp(1:find(m==85))).
Bécher

Votre solution fonctionne très bien et manque beaucoup de choses à la première lecture (il suffit de tester Matlab pour ajouter tant de variables intermédiaires)
Erwan

0

C, 629 octets

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

Fondamentalement, je viens de faire un passage pour convertir la chaîne d'entrée pour tout adapter dans une ligne, puis


Bienvenue dans Programming Puzzles & Code Golf! Vous pouvez (et devriez) être en mesure de réduire considérablement la taille en éliminant la plupart des espaces; vous pouvez réduire une partie de votre if/ elsepar exemple x+=*n==' ')?1:*n=='\n'?-x:(olc[x]=*n,1. Autre astuce: en C, vous unsigned intpouvez écrire tout unsigneden économisant 4 octets.
Toby Speight le

0

Python, 212 201 188 143 octets

Une grande partie du mérite de cette itération de ce script revient à @Erwan, qui m'a proposé une approche totalement différente et des astuces qui m'ont permis d'économiser 55 octets à la fin.

Non récursif, il devrait donc être sensiblement différent de l’autre solution 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]

Ungolfed un peu:

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]

si vous voulez une solution plus courte, vous pouvez utiliser Cyoce tip et utiliser la fonction intégrée transpose. o=[''.join(x).split()[0] for x in zip(*c.split('\n'))]Je pense que des choses comme celle- là gagnent 40 octets
Erwan

vous pouvez également remplacer breakpar return p>0et enleverif p...
Erwan

vous devez ajouter une condition if"U"==v or p<1 s'il y a un maximum local comme_//\\\\\U
Erwan

@Erwan Votre premier conseil ne fonctionne pas si les lignes ne sont pas toutes de la même longueur (les lignes courtes ayant des espaces de fin pour correspondre aux lignes longues). Comme le message disait "Les cours peuvent éventuellement être remplis d'espaces", je ne suis pas sûr que nous puissions supposer que c'est vrai. J'ai demandé à ce sujet dans un commentaire.
SnoringFrog

oui, je suppose que toutes les lignes ont la même longueur (égalisé par des espaces). Peut-être que je me trompe dans ce cas, je pense que ma solution est mauvaise
Erwan
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.