The Golfer Adventure - Bab 1: Vas

13

Petualangan Golfer

Ini tantangan pertama! Akan ada lebih banyak tantangan nanti yang akan membutuhkan data dari tantangan sebelumnya :)

Bab 1: Vas

Mari kita bayangkan sebentar .. Anda adalah Dewa yang kuat, kekuatan Anda tidak terbatas tetapi membutuhkan satu hal: Jiwa. Setiap jiwa di sini diwakili oleh satu byte, setiap byte yang Anda gunakan tidak mengorbankan jiwa. Jadi tujuannya jelas untuk menyelamatkan jumlah terbesar orang sambil mengorbankan jumlah jiwa paling sedikit.

Tantangan pertama Anda adalah menyelamatkan sebuah desa kecil, iblis tidak mau menghancurkan seluruh desa jika Anda menyelesaikan tantangannya.

Tantangan :

Anda memiliki vas vertikal yang dapat berisi tepat 10 hal (termasuk udara). Jika Anda memasukkan sesuatu ke dalam vas itu, gravitasi akan membuat benda itu jatuh ke dasar. Jika vas sudah penuh (dan selalu penuh jika Anda menganggapnya "penuh udara"), input akan menggantikan elemen di bagian atas vas.

Ini adalah seperangkat hal yang diizinkan:

  • Udara 0 /
  • Sebuah batu 1 / -
  • Daun 2 / ~
  • Sebuah bom 3 / x

Jika ada batu atau daun di atas "Bom", itu akan meledak dan menghancurkan benda di atasnya.

Input adalah daftar hal-hal yang akan Anda masukkan ke dalam vas setiap belokan.

Contoh: 11231: Anda akan meletakkan 2 batu, lalu daun, lalu bom dan akhirnya batu terakhir.

Saat vasnya statis, Anda bisa mulai menghitung dengan aturan berikut:

  • Rock menambahkan 1 unit ke akumulator
  • Leaf mengalikan akumulator dengan 2
  • Bom mengurangi akumulator dengan 1
  • Udara tidak melakukan apa-apa

(Anda harus mulai menghitung dari atas vas)

Berikut ini simulasi yang kami dapat menggunakan "11231" sebagai input:

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

Dan hasilnya akan 2 (dihitung sebagai ((0 x 2) + 1) + 1) Tidak perlu mencetak semua status vas!

Program dasar (Python3)

Anda dapat menjalankannya untuk memahami cara kerjanya.

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)

Versi golf (Python3, tanpa Layar Vas): 360 byte = 360 poin

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)

Jika Anda ingin menguji apakah program Anda berfungsi dengan benar, Anda dapat menguji input ini: 12122111131

Jawaban yang benar adalah 43 :) (Terima kasih Emigna)

Sekarang untuk poin:

  • (x) menunjukkan di mana: x adalah jumlah byte yang diperlukan untuk menulis program Anda. Jika Anda menjawab setelah tantangan berikutnya diposting, poin untuk tantangan ini tidak akan ditambahkan ke jumlah total poin Anda.

Tujuannya adalah untuk menjaga jumlah minimum poin selama seluruh tantangan :) Jika Anda melewatkan salah satu bagian dari tantangan, Anda akan memiliki (wx + 1) poin secara default untuk bagian yang dilewati (di mana wx adalah skor terburuk untuk tantangan itu).

Data yang akan dibutuhkan untuk tantangan berikutnya:

Output saat input = 10100000200310310113030200221013111213110130332101

Juara Saat Ini: Emigna

Semoga beruntung semuanya !

Sygmei
sumber
2
Ada apa dengan "dapat berisi persis 10 hal"? Apakah "Air" dianggap sebagai sesuatu? Apakah input dijamin sedemikian rupa sehingga vas hanya akan berisi 10 hal (saya tidak melihatnya dipenuhi dalam implementasi referensi)? Juga input yang menghasilkan data untuk tantangan selanjutnya tampaknya memiliki lebih dari 10 hal (bahkan jika udara tidak seperti apa-apa dan bom meledakkan hal berikutnya di atas udara akan ada 14 hal, saya pikir).
Jonathan Allan
1
Input 333membuat vas [0, 0, 0, 0, 0, 0, 0, 3, 3, 3]dalam algoritme golf Anda dan karenanya skor -3, tetapi bukankah seharusnya demikian [0, 0, 0, 0, 0, 0, 0, 0, 0, 3]dan kemudian skor -1sesuai dengan spesifikasi Anda?
Laikoni
2
@Laikoni Saya lupa menentukan bahwa bom tidak meledak ketika bom ada di atas bom lainnya, terima kasih!
Sygmei
1
Output untuk 10100000200310310113030200221013111213110130332101 tampaknya 22, kan?
Erik the Outgolfer
2
Menambahkan test case yang rumit seperti 12122111131 mungkin ide yang bagus.
Emigna

Jawaban:

5

Python 2 - 208 191 185 180 172 172 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

Kerusakan itu menghilangkan udara dan bom jika ada di tumpukan kemudian dihitung.

EDIT: Saya bertukar ke Python 2 untuk menyimpan byte, tetapi sekarang input harus dimasukkan ke dalam kawat gigi seperti '3312123

EDIT2: Saya juga agak bangga dengan jumlah akumulator

EDIT3: Terima kasih atas semua saran Anda, saya tidak akan pernah berpikir saya bisa mendapatkannya begitu rendah

Pâris Douady
sumber
Jawaban pertama yang bagus! Saya juga berpikir dengan Python tetapi kekurangan waktu hari ini. Kupikir kau akan mengalahkan pendekatanku.
ElPedro
Terima kasih atas komentar baiknya :) Pertama kali saya melakukan kode golf dan saya harus mengatakan itu cukup menyenangkan.
Pâris Douady
Gunakan t[:10][::-1]alih-alih reverse()untuk menyimpan 4 byte dan juga mungkin menggunakan Python 2 untuk menyimpan braket pada print? Datang ke 5 lebih banyak jiwa yang diselamatkan untuk saya :)
ElPedro
Tidak ada Python2 untuk saya karena saya harus memberikan input () untuk str agar bisa bekerja, membunuh 5 jiwa lagi.
Hasil
btw, saya tidak melihat apa pun dalam pertanyaan yang mengatakan bahwa input dapat 'dibungkus dengan tanda kutip. Hanya mengatakan "Input adalah daftar hal". Bekerja di Python 2 :)
ElPedro
4

05AB1E , 28 36 byte

05AB1E menggunakan pengkodean CP-1252 .

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

Cobalah online!

Emigna
sumber
1
Mengesankan seperti biasa: D Akan sulit untuk mengalahkan itu
Sygmei
2
T£ÀRS ->Air mata ->saya menangis baik-baik saja ...
steenbergh
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

Terima kasih kepada Pâris Douady untuk rumus poin, dan untuk menghemat 4 byte.

TFeld
sumber
Apakah Anda mengambil formula saya untuk menghitung poin? Apapun solusi yang baik, Anda mengalahkan saya dan itu jauh lebih bersih. Anda juga dapat menyimpan beberapa byte dengan melakukan for c in input()langsung
Pâris Douady
2

Javascript, 267 264 249 jiwa dikorbankan

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}

Versi yang diedit, karena yang sebelumnya salah untuk input yang lebih besar. Golf sedikit lebih jauh dengan membuat string.prototype.replace()panggilan fungsi array-diakses. Penjelasan:

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');kembali 2. Cobalah online

steenbergh
sumber
10100000200310310113030200221013111213110130332101 tidak mengembalikan hasil yang baik :) Anda sudah dekat :)
Sygmei
@Sygmei saya tahu, dan saya telah men-debug omong kosong itu, tapi saya tidak tahu mengapa. Bisakah Anda melihat saya dalam obrolan?
steenbergh
1

Haskell, 221 202 181 177 166 byte jiwa

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

Cobalah di ideone . Mengambil item sebagai daftar integer.

Pemakaian:

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

(Sunting: Lama) Penjelasan:

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
Laikoni
sumber
Kerja bagus :) ! Apa tiga yang terakhir "?
Sygmei
@Sygmei itu dua string f "0000000000" "", Anda tidak perlu spasi di antara mereka. Saya menambahkan penjelasan ke kode.
Laikoni
Bagus, lebih mudah dimengerti sekarang :)
Sygmei