Quand le Père Noël entre-t-il au sous-sol? (Jour 1 de l'AOC)

20

Je reproduis la deuxième partie du premier jour de l'Avent de Code, avec la permission du créateur.

Le Père Noël essaie de livrer des cadeaux dans un grand immeuble d'appartements, mais il ne trouve pas le bon étage - les instructions qu'il a obtenues sont un peu déroutantes. Il commence au rez-de-chaussée (étage 0) et suit ensuite les instructions un caractère à la fois.

Une parenthèse ouvrante (signifie qu'il doit monter d'un étage et une parenthèse fermante )signifie qu'il doit descendre d'un étage.

L'immeuble est très haut et le sous-sol est très profond; il ne trouvera jamais les étages supérieurs ou inférieurs.

Étant donné un ensemble d'instructions, trouvez la position du premier personnage qui le fait entrer dans le sous-sol (étage -1).

À titre d'exemples:

l'entrée le )fait entrer dans le sous-sol à la position de caractère 1.

l'entrée le ()())fait entrer dans le sous-sol à la position de caractère 5.

Une entrée longue est donnée ici qui devrait donner la solution 1797.

C'est le golf de code, donc la solution la plus courte l'emporte!

A Simmons
la source
Faut-il utiliser ces caractères exacts?
Blue
1
@muddyfish Dans les défis d'origine, les entrées étaient données sous une forme spécifique et si souvent, une partie clé du défi consistait à analyser les entrées; même si je ne veux pas que cela devienne un "problème de caméléon", je pense que l'esprit de l'original est que l'entrée doit être une chaîne de crochets. Je me rends compte que cela privilégie certaines langues par rapport à d'autres, mais j'invite les électeurs à en tenir compte lors de l'attribution de votes positifs à des solutions.
Un Simmons
Très étroitement lié aux nombres binaires parenthifiables ... Je ne pense pas assez que ce soit un dupe, je vais donc laisser un commentaire à la place.
AdmBorkBork
@TimmyD Je vois ce que tu veux dire mais j'ai l'impression que cette question est suffisamment différente pour que les réponses compétitives ne puissent pas trop en tirer!
Un Simmons
1
J'essaie de résoudre cela dans SMBF (essentiellement BF), et ce langage SUCKS à déboguer ... ugh.
mbomb007

Réponses:

17

Gelée, 8 7 octets

O-*+\i-

Merci à @ Sp3000 d'avoir joué au golf sur 1 octet!

Essayez-le en ligne!

Comment ça fonctionne

O-*+\i-    Main link. Input: s (string)

O          Ordinal; replace each character with its code point.
           This maps "()" to [48, 49].
 -*        Apply x -> (-1) ** x.
           This maps [48, 49] to [1, -1].
   +\      Compute the cumulative sum, i.e., the list of partial sums.
     i-    Find the first index of -1.
Dennis
la source
16

Python 2, 44 octets

try:input()
except Exception,e:print e[1][2]

Cette solution intelligente a été trouvée par hallvabo, xsot, mitchs et whatisgolf sur ce problème sur le golf Anarchy . Si l'un d'entre vous souhaite le publier à la place, je le supprimerai.

L'astuce consiste à laisser l'analyseur de Python faire le travail. La fonction input()essaie d'évaluer une chaîne d'entrée et renvoie une erreur sur le premier paren sans correspondance. Cette erreur, lorsqu'elle est détectée, a la forme

SyntaxError('unexpected EOF while parsing', ('<string>', 1, 1, ')'))

qui comprend le numéro de caractère où l'erreur s'est produite.

xnor
la source
7

Python, 79 77 octets

lambda m:[sum([2*(z<')')-1for z in m][:g])for g in range(len(m)+1)].index(-1)

Il y a probablement une meilleure façon de procéder, mais je suis à court d'idées. C'est aussi mon premier post sur codegolf.

Merci à @Erwan. pour jouer au golf sur 2 octets.

drobilc
la source
Bienvenue sur le site! Ceci est un très bon premier article. :)
Alex A.
vous pouvez remplacer [0:g]par[:g]
Erwan
et ce remplacement économiser 1 octet je pense -2*ord(z)+81par2*(z<')')-1
Erwan
5

Python 3, 59

Enregistré 3 octets grâce à grc.

Je n'aime vraiment pas faire l'indexation manuelle des chaînes en Python. Ça fait tellement mal.

def f(x):
 c=q=0
 while-~c:c+=1-(x[q]>'(')*2;q+=1
 return q
Morgan Thrapp
la source
5

C, 55 octets

g;main(f){for(;f;g++)f+=81-getchar()*2;printf("%d",g);}

Essayez-le ici .

Edit: Je ne sais pas pourquoi j'ai laissé une variable inutilisée là-dedans ...

Cole Cameron
la source
5

CJam, 10 octets

0l'_*:~1#)

ou

0l'_*~]1#)

ou (crédits à Dennis)

Wl+'_*:~1#

Testez-le ici.

Explication

Comme A Simmons l'a déjà noté, ()est un choix chanceux pour CJam car ce sont les opérateurs de décrémentation / incrémentation, respectivement. Cela signifie que si nous partons de zéro, nous recherchons l'étape à laquelle le Père Noël atteint l'étage 1.

0   e# Push 0, the initial floor.
l   e# Read input.
'_* e# Riffle the input string with underscores, which duplicate the top of the stack.
:~  e# Evaluate each character, using a map which wraps the result in an array.
1#  e# Find the position of the first 1.
)   e# Increment because we're looking for a one-based index.
Martin Ender
la source
4

Labyrinthe , 18 octets

+(+"#(!@
:  :
%2_,

Essayez-le en ligne! Cette réponse est le résultat d'une collaboration avec @ MartinBüttner.

Explication

L'amorce Labyrinth habituelle (je dis "habituelle", mais je la réécris à chaque fois):

  • Labyrinth est un langage 2D basé sur la pile, avec une exécution à partir du premier caractère valide (ici en haut à gauche). À chaque jonction, où il y a deux ou plusieurs chemins possibles pour le pointeur d'instruction à prendre, le haut de la pile est vérifié pour déterminer où aller ensuite. Négatif est tourner à gauche, zéro est aller de l'avant et positif est tourner à droite.
  • La pile est sans fond et remplie de zéros, donc sauter d'une pile vide n'est pas une erreur.
  • Les chiffres dans le code source ne poussent pas le nombre correspondant - à la place, ils sautent le haut de la pile et poussent n*10 + <digit>. Cela permet de constituer facilement de grands nombres. Pour commencer un nouveau nombre, utilisez _, qui pousse zéro.

Ce code est un peu bizarre car, à des fins de golf, la boucle principale combine deux tâches en une. Pour la première moitié de la première passe, voici ce qui se passe:

+(+             Add two zeroes, decrement, add with zero
                This leaves -1 on the stack
"               NOP at a junction. -1 is negative so we try to turn left, fail, and
                turn right instead.
:               Duplicate -1

Maintenant que la pile a été initialisée avec un -1 en haut, le traitement réel peut commencer. Voici ce que fait la boucle principale.

,               Read a byte of input
_2%             Take modulo 2.
:+              Duplicate and add, i.e. double
(               Decrement
                This maps "(" -> -1, ")" -> 1
+               Add to running total
"               NOP at a junction. Go forward if zero, otherwise turn right.
:               Duplicate the top of the stack

Le dernier doublon ajoute un élément à la pile pour chaque itération que nous effectuons. C'est important parce que, lorsque nous atteignons zéro et que nous allons de l'avant au NOP, nous faisons:

#               Push stack depth
(               Decrement
!               Output as num
@               Terminate
Sp3000
la source
3

Oracle SQL 11.2, 160 159 octets

SELECT MIN(l)FROM(SELECT l,SUM(m)OVER(ORDER BY l)p FROM(SELECT LEVEL l,DECODE(SUBSTR(:1,LEVEL,1),'(',1,-1)m FROM DUAL CONNECT BY LEVEL<=LENGTH(:1)))WHERE p=-1;

Non golfé

SELECT MIN(l) -- Keep the min level
FROM(
  SELECT l,SUM(m)OVER(ORDER BY l)p -- Sum the () up to the current row
  FROM(
    SELECT LEVEL l,DECODE(SUBSTR(:1,LEVEL,1),'(',1,-1)m -- ( equal 1 and ) equal -1 
    FROM DUAL 
    CONNECT BY LEVEL<= LENGTH(:1)
  )
)
WHERE p=-1 -- Keep the rows where the () sum is equal to -1
Jeto
la source
3

Retina ,22 21

! M` ^ ((\ () | (? <-2>.)) +

Essayez-le en ligne ou essayez le grand cas de test. (L'URL est grande pour le grand cas de test, faites-moi savoir si elle se casse pour vous, semble OK en chrome.)

1 octet économisé grâce à Martin!

Nous faisons correspondre le premier ensemble de parenthèses équilibrées et l'extrayons, puis nous comptons le nombre de fois où la chaîne vide correspondra à ce résultat. Je ne sais pas si c'est la meilleure façon de le faire dans Retina, en particulier si le mode PCRE le rend plus court, mais l'utilisation du $#_remplacement semblait être plus longue en raison d'une erreur par une erreur et du problème d'avoir plus d'une correspondance.

Cet algorithme provoque un comportement étrange pour une entrée invalide, il suppose essentiellement que si le Père Noël ne se rend pas au sous-sol, il s'y téléporte mystérieusement après les autres mouvements.

FryAmTheEggman
la source
3

Grep + AWK, 51 octets

grep -o .|awk '/\(/{s++}/)/{s--}s<0{print NR;exit}'

La grepcommande place chaque caractère sur une nouvelle ligne.

Robert Benson
la source
3

Pyth, 13 octets

f!hsm^_1Cd<zT

Explication

              - autoassign z = input()
f             - First where V returns Truthy.
          <zT -     z[:T]
    m         -    [V for d in ^]
        Cd    -     ord(d)
     ^_1      -      -1**^
   s          -   sum(^)
 !h           -  not (^+1)

Essayez-le ici

Ancien algorithme, 15 octets

f!h-/J<zT\(/J\)

Explication:

                - autoassign z = input()
f               - First where V returns Truthy.
      <zT       -      z[:T]
     J          -     autoassign J = ^
    /    \(     -    ^.count("(")
           /J\) -    J.count(")")
   -            -   ^-^
 !h             -  not (^+1)

Essayez-le ici

Ou si autorisé à utiliser des caractères autres que (and ), 9 octets (déplacement du prétraitement vers l'entrée)

f!.v+<zT1

Explication

          - autoassign z = input()
f         - First where V returns Truthy.
     <zT  -     z[:T]
    +   1 -    ^+"1"
  .v      -   eval(^)
 !        -  not ^

Essayez-le ici

Bleu
la source
3

JavaScript (ES6), 58 octets

f=(s,t=s)=>s<')'?f(s.replace('()',''),t):t.length-s.length+1

Fonctionne en supprimant récursivement une paire de ()s correspondants jusqu'à ce que le premier caractère soit a ). Avertissement: n'essayez pas ceci sur des chaînes qui n'ont pas assez de )s. Exemple:

((()())()))
((())()))
(()()))
(()))
())
)

À ce stade, il constate que 12 caractères ont été supprimés au total, de sorte que la réponse est 13.

Neil
la source
Vous pouvez plutôt mettre ce commentaire dans votre réponse.
mbomb007
3

MATL , 12 11 octets

1 octet enregistré en utilisant l'idée de Dennis de calculer -1 élevé à la chaîne d'entrée

1_j^Ys0<f1)

Essayez-le en ligne!

1_         % number -1
j          % take string input
^          % element-wise power. This transforms '('  to 1 and ')' to -1
Ys         % cumulative sum
0<         % true for negative values
f          % find all such values 
1)         % pick first. Implicit display
Luis Mendo
la source
2

CJam, 12 10 octets

0q{~_}%1#)

Essayez-le ici.

Deux octets enregistrés grâce à Martin.

Explication:

0              Load 0 onto the stack
 q             Load input onto the stack without evaluating
  {  }       Code block
   ~_          Evaluate the next command and duplicate the top stack element. The format of the question is good for CJam and Golfscript since ) and ( are increment and decrement operators (though the wrong way round).
        %      Map this code block over the string. This yields an array of Santa's floor positions
         1#   Find the first instance of a 1, since decrement and increment are swapped
           )  Fix the off-by-1 error caused by zero-indexing
A Simmons
la source
2

Javascript, 117 octets

o=f=0;i=prompt().split('');for(c in i){switch (i[c]){case '(':f++;break;case ')':f--;if(f<0){alert(o+1);i=[];}}o++;}

Ignore les autres personnages. Utilise promptet alert.

Solomon Ucko
la source
2

Perl, 34 + 1 = 35 octets

$.+=s+.+++s+\)++while")"gt$_;$_=$.

Merci à Dennis pour quelques conseils.

Courez avec le -pdrapeau. Cela fonctionne en Perl 5.10, mais les versions ultérieures ont besoin d'un espace ici:++ while

Version plus ancienne, non golfée:

$_ = <>;                # get a line of input
while ($_ lt ')') {     # while it begins with a (
    s/.//;              # remove the first (
    s/\)//;             # remove the first )
    $i += 2;            # increase index by 2
}
print $i + 1;           # print the position
grc
la source
2

Python, 44 octets

f=lambda s,i=1:i and-~f(s[1:],i-1+2*(s<')'))

Le plancher icommence à 1ce que nous ifinissions par être la valeur de falsey 0. S'il n'est pas terminé, ajoutez-en un récursivement pour obtenir le premier caractère supprimé et le numéro d'étage mis à jour en fonction de ce caractère.

xnor
la source
2

Javascript, 57 octets

p=>{c=0;for(i in p){c+=p[i]==')'?-1:1;if(c<0)return+i+1}}

Assez simple, itère simplement sur l'entrée, incs if '(' decs if ')'. Rend le premier négatif.

SethWhite
la source
2

Rubis, 47 octets

Fonction anonyme.

->s{i,l=-1,0;l+=s[i+=1]>?(?-1:1 while l>-1;i+1}
Encre de valeur
la source
1

C, 73 octets

main(f,c){f=c=0;for(;f!=-1;c++){f+=1-((getchar()&1)<<1);}printf("%d",c);}

Attend une entrée sur STDIN; aucun caractère autre que (et )peut apparaître dans l'entrée (au moins jusqu'à ce que nous ayons atteint la réponse). L'entrée doit être ASCII.

Emet la réponse sur STDOUT.

Utilise la différence de 1 bit entre l'ASCII pour (et ).

/* old-style arguments, implicitly int */
main(x, f)
{
    /* c is our character counter, f is the floor*/
    c = f = 0;
    /* increase c while f is not -1 */
    for (;f != -1; c++) {
        /* use difference in LSB to add one for (, subtract one for ) */
        f += 1-((getchar()&1)<<1);
    }
    /* answer */
    printf("%d", c);
}

Version bien formatée:

David Morris
la source
Pouvez-vous déplacer l' f=c=0initialisation de la boucle for(f=c=0;f!=...pour enregistrer un octet?
AdmBorkBork
@TimmyD mieux pour les rendre globales afin qu'elles soient initialisées automatiquement.
Cole Cameron
1

PowerShell, 75 65 62 octets

[char[]]$args[0]|%{$c+=(1,-1)[$_%40];$d++;if($c-lt0){$d;exit}}

Utilise une technique similaire à celle des nombres binaires parenthifiables pour parcourir tous les caractères en entrée, en conservant une longe en cours d' $cexécution +1pour chacun (et -1pour chacun ), puis en testant si nous avons atteint un résultat négatif (c'est-à-dire que nous sommes au sous-sol).

Édition - économisé 10 octets en itérant sur les caractères réels plutôt que sur leurs index
Édition 2 - économisé 3 octets supplémentaires en échangeant la vérification d'égalité pour modulo, donc la conversion est implicite

AdmBorkBork
la source
1

Mathematica, 62 55 octets

Position[Accumulate[(-1)^ToCharacterCode@#],-1][[1,1]]&

Tous les noms de fonction longs! Fonctionne de manière similaire à la réponse CJam de Simmons.

LegionMammal978
la source
1

Befunge 25 octets

Sorties en unaire. Cela vous démarre au premier étage et ira jusqu'à 0.

1<\1_v#:+-*2%2~
:#._@>$1>
MegaTom
la source
1

Raquette (102)

(λ(s)(let l((c 0)(b 0)(s(string->list s)))(if(> 0 b)c(l(+ 1 c)((if(eqv?(car s)#\()+ -)b 1)(cdr s)))))

Non golfé

(λ (input)
  (let loop ((count 0) (balance 0) (chars (string->list input)))
    (if (> 0 balance)
        count
        (loop (+ 1 count)
              ((if (eqv? (car chars) #\() + -) balance 1)
              (cdr chars)))))
Sylwester
la source
1

APL, 18 caractères

{1⍳⍨¯1=+\¯1*')'=⍵}

En anglais:

  • ¯1*')'=⍵: -1 où input = ")", 1 sinon;
  • +\: somme courante;
  • 1⍳⍨¯1=: trouve l'indice du premier -1.
lstefano
la source
1

Lua, 92 89 87 octets

Il prend un argument de ligne de commande.

Modifier: enregistré 3 octets

Edit: enregistré 2 octets, et corrigé un bug qui pouvait se produire sur les cas de bord, il sort maintenant via son code de sortie

r=0i=0(...):gsub(".",function(c)i=i+1r=r+(c==")"and-1or 1)if r<0then os.exit(i)end end)

Non golfé

r,i=0,0                     -- set r (the actual floor), and i(the character count)
(...):gsub(".",function(c) -- apply an anonymous functions on each character of the input
  i,r=i+1,                  -- increment i
      r+(c==")"and -1 or 1) -- decrement r if c==")", increment it otherwise
  if r<0 then os.exit(i)end -- if r==-1, exit and output the current index
end)
Katenkyo
la source
1

k / kona , 23 21 octets

2 octets enregistrés en supprimant les parenthèses inutiles.

{1+(+\1 -1"()"?x)?-1}

Usage:

k){1+(+\1 -1"()"?x)?-1} "())"
3
Simon Major
la source
0

Perl, 40 + 1 = 41 octets

$y++,($i+=/\(/*2-1)<0&&last for/./g;$_=$y

Nécessite le -pdrapeau:

$ perl -pe'$y++,($i+=/\(/*2-1)<0&&last for/./g;$_=$y' <<< '()())'
5
$ perl -pe'$y++,($i+=/\(/*2-1)<0&&last for/./g;$_=$y' 1797.txt
1797

Suppose une entrée valide.

Comment ça fonctionne:

                                           # -p read line by line into $_ and auto prints at the end
        $y++,                              # Counter for steps taken
             ($i+=/\(/*2-1) < 0            # The match /\(/ will give 1 or 0 in a numeric context 1 for `(` and 0 for anything else
                                           # times it by 2 and subtracting -1 will yield 1 or -1
                               && last     # End the iteration if $i < 0
for/./g;                                   # Iterate over each items in the input
                                      $_=$y# Print the output
andlrc
la source
0

Javascript (ES6), 68 67 octets

(s,r,f=0)=>s.split``.map((l,i)=>(f+=l=='('?1:-1,f<0?r=r||++i:0))&&r

Prend l'entrée comme premier argument

Explication

(s, r, f=0)                                  //Gets string, declares r and f to equal undefined and 0
         =>
            s.split``                        //Splits string into character array
            .map(                            //Loops over array
                 (l, i)=>(
                         f +=                //Increment f
                         l=='(' ? 1 : -1,    //By either 1 or -1 depending on character
                         f<0 ?               //If the floor is less than 0
                         r=r||++i            //And is first time below, r equals index (+1 to make it '1 indexed not 0')
                         : 0)
                         &&r                   //Return index
reubn
la source
0

Python (3,5), 78 71 62 octets

une solution récursive

f=lambda s,p=0,v=0:p if v<0else f(s[1:],p+1,v+2*(s[0]<')')-1) 

c'est similaire à cette solution pour mini golf

nous pouvons supposer que le père Noël atteint toujours le sous-sol

Erwan
la source