골퍼 어드벤처-1 화


13

골퍼 모험

이것이 첫 번째 도전입니다! 나중에 이전 도전의 데이터를 요구하는 더 많은 도전이있을 것입니다 :)

제 1 장 : 꽃병

잠깐 상상해 봅시다. 당신은 강력한 신이며, 당신의 능력은 무한하지만 한 가지가 필요합니다 : 영혼. 각 영혼은 여기에서 바이트로 표현되며, 사용하는 각 바이트는 영혼을 희생시킵니다. 따라서 목표는 분명히 가장 적은 수의 영혼을 희생하면서 많은 수의 사람들을 구하는 것입니다.

첫 번째 도전은 작은 마을을 구하는 것이며, 악마는 당신이 그의 도전을 해결하면 마을 전체를 파괴하지 않을 것입니다.

도전 과제 :

정확히 10 가지 (공기 포함)를 포함 할 수있는 수직 꽃병이 있습니다. 꽃병에 물건을 넣으면 중력이 그 물건을 바닥에 떨어 뜨립니다. 꽃병이 이미 가득 찬 경우 (그리고 "공기 가득한"것으로 간주하면 항상 가득 찬 경우) 입력이 꽃병 상단의 요소를 대체합니다.

다음은 허용되는 것들입니다.

  • 공기 0 /
  • 바위 1 / -
  • 2 / ~
  • 폭탄 3 / x

"폭탄"위에 바위 나 잎이 있으면 그 위에있는 것이 폭발하여 파괴됩니다.

입력은 매번 꽃병에 넣을 물건의 목록입니다.

예 : 11231 : 바위 2 개, 잎, 폭탄, 마지막 바위를 넣습니다.

꽃병이 정적이면 다음 규칙으로 계산을 시작할 수 있습니다.

  • Rock은 어큐뮬레이터에 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입니다 :) (Emigna 감사합니다)

이제 포인트 :

  • (x) 포인트 : x는 프로그램을 작성하는 데 필요한 바이트 수입니다. 다음 챌린지가 게시 된 후에 대답하면이 챌린지에 대한 포인트가 총 포인트에 추가되지 않습니다.

목표는 전체 챌린지 중에 최소 점수를 유지하는 것입니다. 그 도전을 위해).

다음 도전에 필요한 데이터 :

입력시 출력 = 10100000200310310113030200221013111213110130332101

현재 챔피언 : Emigna

모두 행운을 빌어 요 !


2
"정확하게 10 가지를 포함 할 수있다"는 무엇입니까? "공기"가 하나의 것으로 간주됩니까? 꽃병에 10 가지만 포함되도록 입력이 보장됩니까 (참조 구현에서 제공되지는 않음)? 또한 다음 도전에 대한 데이터를 생성하는 입력에는 10 가지 이상의 것이있는 것 같습니다 (공기가 아무것도 같지 않고 폭탄이 다음 맨 위로 날려 버리더라도 14 가지가 있다고 생각합니다).
Jonathan Allan

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 폭탄이 다른 폭탄 위에있을 때 폭탄이 폭발하지 않도록 지정하는 것을 잊었습니다. 감사합니다!
Sygmei

1
10100000200310310113030200221013111213110130332101의 출력은 22로 보입니다.
Outgolfer Erik

2
12122111131 과 같은 까다로운 테스트 사례를 추가하는 것이 좋습니다.
Emigna

답변:


5

파이썬 2- 208 19185180172164 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 : 모든 제안에 감사드립니다. 저는 그것을 너무 낮게 생각할 수 없었습니다.


좋은 첫 답변! 나는 오늘 파이썬으로도 생각했지만 시간이 짧았습니다. 어쨌든 내 접근 방식을 이길 것이라고 생각하십시오.
ElPedro

친절한 의견 주셔서 감사합니다 :) 처음으로 코드 골프를하고 있는데 꽤 재미 있다고 말해야합니다.
Pâris Douady

사용하십시오 t[:10][::-1]대신 reverse()아마에 브래킷을 저장하는 파이썬 2를 사용 또한 4 바이트를 저장하고 print? :) 나를 위해 저장된 5 개 영혼에 온다
ElPedro

input ()을 캐스팅하여 작동 시키려면 5 개의 영혼을 더 죽여야하기 때문에 Python2는 없습니다. [::-1]에서 좋은 캐치
Pâris Douady

btw, 나는 질문에 입력을 따옴표로 묶을 수 있다고 말하는 것을 보지 못했습니다. "입력은 사물의 목록입니다"라고 말합니다. Python 2에서 작동 :)
ElPedro



3

파이썬 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

포인트 공식 및 4 바이트 절약을위한 Pâris Douady에게 감사합니다.


포인트 계산에 대한 공식을 취했습니까? 어느 쪽이든 좋은 해결책이라면, 당신은 나를 이겼고 훨씬 더 깨끗합니다. 또한 for c in input()직접 수행하여 약간의 바이트를 절약 할 수 있습니다
Pâris Douady

2

자바 스크립트, 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

(편집 : Old) 설명 :

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

니스, 쉽게는 : 이제 이해
Sygmei
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.