高尔夫球手历险记-第1章:花瓶


13

高尔夫冒险

这是第一个挑战!以后会有更多挑战,需要上一个挑战的数据:)

第一章:花瓶

让我们想象一下。.您是一位强大的上帝,您的力量是无限的,但需要一件事情:灵魂。每个灵魂在这里都用一个字节表示,您使用的每个字节确实会牺牲一个灵魂。因此,目标显然是拯救最多的人,同时牺牲最少的灵魂。

您的第一个挑战是拯救一个小村庄,如果您解决了他的挑战,魔鬼愿意不破坏整个村庄。

挑战:

您有一个垂直花瓶,可以容纳10个东西(包括空气)。如果在花瓶里放东西,重力会使那东西掉到底部。如果花瓶已经装满了(如果您认为它“充满了空气”,则它总是装满的),输入将替换花瓶顶部的元素。

这是一组允许的东西:

  • 空气 0 /
  • 一块岩石 1 / -
  • 一片树叶 2 / ~
  • 一颗炸弹 3 / x

如果“炸弹”上有一块岩石或一片叶子,它会爆炸并摧毁上面的东西。

输入的内容是您每转将要放入花瓶中的物品的列表。

示例: 11231:您将放置2块岩石,然后是一片叶子,然后是炸弹,最后是最后一块岩石。

当花瓶静止时,您可以按照以下规则开始计数:

  • Rock向累加器增加1个单位
  • Leaf将累加器乘以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 :)(感谢Emigna)

现在要点:

  • (x)点,其中:x是编写程序所需的字节数。如果您在发布下一个挑战后回答,则此挑战的积分不会添加到您的总积分中。

目标是在整个挑战过程中保持最少的分数:)如果您跳过挑战的其中一部分,则默认情况下,您跳过的部分将获得(wx + 1)分(其中wx是最差的分数)应对挑战)。

下一个挑战所需的数据:

输入= 10100000200310310113030200221013111213110130332101时的输出

现任冠军:艾米娜

祝大家好运 !


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 '16

2
@Laikoni我忘记指定炸弹在另一枚炸弹之上时炸弹不会爆炸的原因,谢谢!
Sygmei

1
10100000200310310113030200221013111213110130332101的输出似乎是22,对吗?
暴民埃里克

2
添加一个棘手的测试用例(例如12122111131)可能是一个好主意。
Emigna '16

Answers:


5

Python 2- 208 191185180172164 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:我也为累加器计数感到骄傲

EDIT3:感谢您的所有建议,我永远都不会想到我可以将其降低到如此之低


不错的第一答案!我也在考虑使用Python,但是今天时间很短。认为您还是会击败我的方法。
ElPedro '16

感谢您的客气评论:)第一次我做代码高尔夫,我必须说这很有趣。
佩里斯·杜阿迪

使用t[:10][::-1]而不是reverse()保存4个字节,也可以使用Python 2在print?上保存一个括号。来为我节省了5个灵魂:)
ElPedro

我没有Python2,因为我必须将input()强制转换为str才能正常工作,从而杀死5个以上的灵魂。在[ - 1 ::]尼斯追赶
巴黎道阿地

顺便说一句,我没有在问题中看到任何内容表明输入可以用引号引起来。只需说“输入就是事物列表”。可在Python 2中工作:)
ElPedro



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ârisDouady提供积分公式,并节省了4个字节。


您是否采用了我的公式来计算该点?无论哪种方式,不错的解决方案,您都击败了我,而且干净得多。你也可以这样做节省一些字节for c in input()直接
巴黎道阿地

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在线尝试


10100000200310310113030200221013111213110130332101没有返回好的结果:)尽管您很接近:)
Sygmei

@Sygmei我知道,我一直在调试它的废话,但是我找不到原因。你可以在聊天中看到我吗?
steenbergh

1

哈斯克尔,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

做得好 :) !最后三个是什么?
Sygmei

@Sygmei这是两个字符串f "0000000000" "",您之间不需要任何空格。我在代码中添加了解释。
Laikoni '16

不错,现在更容易理解了:)
Sygmei
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.