Коли Санта входить у підвал? (AOC Day 1)


20

Я відтворюю другу частину першого дня приходу коду з дозволу творця.

Санта намагається доставити подарунки у великому багатоквартирному будинку, але не може знайти потрібний поверх - напрямки, які він отримав, трохи заплутані. Він починається на першому поверсі (поверх 0), а потім виконує вказівки по одному персонажу.

Вхідні дужки (означають, що він повинен піднятися на один поверх, а дужки, що закриваються ), означає, що він повинен спуститися на один поверх.

Житловий будинок дуже високий, а підвал - дуже глибокий; він ніколи не знайде верхній або нижній поверхи.

Давши набір інструкцій, знайдіть положення першого персонажа, що змушує його зайти в підвал (поверх -1).

Як приклад:

Вхід )змушує його зайти в підвал у позиції символу 1.

Вхід ()())змушує його зайти в підвал у позиції символу 5.

Довгий вхід дається тут , що має дати рішення 1797.

Це кодовий гольф, тому найкоротше рішення виграє!


Чи потрібно використовувати ці точні символи?
Синій

1
@muddyfish У оригінальних викликах входи давались у певній формі, тому часто ключовою частиною завдання було розбір даних; хоча я не хочу, щоб це стало «проблемою хамелеона», я думаю, що дух оригіналу полягає в тому, що вхід повинен бути рядком дужок. Я усвідомлюю, що це привілейовує деякі мови перед іншими, але я б закликав виборців враховувати це при нагоді за рішеннями.
Сіммонс

Дуже тісно пов’язаний з Parenthifiable бінарними номерами ... Я не відчуваю себе досить сильно, що це дура, тому я просто залишу коментар замість цього.
AdmBorkBork

@TimmyD Я бачу, що ти маєш на увазі, але мені здається, що це питання настільки інше, що конкурентоспроможні відповіді не зможуть зробити з цього питання занадто багато!
Сіммонс

1
Я намагаюся вирішити це в SMBF (в основному BF), і ця мова ЗАПУСКАЄ налагодження ... тьфу.
mbomb007

Відповіді:


17

Желе, 8 7 байт

O-*+\i-

Дякуємо @ Sp3000 за те, що гольф на 1 байт!

Спробуйте в Інтернеті!

Як це працює

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.

16

Python 2, 44 байти

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

Це розумне рішення знайшли hallvabo, xsot, mitchs та whatisgolf у цій проблемі на Anarchy golf . Якщо хтось із вас захоче опублікувати його замість цього, я видалю це.

Трюк полягає в тому, щоб дозволити партеру Python зробити роботу. Функція input()намагається оцінити вхідний рядок і видає помилку на перший невідповідний батьків. Ця помилка при попаданні має форму

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

який включає номер символу, де сталася помилка.


7

Пітон, 79 77 байт

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

Напевно, є кращий спосіб зробити це, але я не в ідеях. Також це моє перше повідомлення про codegolf.

Дякуємо @Erwan. для гри в гольф на 2 байти.


Ласкаво просимо на сайт! Це дуже приємне перше повідомлення. :)
Олексій А.

ви можете замінити [0:g]на[:g]
Ерван

і ця заміна зберегти 1 байт я думаю , що -2*ord(z)+81по2*(z<')')-1
Ервана

5

Пітон 3, 59

Збережено 3 байти завдяки grc.

Мені дуже не подобається робити ручну індексацію рядків у Python. Це почувається так неправильно.

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

5

C, 55 байт

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

Спробуйте тут .

Редагувати: Не впевнений, чому я там залишив невикористану змінну ...


5

CJam, 10 байт

0l'_*:~1#)

або

0l'_*~]1#)

або (кредити Деннісу)

Wl+'_*:~1#

Тестуйте це тут.

Пояснення

Як вже зазначав Сіммонс, ()це вдалий вибір для CJam, оскільки це відповідно оператори зменшення / збільшення. Це означає, що якщо ми починаємо з нуля, ми шукаємо крок, на якому Санта досягає першого поверху.

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.

4

Лабіринт , 18 байт

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

Спробуйте в Інтернеті! Ця відповідь стала результатом співпраці з @ MartinBüttner.

Пояснення

Звичайний лабіринтний буквар (я кажу "звичайний", але насправді переписую це кожен раз):

  • Лабіринт - це двоскладна мова на основі стека, виконання якої починається з першого дійсного знака (тут угорі зліва). На кожному перехресті, де є два або більше можливих шляхів для вказівника вказівки, слід перевіряти верхню частину стека, щоб визначити, куди йти далі. Негатив - поворот ліворуч, нуль - вперед, а позитив - поворот праворуч.
  • Стек є бездонним і заповненим нулями, тому вискакування з порожнього стека не є помилкою.
  • Цифри у вихідному коді не натискають відповідне число - натомість вони спливають верхню частину стека та натискають n*10 + <digit>. Це дозволяє легко нарощувати велику кількість. Щоб почати нове число, використовуйте _, яке натискає нуль.

Цей код трохи дивний, оскільки для цілей гольфу головний цикл поєднує дві задачі в одну. У першій половині першого проходу ось що відбувається:

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

Тепер, коли стек був ініціалізований -1 на вершині, реальна обробка може початися. Ось що робить головний цикл.

,               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

Останній дублікат додає елемент до стеку для кожної ітерації, яку ми виконуємо. Це важливо, тому що, коли ми стискаємо нуль і рухаємось вперед до НОП, ми робимо:

#               Push stack depth
(               Decrement
!               Output as num
@               Terminate

3

Oracle SQL 11.2, 160 159 байт

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;

Без гольфу

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

3

Сітківка ,22 21

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

Спробуйте в Інтернеті або спробуйте великий тестовий випадок. (URL-адреса велика для великого тестового випадку, дайте мені знати, якщо вона порушиться для вас, здається, нормально в хромі.)

1 байт збережено завдяки Мартіну!

Ми співставляємо перший набір збалансованих дужок і витягуємо його, потім підраховуємо кількість разів, коли порожній рядок буде відповідати цьому результату. Я не впевнений, чи це найкращий спосіб зробити це в Retina, особливо якщо режим PCRE робить його коротшим, але використання $#_заміни, здається, довше через відключення однієї помилки та проблеми з більш ніж однією відповідністю.

Цей алгоритм викликає дивну поведінку щодо недійсного входу, він по суті передбачає, що якщо Санта не потрапить у підвал, він загадково телепортується туди після інших рухів.



3

Греп + AWK, 51 байт

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

grepКоманда поміщає кожен символ в новому рядку.


3

Pyth, 13 байт

f!hsm^_1Cd<zT

Пояснення

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

Спробуйте тут

Старий алгоритм, 15 байт

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

Пояснення:

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

Спробуйте тут

Або якщо дозволено використовувати символи, відмінні від (та ), 9 байт (переміщення попередньої обробки на вхід)

f!.v+<zT1

Пояснення

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

Спробуйте тут


3

JavaScript (ES6), 58 байт

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

Працює шляхом рекурсивного видалення пари збігу ()s, поки перший символ не стане a ). Попередження: Не намагайтеся це робити на рядках, у яких недостатньо )s. Приклад:

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

У цей момент він бачить, що 12 символів було видалено загалом, так що відповідь - 13.


Ви можете замість цього замінити коментар у свою відповідь.
mbomb007

3

MATL , 12 11 байт

1 байт збережено за допомогою ідеї Денніса про обчислення -1, піднятої до вхідного рядка

1_j^Ys0<f1)

Спробуйте в Інтернеті!

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

2

CJam, 12 10 байт

0q{~_}%1#)

Спробуйте тут.

Два байти збережено завдяки Мартіну.

Пояснення:

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

2

Javascript, 117 байт

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

Ігнорує інших символів. Використання promptта alert.


2

Perl, 34 + 1 = 35 байт

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

Дякуємо Деннісу за кілька порад.

Бігайте з -p прапором. Він працює в Perl 5.10, але для пізніших версій тут потрібно пробіл:++ while

Старіша версія, що не має волі:

$_ = <>;                # 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

2

Пітон, 44 байти

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

Підлога iпочинається з 1того, що ми закінчуємо iзначення фальси 0. Якщо не припинено, рекурсивно додайте його до результату, коли перший символ вилучено, а номер підлоги оновлено на основі цього символу.


2

Javascript, 57 байт

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

Досить простий, просто ітерацію над введенням, дюйми, якщо '(' decs if ')'. Повертається на перший мінус.



1

C, 73 байти

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

Очікує введення на STDIN; жодні символи, окрім (та не )можуть з’являтися у вводі (принаймні, поки ми не дійшли до відповіді). Вхід повинен бути ASCII.

Показує відповідь на STDOUT.

Використовує 1-бітну різницю між ASCII для (та ).

/* 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);
}

Гарно відформатована версія:


Чи можете ви перемістити f=c=0в ініціалізацію циклу, for(f=c=0;f!=...щоб зберегти байт?
AdmBorkBork

@TimmyD краще зробити їх глобальними, щоб вони автоматично ініціалізувалися.
Коул Камерон

1

PowerShell, 75 65 62 байт

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

Використовує аналогічну техніку, як на Parenthifiable двійкові числа, щоб провести через всі вхідні символи, зберігаючи запущену $cонутер +1для кожного (та -1кожного ), а потім перевірити, чи потрапили ми в мінус (тобто ми в підвалі).

Редагувати - збережено 10 байт шляхом ітерації над фактичними символами, а не їх індексами.
Правка 2 - збережена 3 додаткові байти шляхом заміни перевірки рівності на модуль, тому кастинг неявний


1

Математика, 62 55 байт

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

Всі довгі назви функцій! Працює подібно до відповіді Сіммонса CJam.


1

Befunge 25 байт

Виходи одинарні. Це запустить вас на перший поверх і триватиме до 0.

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

1

Ракетка (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)))))

Безумовно

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

1

APL, 18 символів

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

Англійською:

  • ¯1*')'=⍵: -1 де input = ")", 1 в іншому випадку;
  • +\: поточна сума;
  • 1⍳⍨¯1=: знайдіть індекс першого -1.

1

Луа, 92 89 87 байт

Він бере аргумент командного рядка.

Редагувати: збережено 3 байти

Редагувати: збережено 2 байти та виправлено помилку, яка могла трапитися у кращих випадках, тепер виводиться через вихідний код

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

Безумовно

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)


0

Perl, 40 + 1 = 41 байт

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

Потрібен -pпрапор:

$ 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

Передбачає дійсне введення.

Як це працює:

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

0

Javascript (ES6), 68 67 байт

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

Вводиться як перший аргумент

Пояснення

(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

0

Пітон (3,5), 78 71 62 байт

рекурсивне рішення

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

це подібне до цього рішення для міні-гольфу

ми можемо припустити, що Санта завжди добирається до підвалу

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.