Cuộc phiêu lưu của Golfer - Chương 1: Chiếc bình


13

Cuộc phiêu lưu của Golfer

Đây là thử thách đầu tiên! Sẽ có nhiều thử thách sau này sẽ yêu cầu dữ liệu từ thử thách trước đó :)

Chương 1: Chiếc bình

Hãy tưởng tượng một phút .. Bạn là một vị thần mạnh mẽ, sức mạnh của bạn là vô hạn nhưng đòi hỏi một điều: Linh hồn. Mỗi linh hồn ở đây được đại diện bởi một byte, mỗi byte bạn sử dụng sẽ hy sinh một linh hồn. Vì vậy, mục tiêu rõ ràng là cứu được số lượng người lớn nhất trong khi hy sinh ít linh hồn nhất.

Thử thách đầu tiên của bạn là cứu một ngôi làng nhỏ, ma quỷ sẵn sàng không phá hủy toàn bộ ngôi làng nếu bạn giải quyết thử thách của mình.

Các thách thức :

Bạn có một bình hoa thẳng đứng có thể chứa chính xác 10 thứ (Bao gồm không khí). Nếu bạn đặt một vật trong chiếc bình đó, lực hấp dẫn sẽ khiến vật đó rơi xuống đáy. Nếu chiếc bình đã đầy (và nó luôn đầy nếu bạn coi nó là "đầy không khí"), đầu vào sẽ thay thế phần tử ở trên cùng của chiếc bình.

Đây là tập hợp những thứ được phép:

  • Không khí 0 /
  • Một hòn đá 1 / -
  • Một chiếc lá 2 / ~
  • Một quả bom 3 / x

Nếu có một hòn đá hoặc một chiếc lá trên đỉnh "Bom", nó sẽ phát nổ và phá hủy thứ trên đỉnh của nó.

Đầu vào là danh sách những thứ bạn sẽ đặt trong chiếc bình mỗi lượt.

Ví dụ: 11231: Bạn sẽ đặt 2 hòn đá, rồi một chiếc lá, rồi một quả bom và cuối cùng là hòn đá cuối cùng.

Khi bình tĩnh, bạn có thể bắt đầu đếm theo quy tắc sau:

  • Rock thêm 1 đơn vị vào bộ tích lũy
  • Lá nhân số nhân với 2
  • Bom giảm tích lũy bằng 1
  • Không khí không làm gì cả

(Bạn cần bắt đầu đếm từ đỉnh của chiếc bình)

Đây là mô phỏng chúng tôi nhận được bằng cách sử dụng "11231" làm đầu vào:

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

Và đầu ra sẽ là 2 (tính như ((0 x 2) + 1) + 1) Không cần in tất cả các trạng thái của chiếc bình!

Chương trình cơ sở (Python3)

Bạn có thể thực hiện nó để hiểu làm thế nào nó hoạt động.

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)

Phiên bản được chơi gôn (Python3, không hiển thị bình hoa): 360 byte = 360 điểm

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)

Nếu bạn muốn kiểm tra xem chương trình của bạn có hoạt động chính xác không, bạn có thể kiểm tra đầu vào này: 12122111131

Câu trả lời đúng là 43 :) (Cảm ơn Emigna)

Bây giờ cho các điểm:

  • (x) điểm trong đó: x là lượng byte cần thiết để viết chương trình của bạn. Nếu bạn trả lời sau khi thử thách tiếp theo được đăng, điểm cho thử thách này sẽ không được thêm vào tổng số điểm của bạn.

Mục tiêu là giữ một số điểm tối thiểu trong toàn bộ thử thách :) Nếu bạn bỏ qua một trong những phần của thử thách, bạn sẽ có (wx + 1) điểm theo mặc định cho phần bị bỏ qua (trong đó wx là điểm kém nhất cho thử thách đó).

Dữ liệu sẽ được yêu cầu cho thử thách tiếp theo:

Đầu ra khi đầu vào = 10100000200 310310113030200221013111213110130332101

Quán quân hiện tại: Emigna

Chúc mọi người may mắn !


2
Cái gì với "có thể chứa chính xác 10 thứ"? "Không khí" có được tính là một thứ không? Đầu vào có được đảm bảo sao cho chiếc bình sẽ chỉ chứa 10 thứ (tôi không thấy nó phục vụ cho việc thực hiện tham chiếu)? Ngoài ra, đầu vào tạo ra dữ liệu cho thử thách tiếp theo dường như có hơn 10 thứ (ngay cả khi không khí chẳng khác gì và bom nổ tung thứ tiếp theo trên không trung sẽ có 14 thứ, tôi nghĩ vậy).
Jonathan Allan

1
Một đầu vào 333xây dựng một chiếc bình [0, 0, 0, 0, 0, 0, 0, 3, 3, 3]trong thuật toán chơi gôn của bạn và do đó là một số điểm -3, nhưng không nên [0, 0, 0, 0, 0, 0, 0, 0, 0, 3]và sau đó là một điểm -1theo đặc điểm kỹ thuật của bạn?
Laikoni

2
@Laikoni Tôi quên xác định rằng bom không phát nổ khi một quả bom nằm trên một quả bom khác, cảm ơn!
Sygmei

1
Đầu ra cho 10100000200 310310113030200221013111213110130332101 dường như là 22, phải không?
Erik các Outgolfer

2
Thêm một trường hợp thử nghiệm khó khăn như 12122111131 có thể là một ý tưởng tốt.
Emigna

Câu trả lời:


5

Con trăn 2 - 208 191 185 180 172 164 156 byte

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

Sự cố là nó loại bỏ không khí và bom nếu nó nằm trên chồng rồi tính.

EDIT: Tôi đã trao đổi với Python 2 để lưu một byte, nhưng bây giờ đầu vào phải được đặt trong dấu ngoặc nhọn như '3312123'

EDIT2: Tôi cũng tự hào về số lượng tích lũy

EDIT3: Cảm ơn tất cả các đề xuất của bạn, tôi sẽ không bao giờ nghĩ rằng tôi có thể nhận được nó quá thấp


Câu trả lời đầu tiên tốt đẹp! Tôi đã suy nghĩ với Python là tốt nhưng thời gian ngắn ngày hôm nay. Hãy nghĩ rằng bạn sẽ đánh bại cách tiếp cận của tôi nào.
ElPedro

Cảm ơn vì nhận xét tốt bụng :) Lần đầu tiên tôi chơi golf mã và tôi phải nói rằng nó khá thú vị.
Pâris Douady

Sử dụng t[:10][::-1]thay vì reverse()để lưu 4 byte và cũng có thể sử dụng Python 2 để lưu dấu ngoặc trên print? Có thêm 5 linh hồn được cứu cho tôi :)
ElPedro

Không có Python2 cho tôi vì tôi sẽ phải sử dụng input () để str cho nó hoạt động, giết thêm 5 linh hồn. Bắt tuyệt vời trên [:: - 1]
Pâris Douady

btw, tôi không thấy bất cứ điều gì trong câu hỏi nói rằng đầu vào có thể được gói trong dấu ngoặc kép. Chỉ cần nói "Đầu vào là danh sách các thứ". Hoạt động trong Python 2 :)
ElPedro



3

Python 2, 150 146 byte

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

Cảm ơn Pâris Douady cho công thức tính điểm và để lưu 4 byte.


Bạn đã lấy công thức của tôi để đếm điểm? Dù bằng cách nào, giải pháp tốt đẹp, bạn đánh bại tôi và nó sạch sẽ hơn nhiều. ngoài ra, bạn có thể lưu một số byte bằng cách thực hiện for c in input()trực tiếp
Pâris Douady

2

Javascript, 267 264 249 linh hồn đã hy sinh

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}

Phiên bản đã chỉnh sửa, vì phiên bản trước không chính xác cho đầu vào lớn hơn. Đánh gôn thêm một chút bằng cách thực hiện string.prototype.replace()một cuộc gọi hàm truy cập mảng. Giải trình:

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');trả lại 2. Dùng thử trực tuyến


10100000200310310113030200221013111213110130332101 không trả lại kết quả tốt :) Mặc dù vậy bạn vẫn thân thiết :)
Sygmei

@Sygmei Tôi biết, và tôi đã gỡ lỗi cho nó, nhưng tôi không thể tìm hiểu tại sao. Bạn có thể thấy tôi trong trò chuyện?
steenbergh

1

Haskell, 221 202 181 177 166 byte linh hồn

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

Hãy thử nó trên ideone . Lấy các mục làm danh sách số nguyên.

Sử dụng:

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

(Chỉnh sửa: Cũ) Giải thích:

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

Làm tốt lắm :) ! Ba người cuối cùng là gì? "
Sygmei

@Sygmei đó là hai chuỗi f "0000000000" "", bạn không cần bất kỳ khoảng trống nào giữa chúng. Tôi đã thêm một lời giải thích cho mã.
Laikoni

Đẹp, dễ hiểu hơn bây giờ :)
Sygmei
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.