13
\$\begingroup\$

The Golfer Adventure

This is the first challenge ! There will be more challenges later that will require data from the previous challenge :)

Chapter 1 : The Vase

Let's imagine a minute.. You are a powerful God, your powers are limitless but require one thing : Souls. Each soul is here represented by a byte, each byte you use does sacrifice a soul. So the goal is obviously to save the biggest amount of people while sacrificing the least amount of souls.

Your first challenge is to save a little village, the devil is willing not to destroy the entire village if you resolve his challenge.

The Challenge :

You have a vertical vase which can contain exactly 10 things (Air included). If you put a thing in that vase, gravity will make that thing fall to the bottom. If the vase is already full (and it's always full if you consider it as "full of air"), the input will replace the element at the top of the vase.

Here is the set of allowed things :

  • Air 0 /
  • A Rock 1 / -
  • A Leaf 2 / ~
  • A Bomb 3 / x

If there is a rock or a leaf on top of "A Bomb", it will explode and destroy the thing on the top of it.

The input is the list of the things you'll put in the vase every turn.

Example : 11231 : You'll put 2 rocks, then a leaf, then a bomb and finally a last rock.

When the vase is static, you can begin to count with the following rule :

  • Rock adds 1 unit to the accumulator
  • Leaf multiplies the accumulator by 2
  • Bomb decrement the accumulator by 1
  • Air does nothing

(You need to start counting from the top of the vase)

Here is the simulation we get using "11231" as input :

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

And the output will be 2 (calculated as ((0 x 2) + 1) + 1) No need to print all the states of the vase !

The base program (Python3)

You can execute it to understand how it works.

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)

Golfed version (Python3, no Vase Display) : 360 bytes = 360 points

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)

If you want to test if your program works correctly, you can test this input : 12122111131

Correct answer is 43 :) (Thanks Emigna)

Now for the points :

  • (x) points where : x is the amount of bytes needed to write your program. If you answer after the next challenge is posted, points for this challenge won't be added to your total amount of points.

The goal is to keep a minimum amount of points during the whole challenge :) If you skip one of the part of the challenge, you'll have (wx + 1) points by default for the skipped part (where wx is the worst score for that challenge).

Data that will be required for the next challenge :

Output when input = 10100000200310310113030200221013111213110130332101

Current Champion : Emigna

Good luck everyone !

\$\endgroup\$
  • 2
    \$\begingroup\$ What's with the "can contain exactly 10 things"? Does "Air" count as a thing? Is input guaranteed to be such that the vase will only contain 10 things (I don't see it catered for in the reference implementation)? Also the input that produces the data for next challenge seems to have more than 10 things (even if air is like nothing and bombs blow up the next thing on top of the air there will be 14 things, I think). \$\endgroup\$ – Jonathan Allan Nov 24 '16 at 16:03
  • 1
    \$\begingroup\$ An input 333 constructs a vase [0, 0, 0, 0, 0, 0, 0, 3, 3, 3] in your golfed algorithm and hence a score of -3, but shouldn't it be [0, 0, 0, 0, 0, 0, 0, 0, 0, 3] and then a score of -1 according to your specification? \$\endgroup\$ – Laikoni Nov 24 '16 at 16:06
  • 2
    \$\begingroup\$ @Laikoni I forgot to specify that bombs doesn't explode when a bomb is on top of another one, thanks ! \$\endgroup\$ – Sygmei Nov 24 '16 at 16:16
  • 1
    \$\begingroup\$ Output for 10100000200310310113030200221013111213110130332101 seems to be 22, right? \$\endgroup\$ – Erik the Outgolfer Nov 24 '16 at 18:36
  • 2
    \$\begingroup\$ Adding a tricky test-case like 12122111131 might be a good idea. \$\endgroup\$ – Emigna Nov 24 '16 at 22:52
5
\$\begingroup\$

Python 2 - 208 191 185 180 172 164 156 bytes

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

The breakdown is it removes air and the bombs if it is on the stack then counts.

EDIT : I swapped to Python 2 to save a byte, but now the input should be put in braces like '3312123'

EDIT2 : Im also kinda proud of the accumulator count

EDIT3 : Thanks for all your suggestions I would never have thought I could get it so low

\$\endgroup\$
  • \$\begingroup\$ Nice first answer! I was thinking with Python as well but short of time today. Think you would have beaten my approach anyway. \$\endgroup\$ – ElPedro Nov 24 '16 at 21:50
  • \$\begingroup\$ Thanks for the kind comment :) First time I'm doing a code golf and I've got to say it's quite fun. \$\endgroup\$ – Pâris Douady Nov 24 '16 at 21:59
  • \$\begingroup\$ Use t[:10][::-1] instead of reverse() to save 4 bytes and also maybe use Python 2 to save a bracket on the print? Comes to 5 more souls saved for me :) \$\endgroup\$ – ElPedro Nov 24 '16 at 22:03
  • \$\begingroup\$ No Python2 for me since I would have to cast input() to str for it to work, killing 5 more souls. Nice catch on the [::-1] \$\endgroup\$ – Pâris Douady Nov 24 '16 at 22:05
  • \$\begingroup\$ btw, I didn't see anything in the question that says the input can' be wrapped in quotes. Just says "The input is the list of the things". Works in Python 2 :) \$\endgroup\$ – ElPedro Nov 24 '16 at 22:12
4
\$\begingroup\$

05AB1E, 28 36 bytes

05AB1E uses CP-1252 encoding.

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

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ Impressive as always :D It'll be hard to beat that \$\endgroup\$ – Sygmei Nov 24 '16 at 22:40
  • 2
    \$\begingroup\$ T£ÀRS -> Tears -> I'm crying alright... \$\endgroup\$ – steenbergh Nov 25 '16 at 6:23
4
\$\begingroup\$

Retina, 58 56 bytes

1+`0|(?<=.{9}).\B|3[12]

+-1=`2
$'
+`13

*\(1`3
-
)T`d
.

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Python 2, 150 146 bytes

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

Thanks to Pâris Douady for the points formula, and for saving 4 bytes.

\$\endgroup\$
  • \$\begingroup\$ Did you took my formula for the counting of the point ? Either way nice solution, you beat me and it's much cleaner. also you can save some bytes with by doing for c in input() directly \$\endgroup\$ – Pâris Douady Nov 25 '16 at 16:13
2
\$\begingroup\$

Javascript, 267 264 249 souls sacrificed

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}

Edited version, because the previous one was incorrect for larger inputs. Golfed it a little further by making string.prototype.replace() into an array-accessed function call. Explanation:

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'); returns 2. Try it online

\$\endgroup\$
  • \$\begingroup\$ 10100000200310310113030200221013111213110130332101 doesn't return the good result :) You're close though :) \$\endgroup\$ – Sygmei Nov 24 '16 at 22:39
  • \$\begingroup\$ @Sygmei I know, and I've been debugging the crap out of it, but I can't find out why. Can you see me in chat? \$\endgroup\$ – steenbergh Nov 25 '16 at 6:56
1
\$\begingroup\$

Haskell, 221 202 181 177 166 souls bytes

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

Try it on ideone. Takes items as integer list.

Usage:

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

(Edit: Old) Explanation:

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
\$\endgroup\$
  • \$\begingroup\$ Good job :) ! What are the last three " ? \$\endgroup\$ – Sygmei Nov 25 '16 at 9:05
  • \$\begingroup\$ @Sygmei it's two strings f "0000000000" "", you just don't need any spaces between them. I added an explanation to the code. \$\endgroup\$ – Laikoni Nov 25 '16 at 10:01
  • \$\begingroup\$ Nice, easier to understand now :) \$\endgroup\$ – Sygmei Nov 25 '16 at 10:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.