Codice (Mini) Golf


50

Vista la vista laterale di un campo da mini-golf e la potenza dell'altalena, determinare se la palla entrerà nella buca.


Un corso sarà in questo formato:

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

La palla inizia direttamente prima del primo pezzo di terreno a sinistra e segue il contorno del percorso fino a raggiungere il buco (una maiuscola Usotto l'attuale livello del terreno). Se raggiunge il buco, genera un valore veritiero. La potenza dell'oscillazione sarà la velocità iniziale della palla. La palla si sposta sul personaggio successivo a destra ad ogni iterazione, quindi la velocità viene modificata a seconda del personaggio che è ora. Se la velocità raggiunge 0o meno prima del buco, emettere un valore di falso.

  • _ diminuisce la velocità di 1
  • / diminuisce la velocità di 5
  • \ aumenta la velocità di 4

I corsi possono essere facoltativamente riempiti di spazi. La potenza dell'oscillazione sarà sempre un numero intero positivo.

Non devi preoccuparti che la palla vada troppo veloce per entrare nella buca, rotolare all'indietro o saltare / rimbalzare dalle colline.

Casi 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

Questo è il mini-golf in codice, la risposta più breve in byte vince!


1
Se la tua lingua ha buoni array incorporati, puoi trasformare l'input in un flusso di operazioni ( \_/) con i seguenti passaggi: dividere in array di linee, ruotare, appiattire, spogliare gli spazi.
Cyoce,

1
Questo è davvero più un meccanismo a binario fisso che un campo da golf: P
Zach Gates,

24
Mi piace che \/\/\/\/\/sia un corso più efficiente di __________.
ezrast,

2
Questo è quello che stavo pensando, 4 in basso, 5 in alto, quindi 0,5 deve essere nella media. Oh, flat è 1?
Leif Willerts,

Ogni linea di un corso avrà sempre la stessa lunghezza (con spazi finali che riempiono la fine di linee più brevi)?
SnoringFrog

Risposte:


17

Pyth, 27 byte

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

Dimostrazione

Questo codice fa qualcosa di molto intelligente e per niente sicuro X. Dai un'occhiata qui sotto.

Spiegazione:

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

Potrei mancare qualcosa, ma si ferma a Q? Cioè l'ultimo esempio potrebbe causare alcuni problemi?
flindeberg,

@flindeberg Non è così che funziona. Il < ... Qfunziona come un confronto numerico finché il foro, non una fetta. Dopo il buco, tutto ciò che conta è che il risultato è veritiero.
Isaacg,

14

Haskell, 111 109 byte

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

Esempio di utilizzo:

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

Come funziona:

                            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                                 

Modifica: @ user81655 trovato 2 byte da salvare. Grazie!


7

Rubino, 104 87 caratteri

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

Esecuzione di esempio:

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 byte

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

Try it here!

Beating CJam!

Spiegazione

Praticamente prende l'input della stringa, lo ruota di 90 gradi in senso orario, elimina gli spazi e le nuove linee, rimuove il buco e tutto ciò che lo segue e si divide lungo i caratteri. Quindi controlla se la palla arriva a zero o al di sotto usando la everyfunzione.


Penso che `` dovrebbe essere positivo (la descrizione sembra sbagliata)
isaacg

Non penso che funzioni. Immagina questo: una serie di pendenze porta la velocità della palla a -2, ma poi ci sono una rete +4 in seguito. La somma dovrebbe riflettere +2, quindi la palla l'ha fatta. In realtà, non sarebbe mai arrivato alla sezione positiva dopo aver raggiunto gli aspetti negativi.
Cyoce,

Penso di aver risolto il problema.
Mama Fun Roll,

È un bel pulsante;)
J Atkin,

Bello! Quindi, il golf ... La doppia barra rovesciata è sostituibile con %, e >0può essere sostituita con ¬, poiché il sqrt di un numero non positivo è sempre falso ( 0 -> 0, -1 -> NaN).
ETHproductions

6

CJam, 40 39 byte

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

L'ingresso ha la potenza sulla prima riga e il corso inizia sulla seconda riga. L'output è 0o 1.

Provalo qui.

Spiegazione

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 byte

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

^>*U

Provalo online

  • L'input è rappresentato in base unaria , come n >s - per esempio, 4 lo è >>>>\n. (è legale?)
  • +`(?<=(.)*) (?=.*¶(?<-1>.)*(.)) $2 - appiattire il percorso - sostituire gli spazi con il carattere sottostante.

    Dopo questa fase i dati appariranno così:

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

    Possiamo semplicemente ignorare tutto dopo il primo U, non ci arriveremo comunque.

  • > rappresentano un passo che ci è permesso fare, o l'energia rimanente.
  • Sostituisci ciascuno \con quattro >: una pendenza ci fornisce energia aggiuntiva.
  • Ciclo: rimuovere controverso >_o >>>>>/fino a quando non ce ne sono più. _s e /s consumano energia.
  • Infine, prova ad abbinare ^>*U- controlla se possiamo raggiungere Uenergia positiva (o nessuna energia).
    Questo produrrà 0o 1.

Un'altra opzione stretta con 91 79 byte è:

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

Provalo online

Questo è lo stesso approccio ma con un gruppo di bilanciamento anziché un sostituto controverso.

Sono sicuro che entrambi questi possono essere ulteriormente giocati a golf, quindi ognuno di essi può essere più corto.


1
Sì, l' input unario è legittimo (a meno che la sfida non specifichi "decimale"), anche se probabilmente utilizzerei 0o 1come cifra se ciò non comporta alcun byte aggiuntivo.
Martin Ender,

1
Benvenuto anche in PPCG, sono davvero felice di vederti qui! :) (E anche usando Retina.)
Martin Ender,

Sicuro! Era sulla lista delle domande calde e sembrava divertente. Ho pensato di provarlo :-)
Kobi,

3

ES6, 117 byte

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

Modifica: salvato 4 byte grazie a ՊՓԼՃՐՊՃՈԲՍԼ.


@ ՊՓԼՃՐՊՃՈԲՍԼ Grazie, continuo a cercare di ottimizzare la velocità ...
Neil

3

JavaScript (ES6), 108 107 106 byte

Questa è la soluzione che mi è venuta in mente quando ho creato la sfida.

(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

Spiegazione

Prende il potere come un numero e il corso come una stringa. Restituisce 1per trueo 0per false. Il corso deve essere riempito con spazi.

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


3

Python (3.5) 169 160 byte

Una soluzione ricorsiva senza la funzione di trasposizione (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 per esempio, p per potenza, v per velocità, h per altezza

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

uso

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

2

Pyth, 35 byte

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

Spiegazione

                                    - 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

Rubino, 85 caratteri

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

Risposta di @ manatwork adattata


1

JavaScript, 266 263 244 byte

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

uso

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

Errore mio; Pensavo di aver copiato nel primo esempio "27" come primo argomento. Ho corretto questo. Grazie.
user49328

1

Java, 219 byte

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;}
  • Appiattire la rotta, poiché la coordinata y non ha importanza, purtroppo Java non ha un taglio verticale. Inoltre non ha una trasposizione di stringhe.

  • Scorrere sul percorso appiattito e tenere traccia della velocità della palla.


1

Ottava, 111 110 byte

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

Spiegazione:

  • Dividi l'input su newline e converti quel fastidioso array di celle in una matrice
  • Appiattire la matrice trovando il maxper ogni colonna
  • Mappa i caratteri '_/\'su [1, 5, -4](tutti gli altri caratteri inferiori a quelli '_'mappati 0)
  • Calcola la somma cumulativa di tutti gli elementi dell'array mappato
  • Emissione Truese tutte le somme cumulative dall'inizio della rotta alla coppa sono inferiori alla velocità iniziale ( Falsealtrimenti).

Ecco un caso di test che avevo già sviluppato in modo simile al secondo proposto da @Erwan e un paio di risultati:

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

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

Ed ecco il primo caso di test:

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

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

penso che se il corso è come "//_U\\\\\\\_il risultato non è corretto poiché non rimuovi il carattere dopo le Ustesse cose se hai un corso con massimo locale come_//\\\\\U
Erwan,

@Erwan Ma io non rimuovono i caratteri dopo il U. Questo è ciò che (1:find(m==85))fa; prende il subarray dal primo indice alla posizione di U. Controllerò il tuo caso di test con un paio di velocità iniziali e ti risponderò.
becher

Non ho potuto eseguire la tua soluzione (non ho Octave) sul perché chiedo solo ... e perché trovo il issu con i massimi locali nell'altra soluzione Python :) finalmente la tua soluzione funziona con i massimi locali poiché usi cumsum e non solo la somma (non vederlo alla prima lettura)
Erwan,

@Erwan Ho aggiunto i due casi di test che mi hai suggerito. Dai un'occhiata e vedi se i risultati sono quelli che ti aspetti. Se stai provando questo in MATLAB, allora non sarai in grado di eseguirlo perché usa un po 'di indicizzazione che funziona solo in Octave. Dovresti assegnare il risultato cumsuma una variabile intermedia e poi usarlo per il confronto finale all(v>tmp(1:find(m==85))).
becher

La tua soluzione funziona bene e manca molte cose alla prima lettura (basta provare in Matlab tante variabili intermedie da aggiungere)
Erwan

0

C, 629 byte

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

Fondamentalmente faccio solo un passaggio per convertire la stringa di input per adattarsi a tutto in una riga, quindi


Benvenuto in Programmazione di puzzle e codice golf! Puoi (e dovresti) essere in grado di ridurre sostanzialmente le dimensioni eliminando la maggior parte degli spazi bianchi; puoi ridurre parte del tuo if/ elsead es x+=*n==' ')?1:*n=='\n'?-x:(olc[x]=*n,1. Un altro suggerimento: in C, unsigned intpuò essere scritto unsigned, salvando subito 4 byte.
Toby Speight,

0

Python, 212 201 188 143 byte

Gran parte del merito di questa iterazione di questo script va a @Erwan, che mi ha dato un approccio completamente diverso da provare e alcuni suggerimenti che mi hanno salvato 55 byte alla fine.

Non ricorsivo, quindi dovrebbe essere sostanzialmente diverso dall'altra soluzione 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 po ':

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]

se si desidera una soluzione più breve, è possibile utilizzare la punta Cyoce e utilizzare la funzione integrata di trasposizione. o=[''.join(x).split()[0] for x in zip(*c.split('\n'))]credo che qualcosa del genere vinca 40 byte
Erwan,

si può anche sostituire breakda return p>0e rimuovereif p...
Erwan

è necessario aggiungere una condizione if"U"==v or p<1 se esiste un massimo locale simile_//\\\\\U
Erwan,

@Erwan Il tuo primo suggerimento non funziona se le linee non sono tutte della stessa lunghezza (linee brevi con spazi finali corrispondenti a linee lunghe). Poiché il post diceva "I corsi possono essere opzionalmente riempiti di spazi" Non sono sicuro che possiamo supporre che sia vero. L'ho chiesto in un commento.
SnoringFrog

sì, suppongo che tutte le linee abbiano la stessa lunghezza (egalizzate con spazi bianchi) forse mi sbaglio in questo caso, penso che la mia soluzione sia sbagliata
Erwan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.