The Golfer Adventure - Глава 1: Ваза

13

Гольфист приключение

Это первый вызов! Позже будет больше испытаний, которые потребуют данных из предыдущего испытания :)

Глава 1: Ваза

Давайте представим минуту. Вы - могущественный Бог, ваши силы безграничны, но требуют одного: душ. Каждая душа здесь представлена ​​байтом, каждый байт, который вы используете, жертвует душой. Таким образом, цель, очевидно, состоит в том, чтобы спасти наибольшее количество людей, пожертвовав при этом наименьшим количеством душ.

Ваша первая задача - спасти маленькую деревню, дьявол готов не уничтожить всю деревню, если вы решите его задачу.

Соревнование :

У вас есть вертикальная ваза, которая может содержать ровно 10 вещей (включая воздух). Если вы положите вещь в эту вазу, гравитация заставит ее упасть на дно. Если ваза уже заполнена (и всегда заполнена, если вы считаете ее «наполненной воздухом»), вход заменит элемент в верхней части вазы.

Вот набор разрешенных вещей:

  • Воздуха 0 /
  • Скала 1 / -
  • Лист 2 / ~
  • Бомба 3 / x

Если на «Бомбе» есть камень или лист, он взорвется и уничтожит вещь на вершине.

Входными данными является список вещей, которые вы будете помещать в вазу каждый ход.

Пример: 11231: Вы положите 2 камня, затем лист, затем бомбу и, наконец, последний камень.

Когда ваза статична, вы можете начать отсчет со следующим правилом:

  • Рок добавляет 1 единицу к аккумулятору
  • Лист умножает аккумулятор на 2
  • Бомба уменьшит аккумулятор на 1
  • Воздух ничего не делает

(Нужно начинать отсчет с вершины вазы)

Вот симуляция, которую мы получаем, используя «11231» в качестве входных данных:

|-|  |-|  |~|  |x|  |-|  | |  | |  | |  | |  | |  | |
| |  |-|  |-|  |~|  |x|  |-|  | |  | |  | |  | |  | |
| |  | |  |-|  |-|  |~|  |x|  |-|  | |  | |  | |  | |
| |  | |  | |  |-|  |-|  |~|  |x|  |-|  | |  | |  | |
| |  | |  | |  | |  |-|  |-|  |~|  |x|  |-|  | |  | |
| |  | |  | |  | |  | |  |-|  |-|  |~|  |x|  |-|  | |
| |  | |  | |  | |  | |  | |  |-|  |-|  |~|  |x|  | |
| |  | |  | |  | |  | |  | |  | |  |-|  |-|  |~|  |~|
| |  | |  | |  | |  | |  | |  | |  | |  |-|  |-|  |-|
| |  | |  | |  | |  | |  | |  | |  | |  | |  |-|  |-|

И на выходе будет 2 (рассчитывается как ((0 x 2) + 1) + 1) Не нужно печатать все состояния вазы!

Базовая программа (Python3)

Вы можете выполнить это, чтобы понять, как это работает.

def printVase(vase):
  for i in vase:
    if i == 1:
      print("|-|")
    elif i == 2:
      print("|~|")
    elif i == 3:
      print("|x|")
    else:
      print("| |")

def updateVase(vase):
  changed = False
  for i in range(len(vase), -1, -1):
    if i < len(vase) - 1:
      if vase[i+1] == 3 and vase[i] in [1,2]:
        vase[i], vase[i+1] = 0, 0
        changed = True
      if not vase[i+1] and vase[i] in [1, 2, 3]:
        vase[i], vase[i+1] = vase[i+1], vase[i]
        changed = True
  return changed

userInput = input("Vase : ")
vase = [0 for i in range(0, 10)]
oldVase = vase
while updateVase(vase) or userInput != "":
  if userInput != "":
    vase[0] = int(userInput[0])
  userInput = userInput[1::]
  printVase(vase)
  input()

accumulator = 0
for i in vase:
  if i == 1:
    accumulator += 1
  if i == 2:
    accumulator *= 2
  if i == 3:
    accumulator -= 1
print(accumulator)

Гольф-версия (Python3, без вазы): 360 байт = 360 баллов

def u(v):
  c=0
  for i in range(len(v),-1,-1):
    if i<len(v)-1:
      if v[i+1]==3 and v[i]in[1,2]:v[i],v[i+1],c=0,0,1
      if not v[i+1]and v[i]in[1,2,3]:v[i],v[i+1],c=v[i+1],v[i],1
  return c
l,v=input(),[0 for i in range(0, 10)]
while u(v)or l!="":
  if l!="":v[0],l=int(l[0]),l[1::]
a=0
for i in v:
  if i==1:a+=1
  if i==2:a*=2
  if i==3:a-=1
print(a)

Если вы хотите проверить, правильно ли работает ваша программа, вы можете проверить этот ввод: 12122111131

Правильный ответ 43 :) (Спасибо, Эминья)

Теперь по пунктам:

  • (x) точки, где: x - количество байтов, необходимое для написания вашей программы. Если вы ответите после публикации следующего задания, баллы за это задание не будут добавлены к вашему общему количеству баллов.

Цель состоит в том, чтобы сохранить минимальное количество баллов в течение всего испытания :) Если вы пропустите одну из частей испытания, у вас будет (wx + 1) баллов по умолчанию для пропущенной части (где wx - худший результат) для этого вызова).

Данные, которые потребуются для следующей задачи:

Выход при вводе = 10100000200310310113030200221013111213110130332101

Действующий чемпион: Эминья

Всем удачи !

Sygmei
источник
2
Что с "может содержать ровно 10 вещей"? Считается ли «воздух» как вещь? Гарантируется, что входные данные будут такими, что ваза будет содержать только 10 вещей (я не вижу, чтобы это учитывалось в эталонной реализации)? Кроме того, кажется, что вход, который производит данные для следующего испытания, содержит более 10 вещей (даже если воздух не похож на ничто и бомбы взрывают следующую вещь на воздухе, я думаю, что будет 14 вещей).
Джонатан Аллан
1
Входные данные создают 333вазу [0, 0, 0, 0, 0, 0, 0, 3, 3, 3]в вашем алгоритме игры в гольф и, следовательно, оценку -3, но не должна ли она быть, [0, 0, 0, 0, 0, 0, 0, 0, 0, 3]а затем оценка -1согласно вашей спецификации?
Laikoni
2
@Laikoni Я забыл указать, что бомбы не взрываются, когда бомба находится над другой, спасибо!
Сигмей,
1
Выход для 10100000200310310113030200221013111213110130332101, кажется, 22, верно?
Эрик Outgolfer
2
Добавление сложного контрольного примера, такого как 12122111131, может быть хорошей идеей.
Emigna

Ответы:

5

Python 2 - 208 191 185 180 172 164 156 байт

t=filter(bool,map(int,input()))
i=a=0
n=len(t)
while 0<n-1>i<11:
 if(t[i]>=3>t[i+1]):del t[i:i+2];i,n=0,n-2
 i+=1
for x in t[9::-1]:a+=a+x%2*(2-x-a)
print a

Сбой в том, что он удаляет воздух и бомбы, если он находится в стеке, а затем считается.

РЕДАКТИРОВАТЬ: я перешел на Python 2, чтобы сохранить байт, но теперь ввод должен быть заключен в фигурные скобки, как «3312123»

EDIT2: я также горжусь счетчиком аккумуляторов

РЕДАКТИРОВАТЬ 3: Спасибо за все ваши предложения, я никогда бы не подумал, что я мог бы получить это так низко

Пэрис Дуади
источник
Хороший первый ответ! Я тоже думал с Python, но сегодня мне не хватало времени. Думаю, ты бы все равно побил мой подход.
ElPedro
Спасибо за добрый комментарий :) В первый раз я занимаюсь гольф-кодом, и должен сказать, что это довольно весело.
Пэрис Дуади,
Используйте t[:10][::-1]вместо того, reverse()чтобы сохранить 4 байта, а также, возможно, используйте Python 2, чтобы сохранить скобку на print? Приходит еще 5 душ, спасенных для меня :)
ElPedro
Нет Python2 для меня, так как я должен был бы вызвать input (), чтобы str работал, убивая еще 5 душ. Хороший улов на [:: - 1]
Pâris Douady
Кстати, я не видел ничего в вопросе, который говорит, что ввод может быть заключен в кавычки. Просто говорит «Вход - это список вещей». Работает в Python 2 :)
ElPedro
4

05AB1E , 28 36 байт

05AB1E использует кодировку CP-1252 .

Î0KDvT¹g‚£`sTØõ:žwõ:ì}ÁT£ÀRS"<>·"è.V

Попробуйте онлайн!

Emigna
источник
1
Впечатляет, как всегда: D Это будет трудно победить
Sygmei
2
T£ÀRS ->Слезы, ->я плачу хорошо ...
Steenbergh
3

Python 2, 150 146 байт

v=[]
s=0
for c in input():
 v=v[:9]
 if'0'==c:1
 elif 3 in v[-1:]and c in'21':v=v[:-1]
 else:v+=[int(c)]
for x in v[::-1]:s+=s+x%2*(2-x-s)
print s

Спасибо Pâris Douady за формулу очков и за сохранение 4 байтов.

TFeld
источник
Вы взяли мою формулу для подсчета очков? В любом случае, хорошее решение, ты побил меня, и это намного чище. Также вы можете сэкономить несколько байтов, выполнив for c in input()прямое действие
Pâris Douady
2

Javascript, 267 264 249 душ пожертвовано

r='replace'
f=t=>{t=t[r](/0/g,'');while(/3[12]/.test(t.substring(0,10)))t=t[r](/3[12]/,'');
a=t.length-1;x=(t.substring(0,9)+(a>8?t[a]:'')).split('').reverse().join('');
c='c=0'+x[r](/1/g,'+1')[r](/2/g,';c*=2;c=c')[r](/3/g,'-1');eval(c);return c}

Отредактированная версия, потому что предыдущая была неправильной для больших входов. Гольф это немного дальше, сделав string.prototype.replace()вызов функции доступа к массиву. Объяснение:

f=t=>{                                  Function declaration, input t
t=t.replace(/0/g,'');                   Remove air
while(/3[12]/.test(t.substring(0,10)))  Look for bombs; not double bombs, and only in the first 10 chars
    t=t.replace(/3[12]/,'');            Detonate bombs. If this makes a new bomb fall into the vase, or
                                        a double bomb is now a single bomb, it'll detonate that bomb too.
x=(t.substring(0,9)+                    Fill the vase, take the first 9 items
    (t.length>9?t[t.length-1]:''))      If we have more than 9 items, then add the last one
    .split('').reverse().join('');      Flip the instruction string.
c='c=0'+x.replace(/1/g,'+1')            Replace each item with the proper instruction to the ACC
         .replace(/2/g,';c*=2;c=c')
         .replace(/3/g,'-1');
eval(c);return c}                       Eval to get the value of ACC and return it.

f('11231');возвращается 2. Попробуйте онлайн

steenbergh
источник
10100000200310310113030200221013111213110130332101 не возвращает хороший результат :) Вы близко, хотя :)
Sygmei
@Sygmei Я знаю, и я отлаживал это дерьмо, но не могу понять почему. Вы видите меня в чате?
Стинберг
1

Haskell, 221 202 181 177 166 душ байтов

g(0:r)=r++[0]
g(3:x:r)|0<x,x<3=0:0:g r|1<3=3:g(x:r)
g(x:r)=x:g r
g r=r
v%(x:r)=g(init v++[x])%r
v%[]|v==g v=foldr([id,(+)1,(*)2,(-)1]!!)0v|1<3=g v%[]
(([0..9]>>[0])%)

Попробуйте это на Ideone . Принимает элементы в виде целого списка.

Использование:

*Prelude> (([0..9]>>[0])%) [1,2,1,2,2,1,1,1,1,3,1]
43

(Изменить: Старый) Объяснение:

g [] = []                             -- g simulates gravity in the vase
g ('0':r) = r ++ "0"                  -- the first 0 from the bottom is removed
g ('3':x:r) | elem x "12" = "00"++g r -- if a 1 or 2 is on a bomb, explode 
            | True = '3' : g(x:r)     -- else continue
g (x:r) = x : g r                     -- no air and no bomb, so check next item

c x = [id,(+)1,(*)2,(-)1]!!(read[x])  -- map 0, 1, 2, 3 to their score functions

f v w (x:r) =                         -- v is the current vase state, w the previous one
               init v++[x]            -- replace last vase element with input
             g(init v++[x])           -- simulate one gravity step
           f(g(init v++[x]))v r       -- repeat, w becomes v
f v w[] | v==w =                      -- if the input is empty and vase reached a fixpoint
                 foldr c 0 v          -- then compute score 
        | True = f (g v) v []         -- else simulate another gravity step


vase input = f "0000000000" "" input  -- call f with empty vase, previous vase state and
                                      -- the input as string of numbers
Laikoni
источник
Молодец :) ! Какие последние три "?
Sygmei
@Sygmei это две строки f "0000000000" "", между ними просто не должно быть пробелов. Я добавил объяснение к коду.
Лайкони
Хорошо,