ゴルファーの冒険-第1章:花瓶


13

ゴルファーの冒険

これが最初の挑戦です!以前のチャレンジからのデータを必要とするより多くのチャレンジが後であります:)

第1章:花瓶

ちょっと想像してみてください。あなたは強力な神であり、あなたの力は無限ですが、一つのことを必要としています:魂。ここでは、各魂はバイトで表されます。使用する各バイトは魂を犠牲にします。したがって、目標は明らかに、最小量の魂を犠牲にしながら、最大量の人々を救うことです。

あなたの最初の挑戦は小さな村を救うことです。悪魔は彼の挑戦を解決したら村全体を破壊しないことをいとわないでしょう。

チャレンジ :

ちょうど10個の物(空気を含む)を含むことができる垂直花瓶があります。その花瓶に物を入れると、重力がその物を底に落とします。花瓶がすでにいっぱいになっている場合(および「空気で満たされている」とみなすと常に花瓶がいっぱいになります)、花瓶の上部にある要素が入力に置き換えられます。

許可されているもののセットは次のとおりです。

  • 空気 0 /
  • 岩石 1 / -
  • 2 / ~
  • 爆弾 3 / x

「A Bomb」の上に岩や葉がある場合、それは爆発して、その上のものを破壊します。

入力は、毎回花瓶に入れるもののリストです。

例: 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です :)(エミグナに感謝)

次にポイントについて:

  • (x)ポイントここで、xはプログラムの作成に必要なバイト数です。次のチャレンジが投稿された後に回答すると、このチャレンジのポイントは合計ポイントに加算されません。

目標は、チャレンジ全体を通して最小限のポイントを維持することです:)チャレンジの一部の1つをスキップすると、スキップされた部分にデフォルトで(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になります、仕様応じ必要がありますか?
ライコニ

2
@Laikoni爆弾が別の爆弾の上にあるときに爆弾が爆発しないことを指定するのを忘れました、ありがとう!
シグメイ

1
10100000200310310113030200221013111213110130332101の出力は22のようです。
エリックアウトゴルファー

2
12122111131のようなトリッキーなテストケースを追加することをお勧めします。
エミグナ

回答:


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:Imは、アキュムレータの数も少し誇りに思っています

EDIT3:あなたのすべての提案に感謝します。


素敵な最初の答え!Pythonも考えていましたが、今日は短い時間でした。とにかく私のアプローチを破ったと思います。
エルペドロ

親切なコメントをありがとう:)初めてコードゴルフをするとき、それはとても楽しいと言わざるを得ません。
パリスDouady

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

ポイントの計算と4バイトの節約について、PârisDouadyに感謝します。


ポイントを数えるために私の式をとったのですか?いずれにせよ素晴らしい解決策、あなたは私を打ち負かし、それははるかにきれいです。また、for c in input()直接行うことでいくつかのバイトを節約することができます
パリス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オンラインで試す


10100000200310310113030200221013111213110130332101は良い結果を返しません:)近いです:)
Sygmei

@Sygmei私は知っています、そして私はそれからがらくたをデバッグしてきましたが、私はその理由を見つけることができません。チャットで私
-steenbergh

1

Haskell、221 202181177166 soulsバイト

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

イデオンで試してみてください。アイテムを整数リストとして受け取ります。

使用法:

*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

よくやった :) !最後の3つは何ですか?
シグメイ

@Sygmeiは2つの文字列f "0000000000" ""です。それらの間にスペースは必要ありません。コードに説明を追加しました。
ライコニ

わかりやすく、わかりやすくなりました:)
シグメイ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.